mirror of
https://github.com/honeymoose/OpenSearch.git
synced 2025-02-25 22:36:20 +00:00
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.
|
// 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
|
// 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
|
// 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
|
// 2. the second logic check ensures the two candidate edges aren't already connected by an
|
||||||
// existing along the dateline - this is necessary due to a logic change that
|
// existing edge along the dateline - this is necessary due to a logic change in
|
||||||
// computes dateline edges as valid intersect points in support of OGC standards
|
// 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
|
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
|
&& !(e1.next.next.coordinate.equals3D(e2.coordinate) && Math.abs(e1.next.coordinate.x) == DATELINE
|
||||||
&& Math.abs(e2.coordinate.x) == DATELINE) ) {
|
&& Math.abs(e2.coordinate.x) == DATELINE) ) {
|
||||||
|
@ -486,7 +486,7 @@ public abstract class ShapeBuilder implements ToXContent {
|
|||||||
* @return Array of edges
|
* @return Array of edges
|
||||||
*/
|
*/
|
||||||
protected static Edge[] ring(int component, boolean direction, BaseLineStringBuilder<?> shell, Coordinate[] points, int offset,
|
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:
|
// calculate the direction of the points:
|
||||||
// find the point a the top of the set and check its
|
// find the point a the top of the set and check its
|
||||||
// neighbors orientation. So direction is equivalent
|
// neighbors orientation. So direction is equivalent
|
||||||
@ -505,11 +505,11 @@ public abstract class ShapeBuilder implements ToXContent {
|
|||||||
Pair<Pair, Pair> range = range(points, offset, length);
|
Pair<Pair, Pair> range = range(points, offset, length);
|
||||||
final double rng = (Double)range.getLeft().getRight() - (Double)range.getLeft().getLeft();
|
final double rng = (Double)range.getLeft().getRight() - (Double)range.getLeft().getLeft();
|
||||||
// translate the points if the following is true
|
// 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
|
// 1. shell orientation is cw and range is greater than a hemisphere (180 degrees) but not spanning 2 hemispheres
|
||||||
// a collapsed poly)
|
// (translation would result in a collapsed poly)
|
||||||
// 2. the shell of the candidate hole has been translated (to preserve the coordinate system)
|
// 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)) {
|
if ((rng > DATELINE && rng != 2*DATELINE && orientation && component == 0) || (shell.translated && component != 0)) {
|
||||||
transform(points);
|
translate(points);
|
||||||
// flip the translation bit if the shell is being translated
|
// flip the translation bit if the shell is being translated
|
||||||
if (component == 0 && !shell.translated) {
|
if (component == 0 && !shell.translated) {
|
||||||
shell.translated = true;
|
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
|
* Transforms coordinates in the eastern hemisphere (-180:0) to a (180:360) range
|
||||||
* @param points
|
* @param points
|
||||||
*/
|
*/
|
||||||
protected static void transform(Coordinate[] points) {
|
protected static void translate(Coordinate[] points) {
|
||||||
for (Coordinate c : points) {
|
for (Coordinate c : points) {
|
||||||
if (c.x < 0) {
|
if (c.x < 0) {
|
||||||
c.x += 2*DATELINE;
|
c.x += 2*DATELINE;
|
||||||
|
@ -210,8 +210,8 @@ public class GeoJSONShapeParserTests extends ElasticsearchTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testParse_polygonNoHolesOGCCompliance() throws IOException {
|
public void testParse_OGCPolygonWithoutHoles() throws IOException {
|
||||||
// test ccw poly (large poly intended to not cross dateline)
|
// test ccw poly not crossing dateline
|
||||||
String polygonGeoJson = XContentFactory.jsonBuilder().startObject().field("type", "Polygon")
|
String polygonGeoJson = XContentFactory.jsonBuilder().startObject().field("type", "Polygon")
|
||||||
.startArray("coordinates")
|
.startArray("coordinates")
|
||||||
.startArray()
|
.startArray()
|
||||||
@ -229,7 +229,9 @@ public class GeoJSONShapeParserTests extends ElasticsearchTestCase {
|
|||||||
parser.nextToken();
|
parser.nextToken();
|
||||||
Shape shape = ShapeBuilder.parse(parser).build();
|
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")
|
polygonGeoJson = XContentFactory.jsonBuilder().startObject().field("type", "Polygon")
|
||||||
.startArray("coordinates")
|
.startArray("coordinates")
|
||||||
.startArray()
|
.startArray()
|
||||||
@ -246,12 +248,64 @@ public class GeoJSONShapeParserTests extends ElasticsearchTestCase {
|
|||||||
parser = JsonXContent.jsonXContent.createParser(polygonGeoJson);
|
parser = JsonXContent.jsonXContent.createParser(polygonGeoJson);
|
||||||
parser.nextToken();
|
parser.nextToken();
|
||||||
shape = ShapeBuilder.parse(parser).build();
|
shape = ShapeBuilder.parse(parser).build();
|
||||||
|
|
||||||
|
ElasticsearchGeoAssertions.assertMultiPolygon(shape);
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Test
|
@Test
|
||||||
// public void testParse_polygonWithHolesWKTReorder() throws IOException {
|
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
|
@Test
|
||||||
public void testParse_invalidPolygon() throws IOException {
|
public void testParse_invalidPolygon() throws IOException {
|
||||||
|
@ -246,35 +246,35 @@ public class ShapeBuilderTests extends ElasticsearchTestCase {
|
|||||||
|
|
||||||
// a giant c shape
|
// a giant c shape
|
||||||
PolygonBuilder builder = ShapeBuilder.newPolygon()
|
PolygonBuilder builder = ShapeBuilder.newPolygon()
|
||||||
.point(174,0)
|
.point(174,0)
|
||||||
.point(-176,0)
|
.point(-176,0)
|
||||||
.point(-176,3)
|
.point(-176,3)
|
||||||
.point(177,3)
|
.point(177,3)
|
||||||
.point(177,5)
|
.point(177,5)
|
||||||
.point(-176,5)
|
.point(-176,5)
|
||||||
.point(-176,8)
|
.point(-176,8)
|
||||||
.point(174,8)
|
.point(174,8)
|
||||||
.point(174,0);
|
.point(174,0);
|
||||||
|
|
||||||
// 3/4 of an embedded 'c', crossing dateline once
|
// 3/4 of an embedded 'c', crossing dateline once
|
||||||
builder.hole()
|
builder.hole()
|
||||||
.point(175, 1)
|
.point(175, 1)
|
||||||
.point(175, 7)
|
.point(175, 7)
|
||||||
.point(-178, 7)
|
.point(-178, 7)
|
||||||
.point(-178, 6)
|
.point(-178, 6)
|
||||||
.point(176, 6)
|
.point(176, 6)
|
||||||
.point(176, 2)
|
.point(176, 2)
|
||||||
.point(179, 2)
|
.point(179, 2)
|
||||||
.point(179,1)
|
.point(179,1)
|
||||||
.point(175, 1);
|
.point(175, 1);
|
||||||
|
|
||||||
// embedded hole right of the dateline
|
// embedded hole right of the dateline
|
||||||
builder.hole()
|
builder.hole()
|
||||||
.point(-179, 1)
|
.point(-179, 1)
|
||||||
.point(-179, 2)
|
.point(-179, 2)
|
||||||
.point(-177, 2)
|
.point(-177, 2)
|
||||||
.point(-177,1)
|
.point(-177,1)
|
||||||
.point(-179,1);
|
.point(-179,1);
|
||||||
|
|
||||||
Shape shape = builder.close().build();
|
Shape shape = builder.close().build();
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user