LUCENE-7412: Make sure no combined edge of a polygon extends for more than 180 degrees.

This commit is contained in:
Karl Wright 2016-08-20 07:35:38 -04:00
parent 22eeba9920
commit aa9b5204da
3 changed files with 54 additions and 5 deletions

View File

@ -237,7 +237,21 @@ class GeoConcavePolygon extends GeoBasePolygon {
while (invertedEdges[legalIndex(bound2Index)].isNumericallyIdentical(invertedEdge)) {
bound2Index--;
}
eitherBounds.put(edge, new EitherBound(invertedEdges[legalIndex(bound1Index)], invertedEdges[legalIndex(bound2Index)]));
bound1Index = legalIndex(bound1Index);
bound2Index = legalIndex(bound2Index);
// Also confirm that all interior points are within the bounds
int startingIndex = bound2Index;
while (true) {
startingIndex = legalIndex(startingIndex+1);
if (startingIndex == bound1Index) {
break;
}
final GeoPoint interiorPoint = points.get(startingIndex);
if (!invertedEdges[bound1Index].isWithin(interiorPoint) || !invertedEdges[bound2Index].isWithin(interiorPoint)) {
throw new IllegalArgumentException("Concave polygon has a side that is more than 180 degrees");
}
}
eitherBounds.put(edge, new EitherBound(invertedEdges[bound1Index], invertedEdges[bound2Index]));
// For intersections, we look at the point at the intersection between the previous edge and this one. We need to locate the
// Intersection bounds needs to look even further forwards/backwards
if (otherInvertedEdge != null) {

View File

@ -230,7 +230,21 @@ class GeoConvexPolygon extends GeoBasePolygon {
while (edges[legalIndex(bound2Index)].isNumericallyIdentical(edge)) {
bound2Index--;
}
eitherBounds.put(edge, new EitherBound(edges[legalIndex(bound1Index)], edges[legalIndex(bound2Index)]));
bound1Index = legalIndex(bound1Index);
bound2Index = legalIndex(bound2Index);
// Also confirm that all interior points are within the bounds
int startingIndex = bound2Index;
while (true) {
startingIndex = legalIndex(startingIndex+1);
if (startingIndex == bound1Index) {
break;
}
final GeoPoint interiorPoint = points.get(startingIndex);
if (!edges[bound1Index].isWithin(interiorPoint) || !edges[bound2Index].isWithin(interiorPoint)) {
throw new IllegalArgumentException("Convex polygon has a side that is more than 180 degrees");
}
}
eitherBounds.put(edge, new EitherBound(edges[bound1Index], edges[bound2Index]));
// For intersections, we look at the point at the intersection between the previous edge and this one. We need to locate the
// Intersection bounds needs to look even further forwards/backwards
if (otherEdge != null) {

View File

@ -692,7 +692,7 @@ shape:
polyList.add(p5);
GeoPolygon p = GeoPolygonFactory.makeGeoPolygon(PlanetModel.WGS84, polyList);
System.out.println("p = "+p);
//System.out.println("p = "+p);
XYZBounds bounds = new XYZBounds();
p.getBounds(bounds);
@ -733,8 +733,8 @@ shape:
final GeoPoint point = new GeoPoint(PlanetModel.WGS84, -0.41518838180529244, 3.141592653589793);
final GeoPoint encodedPoint = new GeoPoint(-0.9155623168963972, 2.3309121299774915E-10, -0.40359240449795253);
System.out.println("point = "+point);
System.out.println("encodedPoint = "+encodedPoint);
//System.out.println("point = "+point);
//System.out.println("encodedPoint = "+encodedPoint);
assertTrue(p.isWithin(point));
assertTrue(solid.isWithin(point));
@ -906,5 +906,26 @@ shape:
assertTrue(solid.isWithin(checkPoint));
}
@Test
public void testPolygonFailureCase1() {
final List<GeoPoint> poly2List = new ArrayList<>();
poly2List.add(new GeoPoint(PlanetModel.WGS84, -0.6370451769779303, 2.5318373679431616));
poly2List.add(new GeoPoint(PlanetModel.WGS84, 1.5707963267948966, -3.141592653589793));
poly2List.add(new GeoPoint(PlanetModel.WGS84, -1.0850383189690824, 2.4457272005608357E-47));
poly2List.add(new GeoPoint(PlanetModel.WGS84, -0.5703530503197992, -3.141592653589793));
final BitSet poly2Bitset = new BitSet();
poly2Bitset.set(1);
boolean result;
try {
final GeoConvexPolygon poly2 = new GeoConvexPolygon(PlanetModel.WGS84, poly2List);
result = true;
} catch (IllegalArgumentException e) {
result = false;
}
assertTrue(!result);
}
}