[GEO] Fix for geo_shape query with polygon from -180/90 to 180/-90

This fix adds a simple consistency check that intersection edges appear pairwise. Polygonal boundary tests were passing (false positive) on the Eastern side of the dateline simply due to the initial order (edge direction) of the intersection edges.  Polygons in the Eastern hemispehere (which were not being tested) were correctly failing inside of JTS due to an attempt to connect incorrect intersection edges (that is, edges that were not even intersections). While this patch fixes issue/8467 (and adds broader test coverage) it is not intented as a long term solution.  The mid term fix (in work) will refactor all geospatial computational geometry to use ENU / ECF coordinate systems for higher accuracy and eliminate brute force mercator checks and conversions.

Closes #8467
This commit is contained in:
Nicholas Knize 2014-11-17 16:23:03 -06:00
parent 1d7cdd7d22
commit fc955551d4
3 changed files with 35 additions and 2 deletions

View File

@ -395,7 +395,10 @@ public abstract class BasePolygonBuilder<E extends BasePolygonBuilder<E>> extend
holes[e2.component-1] = holes[numHoles];
holes[numHoles] = null;
}
connect(e1, e2);
// only connect edges if intersections are pairwise (per comment above)
if (e1.intersect != Edge.maxCoordinate() && e2.intersect != Edge.maxCoordinate()) {
connect(e1, e2);
}
}
return numHoles;
}

View File

@ -490,6 +490,10 @@ public abstract class ShapeBuilder implements ToXContent {
}
}
public static Coordinate maxCoordinate() {
return IntersectionOrder.SENTINEL;
}
@Override
public String toString() {
return "Edge[Component=" + component + "; start=" + coordinate + " " + "; intersection=" + intersect + "]";

View File

@ -394,6 +394,7 @@ public class ShapeBuilderTests extends ElasticsearchTestCase {
@Test
public void testShapeWithEdgeAlongDateline() {
// test case 1: test the positive side of the dateline
PolygonBuilder builder = ShapeBuilder.newPolygon()
.point(180, 0)
.point(176, 4)
@ -401,10 +402,35 @@ public class ShapeBuilderTests extends ElasticsearchTestCase {
.point(180, 0);
Shape shape = builder.close().build();
assertPolygon(shape);
assertPolygon(shape);
// test case 2: test the negative side of the dateline
builder = ShapeBuilder.newPolygon()
.point(-180, 0)
.point(-176, 4)
.point(-180, -4)
.point(-180, 0);
shape = builder.close().build();
assertPolygon(shape);
}
/**
* Test an enveloping polygon around the max mercator bounds
*/
@Test
public void testBoundaryShape() {
PolygonBuilder builder = ShapeBuilder.newPolygon()
.point(-180, 90)
.point(180, 90)
.point(180, -90)
.point(-180, -90);
Shape shape = builder.close().build();
assertPolygon(shape);
}
@Test
public void testShapeWithEdgeAcrossDateline() {
PolygonBuilder builder = ShapeBuilder.newPolygon()