github.com/blevesearch/bleve/v2@v2.4.0/search/searcher/geoshape_intersects_test.go (about) 1 // Copyright (c) 2022 Couchbase, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package searcher 16 17 import ( 18 "reflect" 19 "testing" 20 21 "github.com/blevesearch/bleve/v2/index/scorch" 22 "github.com/blevesearch/bleve/v2/index/upsidedown/store/gtreap" 23 index "github.com/blevesearch/bleve_index_api" 24 ) 25 26 func setupIndex(t *testing.T) index.Index { 27 analysisQueue := index.NewAnalysisQueue(1) 28 i, err := scorch.NewScorch( 29 gtreap.Name, 30 map[string]interface{}{ 31 "path": "", 32 }, 33 analysisQueue) 34 if err != nil { 35 t.Fatal(err) 36 } 37 err = i.Open() 38 if err != nil { 39 t.Fatal(err) 40 } 41 42 return i 43 } 44 45 func TestPointIntersects(t *testing.T) { 46 tests := []struct { 47 QueryShape []float64 48 DocShapeVertices []float64 49 DocShapeName string 50 Desc string 51 Expected []string 52 }{ 53 { 54 QueryShape: []float64{2.0, 2.0}, 55 DocShapeVertices: []float64{2.0, 2.0}, 56 DocShapeName: "point1", 57 Desc: "coincident points", 58 Expected: []string{"point1"}, 59 }, 60 { 61 QueryShape: []float64{2.0, 2.0}, 62 DocShapeVertices: []float64{2.0, 2.1}, 63 DocShapeName: "point2", 64 Desc: "non coincident points", 65 Expected: nil, 66 }, 67 } 68 i := setupIndex(t) 69 70 for _, test := range tests { 71 indexReader, closeFn, err := testCaseSetup(t, test.DocShapeName, "point", 72 [][][][]float64{{{test.DocShapeVertices}}}, i) 73 if err != nil { 74 t.Errorf(err.Error()) 75 } 76 77 // indexing and searching independently for each case. 78 t.Run(test.Desc, func(t *testing.T) { 79 got, err := runGeoShapePointRelationQuery("intersects", 80 false, indexReader, [][]float64{test.QueryShape}, "geometry") 81 if err != nil { 82 t.Errorf(err.Error()) 83 } 84 if !reflect.DeepEqual(got, test.Expected) { 85 t.Errorf("expected %v, got %v for point: %+v", 86 test.Expected, got, test.QueryShape) 87 } 88 }) 89 90 err = closeFn() 91 if err != nil { 92 t.Errorf(err.Error()) 93 } 94 } 95 } 96 97 func TestPointMultiPointIntersects(t *testing.T) { 98 tests := []struct { 99 QueryShape []float64 100 DocShapeVertices [][]float64 101 DocShapeName string 102 Desc string 103 Expected []string 104 }{ 105 { 106 QueryShape: []float64{2.0, 2.0}, 107 DocShapeVertices: [][]float64{{2.0, 2.0}, {3.0, 2.0}}, 108 DocShapeName: "point1", 109 Desc: "point coincides with one point in multipoint", 110 Expected: []string{"point1"}, 111 }, 112 { 113 QueryShape: []float64{2.0, 2.0}, 114 DocShapeVertices: [][]float64{{2.0, 2.1}, {3.0, 3.1}}, 115 DocShapeName: "point2", 116 Desc: "non coincident points", 117 Expected: nil, 118 }, 119 } 120 i := setupIndex(t) 121 122 for _, test := range tests { 123 indexReader, closeFn, err := testCaseSetup(t, test.DocShapeName, "point", 124 [][][][]float64{{test.DocShapeVertices}}, i) 125 if err != nil { 126 t.Errorf(err.Error()) 127 } 128 129 // indexing and searching independently for each case. 130 t.Run(test.Desc, func(t *testing.T) { 131 got, err := runGeoShapePointRelationQuery("intersects", 132 false, indexReader, [][]float64{test.QueryShape}, "geometry") 133 if err != nil { 134 t.Errorf(err.Error()) 135 } 136 if !reflect.DeepEqual(got, test.Expected) { 137 t.Errorf("expected %v, got %v for point: %+v", 138 test.Expected, got, test.QueryShape) 139 } 140 }) 141 err = closeFn() 142 if err != nil { 143 t.Errorf(err.Error()) 144 } 145 } 146 } 147 148 func TestPointLinestringIntersects(t *testing.T) { 149 tests := []struct { 150 QueryShape []float64 151 DocShapeVertices [][]float64 152 DocShapeName string 153 Desc string 154 Expected []string 155 }{ 156 { 157 QueryShape: []float64{4.0, 4.0}, 158 DocShapeVertices: [][]float64{{2.0, 2.0}, {3.0, 3.0}, {4.0, 4.0}}, 159 DocShapeName: "linestring1", 160 Desc: "point at the vertex of linestring", 161 Expected: []string{"linestring1"}, 162 }, 163 { 164 QueryShape: []float64{1.5, 1.5001714}, 165 DocShapeVertices: [][]float64{{0.0, 0.0}, {1.0, 1.0}, {2.0, 2.0}, {3.0, 3.0}}, 166 DocShapeName: "linestring1", 167 Desc: "point along linestring", 168 Expected: nil, // nil since point is said to intersect only when it matches any 169 // of the endpoints of the linestring 170 }, 171 { 172 QueryShape: []float64{1.5, 1.6001714}, 173 DocShapeVertices: [][]float64{{0.0, 0.0}, {1.0, 1.0}, {2.0, 2.0}, {3.0, 3.0}}, 174 DocShapeName: "linestring1", 175 Desc: "point outside linestring", 176 Expected: nil, 177 }, 178 } 179 180 i := setupIndex(t) 181 182 for _, test := range tests { 183 indexReader, closeFn, err := testCaseSetup(t, test.DocShapeName, "linestring", 184 [][][][]float64{{test.DocShapeVertices}}, i) 185 if err != nil { 186 t.Errorf(err.Error()) 187 } 188 189 t.Run(test.Desc, func(t *testing.T) { 190 got, err := runGeoShapePointRelationQuery("intersects", 191 false, indexReader, [][]float64{test.QueryShape}, "geometry") 192 if err != nil { 193 t.Errorf(err.Error()) 194 } 195 if !reflect.DeepEqual(got, test.Expected) { 196 t.Errorf("expected %v, got %v for point: %+v", 197 test.Expected, got, test.QueryShape) 198 } 199 }) 200 201 err = closeFn() 202 if err != nil { 203 t.Errorf(err.Error()) 204 } 205 } 206 } 207 208 func TestPointMultiLinestringIntersects(t *testing.T) { 209 tests := []struct { 210 QueryShape []float64 211 DocShapeVertices [][][]float64 212 DocShapeName string 213 Desc string 214 Expected []string 215 }{ 216 { 217 QueryShape: []float64{3.0, 3.0}, 218 DocShapeVertices: [][][]float64{{{2.0, 2.0}, {3.0, 3.0}, {4.0, 4.0}}}, 219 DocShapeName: "linestring1", 220 Desc: "point at the vertex of linestring", 221 Expected: []string{"linestring1"}, 222 }, 223 { 224 QueryShape: []float64{1.5, 1.5001714}, 225 DocShapeVertices: [][][]float64{{{0.0, 0.0}, {1.0, 1.0}, {2.0, 2.0}, {3.0, 3.0}}}, 226 DocShapeName: "linestring1", 227 Desc: "point along a linestring", 228 Expected: nil, // nil since point is said to intersect only when it matches any 229 // of the endpoints of any of the linestrings 230 }, 231 { 232 QueryShape: []float64{1.5, 1.6001714}, 233 DocShapeVertices: [][][]float64{{{0.0, 0.0}, {1.0, 1.0}, {2.0, 2.0}, {3.0, 3.0}}, {{1, 1.1}, {2, 2.1}, {3, 3.4}}}, 234 DocShapeName: "linestring1", 235 Desc: "point outside all linestrings", 236 Expected: nil, 237 }, 238 } 239 240 i := setupIndex(t) 241 242 for _, test := range tests { 243 indexReader, closeFn, err := testCaseSetup(t, test.DocShapeName, "multilinestring", 244 [][][][]float64{test.DocShapeVertices}, i) 245 if err != nil { 246 t.Errorf(err.Error()) 247 } 248 249 t.Run(test.Desc, func(t *testing.T) { 250 got, err := runGeoShapePointRelationQuery("intersects", 251 false, indexReader, [][]float64{test.QueryShape}, "geometry") 252 if err != nil { 253 t.Errorf(err.Error()) 254 } 255 if !reflect.DeepEqual(got, test.Expected) { 256 t.Errorf("expected %v, got %v for point: %+v", 257 test.Expected, got, test.QueryShape) 258 } 259 }) 260 261 err = closeFn() 262 if err != nil { 263 t.Errorf(err.Error()) 264 } 265 } 266 } 267 268 func TestPointPolygonIntersects(t *testing.T) { 269 tests := []struct { 270 QueryShape []float64 271 DocShapeVertices [][][]float64 272 DocShapeName string 273 Desc string 274 Expected []string 275 }{ 276 { 277 QueryShape: []float64{3.0, 3.0}, 278 DocShapeVertices: [][][]float64{{{2.0, 2.0}, {3.0, 3.0}, {1.0, 3.0}, {2.0, 2.0}}}, 279 DocShapeName: "polygon1", 280 Desc: "point on polygon vertex", 281 Expected: []string{"polygon1"}, 282 }, 283 { 284 QueryShape: []float64{1.5, 1.500714}, 285 DocShapeVertices: [][][]float64{{{1.0, 1.0}, {2.0, 2.0}, {0.0, 2.0}, {1.0, 1.0}}}, 286 DocShapeName: "polygon1", 287 Desc: "point on polygon edge", 288 Expected: []string{"polygon1"}, 289 }, 290 { 291 QueryShape: []float64{1.5, 1.9}, 292 DocShapeVertices: [][][]float64{{{1.0, 1.0}, {2.0, 2.0}, {0.0, 2.0}, {1.0, 1.0}}}, 293 DocShapeName: "polygon1", 294 Desc: "point inside polygon", 295 Expected: []string{"polygon1"}, 296 }, 297 { 298 QueryShape: []float64{0.3, 0.3}, 299 DocShapeVertices: [][][]float64{{{0.0, 0.0}, {1.0, 0.0}, {1.0, 1.0}, {0.0, 1.0}, {0.0, 0.0}}, 300 {{0.2, 0.2}, {0.2, 0.4}, {0.4, 0.4}, {0.4, 0.2}, {0.2, 0.2}}}, 301 DocShapeName: "polygon1", 302 Desc: "point inside hole inside polygon", 303 Expected: nil, 304 }, 305 } 306 307 i := setupIndex(t) 308 309 for _, test := range tests { 310 indexReader, closeFn, err := testCaseSetup(t, test.DocShapeName, "polygon", 311 [][][][]float64{test.DocShapeVertices}, i) 312 if err != nil { 313 t.Errorf(err.Error()) 314 } 315 316 t.Run(test.Desc, func(t *testing.T) { 317 got, err := runGeoShapePointRelationQuery("intersects", 318 false, indexReader, [][]float64{test.QueryShape}, "geometry") 319 if err != nil { 320 t.Errorf(err.Error()) 321 } 322 if !reflect.DeepEqual(got, test.Expected) { 323 t.Errorf("expected %v, got %v for point: %+v", 324 test.Expected, got, test.QueryShape) 325 } 326 }) 327 err = closeFn() 328 if err != nil { 329 t.Errorf(err.Error()) 330 } 331 } 332 } 333 334 func TestPointMultiPolygonIntersects(t *testing.T) { 335 tests := []struct { 336 QueryShape []float64 337 DocShapeVertices [][][][]float64 338 DocShapeName string 339 Desc string 340 Expected []string 341 }{ 342 { 343 QueryShape: []float64{3.0, 3.0}, 344 DocShapeVertices: [][][][]float64{{{{2.0, 2.0}, {3.0, 3.0}, {1.0, 3.0}, {2.0, 2.0}}}}, 345 DocShapeName: "multipolygon1", 346 Desc: "point on a polygon vertex", 347 Expected: []string{"multipolygon1"}, 348 }, 349 { 350 QueryShape: []float64{1.5, 1.500714}, 351 DocShapeVertices: [][][][]float64{{{{1.0, 1.0}, {2.0, 2.0}, {0.0, 2.0}, {1.0, 1.0}}}}, 352 DocShapeName: "multipolygon1", 353 Desc: "point on polygon edge", 354 Expected: []string{"multipolygon1"}, 355 }, 356 { 357 QueryShape: []float64{1.5, 1.9}, 358 DocShapeVertices: [][][][]float64{{{{1.0, 1.0}, {2.0, 2.0}, {0.0, 2.0}, {1.0, 1.0}}}, 359 {{{1.5, 1.9}, {2.5, 2.9}, {0.5, 2.9}, {1.5, 1.9}}}}, 360 DocShapeName: "multipolygon1", 361 Desc: "point inside a polygon and on vertex of another polygon", 362 Expected: []string{"multipolygon1"}, 363 }, 364 { 365 QueryShape: []float64{0.3, 0.3}, 366 DocShapeVertices: [][][][]float64{{{{0.0, 0.0}, {1.0, 0.0}, {1.0, 1.0}, {0.0, 1.0}, {0.0, 0.0}}, 367 {{0.2, 0.2}, {0.2, 0.4}, {0.4, 0.4}, {0.4, 0.2}, {0.2, 0.2}}}}, 368 DocShapeName: "multipolygon1", 369 Desc: "point inside hole inside one of the polygons", 370 Expected: nil, 371 }, 372 } 373 374 i := setupIndex(t) 375 376 for _, test := range tests { 377 indexReader, closeFn, err := testCaseSetup(t, test.DocShapeName, "multipolygon", test.DocShapeVertices, i) 378 if err != nil { 379 t.Errorf(err.Error()) 380 } 381 382 t.Run(test.Desc, func(t *testing.T) { 383 got, err := runGeoShapePointRelationQuery("intersects", 384 false, indexReader, [][]float64{test.QueryShape}, "geometry") 385 if err != nil { 386 t.Errorf(err.Error()) 387 } 388 if !reflect.DeepEqual(got, test.Expected) { 389 t.Errorf("expected %v, got %v for point: %+v", 390 test.Expected, got, test.QueryShape) 391 } 392 }) 393 394 err = closeFn() 395 if err != nil { 396 t.Errorf(err.Error()) 397 } 398 } 399 } 400 401 func TestEnvelopePointIntersects(t *testing.T) { 402 tests := []struct { 403 QueryShape [][]float64 404 DocShapeVertices []float64 405 DocShapeName string 406 Desc string 407 Expected []string 408 QueryType string 409 }{ 410 { 411 QueryShape: [][]float64{{0, 1}, {1, 0}}, 412 DocShapeVertices: rightRectPoint, 413 DocShapeName: "point1", 414 Desc: "point on vertex of bounded rectangle", 415 Expected: []string{"point1"}, 416 QueryType: "intersects", 417 }, 418 { 419 QueryShape: [][]float64{{0, 1}, {1, 0}}, 420 DocShapeVertices: []float64{10, 10}, 421 DocShapeName: "point1", 422 Desc: "point outside bounded rectangle", 423 Expected: nil, 424 QueryType: "intersects", 425 }, 426 } 427 428 i := setupIndex(t) 429 430 for _, test := range tests { 431 indexReader, closeFn, err := testCaseSetup(t, test.DocShapeName, "point", 432 [][][][]float64{{{test.DocShapeVertices}}}, i) 433 if err != nil { 434 t.Errorf(err.Error()) 435 } 436 437 t.Run(test.Desc, func(t *testing.T) { 438 got, err := runGeoShapeEnvelopeRelationQuery(test.QueryType, 439 indexReader, test.QueryShape, "geometry") 440 if err != nil { 441 t.Fatal(err) 442 } 443 if !reflect.DeepEqual(got, test.Expected) { 444 t.Errorf("expected %v, got %v for Envelope: %+v", 445 test.Expected, got, test.QueryShape) 446 } 447 }) 448 449 err = closeFn() 450 if err != nil { 451 t.Errorf(err.Error()) 452 } 453 } 454 } 455 456 func TestEnvelopeLinestringIntersect(t *testing.T) { 457 tests := []struct { 458 QueryShape [][]float64 459 DocShapeVertices [][]float64 460 DocShapeName string 461 Desc string 462 Expected []string 463 QueryType string 464 }{ 465 { 466 QueryShape: [][]float64{{0, 1}, {1, 0}}, 467 DocShapeVertices: [][]float64{{0.25, 0.25}, {0.5, 0.5}}, 468 DocShapeName: "linestring1", 469 Desc: "linestring completely in bounded rectangle", 470 Expected: []string{"linestring1"}, 471 QueryType: "intersects", 472 }, 473 { 474 QueryShape: [][]float64{{0, 1}, {1, 0}}, 475 DocShapeVertices: [][]float64{{2.5, 2.5}, {4.5, 4.5}}, 476 DocShapeName: "linestring1", 477 Desc: "linestring outside bounded rectangle", 478 Expected: nil, 479 QueryType: "intersects", 480 }, 481 { 482 QueryShape: [][]float64{{0, 1}, {1, 0}}, 483 DocShapeVertices: [][]float64{{0.25, 0.25}, {4.5, 4.5}}, 484 DocShapeName: "linestring1", 485 Desc: "linestring partially in bounded rectangle", 486 Expected: []string{"linestring1"}, 487 QueryType: "intersects", 488 }, 489 } 490 491 i := setupIndex(t) 492 493 for _, test := range tests { 494 indexReader, closeFn, err := testCaseSetup(t, test.DocShapeName, "linestring", 495 [][][][]float64{{test.DocShapeVertices}}, i) 496 if err != nil { 497 t.Errorf(err.Error()) 498 } 499 500 t.Run(test.Desc, func(t *testing.T) { 501 got, err := runGeoShapeEnvelopeRelationQuery(test.QueryType, 502 indexReader, test.QueryShape, "geometry") 503 if err != nil { 504 t.Fatal(err) 505 } 506 if !reflect.DeepEqual(got, test.Expected) { 507 t.Errorf("expected %v, got %v for Envelope: %+v", 508 test.Expected, got, test.QueryShape) 509 } 510 }) 511 512 err = closeFn() 513 if err != nil { 514 t.Errorf(err.Error()) 515 } 516 } 517 } 518 519 func TestEnvelopePolygonIntersect(t *testing.T) { 520 tests := []struct { 521 QueryShape [][]float64 522 DocShapeVertices [][][]float64 523 DocShapeName string 524 Desc string 525 Expected []string 526 QueryType string 527 }{ 528 { 529 QueryShape: [][]float64{{0, 1}, {1, 0}}, 530 DocShapeVertices: [][][]float64{{{0.5, 0.5}, {1.5, 0.5}, {1.5, 1.5}, {0.5, 1.5}, {0.5, 0.5}}}, 531 DocShapeName: "polygon1", 532 Desc: "polygon intersects bounded rectangle", 533 Expected: []string{"polygon1"}, 534 QueryType: "intersects", 535 }, 536 { 537 QueryShape: [][]float64{{0, 1}, {1, 0}}, 538 DocShapeVertices: [][][]float64{{{10.5, 10.5}, {11.5, 10.5}, {11.5, 11.5}, {10.5, 11.5}, {10.5, 10.5}}}, 539 DocShapeName: "polygon1", 540 Desc: "polygon completely outside bounded rectangle", 541 Expected: nil, 542 QueryType: "intersects", 543 }, 544 } 545 546 i := setupIndex(t) 547 548 for _, test := range tests { 549 indexReader, closeFn, err := testCaseSetup(t, test.DocShapeName, "polygon", 550 [][][][]float64{test.DocShapeVertices}, i) 551 if err != nil { 552 t.Errorf(err.Error()) 553 } 554 555 t.Run(test.Desc, func(t *testing.T) { 556 got, err := runGeoShapeEnvelopeRelationQuery(test.QueryType, 557 indexReader, test.QueryShape, "geometry") 558 if err != nil { 559 t.Fatal(err) 560 } 561 if !reflect.DeepEqual(got, test.Expected) { 562 t.Errorf("expected %v, got %v for Envelope: %+v", 563 test.Expected, got, test.QueryShape) 564 } 565 }) 566 567 err = closeFn() 568 if err != nil { 569 t.Errorf(err.Error()) 570 } 571 } 572 } 573 574 func TestMultiPointIntersects(t *testing.T) { 575 tests := []struct { 576 QueryShape [][]float64 577 DocShapeVertices [][]float64 578 DocShapeName string 579 Desc string 580 Expected []string 581 }{ 582 { 583 QueryShape: [][]float64{{3.0, 3.0}, {4.0, 4.0}}, 584 DocShapeVertices: [][]float64{{4.0, 4.0}}, 585 DocShapeName: "multipoint1", 586 Desc: "single coincident multipoint", 587 Expected: []string{"multipoint1"}, 588 }, 589 } 590 i := setupIndex(t) 591 592 for _, test := range tests { 593 indexReader, closeFn, err := testCaseSetup(t, test.DocShapeName, "multipoint", 594 [][][][]float64{{test.DocShapeVertices}}, i) 595 if err != nil { 596 t.Errorf(err.Error()) 597 } 598 599 t.Run(test.Desc, func(t *testing.T) { 600 got, err := runGeoShapePointRelationQuery("intersects", 601 true, indexReader, test.QueryShape, "geometry") 602 if err != nil { 603 t.Errorf(err.Error()) 604 } 605 if !reflect.DeepEqual(got, test.Expected) { 606 t.Errorf("expected %v, got %v for multipoint: %+v", 607 test.Expected, got, test.QueryShape) 608 } 609 }) 610 err = closeFn() 611 if err != nil { 612 t.Errorf(err.Error()) 613 } 614 } 615 } 616 617 func TestLinestringIntersects(t *testing.T) { 618 tests := []struct { 619 QueryShape [][]float64 620 DocShapeVertices [][]float64 621 DocShapeName string 622 Desc string 623 Expected []string 624 }{ 625 { 626 QueryShape: [][]float64{{3.0, 2.0}, {4.0, 2.0}}, 627 DocShapeVertices: [][]float64{{3.0, 2.0}, {4.0, 2.0}}, 628 DocShapeName: "linestring1", 629 Desc: "coincident linestrings", 630 Expected: []string{"linestring1"}, 631 }, 632 { 633 QueryShape: [][]float64{{1.0, 1.0}, {1.5, 1.5}, {2.0, 2.0}}, 634 DocShapeVertices: [][]float64{{2.0, 2.0}, {4.0, 3.0}}, 635 DocShapeName: "linestring1", 636 Desc: "linestrings intersecting at the ends", 637 Expected: []string{"linestring1"}, 638 }, 639 { 640 QueryShape: [][]float64{{1.0, 1.0}, {3.0, 3.0}}, 641 DocShapeVertices: [][]float64{{1.5499860, 1.5501575}, {4.0, 6.0}}, 642 DocShapeName: "linestring1", 643 Desc: "subline not at vertex", 644 Expected: []string{"linestring1"}, 645 }, 646 { 647 QueryShape: [][]float64{{1.0, 1.0}, {2.0, 2.0}}, 648 DocShapeVertices: [][]float64{{1.5499860, 1.5501575}, {1.5, 1.5001714}}, 649 DocShapeName: "linestring1", 650 Desc: "subline inside linestring", 651 Expected: []string{"linestring1"}, 652 }, 653 { 654 QueryShape: [][]float64{{1.0, 1.0}, {1.5, 1.5}, {2.0, 2.0}}, 655 DocShapeVertices: [][]float64{{1.0, 2.0}, {2.0, 1.0}}, 656 DocShapeName: "linestring1", 657 Desc: "linestrings intersecting at some edge", 658 Expected: []string{"linestring1"}, 659 }, 660 { 661 QueryShape: [][]float64{{1.0, 1.0}, {1.5, 1.5}, {2.0, 2.0}}, 662 DocShapeVertices: [][]float64{{1.0, 2.0}, {1.0, 4.0}}, 663 DocShapeName: "linestring1", 664 Desc: "non intersecting linestrings", 665 Expected: nil, 666 }, 667 { 668 QueryShape: [][]float64{{59.32, 0.52}, {68.99, -7.36}, {75.49, -12.21}}, 669 DocShapeVertices: [][]float64{{71.98, 0}, {67.58, -6.57}, {63.19, -12.72}}, 670 DocShapeName: "linestring1", 671 Desc: "linestrings with more than 2 points intersecting at some edges", 672 Expected: []string{"linestring1"}, 673 }, 674 } 675 676 i := setupIndex(t) 677 678 for _, test := range tests { 679 indexReader, closeFn, err := testCaseSetup(t, test.DocShapeName, "linestring", 680 [][][][]float64{{test.DocShapeVertices}}, i) 681 if err != nil { 682 t.Errorf(err.Error()) 683 } 684 685 t.Run(test.Desc, func(t *testing.T) { 686 got, err := runGeoShapeLinestringQueryWithRelation("intersects", 687 indexReader, test.QueryShape, "geometry") 688 if err != nil { 689 t.Fatal(err) 690 } 691 if !reflect.DeepEqual(got, test.Expected) { 692 t.Errorf("expected %v, got %v for polygon: %+v", 693 test.Expected, got, test.QueryShape) 694 } 695 }) 696 err = closeFn() 697 if err != nil { 698 t.Errorf(err.Error()) 699 } 700 } 701 } 702 703 func TestLinestringPolygonIntersects(t *testing.T) { 704 tests := []struct { 705 QueryShape [][]float64 706 DocShapeVertices [][][]float64 707 DocShapeName string 708 Desc string 709 Expected []string 710 }{ 711 { 712 QueryShape: [][]float64{{1.0, 1.0}, {1.5, 1.5}, {2.0, 2.0}}, 713 DocShapeVertices: [][][]float64{{{0.0, 0.0}, {1.0, 0.0}, {1.0, 1.0}, {0.0, 1.0}, {0.0, 0.0}}}, 714 DocShapeName: "polygon1", 715 Desc: "linestring intersects polygon at a vertex", 716 Expected: []string{"polygon1"}, 717 }, 718 { 719 QueryShape: [][]float64{{0.2, 0.2}, {0.4, 0.4}}, 720 DocShapeVertices: [][][]float64{{{0.0, 0.0}, {1.0, 0.0}, {1.0, 1.0}, {0.0, 1.0}, {0.0, 0.0}}}, 721 DocShapeName: "polygon1", 722 Desc: "linestring within polygon", 723 Expected: []string{"polygon1"}, 724 }, 725 { 726 QueryShape: [][]float64{{-0.5, 0.5}, {0.5, 0.5}}, 727 DocShapeVertices: [][][]float64{{{0.0, 0.0}, {1.0, 0.0}, {1.0, 1.0}, {0.0, 1.0}, {0.0, 0.0}}}, 728 DocShapeName: "polygon1", 729 Desc: "linestring intersects polygon at an edge", 730 Expected: []string{"polygon1"}, 731 }, 732 { 733 QueryShape: [][]float64{{-0.5, 0.5}, {1.5, 0.5}}, 734 DocShapeVertices: [][][]float64{{{0.0, 0.0}, {1.0, 0.0}, {1.0, 1.0}, {0.0, 1.0}, {0.0, 0.0}}}, 735 DocShapeName: "polygon1", 736 Desc: "linestring intersects polygon as a whole", 737 Expected: []string{"polygon1"}, 738 }, 739 { 740 QueryShape: [][]float64{{-0.5, 0.5}, {-1.5, -1.5}}, 741 DocShapeVertices: [][][]float64{{{0.0, 0.0}, {1.0, 0.0}, {1.0, 1.0}, {0.0, 1.0}, {0.0, 0.0}}}, 742 DocShapeName: "polygon1", 743 Desc: "linestring does not intersect polygon", 744 Expected: nil, 745 }, 746 { 747 QueryShape: [][]float64{{0.3, 0.3}, {0.35, 0.35}}, 748 DocShapeVertices: [][][]float64{{{0.0, 0.0}, {1.0, 0.0}, {1.0, 1.0}, {0.0, 1.0}, {0.0, 0.0}}, 749 {{0.2, 0.2}, {0.2, 0.4}, {0.4, 0.4}, {0.4, 0.2}, {0.2, 0.2}}}, 750 DocShapeName: "polygon1", 751 Desc: "linestring does not intersect polygon when contained in the hole", 752 Expected: nil, 753 }, 754 { 755 QueryShape: [][]float64{{0.3, 0.3}, {0.5, 0.5}}, 756 DocShapeVertices: [][][]float64{{{0.0, 0.0}, {1.0, 0.0}, {1.0, 1.0}, {0.0, 1.0}, {0.0, 0.0}}, 757 {{0.2, 0.2}, {0.2, 0.4}, {0.4, 0.4}, {0.4, 0.2}, {0.2, 0.2}}}, 758 DocShapeName: "polygon1", 759 Desc: "linestring intersects polygon in the hole", 760 Expected: []string{"polygon1"}, 761 }, 762 { 763 QueryShape: [][]float64{{0.4, 0.3}, {0.6, 0.3}}, 764 DocShapeVertices: [][][]float64{{{0.0, 0.0}, {1.0, 0.0}, {1.0, 1.0}, {0.0, 1.0}, {0.0, 0.0}}, 765 {{0.3, 0.3}, {0.4, 0.2}, {0.5, 0.3}, {0.4, 0.4}, {0.3, 0.3}}, 766 {{0.5, 0.3}, {0.6, 0.2}, {0.7, 0.3}, {0.6, 0.4}, {0.5, 0.3}}}, 767 DocShapeName: "polygon1", 768 Desc: "linestring intersects polygon through touching holes", 769 Expected: []string{"polygon1"}, 770 }, 771 } 772 773 i := setupIndex(t) 774 775 for _, test := range tests { 776 indexReader, closeFn, err := testCaseSetup(t, test.DocShapeName, "polygon", 777 [][][][]float64{test.DocShapeVertices}, i) 778 if err != nil { 779 t.Errorf(err.Error()) 780 } 781 782 t.Run(test.Desc, func(t *testing.T) { 783 got, err := runGeoShapeLinestringQueryWithRelation("intersects", 784 indexReader, test.QueryShape, "geometry") 785 if err != nil { 786 t.Fatal(err) 787 } 788 if !reflect.DeepEqual(got, test.Expected) { 789 t.Errorf("expected %v, got %v for linestring: %+v", 790 test.Expected, got, test.QueryShape) 791 } 792 }) 793 err = closeFn() 794 if err != nil { 795 t.Errorf(err.Error()) 796 } 797 } 798 } 799 800 func TestLinestringPointIntersects(t *testing.T) { 801 tests := []struct { 802 QueryShape [][]float64 803 DocShapeVertices []float64 804 DocShapeName string 805 Desc string 806 Expected []string 807 }{ 808 { 809 QueryShape: [][]float64{{179, 0}, {-179, 0}}, 810 DocShapeVertices: []float64{179.1, 0}, 811 DocShapeName: "point1", 812 Desc: "point across longitudinal boundary of linestring", 813 Expected: []string{"point1"}, 814 }, 815 { 816 QueryShape: [][]float64{{-179, 0}, {179, 0}}, 817 DocShapeVertices: []float64{179.1, 0}, 818 DocShapeName: "point1", 819 Desc: "point across longitudinal boundary of reversed linestring", 820 Expected: []string{"point1"}, 821 }, 822 { 823 QueryShape: [][]float64{{179, 0}, {-179, 0}}, 824 DocShapeVertices: []float64{170, 0}, 825 DocShapeName: "point1", 826 Desc: "point does not intersect linestring", 827 Expected: nil, 828 }, 829 { 830 QueryShape: [][]float64{{-179, 0}, {179, 0}}, 831 DocShapeVertices: []float64{170, 0}, 832 DocShapeName: "point1", 833 Desc: "point does not intersect reversed linestring", 834 Expected: nil, 835 }, 836 { 837 QueryShape: [][]float64{{-179, 0}, {179, 0}, {178, 0}}, 838 DocShapeVertices: []float64{178, 0}, 839 DocShapeName: "point1", 840 Desc: "point intersects linestring at end vertex", 841 Expected: []string{"point1"}, 842 }, 843 { 844 QueryShape: [][]float64{{-179, 0}, {179, 0}, {178, 0}, {180, 0}}, 845 DocShapeVertices: []float64{178, 0}, 846 DocShapeName: "point1", 847 Desc: "point intersects linestring with more than two points", 848 Expected: []string{"point1"}, 849 }, 850 } 851 852 i := setupIndex(t) 853 854 for _, test := range tests { 855 indexReader, closeFn, err := testCaseSetup(t, test.DocShapeName, "point", 856 [][][][]float64{{{test.DocShapeVertices}}}, i) 857 if err != nil { 858 t.Errorf(err.Error()) 859 } 860 861 t.Run(test.Desc, func(t *testing.T) { 862 got, err := runGeoShapeLinestringQueryWithRelation("intersects", 863 indexReader, test.QueryShape, "geometry") 864 if err != nil { 865 t.Fatal(err) 866 } 867 if !reflect.DeepEqual(got, test.Expected) { 868 t.Errorf("expected %v, got %v for linestring: %+v", 869 test.Expected, got, test.QueryShape) 870 } 871 }) 872 err = closeFn() 873 if err != nil { 874 t.Errorf(err.Error()) 875 } 876 } 877 } 878 879 func TestMultiLinestringIntersects(t *testing.T) { 880 tests := []struct { 881 QueryShape [][][]float64 882 DocShapeVertices [][][]float64 883 DocShapeName string 884 Desc string 885 Expected []string 886 }{ 887 { 888 QueryShape: [][][]float64{{{1.0, 1.0}, {1.1, 1.1}, {2.0, 2.0}, {2.1, 2.1}}}, 889 DocShapeVertices: [][][]float64{{{0.0, 0.5132}, {-1.1, -1.1}, {1.5, 1.512}, {2.1, 2.1}}}, 890 DocShapeName: "multilinestring1", 891 Desc: "intersecting multilinestrings", 892 Expected: []string{"multilinestring1"}, 893 }, 894 { 895 QueryShape: [][][]float64{{{1.0, 1.0}, {1.1, 1.1}, {2.0, 2.0}, {2.1, 2.1}}}, 896 DocShapeVertices: [][][]float64{{{10.1, 100.5}, {11.5, 102.5}}}, 897 DocShapeName: "multilinestring1", 898 Desc: "non-intersecting multilinestrings", 899 Expected: nil, 900 }, 901 } 902 903 i := setupIndex(t) 904 905 for _, test := range tests { 906 indexReader, closeFn, err := testCaseSetup(t, test.DocShapeName, "multilinestring", 907 [][][][]float64{test.DocShapeVertices}, i) 908 if err != nil { 909 t.Errorf(err.Error()) 910 } 911 912 t.Run(test.Desc, func(t *testing.T) { 913 got, err := runGeoShapeMultiLinestringQueryWithRelation("intersects", 914 indexReader, test.QueryShape, "geometry") 915 if err != nil { 916 t.Fatal(err) 917 } 918 if !reflect.DeepEqual(got, test.Expected) { 919 t.Errorf("expected %v, got %v for multilinestring: %+v", 920 test.Expected, got, test.QueryShape) 921 } 922 }) 923 err = closeFn() 924 if err != nil { 925 t.Errorf(err.Error()) 926 } 927 } 928 } 929 930 func TestMultiLinestringMultiPointIntersects(t *testing.T) { 931 tests := []struct { 932 QueryShape [][][]float64 933 DocShapeVertices [][]float64 934 DocShapeName string 935 Desc string 936 Expected []string 937 }{ 938 { 939 QueryShape: [][][]float64{{{2.0, 2.0}, {2.1, 2.1}}, {{3.0, 3.0}, {3.1, 3.1}}}, 940 DocShapeVertices: [][]float64{{5.0, 6.0}, {67, 67}, {3.1, 3.1}}, 941 DocShapeName: "multipoint1", 942 Desc: "multilinestring intersects one of the multipoints", 943 Expected: []string{"multipoint1"}, 944 }, 945 { 946 QueryShape: [][][]float64{{{2.0, 2.0}, {2.1, 2.1}}, {{3.0, 3.0}, {3.1, 3.1}}}, 947 DocShapeVertices: [][]float64{{56.0, 56.0}, {66, 66}}, 948 DocShapeName: "multipoint1", 949 Desc: "multilinestring does not intersect any of the multipoints", 950 Expected: nil, 951 }, 952 } 953 954 i := setupIndex(t) 955 956 for _, test := range tests { 957 indexReader, closeFn, err := testCaseSetup(t, test.DocShapeName, "multipoint", 958 [][][][]float64{{test.DocShapeVertices}}, i) 959 if err != nil { 960 t.Errorf(err.Error()) 961 } 962 963 t.Run(test.Desc, func(t *testing.T) { 964 got, err := runGeoShapeMultiLinestringQueryWithRelation("intersects", 965 indexReader, test.QueryShape, "geometry") 966 if err != nil { 967 t.Fatal(err) 968 } 969 if !reflect.DeepEqual(got, test.Expected) { 970 t.Errorf("expected %v, got %v for polygon: %+v", 971 test.Expected, got, test.QueryShape) 972 } 973 }) 974 err = closeFn() 975 if err != nil { 976 t.Errorf(err.Error()) 977 } 978 } 979 } 980 981 func TestPolygonIntersects(t *testing.T) { 982 tests := []struct { 983 QueryShape [][][]float64 984 DocShapeVertices [][][]float64 985 DocShapeName string 986 Desc string 987 Expected []string 988 }{ 989 { 990 QueryShape: [][][]float64{{{1.0, 1.0}, {2.0, 1.0}, {2.0, 2.0}, 991 {1.0, 2.0}, {1.0, 1.0}}}, 992 DocShapeVertices: [][][]float64{{{1.0, 1.0}, {2.0, 1.0}, {2.0, 2.0}, 993 {1.0, 2.0}, {1.0, 1.0}}}, 994 DocShapeName: "polygon1", 995 Desc: "coincident polygons", 996 Expected: []string{"polygon1"}, 997 }, 998 { 999 QueryShape: [][][]float64{{{1.0, 1.0}, {2.0, 1.0}, {2.0, 2.0}, 1000 {1.0, 2.0}, {1.0, 1.0}}}, 1001 DocShapeVertices: [][][]float64{{{1.2, 1.2}, {2.0, 1.0}, {2.0, 2.0}, 1002 {1.0, 2.0}, {1.2, 1.2}}}, 1003 DocShapeName: "polygon1", 1004 Desc: "polygon and a window polygon", 1005 Expected: []string{"polygon1"}, 1006 }, 1007 { 1008 QueryShape: [][][]float64{{{1.0, 1.0}, {2.0, 1.0}, {2.0, 2.0}, 1009 {1.0, 2.0}, {1.0, 1.0}}}, 1010 DocShapeVertices: [][][]float64{{{1.1, 1.1}, {1.2, 1.1}, {1.2, 1.2}, 1011 {1.1, 1.2}, {1.1, 1.1}}}, 1012 DocShapeName: "polygon1", 1013 Desc: "nested polygons", 1014 Expected: []string{"polygon1"}, 1015 }, 1016 { 1017 QueryShape: [][][]float64{{{1.0, 1.0}, {2.0, 1.0}, {2.0, 2.0}, 1018 {1.0, 2.0}, {1.0, 1.0}}}, 1019 DocShapeVertices: [][][]float64{{{0.0, 1.0}, {2.0, 1.0}, {2.0, 2.0}, 1020 {0.0, 2.0}, {0.0, 1.0}}}, 1021 DocShapeName: "polygon1", 1022 Desc: "intersecting polygons", 1023 Expected: []string{"polygon1"}, 1024 }, 1025 { 1026 QueryShape: [][][]float64{{{0, 0}, {5, 0}, {5, 5}, {0, 5}, {0, 0}}, {{1, 4}, {4, 4}, 1027 {4, 1}, {1, 1}, {1, 4}}}, 1028 DocShapeVertices: [][][]float64{{{2, 2}, {3, 2}, {3, 3}, {2, 3}, {2, 2}}}, 1029 DocShapeName: "polygon1", 1030 Desc: "polygon inside hole of a larger polygon", 1031 Expected: nil, 1032 }, 1033 { 1034 QueryShape: [][][]float64{{{1.0, 1.0}, {2.0, 1.0}, {2.0, 2.0}, 1035 {1.0, 2.0}, {1.0, 1.0}}}, 1036 DocShapeVertices: [][][]float64{{{3.0, 3.0}, {4.0, 3.0}, {4.0, 4.0}, 1037 {3.0, 4.0}, {3.0, 3.0}}}, 1038 DocShapeName: "polygon1", 1039 Desc: "disjoint polygons", 1040 Expected: nil, 1041 }, 1042 } 1043 i := setupIndex(t) 1044 1045 for _, test := range tests { 1046 indexReader, closeFn, err := testCaseSetup(t, test.DocShapeName, "polygon", 1047 [][][][]float64{test.DocShapeVertices}, i) 1048 if err != nil { 1049 t.Errorf(err.Error()) 1050 } 1051 1052 t.Run(test.Desc, func(t *testing.T) { 1053 got, err := runGeoShapePolygonQueryWithRelation("intersects", 1054 indexReader, test.QueryShape, "geometry") 1055 if err != nil { 1056 t.Fatal(err) 1057 } 1058 if !reflect.DeepEqual(got, test.Expected) { 1059 t.Errorf("expected %v, got %v for polygon: %+v", 1060 test.Expected, got, test.QueryShape) 1061 } 1062 }) 1063 err = closeFn() 1064 if err != nil { 1065 t.Errorf(err.Error()) 1066 } 1067 } 1068 } 1069 1070 func TestPolygonLinestringIntersects(t *testing.T) { 1071 tests := []struct { 1072 QueryShape [][][]float64 1073 DocShapeVertices [][]float64 1074 DocShapeName string 1075 Desc string 1076 Expected []string 1077 }{ 1078 { 1079 QueryShape: [][][]float64{{{150, 85}, {160, 85}, {-20, 85}, {-30, 85}, {150, 85}}}, 1080 DocShapeVertices: [][]float64{{150, 85}, {160, 85}}, 1081 DocShapeName: "linestring1", 1082 Desc: "polygon intersects line along edge", 1083 Expected: []string{"linestring1"}, 1084 }, 1085 { 1086 QueryShape: [][][]float64{{{0, 0}, {1, 0}, {1, 1}, {0, 1}, {0, 0}}}, 1087 DocShapeVertices: [][]float64{{150, 85}, {160, 85}}, 1088 DocShapeName: "linestring1", 1089 Desc: "polygon not intersecting line", 1090 Expected: nil, 1091 }, 1092 { 1093 QueryShape: [][][]float64{{{0, 0}, {1, 0}, {1, 1}, {0, 1}, {0, 0}}}, 1094 DocShapeVertices: [][]float64{{0.2, 0.2}, {0.4, 0.4}}, 1095 DocShapeName: "linestring1", 1096 Desc: "polygon completely encloses line", 1097 Expected: []string{"linestring1"}, 1098 }, 1099 { 1100 QueryShape: [][][]float64{{{0, 0}, {1, 0}, {1, 1}, {0, 1}, {0, 0}}}, 1101 DocShapeVertices: [][]float64{{-0.5, 0.5}, {1.5, 0.5}}, 1102 DocShapeName: "linestring1", 1103 Desc: "line cuts through entire polygon", 1104 Expected: []string{"linestring1"}, 1105 }, 1106 { 1107 QueryShape: [][][]float64{{{0, 0}, {1, 0}, {1, 1}, {0, 1}, {0, 0}}}, 1108 DocShapeVertices: [][]float64{{-0.439, -0.318}, {0.4339, 0.335}}, 1109 DocShapeName: "linestring1", 1110 Desc: "line partially cuts through polygon", 1111 Expected: []string{"linestring1"}, 1112 }, 1113 } 1114 1115 i := setupIndex(t) 1116 1117 for _, test := range tests { 1118 indexReader, closeFn, err := testCaseSetup(t, test.DocShapeName, "linestring", 1119 [][][][]float64{{test.DocShapeVertices}}, i) 1120 if err != nil { 1121 t.Errorf(err.Error()) 1122 } 1123 1124 t.Run(test.Desc, func(t *testing.T) { 1125 got, err := runGeoShapePolygonQueryWithRelation("intersects", 1126 indexReader, test.QueryShape, "geometry") 1127 if err != nil { 1128 t.Fatal(err) 1129 } 1130 if !reflect.DeepEqual(got, test.Expected) { 1131 t.Errorf("expected %v, got %v for polygon: %+v", 1132 test.Expected, got, test.QueryShape) 1133 } 1134 }) 1135 1136 err = closeFn() 1137 if err != nil { 1138 t.Errorf(err.Error()) 1139 } 1140 } 1141 } 1142 1143 func TestPolygonMultiLinestringIntersects(t *testing.T) { 1144 tests := []struct { 1145 QueryShape [][][]float64 1146 DocShapeVertices [][][]float64 1147 DocShapeName string 1148 Desc string 1149 Expected []string 1150 }{ 1151 { 1152 QueryShape: [][][]float64{{{150, 85}, {160, 85}, {-20, 85}, {-30, 85}, {150, 85}}}, 1153 DocShapeVertices: [][][]float64{{{150, 85}, {160, 85}}, {{0, 1}, {5, 10}}}, 1154 DocShapeName: "multilinestring1", 1155 Desc: "polygon intersects one line along edge", 1156 Expected: []string{"multilinestring1"}, 1157 }, 1158 { 1159 QueryShape: [][][]float64{{{0, 0}, {1, 0}, {1, 1}, {0, 1}, {0, 0}}}, 1160 DocShapeVertices: [][][]float64{{{150, 85}, {160, 85}}}, 1161 DocShapeName: "multilinestring1", 1162 Desc: "polygon not intersecting any line", 1163 Expected: nil, 1164 }, 1165 { 1166 QueryShape: [][][]float64{{{0, 0}, {1, 0}, {1, 1}, {0, 1}, {0, 0}}}, 1167 DocShapeVertices: [][][]float64{{{0.2, 0.2}, {0.4, 0.4}}}, 1168 DocShapeName: "multilinestring1", 1169 Desc: "polygon completely encloses line", 1170 Expected: []string{"multilinestring1"}, 1171 }, 1172 { 1173 QueryShape: [][][]float64{{{0, 0}, {1, 0}, {1, 1}, {0, 1}, {0, 0}}}, 1174 DocShapeVertices: [][][]float64{{{-0.5, 0.5}, {1.5, 0.5}}}, 1175 DocShapeName: "multilinestring1", 1176 Desc: "line cuts through entire polygon", 1177 Expected: []string{"multilinestring1"}, 1178 }, 1179 { 1180 QueryShape: [][][]float64{{{0, 0}, {1, 0}, {1, 1}, {0, 1}, {0, 0}}}, 1181 DocShapeVertices: [][][]float64{{{-0.439, -0.318}, {0.4339, 0.335}}}, 1182 DocShapeName: "multilinestring1", 1183 Desc: "line partially cuts through polygon", 1184 Expected: []string{"multilinestring1"}, 1185 }, 1186 } 1187 1188 i := setupIndex(t) 1189 1190 for _, test := range tests { 1191 indexReader, closeFn, err := testCaseSetup(t, test.DocShapeName, "multilinestring", 1192 [][][][]float64{test.DocShapeVertices}, i) 1193 if err != nil { 1194 t.Errorf(err.Error()) 1195 } 1196 1197 t.Run(test.Desc, func(t *testing.T) { 1198 got, err := runGeoShapePolygonQueryWithRelation("intersects", 1199 indexReader, test.QueryShape, "geometry") 1200 if err != nil { 1201 t.Fatal(err) 1202 } 1203 if !reflect.DeepEqual(got, test.Expected) { 1204 t.Errorf("expected %v, got %v for polygon: %+v", 1205 test.Expected, got, test.QueryShape) 1206 } 1207 }) 1208 1209 err = closeFn() 1210 if err != nil { 1211 t.Errorf(err.Error()) 1212 } 1213 } 1214 } 1215 1216 func TestPolygonPointIntersects(t *testing.T) { 1217 tests := []struct { 1218 QueryShape [][][]float64 1219 DocShapeVertices []float64 1220 DocShapeName string 1221 Desc string 1222 Expected []string 1223 }{ 1224 { 1225 QueryShape: [][][]float64{{{150, 85}, {160, 85}, {-20, 85}, {-30, 85}, {150, 85}}}, 1226 DocShapeVertices: []float64{150, 88}, 1227 DocShapeName: "point1", 1228 Desc: "polygon intersects point in latitudinal boundary", 1229 Expected: []string{"point1"}, 1230 }, 1231 { 1232 QueryShape: [][][]float64{{{150, 85}, {160, 85}, {-20, 85}, {-30, 85}, {150, 85}}}, 1233 DocShapeVertices: []float64{170, 88}, 1234 DocShapeName: "point1", 1235 Desc: "polygon does not intersects point outside latitudinal boundary", 1236 Expected: nil, 1237 }, 1238 } 1239 1240 i := setupIndex(t) 1241 1242 for _, test := range tests { 1243 indexReader, closeFn, err := testCaseSetup(t, test.DocShapeName, "point", 1244 [][][][]float64{{{test.DocShapeVertices}}}, i) 1245 if err != nil { 1246 t.Errorf(err.Error()) 1247 } 1248 1249 t.Run(test.Desc, func(t *testing.T) { 1250 got, err := runGeoShapePolygonQueryWithRelation("intersects", 1251 indexReader, test.QueryShape, "geometry") 1252 if err != nil { 1253 t.Fatal(err) 1254 } 1255 if !reflect.DeepEqual(got, test.Expected) { 1256 t.Errorf("expected %v, got %v for polygon: %+v", 1257 test.Expected, got, test.QueryShape) 1258 } 1259 }) 1260 1261 err = closeFn() 1262 if err != nil { 1263 t.Errorf(err.Error()) 1264 } 1265 } 1266 } 1267 1268 func TestMultiPolygonIntersects(t *testing.T) { 1269 tests := []struct { 1270 QueryShape [][][][]float64 1271 DocShapeVertices [][][][]float64 1272 DocShapeName string 1273 Desc string 1274 Expected []string 1275 }{ 1276 { 1277 QueryShape: [][][][]float64{{{{15, 5}, {40, 10}, {10, 20}, 1278 {5, 10}, {15, 5}}}, {{{30, 20}, {45, 40}, {10, 40}, {30, 20}}}}, 1279 DocShapeVertices: [][][][]float64{{{{0.0, 0.0}, {1.0, 0.0}, {1.0, 1.0}, 1280 {0.0, 1.0}, {0.0, 0.0}}, {{30, 20}, {45, 40}, {10, 40}, {30, 20}}}}, 1281 DocShapeName: "multipolygon1", 1282 Desc: "intersecting multi polygons", 1283 Expected: []string{"multipolygon1"}, 1284 }, 1285 { 1286 QueryShape: [][][][]float64{{{{15, 5}, {40, 10}, {10, 20}, 1287 {5, 10}, {15, 5}}}, {{{30, 20}, {45, 40}, {10, 40}, {30, 20}}}}, 1288 DocShapeVertices: [][][][]float64{{{{0.0, 0.0}, {1.0, 0.0}, {1.0, 1.0}, 1289 {0.0, 1.0}, {0.0, 0.0}}}}, 1290 DocShapeName: "multipolygon1", 1291 Desc: "non intersecting multi polygons", 1292 Expected: nil, 1293 }, 1294 } 1295 i := setupIndex(t) 1296 1297 for _, test := range tests { 1298 indexReader, closeFn, err := testCaseSetup(t, test.DocShapeName, "multipolygon", 1299 test.DocShapeVertices, i) 1300 if err != nil { 1301 t.Errorf(err.Error()) 1302 } 1303 1304 t.Run(test.Desc, func(t *testing.T) { 1305 got, err := runGeoShapeMultiPolygonQueryWithRelation("intersects", 1306 indexReader, test.QueryShape, "geometry") 1307 if err != nil { 1308 t.Fatal(err) 1309 } 1310 if !reflect.DeepEqual(got, test.Expected) { 1311 t.Errorf("expected %v, got %v for multipolygon: %+v", 1312 test.Expected, got, test.QueryShape) 1313 } 1314 }) 1315 err = closeFn() 1316 if err != nil { 1317 t.Errorf(err.Error()) 1318 } 1319 } 1320 } 1321 1322 func TestMultiPolygonMultiPointIntersects(t *testing.T) { 1323 tests := []struct { 1324 QueryShape [][][][]float64 1325 DocShapeVertices [][]float64 1326 DocShapeName string 1327 Desc string 1328 Expected []string 1329 }{ 1330 { 1331 QueryShape: [][][][]float64{{{{30, 20}, {45, 40}, {10, 40}, {30, 20}}}, 1332 {{{15, 5}, {40, 10}, {10, 20}, {5, 10}, {15, 5}}}}, 1333 DocShapeVertices: [][]float64{{30, 20}, {30, 30}}, 1334 DocShapeName: "multipoint1", 1335 Desc: "multipolygon intersects multipoint at the vertex", 1336 Expected: []string{"multipoint1"}, 1337 }, 1338 { 1339 QueryShape: [][][][]float64{{{{15, 5}, {40, 10}, {10, 20}, {5, 10}, {15, 5}}}, 1340 {{{30, 20}, {45, 50}, {10, 50}, {30, 20}}}}, 1341 DocShapeVertices: [][]float64{{30, -20}, {-30, 30}, {45, 66}}, 1342 DocShapeName: "multipoint1", 1343 Desc: "multipolygon does not intersect multipoint", 1344 Expected: nil, 1345 }, 1346 } 1347 i := setupIndex(t) 1348 1349 for _, test := range tests { 1350 indexReader, closeFn, err := testCaseSetup(t, test.DocShapeName, "multipoint", 1351 [][][][]float64{{test.DocShapeVertices}}, i) 1352 if err != nil { 1353 t.Errorf(err.Error()) 1354 } 1355 1356 t.Run(test.Desc, func(t *testing.T) { 1357 got, err := runGeoShapeMultiPolygonQueryWithRelation("intersects", 1358 indexReader, test.QueryShape, "geometry") 1359 if err != nil { 1360 t.Fatal(err) 1361 } 1362 if !reflect.DeepEqual(got, test.Expected) { 1363 t.Errorf("expected %v, got %v for multipolygon: %+v", 1364 test.Expected, got, test.QueryShape) 1365 } 1366 }) 1367 1368 err = closeFn() 1369 if err != nil { 1370 t.Errorf(err.Error()) 1371 } 1372 } 1373 } 1374 1375 func TestMultiPolygonMultiLinestringIntersects(t *testing.T) { 1376 tests := []struct { 1377 QueryShape [][][][]float64 1378 DocShapeVertices [][][]float64 1379 DocShapeName string 1380 Desc string 1381 Expected []string 1382 }{ 1383 { 1384 QueryShape: [][][][]float64{{{{15, 5}, {40, 10}, {10, 20}, {5, 10}, {15, 5}}}, {{{30, 20}, {45, 40}, {10, 40}, {30, 20}}}}, 1385 DocShapeVertices: [][][]float64{{{65, 40}, {60, 40}}, {{45, 40}, {10, 40}, {30, 20}}}, 1386 DocShapeName: "multilinestring1", 1387 Desc: "multipolygon intersects multilinestring", 1388 Expected: []string{"multilinestring1"}, 1389 }, 1390 { 1391 QueryShape: [][][][]float64{{{{15, 5}, {40, 10}, {10, 20}, {5, 10}, {15, 5}}}, {{{30, 20}, {45, 40}, {10, 40}, {30, 20}}}}, 1392 DocShapeVertices: [][][]float64{{{45, 41}, {60, 80}}, {{-45, -40}, {-10, -40}}}, 1393 DocShapeName: "multilinestring1", 1394 Desc: "multipolygon does not intersect multilinestring", 1395 Expected: nil, 1396 }, 1397 } 1398 i := setupIndex(t) 1399 1400 for _, test := range tests { 1401 indexReader, closeFn, err := testCaseSetup(t, test.DocShapeName, "multilinestring", 1402 [][][][]float64{test.DocShapeVertices}, i) 1403 if err != nil { 1404 t.Errorf(err.Error()) 1405 } 1406 1407 t.Run(test.Desc, func(t *testing.T) { 1408 got, err := runGeoShapeMultiPolygonQueryWithRelation("intersects", 1409 indexReader, test.QueryShape, "geometry") 1410 if err != nil { 1411 t.Fatal(err) 1412 } 1413 if !reflect.DeepEqual(got, test.Expected) { 1414 t.Errorf("expected %v, got %v for multipolygon: %+v", 1415 test.Expected, got, test.QueryShape) 1416 } 1417 }) 1418 err = closeFn() 1419 if err != nil { 1420 t.Errorf(err.Error()) 1421 } 1422 } 1423 } 1424 1425 func TestGeometryCollectionIntersects(t *testing.T) { 1426 tests := []struct { 1427 QueryShape [][][][][]float64 1428 DocShapeVertices [][][][][]float64 1429 DocShapeName string 1430 Desc string 1431 Expected []string 1432 Types []string 1433 }{ 1434 { 1435 QueryShape: [][][][][]float64{{{{}}}}, 1436 DocShapeVertices: [][][][][]float64{{{{}}}}, 1437 DocShapeName: "geometrycollection1", 1438 Desc: "empty geometry collections", 1439 Expected: nil, 1440 Types: []string{""}, 1441 }, 1442 } 1443 1444 i := setupIndex(t) 1445 1446 for _, test := range tests { 1447 indexReader, closeFn, err := testCaseSetupGeometryCollection(t, test.DocShapeName, test.Types, 1448 test.DocShapeVertices, i) 1449 if err != nil { 1450 t.Errorf(err.Error()) 1451 } 1452 1453 t.Run(test.Desc, func(t *testing.T) { 1454 got, err := runGeoShapeGeometryCollectionRelationQuery("intersects", 1455 indexReader, test.QueryShape, test.Types, "geometry") 1456 if err != nil { 1457 t.Errorf(err.Error()) 1458 } 1459 if !reflect.DeepEqual(got, test.Expected) { 1460 t.Errorf("expected %v, got %v for geometry collection: %+v", 1461 test.Expected, got, test.QueryShape) 1462 } 1463 }) 1464 1465 err = closeFn() 1466 if err != nil { 1467 t.Errorf(err.Error()) 1468 } 1469 } 1470 } 1471 1472 func TestGeometryCollectionPointIntersects(t *testing.T) { 1473 tests := []struct { 1474 QueryShape [][][][][]float64 1475 DocShapeVertices []float64 1476 DocShapeName string 1477 Desc string 1478 Expected []string 1479 Types []string 1480 }{ 1481 { 1482 QueryShape: [][][][][]float64{{{{{4, 5}}}}}, 1483 DocShapeVertices: []float64{4, 5}, 1484 DocShapeName: "point1", 1485 Desc: "point coincident with point in geometry collection", 1486 Expected: []string{"point1"}, 1487 Types: []string{"point"}, 1488 }, 1489 { 1490 QueryShape: [][][][][]float64{{{{{4, 5}, {6, 7}}}}}, 1491 DocShapeVertices: []float64{4, 5}, 1492 DocShapeName: "point1", 1493 Desc: "point on vertex of linestring in geometry collection", 1494 Expected: []string{"point1"}, 1495 Types: []string{"linestring"}, 1496 }, 1497 { 1498 QueryShape: [][][][][]float64{{{{{1, 1}, {2, 2}, {0, 2}, {1, 0}}, {{5, 6}}}}}, 1499 DocShapeVertices: []float64{1.5, 1.9}, 1500 DocShapeName: "point1", 1501 Desc: "point inside polygon in geometry collection", 1502 Expected: []string{"point1"}, 1503 Types: []string{"polygon", "point"}, 1504 }, 1505 } 1506 1507 i := setupIndex(t) 1508 1509 for _, test := range tests { 1510 indexReader, closeFn, err := testCaseSetup(t, test.DocShapeName, "point", 1511 [][][][]float64{{{test.DocShapeVertices}}}, i) 1512 if err != nil { 1513 t.Fatal(err.Error()) 1514 } 1515 1516 t.Run(test.Desc, func(t *testing.T) { 1517 got, err := runGeoShapeGeometryCollectionRelationQuery("intersects", 1518 indexReader, test.QueryShape, test.Types, "geometry") 1519 if err != nil { 1520 t.Fatal(err) 1521 } 1522 if !reflect.DeepEqual(got, test.Expected) { 1523 t.Errorf("expected %v, got %v for geometry collection: %+v", 1524 test.Expected, got, test.QueryShape) 1525 } 1526 }) 1527 err = closeFn() 1528 if err != nil { 1529 t.Errorf(err.Error()) 1530 } 1531 } 1532 } 1533 1534 func TestGeometryCollectionLinestringIntersects(t *testing.T) { 1535 tests := []struct { 1536 QueryShape [][][][][]float64 1537 DocShapeVertices [][]float64 1538 DocShapeName string 1539 Desc string 1540 Expected []string 1541 Types []string 1542 }{ 1543 { 1544 QueryShape: [][][][][]float64{{{{{4, 5}, {6, 7}, {7, 8}}}}}, 1545 DocShapeVertices: [][]float64{{6, 7}, {7, 8}}, 1546 DocShapeName: "linestring1", 1547 Desc: "linestring intersecting with linestring in geometry collection", 1548 Expected: []string{"linestring1"}, 1549 Types: []string{"linestring"}, 1550 }, 1551 { 1552 QueryShape: [][][][][]float64{{{{{1.5, 1.9}}}}}, 1553 DocShapeVertices: [][]float64{{1.5, 1.9}, {2.5, 2.8}}, 1554 DocShapeName: "linestring1", 1555 Desc: "linestring intersects point in geometry collection at vertex", 1556 Expected: []string{"linestring1"}, 1557 Types: []string{"point"}, 1558 }, 1559 } 1560 1561 i := setupIndex(t) 1562 1563 for _, test := range tests { 1564 indexReader, closeFn, err := testCaseSetup(t, test.DocShapeName, "linestring", 1565 [][][][]float64{{test.DocShapeVertices}}, i) 1566 if err != nil { 1567 t.Errorf(err.Error()) 1568 } 1569 1570 t.Run(test.Desc, func(t *testing.T) { 1571 got, err := runGeoShapeGeometryCollectionRelationQuery("intersects", 1572 indexReader, test.QueryShape, test.Types, "geometry") 1573 if err != nil { 1574 t.Fatal(err) 1575 } 1576 if !reflect.DeepEqual(got, test.Expected) { 1577 t.Errorf("expected %v, got %v for geometry collection: %+v", 1578 test.Expected, got, test.QueryShape) 1579 } 1580 }) 1581 err = closeFn() 1582 if err != nil { 1583 t.Errorf(err.Error()) 1584 } 1585 } 1586 } 1587 1588 func TestGeometryCollectionPolygonIntersects(t *testing.T) { 1589 tests := []struct { 1590 QueryShape [][][][][]float64 1591 DocShapeVertices [][][]float64 1592 DocShapeName string 1593 Desc string 1594 Expected []string 1595 Types []string 1596 }{ 1597 { 1598 QueryShape: [][][][][]float64{{{{{4, 5}, {6, 7}, {7, 8}, {4, 5}}}, {{{1, 2}, {2, 3}, {3, 4}, {1, 2}}}}}, 1599 DocShapeVertices: [][][]float64{{{4, 5}, {6, 7}, {7, 8}, {4, 5}}}, 1600 DocShapeName: "polygon1", 1601 Desc: "polygon coincides with one of the polygons in multipolygon in geometry collection", 1602 Expected: []string{"polygon1"}, 1603 Types: []string{"multipolygon"}, 1604 }, 1605 { 1606 QueryShape: [][][][][]float64{{{{{14, 15}}}}}, 1607 DocShapeVertices: [][][]float64{{{4, 5}, {6, 7}, {7, 8}, {4, 5}}}, 1608 DocShapeName: "polygon1", 1609 Desc: "polygon does not intersect point in geometry collection", 1610 Expected: nil, 1611 Types: []string{"point"}, 1612 }, 1613 } 1614 1615 i := setupIndex(t) 1616 1617 for _, test := range tests { 1618 indexReader, closeFn, err := testCaseSetup(t, test.DocShapeName, "polygon", 1619 [][][][]float64{test.DocShapeVertices}, i) 1620 if err != nil { 1621 t.Errorf(err.Error()) 1622 } 1623 1624 t.Run(test.Desc, func(t *testing.T) { 1625 got, err := runGeoShapeGeometryCollectionRelationQuery("intersects", 1626 indexReader, test.QueryShape, test.Types, "geometry") 1627 if err != nil { 1628 t.Fatal(err) 1629 } 1630 if !reflect.DeepEqual(got, test.Expected) { 1631 t.Errorf("expected %v, got %v for geometry collection: %+v", 1632 test.Expected, got, test.QueryShape) 1633 } 1634 }) 1635 err = closeFn() 1636 if err != nil { 1637 t.Errorf(err.Error()) 1638 } 1639 } 1640 } 1641 1642 func TestPointGeometryCollectionIntersects(t *testing.T) { 1643 tests := []struct { 1644 QueryShape []float64 1645 DocShapeVertices [][][][][]float64 1646 DocShapeName string 1647 Desc string 1648 Expected []string 1649 Types []string 1650 }{ 1651 { 1652 QueryShape: []float64{1.0, 2.0}, 1653 DocShapeVertices: [][][][][]float64{{{{}}}}, 1654 DocShapeName: "geometrycollection1", 1655 Desc: "geometry collection does not intersect with a point", 1656 Expected: nil, 1657 Types: []string{""}, 1658 }, 1659 { 1660 QueryShape: []float64{1.0, 2.0}, 1661 DocShapeVertices: [][][][][]float64{{{{{1.0, 2.0}}}}}, 1662 DocShapeName: "geometrycollection1", 1663 Desc: "geometry collection intersects with a point", 1664 Expected: []string{"geometrycollection1"}, 1665 Types: []string{"point"}, 1666 }, 1667 } 1668 1669 i := setupIndex(t) 1670 1671 for _, test := range tests { 1672 indexReader, closeFn, err := testCaseSetupGeometryCollection(t, test.DocShapeName, test.Types, 1673 test.DocShapeVertices, i) 1674 if err != nil { 1675 t.Errorf(err.Error()) 1676 } 1677 1678 t.Run(test.Desc, func(t *testing.T) { 1679 got, err := runGeoShapePointRelationQuery("intersects", 1680 false, indexReader, [][]float64{test.QueryShape}, "geometry") 1681 if err != nil { 1682 t.Fatal(err) 1683 } 1684 if !reflect.DeepEqual(got, test.Expected) { 1685 t.Errorf("expected %v, got %v for point: %+v", 1686 test.Expected, got, test.QueryShape) 1687 } 1688 }) 1689 err = closeFn() 1690 if err != nil { 1691 t.Errorf(err.Error()) 1692 } 1693 } 1694 }