diff --git a/server/src/main/java/org/elasticsearch/common/geo/builders/PolygonBuilder.java b/server/src/main/java/org/elasticsearch/common/geo/builders/PolygonBuilder.java index e4751de04bf..97503efc033 100644 --- a/server/src/main/java/org/elasticsearch/common/geo/builders/PolygonBuilder.java +++ b/server/src/main/java/org/elasticsearch/common/geo/builders/PolygonBuilder.java @@ -406,7 +406,7 @@ public class PolygonBuilder extends ShapeBuildernull) * @return number of edges that belong to this component */ - private static int component(final Edge edge, final int id, final ArrayList edges) { + private static int component(final Edge edge, final int id, final ArrayList edges, double[] partitionPoint) { // find a coordinate that is not part of the dateline Edge any = edge; while(any.coordinate.x == +DATELINE || any.coordinate.x == -DATELINE) { @@ -438,6 +438,9 @@ public class PolygonBuilder extends ShapeBuilder 0 && current.next != edge) { throw new InvalidShapeException("Shape contains more than one shared point"); } @@ -479,10 +482,20 @@ public class PolygonBuilder extends ShapeBuilder= 0) { - int length = component(edges[i], -(components.size()+numHoles+1), mainEdges); + double[] partitionPoint = new double[3]; + int length = component(edges[i], -(components.size()+numHoles+1), mainEdges, partitionPoint); List component = new ArrayList<>(); - component.add(coordinates(edges[i], new Coordinate[length+1])); + component.add(coordinates(edges[i], new Coordinate[length+1], partitionPoint)); components.add(component); } } diff --git a/server/src/test/java/org/elasticsearch/common/geo/ShapeBuilderTests.java b/server/src/test/java/org/elasticsearch/common/geo/ShapeBuilderTests.java index 32f1b333c4e..3c653db2d15 100644 --- a/server/src/test/java/org/elasticsearch/common/geo/ShapeBuilderTests.java +++ b/server/src/test/java/org/elasticsearch/common/geo/ShapeBuilderTests.java @@ -759,4 +759,22 @@ public class ShapeBuilderTests extends ESTestCase { assertEquals(expected, pb.toString()); } + + public void testInvalidSelfCrossingPolygon() { + PolygonBuilder builder = new PolygonBuilder(new CoordinatesBuilder() + .coordinate(0, 0) + .coordinate(0, 2) + .coordinate(1, 1.9) + .coordinate(0.5, 1.8) + .coordinate(1.5, 1.8) + .coordinate(1, 1.9) + .coordinate(2, 2) + .coordinate(2, 0) + .coordinate(0, 0) + ); + Exception e = expectThrows(InvalidShapeException.class, () -> builder.close().buildS4J()); + assertThat(e.getMessage(), containsString("Self-intersection at or near point [")); + e = expectThrows(InvalidShapeException.class, () -> builder.close().buildGeometry()); + assertThat(e.getMessage(), containsString("Self-intersection at or near point [")); + } }