Updating translation gate check to disregard order of hole vertices for non dateline crossing polys.
Updating comments and code readability Correcting code formatting
This commit is contained in:
parent
e9e13d5cfc
commit
85502ac40a
|
@ -403,9 +403,10 @@ public abstract class BasePolygonBuilder<E extends BasePolygonBuilder<E>> extend
|
|||
// The connect method creates a new edge for these paired edges in the linked list.
|
||||
// For boundary conditions (e.g., intersect but not crossing) there is no sibling edge
|
||||
// to connect. Thus the first logic check enforces the pairwise rule
|
||||
// 2. the second logic ensures the two candidate edges aren't already connected by an
|
||||
// existing along the dateline - this is necessary due to a logic change that
|
||||
// computes dateline edges as valid intersect points in support of OGC standards
|
||||
// 2. the second logic check ensures the two candidate edges aren't already connected by an
|
||||
// existing edge along the dateline - this is necessary due to a logic change in
|
||||
// ShapeBuilder.intersection that computes dateline edges as valid intersect points
|
||||
// in support of OGC standards
|
||||
if (e1.intersect != Edge.MAX_COORDINATE && e2.intersect != Edge.MAX_COORDINATE
|
||||
&& !(e1.next.next.coordinate.equals3D(e2.coordinate) && Math.abs(e1.next.coordinate.x) == DATELINE
|
||||
&& Math.abs(e2.coordinate.x) == DATELINE) ) {
|
||||
|
|
|
@ -486,7 +486,7 @@ public abstract class ShapeBuilder implements ToXContent {
|
|||
* @return Array of edges
|
||||
*/
|
||||
protected static Edge[] ring(int component, boolean direction, BaseLineStringBuilder<?> shell, Coordinate[] points, int offset,
|
||||
Edge[] edges, int toffset, int length) {
|
||||
Edge[] edges, int toffset, int length) {
|
||||
// calculate the direction of the points:
|
||||
// find the point a the top of the set and check its
|
||||
// neighbors orientation. So direction is equivalent
|
||||
|
@ -505,11 +505,11 @@ public abstract class ShapeBuilder implements ToXContent {
|
|||
Pair<Pair, Pair> range = range(points, offset, length);
|
||||
final double rng = (Double)range.getLeft().getRight() - (Double)range.getLeft().getLeft();
|
||||
// translate the points if the following is true
|
||||
// 1. range is greater than a hemisphere (180 degrees) but not spanning 2 hemispheres (translation would result in
|
||||
// a collapsed poly)
|
||||
// 1. shell orientation is cw and range is greater than a hemisphere (180 degrees) but not spanning 2 hemispheres
|
||||
// (translation would result in a collapsed poly)
|
||||
// 2. the shell of the candidate hole has been translated (to preserve the coordinate system)
|
||||
if ((rng > DATELINE && rng != 2*DATELINE && orientation) || (shell.translated && component != 0)) {
|
||||
transform(points);
|
||||
if ((rng > DATELINE && rng != 2*DATELINE && orientation && component == 0) || (shell.translated && component != 0)) {
|
||||
translate(points);
|
||||
// flip the translation bit if the shell is being translated
|
||||
if (component == 0 && !shell.translated) {
|
||||
shell.translated = true;
|
||||
|
@ -526,7 +526,7 @@ public abstract class ShapeBuilder implements ToXContent {
|
|||
* Transforms coordinates in the eastern hemisphere (-180:0) to a (180:360) range
|
||||
* @param points
|
||||
*/
|
||||
protected static void transform(Coordinate[] points) {
|
||||
protected static void translate(Coordinate[] points) {
|
||||
for (Coordinate c : points) {
|
||||
if (c.x < 0) {
|
||||
c.x += 2*DATELINE;
|
||||
|
|
|
@ -210,8 +210,8 @@ public class GeoJSONShapeParserTests extends ElasticsearchTestCase {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testParse_polygonNoHolesOGCCompliance() throws IOException {
|
||||
// test ccw poly (large poly intended to not cross dateline)
|
||||
public void testParse_OGCPolygonWithoutHoles() throws IOException {
|
||||
// test ccw poly not crossing dateline
|
||||
String polygonGeoJson = XContentFactory.jsonBuilder().startObject().field("type", "Polygon")
|
||||
.startArray("coordinates")
|
||||
.startArray()
|
||||
|
@ -229,7 +229,9 @@ public class GeoJSONShapeParserTests extends ElasticsearchTestCase {
|
|||
parser.nextToken();
|
||||
Shape shape = ShapeBuilder.parse(parser).build();
|
||||
|
||||
// test cw poly (small poly expected to cross dateline)
|
||||
ElasticsearchGeoAssertions.assertPolygon(shape);
|
||||
|
||||
// test ccw poly crossing dateline
|
||||
polygonGeoJson = XContentFactory.jsonBuilder().startObject().field("type", "Polygon")
|
||||
.startArray("coordinates")
|
||||
.startArray()
|
||||
|
@ -246,12 +248,64 @@ public class GeoJSONShapeParserTests extends ElasticsearchTestCase {
|
|||
parser = JsonXContent.jsonXContent.createParser(polygonGeoJson);
|
||||
parser.nextToken();
|
||||
shape = ShapeBuilder.parse(parser).build();
|
||||
|
||||
ElasticsearchGeoAssertions.assertMultiPolygon(shape);
|
||||
}
|
||||
|
||||
// @Test
|
||||
// public void testParse_polygonWithHolesWKTReorder() throws IOException {
|
||||
//
|
||||
// }
|
||||
@Test
|
||||
public void testParse_OGCPolygonWithHoles() throws IOException {
|
||||
// test ccw poly not crossing dateline
|
||||
String polygonGeoJson = XContentFactory.jsonBuilder().startObject().field("type", "Polygon")
|
||||
.startArray("coordinates")
|
||||
.startArray()
|
||||
.startArray().value(176.0).value(15.0).endArray()
|
||||
.startArray().value(-177.0).value(10.0).endArray()
|
||||
.startArray().value(-177.0).value(-10.0).endArray()
|
||||
.startArray().value(176.0).value(-15.0).endArray()
|
||||
.startArray().value(172.0).value(0.0).endArray()
|
||||
.startArray().value(176.0).value(15.0).endArray()
|
||||
.endArray()
|
||||
.startArray()
|
||||
.startArray().value(-172.0).value(8.0).endArray()
|
||||
.startArray().value(174.0).value(10.0).endArray()
|
||||
.startArray().value(-172.0).value(-8.0).endArray()
|
||||
.startArray().value(-172.0).value(8.0).endArray()
|
||||
.endArray()
|
||||
.endArray()
|
||||
.endObject().string();
|
||||
|
||||
XContentParser parser = JsonXContent.jsonXContent.createParser(polygonGeoJson);
|
||||
parser.nextToken();
|
||||
Shape shape = ShapeBuilder.parse(parser).build();
|
||||
|
||||
ElasticsearchGeoAssertions.assertPolygon(shape);
|
||||
|
||||
// test ccw poly crossing dateline
|
||||
polygonGeoJson = XContentFactory.jsonBuilder().startObject().field("type", "Polygon")
|
||||
.startArray("coordinates")
|
||||
.startArray()
|
||||
.startArray().value(-177.0).value(10.0).endArray()
|
||||
.startArray().value(176.0).value(15.0).endArray()
|
||||
.startArray().value(172.0).value(0.0).endArray()
|
||||
.startArray().value(176.0).value(-15.0).endArray()
|
||||
.startArray().value(-177.0).value(-10.0).endArray()
|
||||
.startArray().value(-177.0).value(10.0).endArray()
|
||||
.endArray()
|
||||
.startArray()
|
||||
.startArray().value(178.0).value(8.0).endArray()
|
||||
.startArray().value(-178.0).value(8.0).endArray()
|
||||
.startArray().value(-180.0).value(-8.0).endArray()
|
||||
.startArray().value(178.0).value(8.0).endArray()
|
||||
.endArray()
|
||||
.endArray()
|
||||
.endObject().string();
|
||||
|
||||
parser = JsonXContent.jsonXContent.createParser(polygonGeoJson);
|
||||
parser.nextToken();
|
||||
shape = ShapeBuilder.parse(parser).build();
|
||||
|
||||
ElasticsearchGeoAssertions.assertMultiPolygon(shape);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParse_invalidPolygon() throws IOException {
|
||||
|
|
|
@ -246,35 +246,35 @@ public class ShapeBuilderTests extends ElasticsearchTestCase {
|
|||
|
||||
// a giant c shape
|
||||
PolygonBuilder builder = ShapeBuilder.newPolygon()
|
||||
.point(174,0)
|
||||
.point(-176,0)
|
||||
.point(-176,3)
|
||||
.point(177,3)
|
||||
.point(177,5)
|
||||
.point(-176,5)
|
||||
.point(-176,8)
|
||||
.point(174,8)
|
||||
.point(174,0);
|
||||
.point(174,0)
|
||||
.point(-176,0)
|
||||
.point(-176,3)
|
||||
.point(177,3)
|
||||
.point(177,5)
|
||||
.point(-176,5)
|
||||
.point(-176,8)
|
||||
.point(174,8)
|
||||
.point(174,0);
|
||||
|
||||
// 3/4 of an embedded 'c', crossing dateline once
|
||||
builder.hole()
|
||||
.point(175, 1)
|
||||
.point(175, 7)
|
||||
.point(-178, 7)
|
||||
.point(-178, 6)
|
||||
.point(176, 6)
|
||||
.point(176, 2)
|
||||
.point(179, 2)
|
||||
.point(179,1)
|
||||
.point(175, 1);
|
||||
.point(175, 1)
|
||||
.point(175, 7)
|
||||
.point(-178, 7)
|
||||
.point(-178, 6)
|
||||
.point(176, 6)
|
||||
.point(176, 2)
|
||||
.point(179, 2)
|
||||
.point(179,1)
|
||||
.point(175, 1);
|
||||
|
||||
// embedded hole right of the dateline
|
||||
builder.hole()
|
||||
.point(-179, 1)
|
||||
.point(-179, 2)
|
||||
.point(-177, 2)
|
||||
.point(-177,1)
|
||||
.point(-179,1);
|
||||
.point(-179, 1)
|
||||
.point(-179, 2)
|
||||
.point(-177, 2)
|
||||
.point(-177,1)
|
||||
.point(-179,1);
|
||||
|
||||
Shape shape = builder.close().build();
|
||||
|
||||
|
|
Loading…
Reference in New Issue