diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt index 312d40534afd..b81420bd7a66 100644 --- a/lucene/CHANGES.txt +++ b/lucene/CHANGES.txt @@ -209,6 +209,9 @@ Bug Fixes * GITHUB#15702: Fix Potential NullPointException in BytesRefHash initialization#15702 (tyronecai) +* GITHUB#15731: Fix tessellator failure when a hole is touching another hole in the middle of a segment. In this case + we might fail to detect it and choose a wrong bridge to eliminate the hole. (Ignacio Vera) + Other --------------------- * GITHUB#15586: Document that scoring and ranking may change across major Lucene versions, and that applications requiring stable ranking should explicitly configure Similarity. (Parveen Saini) diff --git a/lucene/core/src/java/org/apache/lucene/geo/Tessellator.java b/lucene/core/src/java/org/apache/lucene/geo/Tessellator.java index a81ce31e23b8..d0510543dbd0 100644 --- a/lucene/core/src/java/org/apache/lucene/geo/Tessellator.java +++ b/lucene/core/src/java/org/apache/lucene/geo/Tessellator.java @@ -392,7 +392,9 @@ private static Node eliminateHole( // compute if the bridge overlaps with a polygon edge. boolean fromPolygon = isPointInLine(bridge, bridge.next, holeNode) - || isPointInLine(holeNode, holeNode.next, bridge); + || isPointInLine(bridge, bridge.previous, holeNode) + || isPointInLine(holeNode, holeNode.next, bridge) + || isPointInLine(holeNode, holeNode.previous, bridge); // Split the resulting polygon. splitPolygon(bridge, holeNode, fromPolygon); return outerNode; @@ -1260,8 +1262,8 @@ && area(a.getX(), a.getY(), a.previous.getX(), a.previous.getY(), b.getX(), b.ge >= 0; } else { // ccw - return area(a.getX(), a.getY(), b.getX(), b.getY(), a.previous.getX(), a.previous.getY()) < 0 - || area(a.getX(), a.getY(), a.next.getX(), a.next.getY(), b.getX(), b.getY()) < 0; + return area(a.getX(), a.getY(), b.getX(), b.getY(), a.previous.getX(), a.previous.getY()) <= 0 + || area(a.getX(), a.getY(), a.next.getX(), a.next.getY(), b.getX(), b.getY()) <= 0; } } diff --git a/lucene/core/src/test/org/apache/lucene/geo/TestTessellator.java b/lucene/core/src/test/org/apache/lucene/geo/TestTessellator.java index ae04ff0d1c54..295e7929b377 100644 --- a/lucene/core/src/test/org/apache/lucene/geo/TestTessellator.java +++ b/lucene/core/src/test/org/apache/lucene/geo/TestTessellator.java @@ -938,13 +938,19 @@ public void testComplexPolygon61() throws Exception { public void testComplexPolygon62() throws Exception { String geoJson = GeoTestUtil.readShape("github-15657.geojson.gz"); Polygon[] polygons = Polygon.fromGeoJSON(geoJson); - checkMultiPolygon(polygons, 1e-11); + checkMultiPolygon(polygons, 0.0); } public void testComplexPolygon63() throws Exception { String geoJson = GeoTestUtil.readShape("github-15695.geojson.gz"); Polygon[] polygons = Polygon.fromGeoJSON(geoJson); - checkMultiPolygon(polygons, 1e-11); + checkMultiPolygon(polygons, 0.0); + } + + public void testComplexPolygon64() throws Exception { + String geoJson = GeoTestUtil.readShape("github-15731.geojson.gz"); + Polygon[] polygons = Polygon.fromGeoJSON(geoJson); + checkMultiPolygon(polygons, 0.0); } private static class TestCountingMonitor implements Tessellator.Monitor { diff --git a/lucene/test-framework/src/resources/org/apache/lucene/tests/geo/github-15731.geojson.gz b/lucene/test-framework/src/resources/org/apache/lucene/tests/geo/github-15731.geojson.gz new file mode 100644 index 000000000000..f2bd31506403 Binary files /dev/null and b/lucene/test-framework/src/resources/org/apache/lucene/tests/geo/github-15731.geojson.gz differ