Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions lucene/CHANGES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,9 @@ Bug Fixes

* GITHUB#14616 : Fix mis-interpretation of `maxNumBytes` in FuzzySet#createSetBasedOnMaxMemory (Greg Miller)

* GITHUB#15554: Fix tessellator failure by preferring the shared vertex that is the leftmost vertex of the hole
(Ignacio Vera)

Other
---------------------
* GITHUB#15237: Fix SmartChinese to only deserialize dictionary data from classpath with a native array
Expand Down
26 changes: 24 additions & 2 deletions lucene/core/src/java/org/apache/lucene/geo/Tessellator.java
Original file line number Diff line number Diff line change
Expand Up @@ -408,25 +408,47 @@ private static boolean maybeMergeHoleWithSharedVertices(
// Attempt to find a common point between the HoleNode and OuterNode.
Node sharedVertex = null;
Node sharedVertexConnection = null;
// Track the leftmost vertex match (holeNode is the leftmost vertex of the hole)
Node leftmostSharedVertex = null;
Node leftmostSharedVertexConnection = null;
Node next = outerNode;
do {
if (Rectangle.containsPoint(
next.getY(), next.getX(), holeMinY, holeMaxY, holeMinX, holeMaxX)) {
Node newSharedVertex = getSharedVertex(holeNode, next);
if (newSharedVertex != null) {
// Check if this shared vertex is the leftmost point of the hole (holeNode)
if (isVertexEquals(newSharedVertex, holeNode)) {
if (leftmostSharedVertex == null) {
leftmostSharedVertex = newSharedVertex;
leftmostSharedVertexConnection = next;
} else if (newSharedVertex.equals(leftmostSharedVertex)) {
// Same vertex found again via different connection
leftmostSharedVertexConnection =
getSharedInsideVertex(leftmostSharedVertex, leftmostSharedVertexConnection, next);
}
}
if (sharedVertex == null) {
sharedVertex = newSharedVertex;
sharedVertexConnection = next;
} else if (newSharedVertex.equals(sharedVertex)) {
// This can only happen if this vertex has been already used for a bridge. We need to
// choose the right one.
// Same vertex found again via different connection.
sharedVertexConnection =
getSharedInsideVertex(sharedVertex, sharedVertexConnection, next);
}
}
}
next = next.next;
} while (next != outerNode);

// The leftmost vertex of the hole is a shared vertex. Prefer this connection point if it is
// from a hole that was already merged (higher idx), as this maintains proper connectivity
// for chained holes.
if (leftmostSharedVertex != null
&& leftmostSharedVertexConnection.idx > sharedVertexConnection.idx) {
splitPolygon(leftmostSharedVertexConnection, leftmostSharedVertex, true);
return true;
}
if (sharedVertex != null) {
// Split the resulting polygon.
splitPolygon(sharedVertexConnection, sharedVertex, true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -935,6 +935,12 @@ public void testComplexPolygon61() throws Exception {
checkMultiPolygon(polygons, 1e-11);
}

public void testComplexPolygon62() throws Exception {
String geoJson = GeoTestUtil.readShape("github-15657.geojson.gz");
Polygon[] polygons = Polygon.fromGeoJSON(geoJson);
checkMultiPolygon(polygons, 1e-11);
}

private static class TestCountingMonitor implements Tessellator.Monitor {
private int count = 0;
private int splitsStarted = 0;
Expand Down
Binary file not shown.
Loading