diff --git a/src/main/java/org/elasticsearch/common/geo/builders/ShapeBuilder.java b/src/main/java/org/elasticsearch/common/geo/builders/ShapeBuilder.java index 41d207f37b5..2be99d4c837 100644 --- a/src/main/java/org/elasticsearch/common/geo/builders/ShapeBuilder.java +++ b/src/main/java/org/elasticsearch/common/geo/builders/ShapeBuilder.java @@ -508,14 +508,15 @@ public abstract class ShapeBuilder implements ToXContent { // 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 && component == 0) || (shell.translated && component != 0)) { + if (((component == 0 && orientation) && (rng > DATELINE && rng != 2*DATELINE)) + || (shell.translated && component != 0)) { translate(points); // flip the translation bit if the shell is being translated - if (component == 0 && !shell.translated) { + if (component == 0) { shell.translated = true; } // correct the orientation post translation (ccw for shell, cw for holes) - if ((component == 0 && orientation) || (component != 0 && !orientation)) { + if (component == 0 || (component != 0 && !orientation)) { orientation = !orientation; } } diff --git a/src/test/java/org/elasticsearch/common/geo/ShapeBuilderTests.java b/src/test/java/org/elasticsearch/common/geo/ShapeBuilderTests.java index de3f6446ae6..252b2402eec 100644 --- a/src/test/java/org/elasticsearch/common/geo/ShapeBuilderTests.java +++ b/src/test/java/org/elasticsearch/common/geo/ShapeBuilderTests.java @@ -240,7 +240,7 @@ public class ShapeBuilderTests extends ElasticsearchTestCase { } @Test - public void testDateline() { + public void testDatelineOGC() { // view shape at https://gist.github.com/anonymous/7f1bb6d7e9cd72f5977c // expect 3 polygons, 1 with a hole @@ -281,6 +281,48 @@ public class ShapeBuilderTests extends ElasticsearchTestCase { assertMultiPolygon(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); + } + @Test public void testComplexShapeWithHole() { PolygonBuilder builder = ShapeBuilder.newPolygon()