Adding unit test for self intersecting polygons. Relevant to #7751 even/odd discussion
Updating documentation to describe polygon ambiguity and vertex ordering.
This commit is contained in:
parent
437afd6f45
commit
ac0e37449e
|
@ -157,7 +157,7 @@ units, which default to `METERS`.
|
|||
For all types, both the inner `type` and `coordinates` fields are
|
||||
required.
|
||||
|
||||
Note: In GeoJSON, and therefore Elasticsearch, the correct *coordinate
|
||||
In GeoJSON, and therefore Elasticsearch, the correct *coordinate
|
||||
order is longitude, latitude (X, Y)* within coordinate arrays. This
|
||||
differs from many Geospatial APIs (e.g., Google Maps) that generally
|
||||
use the colloquial latitude, longitude (Y, X).
|
||||
|
@ -235,6 +235,36 @@ arrays represent the interior shapes ("holes"):
|
|||
}
|
||||
--------------------------------------------------
|
||||
|
||||
*IMPORTANT NOTE:* GeoJSON does not mandate a specific order for vertices thus ambiguous
|
||||
polygons around the dateline and poles are possible. To alleviate ambiguity
|
||||
the Open Geospatial Consortium (OGC)
|
||||
http://www.opengeospatial.org/standards/sfa[Simple Feature Access] specification
|
||||
defines the following vertex ordering:
|
||||
|
||||
* Outer Ring - Counterclockwise
|
||||
* Inner Ring(s) / Holes - Clockwise
|
||||
|
||||
For polygons that do not cross the dateline, vertex order will not matter in
|
||||
Elasticsearch. For polygons that do cross the dateline, Elasticsearch requires
|
||||
vertex orderinging comply with the OGC specification. Otherwise, an unintended polygon
|
||||
may be created and unexpected query/filter results will be returned.
|
||||
|
||||
The following provides an example of an ambiguous polygon. Elasticsearch will apply
|
||||
OGC standards to eliminate ambiguity resulting in a polygon that crosses the dateline.
|
||||
|
||||
[source,js]
|
||||
--------------------------------------------------
|
||||
{
|
||||
"location" : {
|
||||
"type" : "polygon",
|
||||
"coordinates" : [
|
||||
[ [-177.0, 10.0], [176.0, 15.0], [172.0, 0.0], [176.0, -15.0], [-177.0, -10.0], [-177.0, 10.0] ],
|
||||
[ [178.2, 8.2], [-178.8, 8.2], [-180.8, -8.8], [178.2, 8.8] ]
|
||||
]
|
||||
}
|
||||
}
|
||||
--------------------------------------------------
|
||||
|
||||
[float]
|
||||
===== http://www.geojson.org/geojson-spec.html#id5[MultiPoint]
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
package org.elasticsearch.common.geo;
|
||||
|
||||
import com.spatial4j.core.exception.InvalidShapeException;
|
||||
import com.spatial4j.core.shape.Circle;
|
||||
import com.spatial4j.core.shape.Rectangle;
|
||||
import com.spatial4j.core.shape.Shape;
|
||||
|
@ -430,6 +431,28 @@ public class GeoJSONShapeParserTests extends ElasticsearchTestCase {
|
|||
assertGeometryEquals(jtsGeom(expected), polygonGeoJson);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParse_selfCrossingPolygon() throws IOException {
|
||||
// test self crossing 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(-177.0).value(15.0).endArray()
|
||||
.startArray().value(172.0).value(0.0).endArray()
|
||||
.startArray().value(176.0).value(15.0).endArray()
|
||||
.endArray()
|
||||
.endArray()
|
||||
.endObject().string();
|
||||
|
||||
XContentParser parser = JsonXContent.jsonXContent.createParser(polygonGeoJson);
|
||||
parser.nextToken();
|
||||
ElasticsearchGeoAssertions.assertValidException(parser, InvalidShapeException.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParse_multiPoint() throws IOException {
|
||||
String multiPointGeoJson = XContentFactory.jsonBuilder().startObject().field("type", "MultiPoint")
|
||||
|
|
|
@ -251,7 +251,7 @@ public class ElasticsearchGeoAssertions {
|
|||
|
||||
public static void assertValidException(XContentParser parser, Class expectedException) {
|
||||
try {
|
||||
ShapeBuilder.parse(parser);
|
||||
ShapeBuilder.parse(parser).build();
|
||||
Assert.fail("process completed successfully when " + expectedException.getName() + " expected");
|
||||
} catch (Exception e) {
|
||||
assert(e.getClass().equals(expectedException)):
|
||||
|
|
Loading…
Reference in New Issue