LUCENE-7226: Remove independent check for backtrack, and remove GeoPolygonFactory methods that use point index for anything.

This commit is contained in:
Karl Wright 2016-04-17 15:37:02 -04:00
parent 35e0e92bb3
commit e90ed57b94
7 changed files with 37 additions and 131 deletions

View File

@ -81,7 +81,7 @@ public class Geo3dRptTest extends RandomSpatialOpStrategyTestCase {
points.add(new GeoPoint(PlanetModel.SPHERE, 14 * DEGREES_TO_RADIANS, -180 * DEGREES_TO_RADIANS));
points.add(new GeoPoint(PlanetModel.SPHERE, -15 * DEGREES_TO_RADIANS, 153 * DEGREES_TO_RADIANS));
final Shape triangle = new Geo3dShape(GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, points,0),ctx);
final Shape triangle = new Geo3dShape(GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, points),ctx);
final Rectangle rect = ctx.makeRectangle(-49, -45, 73, 86);
testOperation(rect,SpatialOperation.Intersects,triangle, false);
}
@ -119,8 +119,7 @@ public class Geo3dRptTest extends RandomSpatialOpStrategyTestCase {
geoPoints.add(new GeoPoint(PlanetModel.SPHERE, y1 * DEGREES_TO_RADIANS, x1 * DEGREES_TO_RADIANS));
geoPoints.add(new GeoPoint(PlanetModel.SPHERE, y2 * DEGREES_TO_RADIANS, x2 * DEGREES_TO_RADIANS));
geoPoints.add(new GeoPoint(PlanetModel.SPHERE, y3 * DEGREES_TO_RADIANS, x3 * DEGREES_TO_RADIANS));
final int convexPointIndex = 0;
final GeoShape shape = GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, geoPoints, convexPointIndex);
final GeoShape shape = GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, geoPoints);
return new Geo3dShape(shape, ctx);
}
@ -145,7 +144,7 @@ public class Geo3dRptTest extends RandomSpatialOpStrategyTestCase {
}
final int convexPointIndex = random().nextInt(vertexCount); //If we get this wrong, hopefully we get IllegalArgumentException
try {
final GeoShape shape = GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, geoPoints, convexPointIndex);
final GeoShape shape = GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, geoPoints);
return new Geo3dShape(shape, ctx);
} catch (IllegalArgumentException e) {
// This is what happens when we create a shape that is invalid. Although it is conceivable that there are cases where

View File

@ -184,9 +184,8 @@ public abstract class Geo3dShapeRectRelationTestCase extends RandomizedShapeTest
final GeoPoint gPt = new GeoPoint(planetModel, point.getY() * DEGREES_TO_RADIANS, point.getX() * DEGREES_TO_RADIANS);
geoPoints.add(gPt);
}
final int convexPointIndex = random().nextInt(vertexCount); //If we get this wrong, hopefully we get IllegalArgumentException
try {
final GeoShape shape = GeoPolygonFactory.makeGeoPolygon(planetModel, geoPoints, convexPointIndex);
final GeoShape shape = GeoPolygonFactory.makeGeoPolygon(planetModel, geoPoints);
return new Geo3dShape(planetModel, shape, ctx);
} catch (IllegalArgumentException e) {
// This is what happens when we create a shape that is invalid. Although it is conceivable that there are cases where

View File

@ -40,10 +40,10 @@ public class Geo3dShapeSphereModelRectRelationTest extends Geo3dShapeRectRelatio
public void testFailure1() {
final GeoBBox rect = GeoBBoxFactory.makeGeoBBox(planetModel, 88 * RADIANS_PER_DEGREE, 30 * RADIANS_PER_DEGREE, -30 * RADIANS_PER_DEGREE, 62 * RADIANS_PER_DEGREE);
final List<GeoPoint> points = new ArrayList<>();
points.add(new GeoPoint(planetModel, 66.2465299717 * RADIANS_PER_DEGREE, -29.1786158537 * RADIANS_PER_DEGREE));
points.add(new GeoPoint(planetModel, 43.684447915 * RADIANS_PER_DEGREE, 46.2210986329 * RADIANS_PER_DEGREE));
points.add(new GeoPoint(planetModel, 30.4579218227 * RADIANS_PER_DEGREE, 14.5238410082 * RADIANS_PER_DEGREE));
final GeoShape path = GeoPolygonFactory.makeGeoPolygon(planetModel, points,0);
points.add(new GeoPoint(planetModel, 43.684447915 * RADIANS_PER_DEGREE, 46.2210986329 * RADIANS_PER_DEGREE));
points.add(new GeoPoint(planetModel, 66.2465299717 * RADIANS_PER_DEGREE, -29.1786158537 * RADIANS_PER_DEGREE));
final GeoShape path = GeoPolygonFactory.makeGeoPolygon(planetModel, points);
final GeoPoint point = new GeoPoint(planetModel, 34.2730264413182 * RADIANS_PER_DEGREE, 82.75500168892472 * RADIANS_PER_DEGREE);

View File

@ -35,49 +35,6 @@ public class GeoPolygonFactory {
private GeoPolygonFactory() {
}
/**
* Create a GeoMembershipShape of the right kind given the specified bounds.
*
* @param pointList is a list of the GeoPoints to build an arbitrary polygon out of.
* @param convexPointIndex is the index of a single convex point whose conformation with
* its neighbors determines inside/outside for the entire polygon.
* @return a GeoPolygon corresponding to what was specified.
*/
public static GeoPolygon makeGeoPolygon(final PlanetModel planetModel,
final List<GeoPoint> pointList,
final int convexPointIndex) {
return makeGeoPolygon(planetModel, pointList, convexPointIndex, null);
}
/**
* Create a GeoMembershipShape of the right kind given the specified bounds.
*
* @param pointList is a list of the GeoPoints to build an arbitrary polygon out of.
* @param convexPointIndex is the index of a single convex point whose conformation with
* its neighbors determines inside/outside for the entire polygon.
* @param holes is a list of polygons representing "holes" in the outside polygon. Null == none.
* @return a GeoPolygon corresponding to what was specified.
*/
public static GeoPolygon makeGeoPolygon(final PlanetModel planetModel,
final List<GeoPoint> pointList,
final int convexPointIndex,
final List<GeoPolygon> holes) {
// The basic operation uses a set of points, two points determining one particular edge, and a sided plane
// describing membership.
//System.out.println("Initial point list = "+pointList+"; convexPointIndex = "+convexPointIndex+"; holes = "+holes);
final GeoCompositePolygon rval = new GeoCompositePolygon();
if (buildPolygonShape(rval,
planetModel, pointList, new BitSet(),
convexPointIndex, getLegalIndex(convexPointIndex + 1, pointList.size()),
new SidedPlane(pointList.get(getLegalIndex(convexPointIndex - 1, pointList.size())),
pointList.get(convexPointIndex), pointList.get(getLegalIndex(convexPointIndex + 1, pointList.size()))),
holes,
null) == false) {
return null;
}
return rval;
}
/** Create a GeoPolygon using the specified points and holes, using order to determine
* siding of the polygon. Much like ESRI, this method uses clockwise to indicate the space
* on the same side of the shape as being inside, and counter-clockwise to indicate the
@ -108,8 +65,7 @@ public class GeoPolygonFactory {
// Create a random number generator. Effectively this furnishes us with a repeatable sequence
// of points to use for poles.
final Random generator = new Random(1234);
//int counter = 0;
while (true) {
for (int counter = 0; counter < 10000; counter++) {
//counter++;
// Pick the next random pole
final GeoPoint pole = pickPole(generator, planetModel, pointList);
@ -123,6 +79,7 @@ public class GeoPolygonFactory {
}
// If pole choice was illegal, try another one
}
throw new IllegalArgumentException("cannot find a point that is inside the polygon");
}
/**
@ -1192,7 +1149,7 @@ public class GeoPolygonFactory {
// The new point is colinear with the current edge. We'll have to look backwards for the first point that isn't.
int checkPointIndex = -1;
// Compute the arc distance before we try to extend, so that we note backtracking when we see it
double accumulatedDistance = newPoint.arcDistance(pointList.get(startIndex));
//double accumulatedDistance = newPoint.arcDistance(pointList.get(startIndex));
final Plane checkPlane = new Plane(pointList.get(startIndex), newPoint);
for (int i = 0; i < pointList.size(); i++) {
final int index = getLegalIndex(startIndex - 1 - i, pointList.size());
@ -1200,11 +1157,11 @@ public class GeoPolygonFactory {
checkPointIndex = index;
break;
} else {
accumulatedDistance += pointList.get(getLegalIndex(index+1, pointList.size())).arcDistance(pointList.get(index));
final double actualDistance = newPoint.arcDistance(pointList.get(index));
if (Math.abs(actualDistance - accumulatedDistance) >= Vector.MINIMUM_RESOLUTION) {
throw new IllegalArgumentException("polygon backtracks over itself");
}
//accumulatedDistance += pointList.get(getLegalIndex(index+1, pointList.size())).arcDistance(pointList.get(index));
//final double actualDistance = newPoint.arcDistance(pointList.get(index));
//if (Math.abs(actualDistance - accumulatedDistance) >= Vector.MINIMUM_RESOLUTION) {
// throw new IllegalArgumentException("polygon backtracks over itself");
//}
}
}
if (checkPointIndex == -1) {

View File

@ -613,9 +613,8 @@ public class TestGeo3DPoint extends LuceneTestCase {
final GeoPoint gPt = new GeoPoint(PlanetModel.WGS84, toRadians(GeoTestUtil.nextLatitude()), toRadians(GeoTestUtil.nextLongitude()));
geoPoints.add(gPt);
}
final int convexPointIndex = random().nextInt(vertexCount); //If we get this wrong, hopefully we get IllegalArgumentException
try {
return GeoPolygonFactory.makeGeoPolygon(PlanetModel.WGS84, geoPoints, convexPointIndex);
return GeoPolygonFactory.makeGeoPolygon(PlanetModel.WGS84, geoPoints);
} catch (IllegalArgumentException e) {
// This is what happens when we create a shape that is invalid. Although it is conceivable that there are cases where
// the exception is thrown incorrectly, we aren't going to be able to do that in this random test.

View File

@ -35,10 +35,10 @@ public class GeoBBoxTest {
GeoConvexPolygon cp;
int relationship;
List<GeoPoint> points = new ArrayList<GeoPoint>();
points.add(new GeoPoint(PlanetModel.SPHERE, 24 * DEGREES_TO_RADIANS, -30 * DEGREES_TO_RADIANS));
points.add(new GeoPoint(PlanetModel.SPHERE, -11 * DEGREES_TO_RADIANS, 101 * DEGREES_TO_RADIANS));
points.add(new GeoPoint(PlanetModel.SPHERE, -49 * DEGREES_TO_RADIANS, -176 * DEGREES_TO_RADIANS));
GeoMembershipShape shape = GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, points, 0);
points.add(new GeoPoint(PlanetModel.SPHERE, -11 * DEGREES_TO_RADIANS, 101 * DEGREES_TO_RADIANS));
points.add(new GeoPoint(PlanetModel.SPHERE, 24 * DEGREES_TO_RADIANS, -30 * DEGREES_TO_RADIANS));
GeoMembershipShape shape = GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, points);
box = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, -64 * DEGREES_TO_RADIANS, -64 * DEGREES_TO_RADIANS, -180 * DEGREES_TO_RADIANS, 180 * DEGREES_TO_RADIANS);
relationship = box.getRelationship(shape);
assertEquals(GeoArea.CONTAINS, relationship);

View File

@ -136,12 +136,12 @@ public class GeoPolygonTest {
List<GeoPoint> points;
points = new ArrayList<GeoPoint>();
points.add(new GeoPoint(PlanetModel.SPHERE, -0.1, -0.5));
points.add(new GeoPoint(PlanetModel.SPHERE, 0.0, -0.6));
points.add(new GeoPoint(PlanetModel.SPHERE, 0.1, -0.5));
points.add(new GeoPoint(PlanetModel.SPHERE, 0.0, -0.4));
points.add(new GeoPoint(PlanetModel.SPHERE, 0.1, -0.5));
points.add(new GeoPoint(PlanetModel.SPHERE, 0.0, -0.6));
points.add(new GeoPoint(PlanetModel.SPHERE, -0.1, -0.5));
c = GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, points, 0);
c = GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, points);
// Sample some points within
gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.5);
assertTrue(c.isWithin(gp));
@ -171,14 +171,14 @@ public class GeoPolygonTest {
assertFalse(c.isWithin(gp));
points = new ArrayList<GeoPoint>();
points.add(new GeoPoint(PlanetModel.SPHERE, -0.1, -0.5));
points.add(new GeoPoint(PlanetModel.SPHERE, -0.01, -0.6));
points.add(new GeoPoint(PlanetModel.SPHERE, -0.1, -0.7));
points.add(new GeoPoint(PlanetModel.SPHERE, 0.0, -0.8));
points.add(new GeoPoint(PlanetModel.SPHERE, 0.1, -0.7));
points.add(new GeoPoint(PlanetModel.SPHERE, 0.01, -0.6));
points.add(new GeoPoint(PlanetModel.SPHERE, 0.1, -0.5));
points.add(new GeoPoint(PlanetModel.SPHERE, 0.0, -0.4));
points.add(new GeoPoint(PlanetModel.SPHERE, 0.1, -0.5));
points.add(new GeoPoint(PlanetModel.SPHERE, 0.01, -0.6));
points.add(new GeoPoint(PlanetModel.SPHERE, 0.1, -0.7));
points.add(new GeoPoint(PlanetModel.SPHERE, 0.0, -0.8));
points.add(new GeoPoint(PlanetModel.SPHERE, -0.1, -0.7));
points.add(new GeoPoint(PlanetModel.SPHERE, -0.01, -0.6));
points.add(new GeoPoint(PlanetModel.SPHERE, -0.1, -0.5));
/*
System.out.println("Points: ");
@ -187,7 +187,7 @@ public class GeoPolygonTest {
}
*/
c = GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, points, 0);
c = GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, points);
// Sample some points within
gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.5);
assertTrue(c.isWithin(gp));
@ -234,7 +234,7 @@ public class GeoPolygonTest {
points.add(new GeoPoint(PlanetModel.WGS84, -0.7376479402362607, -0.5072961758807019));
points.add(new GeoPoint(PlanetModel.WGS84, -0.3760415907667887, 1.4970455334565513));
c = GeoPolygonFactory.makeGeoPolygon(PlanetModel.WGS84, points, 1);
c = GeoPolygonFactory.makeGeoPolygon(PlanetModel.WGS84, points);
point = new GeoPoint(PlanetModel.WGS84, -0.01580760332365284, -0.03956004622490505);
assertTrue(c.isWithin(point));
@ -245,12 +245,12 @@ public class GeoPolygonTest {
assertTrue(area.isWithin(point));
points = new ArrayList<GeoPoint>();
points.add(new GeoPoint(PlanetModel.SPHERE, -0.1, -0.5));
points.add(new GeoPoint(PlanetModel.SPHERE, 0.0, -0.6));
points.add(new GeoPoint(PlanetModel.SPHERE, 0.1, -0.5));
points.add(new GeoPoint(PlanetModel.SPHERE, 0.0, -0.4));
points.add(new GeoPoint(PlanetModel.SPHERE, 0.1, -0.5));
points.add(new GeoPoint(PlanetModel.SPHERE, 0.0, -0.6));
points.add(new GeoPoint(PlanetModel.SPHERE, -0.1, -0.5));
c = GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, points, 0);
c = GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, points);
b = new LatLonBounds();
c.getBounds(b);
@ -279,7 +279,7 @@ public class GeoPolygonTest {
points.add(new GeoPoint(PlanetModel.WGS84, -0.9796549195552824, -0.25078026625235256));
points.add(new GeoPoint(PlanetModel.WGS84, 0.17644522781457245, 2.4225312555674967));
points.add(new GeoPoint(PlanetModel.WGS84, -1.4459804612164617, -1.2970934639728127));
c = GeoPolygonFactory.makeGeoPolygon(PlanetModel.WGS84, points, 3);
c = GeoPolygonFactory.makeGeoPolygon(PlanetModel.WGS84, points);
// GeoCompositeMembershipShape: {[GeoConvexPolygon: {planetmodel=PlanetModel.WGS84, points=
// [[lat=0.17644522781457245, lon=2.4225312555674967],
// [lat=-1.4459804612164617, lon=-1.2970934639728127],
@ -442,52 +442,4 @@ shape:
final GeoPolygon p = GeoPolygonFactory.makeGeoPolygon(PlanetModel.WGS84, points, null);
}
@Test
public void testPolygonIntersectionFailure1() {
final PlanetModel pm = PlanetModel.WGS84;
//[junit4] > Throwable #1: java.lang.AssertionError: invalid hits for shape=GeoCompositeMembershipShape:
//{[GeoConvexPolygon: {planetmodel=PlanetModel.WGS84, points=
//[[lat=0.2669499069140678, lon=-0.31249902828113546([X=0.9186752334433793, Y=-0.2968103450748192, Z=0.2640238502385029])],
//[lat=1.538559019421765, lon=0.0([X=0.03215971057004023, Y=0.0, Z=0.9972473454662941])],
//[lat=-0.5516194571595735, lon=0.0([X=0.8518418310766115, Y=0.0, Z=-0.5241686363384119])]], internalEdges={2}},
//GeoConvexPolygon: {planetmodel=PlanetModel.WGS84, points=
//[[lat=0.0, lon=-3.141592653589793([X=-1.0011188539924791, Y=-1.226017000107956E-16, Z=0.0])],
//[lat=-1.5707963267948966, lon=-2.2780601241431375([X=-3.9697069088211677E-17, Y=-4.644115432258393E-17, Z=-0.997762292022105])],
//[lat=0.2669499069140678, lon=-0.31249902828113546([X=0.9186752334433793, Y=-0.2968103450748192, Z=0.2640238502385029])]], internalEdges={2}},
//GeoConvexPolygon: {planetmodel=PlanetModel.WGS84, points=
//[[lat=0.2669499069140678, lon=-0.31249902828113546([X=0.9186752334433793, Y=-0.2968103450748192, Z=0.2640238502385029])],
//[lat=-0.5516194571595735, lon=0.0([X=0.8518418310766115, Y=0.0, Z=-0.5241686363384119])],
//[lat=0.0, lon=-3.141592653589793([X=-1.0011188539924791, Y=-1.226017000107956E-16, Z=0.0])]], internalEdges={0, 2}}]}
// Build the polygon
//[[lat=-0.5516194571595735, lon=0.0([X=0.8518418310766115, Y=0.0, Z=-0.5241686363384119])],
//[lat=0.0, lon=-3.141592653589793([X=-1.0011188539924791, Y=-1.226017000107956E-16, Z=0.0])],
//[lat=-1.5707963267948966, lon=-2.2780601241431375([X=-3.9697069088211677E-17, Y=-4.644115432258393E-17, Z=-0.997762292022105])],
//[lat=0.2669499069140678, lon=-0.31249902828113546([X=0.9186752334433793, Y=-0.2968103450748192, Z=0.2640238502385029])],
//[lat=1.538559019421765, lon=0.0([X=0.03215971057004023, Y=0.0, Z=0.9972473454662941])]]
List<GeoPoint> polyPoints = new ArrayList<>();
polyPoints.add(new GeoPoint(pm, -0.5516194571595735, 0.0));
polyPoints.add(new GeoPoint(pm, 0.0, -3.141592653589793));
polyPoints.add(new GeoPoint(pm, -1.5707963267948966, -2.2780601241431375));
polyPoints.add(new GeoPoint(pm, 0.2669499069140678, -0.31249902828113546));
polyPoints.add(new GeoPoint(pm, 1.538559019421765, 0.0));
// Make sure we catch the backtrack
boolean backtracks = false;
try {
GeoPolygonFactory.makeGeoPolygon(pm, polyPoints, 4, null);
} catch (IllegalArgumentException e) {
backtracks = true;
}
assertTrue(backtracks);
// Now make sure a legit poly with coplanar points works.
polyPoints.clear();
polyPoints.add(new GeoPoint(pm, -0.5516194571595735, 0.0));
polyPoints.add(new GeoPoint(pm, -1.5707963267948966, -2.2780601241431375));
polyPoints.add(new GeoPoint(pm, 0.2669499069140678, -0.31249902828113546));
polyPoints.add(new GeoPoint(pm, 1.538559019421765, 0.0));
GeoPolygonFactory.makeGeoPolygon(pm, polyPoints, 3, null);
}
}