Geo: Issue with polygons near date line
If a polygon is constructed which overlaps the date line but has a hole which lies entirely one to one side of the date line, JTS error saying that the hole is not within the bounds of the polygon because the code which splits the polygon either side of the date line does not add the hole to the correct component of the final set of polygons. The fix ensures this selection happens correctly. Closes #6179
This commit is contained in:
parent
ea80b381c0
commit
a23e4aefaa
|
@ -19,21 +19,15 @@
|
|||
|
||||
package org.elasticsearch.common.geo.builders;
|
||||
|
||||
import com.spatial4j.core.shape.Shape;
|
||||
import com.vividsolutions.jts.geom.*;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
|
||||
import com.spatial4j.core.shape.Shape;
|
||||
import com.vividsolutions.jts.geom.Coordinate;
|
||||
import com.vividsolutions.jts.geom.Geometry;
|
||||
import com.vividsolutions.jts.geom.GeometryFactory;
|
||||
import com.vividsolutions.jts.geom.LinearRing;
|
||||
import com.vividsolutions.jts.geom.MultiPolygon;
|
||||
import com.vividsolutions.jts.geom.Polygon;
|
||||
|
||||
/**
|
||||
* The {@link BasePolygonBuilder} implements the groundwork to create polygons. This contains
|
||||
* Methods to wrap polygons at the dateline and building shapes from the data held by the
|
||||
|
@ -358,7 +352,10 @@ public abstract class BasePolygonBuilder<E extends BasePolygonBuilder<E>> extend
|
|||
LOGGER.debug("Holes: " + Arrays.toString(holes));
|
||||
}
|
||||
for (int i = 0; i < numHoles; i++) {
|
||||
final Edge current = holes[i];
|
||||
final Edge current = new Edge(holes[i].coordinate, holes[i].next);
|
||||
// the edge intersects with itself at its own coordinate. We need intersect to be set this way so the binary search
|
||||
// will get the correct position in the edge list and therefore the correct component to add the hole
|
||||
current.intersect = current.coordinate;
|
||||
final int intersections = intersections(current.coordinate.x, edges);
|
||||
final int pos = Arrays.binarySearch(edges, 0, intersections, current, INTERSECTION_ORDER);
|
||||
assert pos < 0 : "illegal state: two edges cross the datum at the same position";
|
||||
|
|
|
@ -25,6 +25,7 @@ import com.spatial4j.core.shape.Shape;
|
|||
import com.vividsolutions.jts.geom.Coordinate;
|
||||
import com.vividsolutions.jts.geom.LineString;
|
||||
import com.vividsolutions.jts.geom.Polygon;
|
||||
import org.elasticsearch.common.geo.builders.PolygonBuilder;
|
||||
import org.elasticsearch.common.geo.builders.ShapeBuilder;
|
||||
import org.elasticsearch.test.ElasticsearchTestCase;
|
||||
import org.junit.Test;
|
||||
|
@ -192,5 +193,45 @@ public class ShapeBuilderTests extends ElasticsearchTestCase {
|
|||
assertMultiLineString(shape);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDateline() {
|
||||
// view shape at https://gist.github.com/anonymous/7f1bb6d7e9cd72f5977c
|
||||
// expect 3 polygons, 1 with a hole
|
||||
|
||||
// a giant c shape
|
||||
PolygonBuilder builder = ShapeBuilder.newPolygon()
|
||||
.point(-186,0)
|
||||
.point(-176,0)
|
||||
.point(-176,3)
|
||||
.point(-183,3)
|
||||
.point(-183,5)
|
||||
.point(-176,5)
|
||||
.point(-176,8)
|
||||
.point(-186,8)
|
||||
.point(-186,0);
|
||||
|
||||
// 3/4 of an embedded 'c', crossing dateline once
|
||||
builder.hole()
|
||||
.point(-185,1)
|
||||
.point(-181,1)
|
||||
.point(-181,2)
|
||||
.point(-184,2)
|
||||
.point(-184,6)
|
||||
.point(-178,6)
|
||||
.point(-178,7)
|
||||
.point(-185,7)
|
||||
.point(-185,1);
|
||||
|
||||
// embedded hole right of the dateline
|
||||
builder.hole()
|
||||
.point(-179,1)
|
||||
.point(-177,1)
|
||||
.point(-177,2)
|
||||
.point(-179,2)
|
||||
.point(-179,1);
|
||||
|
||||
Shape shape = builder.close().build();
|
||||
|
||||
assertMultiPolygon(shape);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue