Skip to content

Commit d04c5e3

Browse files
authored
[Tessellator] Fix failure due to hole bridge being coplanar with polygon edge. (#15211)
The fix changes the strategy for removing co-planar points to do it once after all holes are removed instead of doing it for each removed hole.
1 parent 42ad379 commit d04c5e3

File tree

4 files changed

+16
-9
lines changed

4 files changed

+16
-9
lines changed

lucene/CHANGES.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,11 @@ Bug Fixes
173173
* GITHUB#14161: PointInSetQuery's constructor now throws IllegalArgumentException
174174
instead of UnsupportedOperationException when values are out of order. (Shubham Sharma)
175175

176+
* GITHUB#15205: Fixes regression introduced in GITHUB#13980 where polygons might fail to tessellate
177+
because the hole bridge is coplanar with the polygon vertex. The fix changes the strategy for
178+
removing co-planar points to do it once after all holes are removed instead of doing it for each
179+
removed hole.
180+
176181
Other
177182
---------------------
178183
(No changes)

lucene/core/src/java/org/apache/lucene/geo/Tessellator.java

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -359,8 +359,8 @@ private static Node eliminateHoles(
359359
throw new IllegalArgumentException("Illegal hole detected: " + polygon);
360360
}
361361
}
362-
// Return a pointer to the list.
363-
return outerNode;
362+
// Filter co-planar nodes and return a pointer to the list.
363+
return filterPoints(outerNode, null);
364364
}
365365

366366
/** Finds a bridge between vertices that connects a hole with an outer ring, and links it */
@@ -387,9 +387,7 @@ private static boolean eliminateHole(
387387
isPointInLine(outerNode, outerNode.next, holeNode)
388388
|| isPointInLine(holeNode, holeNode.next, outerNode);
389389
// Split the resulting polygon.
390-
Node node = splitPolygon(outerNode, holeNode, fromPolygon);
391-
// Filter the split nodes.
392-
filterPoints(node, node.next);
390+
splitPolygon(outerNode, holeNode, fromPolygon);
393391
return true;
394392
} else {
395393
return false;
@@ -431,9 +429,7 @@ private static boolean maybeMergeHoleWithSharedVertices(
431429
} while (next != outerNode);
432430
if (sharedVertex != null) {
433431
// Split the resulting polygon.
434-
Node node = splitPolygon(sharedVertexConnection, sharedVertex, true);
435-
// Filter the split nodes.
436-
filterPoints(node, node.next);
432+
splitPolygon(sharedVertexConnection, sharedVertex, true);
437433
return true;
438434
}
439435
return false;

lucene/core/src/test/org/apache/lucene/geo/TestTessellator.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -374,7 +374,7 @@ public void testComplexPolygon17() throws Exception {
374374
IllegalArgumentException ex =
375375
expectThrows(IllegalArgumentException.class, () -> Tessellator.tessellate(polygon, true));
376376
assertEquals(
377-
"Polygon ring self-intersection at lat=40.8278688 lon=14.1990929", ex.getMessage());
377+
"Polygon ring self-intersection at lat=40.8277665 lon=14.1993975", ex.getMessage());
378378
}
379379

380380
public void testComplexPolygon18() throws Exception {
@@ -922,6 +922,12 @@ public void testComplexPolygon60() throws Exception {
922922
checkPolygon(wkt);
923923
}
924924

925+
public void testComplexPolygon61() throws Exception {
926+
String geoJson = GeoTestUtil.readShape("github-15205.geojson.gz");
927+
Polygon[] polygons = Polygon.fromGeoJSON(geoJson);
928+
checkMultiPolygon(polygons, 1e-11);
929+
}
930+
925931
private static class TestCountingMonitor implements Tessellator.Monitor {
926932
private int count = 0;
927933
private int splitsStarted = 0;
Binary file not shown.

0 commit comments

Comments
 (0)