LUCENE-8337: Fix problems with how travel planes too close to edge of world are disallowed, and increase the size of the disallowed window by an order of magnitude.

This commit is contained in:
Karl Wright 2018-05-29 21:03:03 -04:00
parent 7ce6dbda18
commit ceb4f768bf
2 changed files with 34 additions and 20 deletions

View File

@ -74,7 +74,7 @@ class GeoComplexPolygon extends GeoBasePolygon {
private final GeoPoint[] edgePoints;
private final Edge[] shapeStartEdges;
private final static double NEAR_EDGE_CUTOFF = -Vector.MINIMUM_RESOLUTION * 1000.0;
private final static double NEAR_EDGE_CUTOFF = -Vector.MINIMUM_RESOLUTION * 10000.0;
/**
* Create a complex polygon from multiple lists of points, and a single point which is known to be in or out of
@ -143,37 +143,40 @@ class GeoComplexPolygon extends GeoBasePolygon {
this.testPoint1FixedZPlane = new Plane(0.0, 0.0, 1.0, -testPoint1.z);
Plane testPoint1FixedYAbovePlane = new Plane(testPoint1FixedYPlane, true);
if (testPoint1FixedYAbovePlane.D - planetModel.getMaximumYValue() > NEAR_EDGE_CUTOFF || planetModel.getMinimumYValue() - testPoint1FixedYAbovePlane.D > NEAR_EDGE_CUTOFF) {
// We compare the plane's Y value (etc), which is -D, with the planet's maximum and minimum Y poles.
if (-testPoint1FixedYAbovePlane.D - planetModel.getMaximumYValue() > NEAR_EDGE_CUTOFF || planetModel.getMinimumYValue() + testPoint1FixedYAbovePlane.D > NEAR_EDGE_CUTOFF) {
testPoint1FixedYAbovePlane = null;
}
this.testPoint1FixedYAbovePlane = testPoint1FixedYAbovePlane;
Plane testPoint1FixedYBelowPlane = new Plane(testPoint1FixedYPlane, false);
if (testPoint1FixedYBelowPlane.D - planetModel.getMaximumYValue() > NEAR_EDGE_CUTOFF || planetModel.getMinimumYValue() - testPoint1FixedYBelowPlane.D > NEAR_EDGE_CUTOFF) {
if (-testPoint1FixedYBelowPlane.D - planetModel.getMaximumYValue() > NEAR_EDGE_CUTOFF || planetModel.getMinimumYValue() + testPoint1FixedYBelowPlane.D > NEAR_EDGE_CUTOFF) {
testPoint1FixedYBelowPlane = null;
}
this.testPoint1FixedYBelowPlane = testPoint1FixedYBelowPlane;
Plane testPoint1FixedXAbovePlane = new Plane(testPoint1FixedXPlane, true);
if (testPoint1FixedXAbovePlane.D - planetModel.getMaximumXValue() > NEAR_EDGE_CUTOFF || planetModel.getMinimumXValue() - testPoint1FixedXAbovePlane.D > NEAR_EDGE_CUTOFF) {
if (-testPoint1FixedXAbovePlane.D - planetModel.getMaximumXValue() > NEAR_EDGE_CUTOFF || planetModel.getMinimumXValue() + testPoint1FixedXAbovePlane.D > NEAR_EDGE_CUTOFF) {
testPoint1FixedXAbovePlane = null;
}
this.testPoint1FixedXAbovePlane = testPoint1FixedXAbovePlane;
Plane testPoint1FixedXBelowPlane = new Plane(testPoint1FixedXPlane, false);
if (testPoint1FixedXBelowPlane.D - planetModel.getMaximumXValue() > NEAR_EDGE_CUTOFF || planetModel.getMinimumXValue() - testPoint1FixedXBelowPlane.D > NEAR_EDGE_CUTOFF) {
if (-testPoint1FixedXBelowPlane.D - planetModel.getMaximumXValue() > NEAR_EDGE_CUTOFF || planetModel.getMinimumXValue() + testPoint1FixedXBelowPlane.D > NEAR_EDGE_CUTOFF) {
testPoint1FixedXBelowPlane = null;
}
this.testPoint1FixedXBelowPlane = testPoint1FixedXBelowPlane;
Plane testPoint1FixedZAbovePlane = new Plane(testPoint1FixedZPlane, true);
if (testPoint1FixedZAbovePlane.D - planetModel.getMaximumZValue() > NEAR_EDGE_CUTOFF ||planetModel.getMinimumZValue() - testPoint1FixedZAbovePlane.D > NEAR_EDGE_CUTOFF) {
if (-testPoint1FixedZAbovePlane.D - planetModel.getMaximumZValue() > NEAR_EDGE_CUTOFF ||planetModel.getMinimumZValue() + testPoint1FixedZAbovePlane.D > NEAR_EDGE_CUTOFF) {
testPoint1FixedZAbovePlane = null;
}
this.testPoint1FixedZAbovePlane = testPoint1FixedZAbovePlane;
Plane testPoint1FixedZBelowPlane = new Plane(testPoint1FixedZPlane, false);
if (testPoint1FixedZBelowPlane.D - planetModel.getMaximumZValue() > NEAR_EDGE_CUTOFF || planetModel.getMinimumZValue() - testPoint1FixedZBelowPlane.D > NEAR_EDGE_CUTOFF) {
if (-testPoint1FixedZBelowPlane.D - planetModel.getMaximumZValue() > NEAR_EDGE_CUTOFF || planetModel.getMinimumZValue() + testPoint1FixedZBelowPlane.D > NEAR_EDGE_CUTOFF) {
testPoint1FixedZBelowPlane = null;
}
this.testPoint1FixedZBelowPlane = testPoint1FixedZBelowPlane;
@ -184,37 +187,37 @@ class GeoComplexPolygon extends GeoBasePolygon {
this.testPoint2FixedZPlane = new Plane(0.0, 0.0, 1.0, -testPoint2.z);
Plane testPoint2FixedYAbovePlane = new Plane(testPoint2FixedYPlane, true);
if (testPoint2FixedYAbovePlane.D - planetModel.getMaximumYValue() > NEAR_EDGE_CUTOFF || planetModel.getMinimumYValue() - testPoint2FixedYAbovePlane.D > NEAR_EDGE_CUTOFF) {
if (-testPoint2FixedYAbovePlane.D - planetModel.getMaximumYValue() > NEAR_EDGE_CUTOFF || planetModel.getMinimumYValue() + testPoint2FixedYAbovePlane.D > NEAR_EDGE_CUTOFF) {
testPoint2FixedYAbovePlane = null;
}
this.testPoint2FixedYAbovePlane = testPoint2FixedYAbovePlane;
Plane testPoint2FixedYBelowPlane = new Plane(testPoint2FixedYPlane, false);
if (testPoint2FixedYBelowPlane.D - planetModel.getMaximumYValue() > NEAR_EDGE_CUTOFF || planetModel.getMinimumYValue() - testPoint2FixedYBelowPlane.D > NEAR_EDGE_CUTOFF) {
if (-testPoint2FixedYBelowPlane.D - planetModel.getMaximumYValue() > NEAR_EDGE_CUTOFF || planetModel.getMinimumYValue() + testPoint2FixedYBelowPlane.D > NEAR_EDGE_CUTOFF) {
testPoint2FixedYBelowPlane = null;
}
this.testPoint2FixedYBelowPlane = testPoint2FixedYBelowPlane;
Plane testPoint2FixedXAbovePlane = new Plane(testPoint2FixedXPlane, true);
if (testPoint2FixedXAbovePlane.D - planetModel.getMaximumXValue() > NEAR_EDGE_CUTOFF || planetModel.getMinimumXValue() - testPoint2FixedXAbovePlane.D > NEAR_EDGE_CUTOFF) {
if (-testPoint2FixedXAbovePlane.D - planetModel.getMaximumXValue() > NEAR_EDGE_CUTOFF || planetModel.getMinimumXValue() + testPoint2FixedXAbovePlane.D > NEAR_EDGE_CUTOFF) {
testPoint2FixedXAbovePlane = null;
}
this.testPoint2FixedXAbovePlane = testPoint2FixedXAbovePlane;
Plane testPoint2FixedXBelowPlane = new Plane(testPoint2FixedXPlane, false);
if (testPoint2FixedXBelowPlane.D - planetModel.getMaximumXValue() > NEAR_EDGE_CUTOFF || planetModel.getMinimumXValue() - testPoint2FixedXBelowPlane.D > NEAR_EDGE_CUTOFF) {
if (-testPoint2FixedXBelowPlane.D - planetModel.getMaximumXValue() > NEAR_EDGE_CUTOFF || planetModel.getMinimumXValue() + testPoint2FixedXBelowPlane.D > NEAR_EDGE_CUTOFF) {
testPoint2FixedXBelowPlane = null;
}
this.testPoint2FixedXBelowPlane = testPoint2FixedXBelowPlane;
Plane testPoint2FixedZAbovePlane = new Plane(testPoint2FixedZPlane, true);
if (testPoint2FixedZAbovePlane.D - planetModel.getMaximumZValue() > NEAR_EDGE_CUTOFF ||planetModel.getMinimumZValue() - testPoint2FixedZAbovePlane.D > NEAR_EDGE_CUTOFF) {
if (-testPoint2FixedZAbovePlane.D - planetModel.getMaximumZValue() > NEAR_EDGE_CUTOFF ||planetModel.getMinimumZValue() + testPoint2FixedZAbovePlane.D > NEAR_EDGE_CUTOFF) {
testPoint2FixedZAbovePlane = null;
}
this.testPoint2FixedZAbovePlane = testPoint2FixedZAbovePlane;
Plane testPoint2FixedZBelowPlane = new Plane(testPoint2FixedZPlane, false);
if (testPoint2FixedZBelowPlane.D - planetModel.getMaximumZValue() > NEAR_EDGE_CUTOFF || planetModel.getMinimumZValue() - testPoint2FixedZBelowPlane.D > NEAR_EDGE_CUTOFF) {
if (-testPoint2FixedZBelowPlane.D - planetModel.getMaximumZValue() > NEAR_EDGE_CUTOFF || planetModel.getMinimumZValue() + testPoint2FixedZBelowPlane.D > NEAR_EDGE_CUTOFF) {
testPoint2FixedZBelowPlane = null;
}
this.testPoint2FixedZBelowPlane = testPoint2FixedZBelowPlane;
@ -352,32 +355,32 @@ class GeoComplexPolygon extends GeoBasePolygon {
final Plane travelPlaneFixedZ = new Plane(0.0, 0.0, 1.0, -z);
Plane fixedYAbovePlane = new Plane(travelPlaneFixedY, true);
if (fixedYAbovePlane.D - planetModel.getMaximumYValue() > NEAR_EDGE_CUTOFF || planetModel.getMinimumYValue() - fixedYAbovePlane.D > NEAR_EDGE_CUTOFF) {
if (-fixedYAbovePlane.D - planetModel.getMaximumYValue() > NEAR_EDGE_CUTOFF || planetModel.getMinimumYValue() + fixedYAbovePlane.D > NEAR_EDGE_CUTOFF) {
fixedYAbovePlane = null;
}
Plane fixedYBelowPlane = new Plane(travelPlaneFixedY, false);
if (fixedYBelowPlane.D - planetModel.getMaximumYValue() > NEAR_EDGE_CUTOFF || planetModel.getMinimumYValue() - fixedYBelowPlane.D > NEAR_EDGE_CUTOFF) {
if (-fixedYBelowPlane.D - planetModel.getMaximumYValue() > NEAR_EDGE_CUTOFF || planetModel.getMinimumYValue() + fixedYBelowPlane.D > NEAR_EDGE_CUTOFF) {
fixedYBelowPlane = null;
}
Plane fixedXAbovePlane = new Plane(travelPlaneFixedX, true);
if (fixedXAbovePlane.D - planetModel.getMaximumXValue() > NEAR_EDGE_CUTOFF || planetModel.getMinimumXValue() - fixedXAbovePlane.D > NEAR_EDGE_CUTOFF) {
if (-fixedXAbovePlane.D - planetModel.getMaximumXValue() > NEAR_EDGE_CUTOFF || planetModel.getMinimumXValue() + fixedXAbovePlane.D > NEAR_EDGE_CUTOFF) {
fixedXAbovePlane = null;
}
Plane fixedXBelowPlane = new Plane(travelPlaneFixedX, false);
if (fixedXBelowPlane.D - planetModel.getMaximumXValue() > NEAR_EDGE_CUTOFF || planetModel.getMinimumXValue() - fixedXBelowPlane.D > NEAR_EDGE_CUTOFF) {
if (-fixedXBelowPlane.D - planetModel.getMaximumXValue() > NEAR_EDGE_CUTOFF || planetModel.getMinimumXValue() + fixedXBelowPlane.D > NEAR_EDGE_CUTOFF) {
fixedXBelowPlane = null;
}
Plane fixedZAbovePlane = new Plane(travelPlaneFixedZ, true);
if (fixedZAbovePlane.D - planetModel.getMaximumZValue() > NEAR_EDGE_CUTOFF || planetModel.getMinimumZValue() - fixedZAbovePlane.D > NEAR_EDGE_CUTOFF) {
if (-fixedZAbovePlane.D - planetModel.getMaximumZValue() > NEAR_EDGE_CUTOFF || planetModel.getMinimumZValue() + fixedZAbovePlane.D > NEAR_EDGE_CUTOFF) {
fixedZAbovePlane = null;
}
Plane fixedZBelowPlane = new Plane(travelPlaneFixedZ, false);
if (fixedZBelowPlane.D - planetModel.getMaximumZValue() > NEAR_EDGE_CUTOFF || planetModel.getMinimumZValue() - fixedZBelowPlane.D > NEAR_EDGE_CUTOFF) {
if (-fixedZBelowPlane.D - planetModel.getMaximumZValue() > NEAR_EDGE_CUTOFF || planetModel.getMinimumZValue() + fixedZBelowPlane.D > NEAR_EDGE_CUTOFF) {
fixedZBelowPlane = null;
}
@ -669,9 +672,11 @@ class GeoComplexPolygon extends GeoBasePolygon {
//return new SectorLinearCrossingEdgeIterator(plane, abovePlane, belowPlane, thePointX, thePointY, thePointZ);
//
try {
//System.out.println(" creating sector linear crossing edge iterator");
return new SectorLinearCrossingEdgeIterator(testPoint, plane, abovePlane, belowPlane, thePointX, thePointY, thePointZ);
} catch (IllegalArgumentException e) {
// Assume we failed because we could not construct bounding planes, so do it another way.
//System.out.println(" create full linear crossing edge iterator");
return new FullLinearCrossingEdgeIterator(testPoint, plane, abovePlane, belowPlane, thePointX, thePointY, thePointZ);
}
}
@ -787,6 +792,7 @@ class GeoComplexPolygon extends GeoBasePolygon {
return rval;
} catch (IllegalArgumentException e) {
// Intersection point apparently was on edge, so try another strategy
//System.out.println(" Trying dual crossing edge iterator");
final CountingEdgeIterator edgeIterator = new DualCrossingEdgeIterator(testPoint,
firstLegPlane, firstLegAbovePlane, firstLegBelowPlane,
secondLegPlane, secondLegAbovePlane, secondLegBelowPlane,
@ -1397,12 +1403,17 @@ class GeoComplexPolygon extends GeoBasePolygon {
private boolean edgeCrossesEnvelope(final Plane edgePlane, final GeoPoint intersectionPoint, final Plane envelopePlane) {
final GeoPoint[] adjoiningPoints = findAdjoiningPoints(edgePlane, intersectionPoint, envelopePlane);
if (adjoiningPoints == null) {
//System.out.println(" No adjoining points");
return true;
}
int withinCount = 0;
for (final GeoPoint adjoining : adjoiningPoints) {
//System.out.println(" Adjoining point "+adjoining);
if (plane.evaluateIsZero(adjoining) && bound1.isWithin(adjoining) && bound2.isWithin(adjoining)) {
//System.out.println(" within!!");
withinCount++;
} else {
//System.out.println(" evaluateIsZero? "+plane.evaluateIsZero(adjoining)+" bound1.isWithin? "+bound1.isWithin(adjoining)+" bound2.isWithin? "+bound2.isWithin(adjoining));
}
}
return (withinCount & 1) != 0;
@ -1834,6 +1845,7 @@ class GeoComplexPolygon extends GeoBasePolygon {
// Loop back around and use a bigger delta
}
// Had to abort, so return null.
//System.out.println(" Adjoining points not found. Are planes parallel? edge = "+plane+"; envelope = "+envelopePlane+"; perpendicular = "+perpendicular);
return null;
}

View File

@ -1817,7 +1817,7 @@ shape:
}
@Test
@AwaitsFix(bugUrl="https://issues.apache.org/jira/browse/LUCENE-8337")
//@AwaitsFix(bugUrl="https://issues.apache.org/jira/browse/LUCENE-8337")
public void testLUCENE8337() {
/*
{planetmodel=PlanetModel.WGS84, number of shapes=1, address=c865f21d,
@ -1844,6 +1844,8 @@ shape:
final GeoPoint thePoint = new GeoPoint(PlanetModel.WGS84, -6.499661194605612E-10, -2.0286460544410216);
System.out.println("large inset: "+largePolygon.isWithin(thePoint));
assertTrue(largePolygon.isWithin(thePoint) == smallPolygon.isWithin(thePoint));
}