|
|
@@ -406,7 +406,7 @@ public class PolygonBuilder extends ShapeBuilder<JtsGeometry, org.elasticsearch.
|
|
|
* @param edges a list of edges to which all edges of the component will be added (could be <code>null</code>)
|
|
|
* @return number of edges that belong to this component
|
|
|
*/
|
|
|
- private static int component(final Edge edge, final int id, final ArrayList<Edge> edges) {
|
|
|
+ private static int component(final Edge edge, final int id, final ArrayList<Edge> 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<JtsGeometry, org.elasticsearch.
|
|
|
if (edges != null) {
|
|
|
// found a closed loop - we have two connected components so we need to slice into two distinct components
|
|
|
if (visitedEdge.containsKey(current.coordinate)) {
|
|
|
+ partitionPoint[0] = current.coordinate.x;
|
|
|
+ partitionPoint[1] = current.coordinate.y;
|
|
|
+ partitionPoint[2] = current.coordinate.z;
|
|
|
if (connectedComponents > 0 && current.next != edge) {
|
|
|
throw new InvalidShapeException("Shape contains more than one shared point");
|
|
|
}
|
|
|
@@ -479,10 +482,20 @@ public class PolygonBuilder extends ShapeBuilder<JtsGeometry, org.elasticsearch.
|
|
|
* @param coordinates Array of coordinates to write the result to
|
|
|
* @return the coordinates parameter
|
|
|
*/
|
|
|
- private static Coordinate[] coordinates(Edge component, Coordinate[] coordinates) {
|
|
|
+ private static Coordinate[] coordinates(Edge component, Coordinate[] coordinates, double[] partitionPoint) {
|
|
|
for (int i = 0; i < coordinates.length; i++) {
|
|
|
coordinates[i] = (component = component.next).coordinate;
|
|
|
}
|
|
|
+ // First and last coordinates must be equal
|
|
|
+ if (coordinates[0].equals(coordinates[coordinates.length - 1]) == false) {
|
|
|
+ if (partitionPoint[2] == Double.NaN) {
|
|
|
+ throw new InvalidShapeException("Self-intersection at or near point ["
|
|
|
+ + partitionPoint[0] + "," + partitionPoint[1] + "]");
|
|
|
+ } else {
|
|
|
+ throw new InvalidShapeException("Self-intersection at or near point ["
|
|
|
+ + partitionPoint[0] + "," + partitionPoint[1] + "," + partitionPoint[2] + "]");
|
|
|
+ }
|
|
|
+ }
|
|
|
return coordinates;
|
|
|
}
|
|
|
|
|
|
@@ -512,8 +525,9 @@ public class PolygonBuilder extends ShapeBuilder<JtsGeometry, org.elasticsearch.
|
|
|
final Coordinate[][] points = new Coordinate[numHoles][];
|
|
|
|
|
|
for (int i = 0; i < numHoles; i++) {
|
|
|
- int length = component(holes[i], -(i+1), null); // mark as visited by inverting the sign
|
|
|
- points[i] = coordinates(holes[i], new Coordinate[length+1]);
|
|
|
+ double[] partitionPoint = new double[3];
|
|
|
+ int length = component(holes[i], -(i+1), null, partitionPoint); // mark as visited by inverting the sign
|
|
|
+ points[i] = coordinates(holes[i], new Coordinate[length+1], partitionPoint);
|
|
|
}
|
|
|
|
|
|
return points;
|
|
|
@@ -524,9 +538,10 @@ public class PolygonBuilder extends ShapeBuilder<JtsGeometry, org.elasticsearch.
|
|
|
|
|
|
for (int i = 0; i < edges.length; i++) {
|
|
|
if (edges[i].component >= 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<Coordinate[]> 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);
|
|
|
}
|
|
|
}
|