Skip to content

Commit 2b42390

Browse files
authored
Port lucene tessellator fix github-12352 to Elasticsearch 7.17 (#96721)
1 parent 969770f commit 2b42390

File tree

5 files changed

+40
-12
lines changed

5 files changed

+40
-12
lines changed

docs/changelog/96721.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pr: 96721
2+
summary: Port lucene tessellator fix github-12352 to Elasticsearch 7.17
3+
area: Geo
4+
type: bug
5+
issues: []

server/src/main/java/org/apache/lucene/geo/XTessellator.java

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -814,23 +814,26 @@ private static Node splitPolygon(final Node a, final Node b, boolean edgeFromPol
814814
* Determines whether a diagonal between two polygon nodes lies within a polygon interior. (This determines the validity of the ray.)
815815
**/
816816
private static boolean isValidDiagonal(final Node a, final Node b) {
817+
if (a.next.idx == b.idx || a.previous.idx == b.idx
818+
// check next edges are locally visible
819+
|| isLocallyInside(a.previous, b) == false
820+
|| isLocallyInside(b.next, a) == false
821+
// check polygons are CCW in both sides
822+
|| isCWPolygon(a, b) == false
823+
|| isCWPolygon(b, a) == false) {
824+
return false;
825+
}
817826
if (isVertexEquals(a, b)) {
818-
// If points are equal then use it if they are valid polygons
819-
return isCWPolygon(a, b);
827+
return true;
820828
}
821-
return a.next.idx != b.idx
822-
&& a.previous.idx != b.idx
823-
&& isIntersectingPolygon(a, a.getX(), a.getY(), b.getX(), b.getY()) == false
824-
&& isLocallyInside(a, b)
825-
&& isLocallyInside(b, a)
826-
&& isLocallyInside(a.previous, b)
827-
&& isLocallyInside(b.next, a)
828-
&& middleInsert(a, a.getX(), a.getY(), b.getX(), b.getY())
829-
// make sure we don't introduce collinear lines
829+
return isLocallyInside(a, b) && isLocallyInside(b, a) && middleInsert(a, a.getX(), a.getY(), b.getX(), b.getY())
830+
// make sure we don't introduce collinear lines
830831
&& area(a.previous.getX(), a.previous.getY(), a.getX(), a.getY(), b.getX(), b.getY()) != 0
831832
&& area(a.getX(), a.getY(), b.getX(), b.getY(), b.next.getX(), b.next.getY()) != 0
832833
&& area(a.next.getX(), a.next.getY(), a.getX(), a.getY(), b.getX(), b.getY()) != 0
833-
&& area(a.getX(), a.getY(), b.getX(), b.getY(), b.previous.getX(), b.previous.getY()) != 0;
834+
&& area(a.getX(), a.getY(), b.getX(), b.getY(), b.previous.getX(), b.previous.getY()) != 0
835+
// this call is expensive so do it last
836+
&& isIntersectingPolygon(a, a.getX(), a.getY(), b.getX(), b.getY()) == false;
834837
}
835838

836839
/** Determine whether the polygon defined between node start and node end is CW */

server/src/test/java/org/apache/lucene/geo/XTessellatorTests.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1090,6 +1090,26 @@ public void testComplexPolygon54() throws Exception {
10901090
}
10911091
}
10921092

1093+
public void testComplexPolygon55() throws Exception {
1094+
String geoJson = GeoTestUtil.readShape("github-12352-1.geojson.gz");
1095+
Polygon[] polygons = Polygon.fromGeoJSON(geoJson);
1096+
for (Polygon polygon : polygons) {
1097+
List<XTessellator.Triangle> tessellation = XTessellator.tessellate(polygon);
1098+
assertEquals(area(polygon), area(tessellation), 0.0);
1099+
// don't check edges as it takes several minutes
1100+
}
1101+
}
1102+
1103+
public void testComplexPolygon56() throws Exception {
1104+
String geoJson = GeoTestUtil.readShape("github-12352-2.geojson.gz");
1105+
Polygon[] polygons = Polygon.fromGeoJSON(geoJson);
1106+
for (Polygon polygon : polygons) {
1107+
List<XTessellator.Triangle> tessellation = XTessellator.tessellate(polygon);
1108+
assertEquals(area(polygon), area(tessellation), 0.0);
1109+
// don't check edges as it takes several minutes
1110+
}
1111+
}
1112+
10931113
private void checkPolygon(String wkt) throws Exception {
10941114
Polygon polygon = (Polygon) SimpleWKTShapeParser.parse(wkt);
10951115
List<XTessellator.Triangle> tessellation = XTessellator.tessellate(polygon);
80.3 KB
Binary file not shown.
109 KB
Binary file not shown.

0 commit comments

Comments
 (0)