You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by iv...@apache.org on 2022/12/15 13:58:41 UTC

[lucene] branch branch_9x updated: Fix flat polygons incorrectly containing intersecting geometries (#12022)

This is an automated email from the ASF dual-hosted git repository.

ivera pushed a commit to branch branch_9x
in repository https://gitbox.apache.org/repos/asf/lucene.git


The following commit(s) were added to refs/heads/branch_9x by this push:
     new a7c66e1c621 Fix flat polygons incorrectly containing intersecting geometries (#12022)
a7c66e1c621 is described below

commit a7c66e1c6217cbe1cc1b26ad74702bd56896e9df
Author: Craig Taverner <cr...@amanzi.com>
AuthorDate: Thu Dec 15 14:56:09 2022 +0100

    Fix flat polygons incorrectly containing intersecting geometries (#12022)
---
 lucene/CHANGES.txt                                 |  2 ++
 .../org/apache/lucene/document/ShapeField.java     |  6 +++++
 .../apache/lucene/document/TestLatLonShape.java    | 28 ++++++++++++++++++++++
 3 files changed, 36 insertions(+)

diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt
index 872b6d672e6..b4c173bd325 100644
--- a/lucene/CHANGES.txt
+++ b/lucene/CHANGES.txt
@@ -101,6 +101,8 @@ Bug Fixes
 * GITHUB#11986: Fix algorithm that chooses the bridge between a polygon and a hole when there is
   common vertex. (Ignacio Vera)
 
+* GITHUB#12020: Fixes bug whereby very flat polygons can incorrectly contain intersecting geometries. (Craig Taverner)
+
 Optimizations
 ---------------------
 * GITHUB#11738: Optimize MultiTermQueryConstantScoreWrapper when a term is present that matches all
diff --git a/lucene/core/src/java/org/apache/lucene/document/ShapeField.java b/lucene/core/src/java/org/apache/lucene/document/ShapeField.java
index bd85a5771fc..804e7f11be8 100644
--- a/lucene/core/src/java/org/apache/lucene/document/ShapeField.java
+++ b/lucene/core/src/java/org/apache/lucene/document/ShapeField.java
@@ -376,6 +376,8 @@ public final class ShapeField {
       if (triangle.aX == triangle.cX && triangle.aY == triangle.cY) {
         triangle.type = DecodedTriangle.TYPE.POINT;
       } else {
+        // a and b are identical, remove ab, and merge bc and ca
+        triangle.ab = triangle.bc | triangle.ca;
         triangle.bX = triangle.cX;
         triangle.bY = triangle.cY;
         triangle.cX = triangle.aX;
@@ -383,8 +385,12 @@ public final class ShapeField {
         triangle.type = DecodedTriangle.TYPE.LINE;
       }
     } else if (triangle.aX == triangle.cX && triangle.aY == triangle.cY) {
+      // a and c are identical, remove ac, and merge ab and bc
+      triangle.ab = triangle.ab | triangle.bc;
       triangle.type = DecodedTriangle.TYPE.LINE;
     } else if (triangle.bX == triangle.cX && triangle.bY == triangle.cY) {
+      // b and c are identical, remove bc, and merge ab and ca
+      triangle.ab = triangle.ab | triangle.ca;
       triangle.cX = triangle.aX;
       triangle.cY = triangle.aY;
       triangle.type = DecodedTriangle.TYPE.LINE;
diff --git a/lucene/core/src/test/org/apache/lucene/document/TestLatLonShape.java b/lucene/core/src/test/org/apache/lucene/document/TestLatLonShape.java
index 1e4caa129b8..b63a388c081 100644
--- a/lucene/core/src/test/org/apache/lucene/document/TestLatLonShape.java
+++ b/lucene/core/src/test/org/apache/lucene/document/TestLatLonShape.java
@@ -949,6 +949,34 @@ public class TestLatLonShape extends LuceneTestCase {
         LatLonShape.createIndexableFields(FIELDNAME, polygonInside));
   }
 
+  public void testFlatPolygonDoesNotContainIntersectingLine() throws IOException {
+    // Create line intersecting very flat polygon (but not contained)
+    double[] lons = new double[] {-0.001, -0.001, 0.001, 0.001, -0.001};
+    double[] lats = new double[] {1e-10, 0, -1e-10, 0, 1e-10};
+    Polygon polygon = new Polygon(lats, lons);
+    Line line = new Line(new double[] {0.0, 0.001}, new double[] {0.0, 0.0});
+
+    // Index the polygon
+    Directory dir = newDirectory();
+    RandomIndexWriter writer = new RandomIndexWriter(random(), dir);
+    Document document = new Document();
+    addPolygonsToDoc(FIELDNAME, document, polygon);
+    writer.addDocument(document);
+
+    // search
+    IndexReader r = writer.getReader();
+    writer.close();
+    IndexSearcher s = newSearcher(r);
+
+    // search for line within the polygon
+    Query q = LatLonShape.newGeometryQuery(FIELDNAME, QueryRelation.CONTAINS, line);
+    TopDocs topDocs = s.search(q, 1);
+    assertEquals("Polygon should not contain the line,", 0, topDocs.scoreDocs.length);
+
+    // cleanup
+    IOUtils.close(r, dir);
+  }
+
   private void doTestContainsGeometryCollectionIntersects(
       Field[] containsFields, Field[] intersectsField) throws IOException {
     Directory dir = newDirectory();