mirror of https://github.com/apache/lucene.git
LUCENE-8227: Widen plane envelopes a small amount to allow for some imprecision when intersecting inner and outer edges.
This commit is contained in:
parent
ae6d29f0ae
commit
e06554ad40
|
@ -23,6 +23,8 @@ package org.apache.lucene.spatial3d.geom;
|
||||||
* @lucene.experimental
|
* @lucene.experimental
|
||||||
*/
|
*/
|
||||||
public class Plane extends Vector {
|
public class Plane extends Vector {
|
||||||
|
/** For plane envelopes, we need a small distance that can't lead to numerical confusion. */
|
||||||
|
public final static double MINIMUM_PLANE_OFFSET = MINIMUM_RESOLUTION * 1.5;
|
||||||
/** An array with no points in it */
|
/** An array with no points in it */
|
||||||
public final static GeoPoint[] NO_POINTS = new GeoPoint[0];
|
public final static GeoPoint[] NO_POINTS = new GeoPoint[0];
|
||||||
/** An array with no bounds in it */
|
/** An array with no bounds in it */
|
||||||
|
@ -114,7 +116,7 @@ public class Plane extends Vector {
|
||||||
* or false in the negative direction.
|
* or false in the negative direction.
|
||||||
*/
|
*/
|
||||||
public Plane(final Plane basePlane, final boolean above) {
|
public Plane(final Plane basePlane, final boolean above) {
|
||||||
this(basePlane.x, basePlane.y, basePlane.z, above?Math.nextUp(basePlane.D + MINIMUM_RESOLUTION):Math.nextDown(basePlane.D - MINIMUM_RESOLUTION));
|
this(basePlane.x, basePlane.y, basePlane.z, above?Math.nextUp(basePlane.D + MINIMUM_PLANE_OFFSET):Math.nextDown(basePlane.D - MINIMUM_PLANE_OFFSET));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Construct the most accurate normalized plane through an x-y point and including the Z axis.
|
/** Construct the most accurate normalized plane through an x-y point and including the Z axis.
|
||||||
|
|
|
@ -188,7 +188,6 @@ public class TestGeo3DPoint extends LuceneTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Tests consistency of GeoArea.getRelationship vs GeoShape.isWithin */
|
/** Tests consistency of GeoArea.getRelationship vs GeoShape.isWithin */
|
||||||
@AwaitsFix(bugUrl="https://issues.apache.org/jira/browse/LUCENE-8227")
|
|
||||||
public void testGeo3DRelations() throws Exception {
|
public void testGeo3DRelations() throws Exception {
|
||||||
|
|
||||||
int numDocs = atLeast(1000);
|
int numDocs = atLeast(1000);
|
||||||
|
|
|
@ -1257,4 +1257,77 @@ shape:
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
[junit4] 1> doc=754 is contained by shape but is outside the returned XYZBounds
|
||||||
|
[junit4] 1> unquantized=[lat=2.4043303687704734E-204, lon=3.1342447995980507([X=-1.0010918284309325, Y=0.007356008974104805, Z=2.4070204634028112E-204])]
|
||||||
|
[junit4] 1> quantized=[X=-1.0010918285430614, Y=0.007356008812298254, Z=2.3309121299774915E-10]
|
||||||
|
|
||||||
|
[junit4] 1> doc=3728 is contained by shape but is outside the returned XYZBounds
|
||||||
|
[junit4] 1> unquantized=[lat=2.4457272005608357E-47, lon=-3.1404077424936307([X=-1.001118151199965, Y=-0.0011862365610909341, Z=2.448463612203698E-47])]
|
||||||
|
[junit4] 1> quantized=[X=-1.0011181510675629, Y=-0.001186236379718708, Z=2.3309121299774915E-10]
|
||||||
|
|
||||||
|
[junit4] 1> shape=GeoComplexPolygon: {planetmodel=PlanetModel.WGS84, number of shapes=1, address=7969cab3,
|
||||||
|
testPoint=[X=-0.07416172733314662, Y=0.5686488061136892, Z=0.8178445379402641], testPointInSet=true, shapes={ {
|
||||||
|
[lat=-1.5707963267948966, lon=-1.0755217966112058([X=2.903696886845155E-17, Y=-5.375400029710238E-17, Z=-0.997762292022105])],
|
||||||
|
[lat=-1.327365682666958, lon=-2.9674513704178316([X=-0.23690293696956322, Y=-0.04167672037374933, Z=-0.9685334156912658])],
|
||||||
|
[lat=0.32288591161895097, lon=3.141592653589793([X=-0.9490627533610154, Y=1.1622666630935417E-16, Z=0.3175519551883462])],
|
||||||
|
[lat=0.0, lon=0.0([X=1.0011188539924791, Y=0.0, Z=0.0])],
|
||||||
|
[lat=0.2839194570254642, lon=-1.2434404554202965([X=0.30893121415043073, Y=-0.9097632721627391, Z=0.2803596238536593])]}}
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testLUCENE8227_case2() {
|
||||||
|
List<GeoPoint> points = new ArrayList<>();
|
||||||
|
points.add(new GeoPoint(PlanetModel.WGS84, -1.5707963267948966, -1.0755217966112058));
|
||||||
|
points.add(new GeoPoint(PlanetModel.WGS84, -1.327365682666958, -2.9674513704178316));
|
||||||
|
points.add(new GeoPoint(PlanetModel.WGS84, 0.32288591161895097, 3.141592653589793));
|
||||||
|
points.add(new GeoPoint(PlanetModel.WGS84, 0.0, 0.0));
|
||||||
|
points.add(new GeoPoint(PlanetModel.WGS84, 0.2839194570254642, -1.2434404554202965));
|
||||||
|
GeoPolygonFactory.PolygonDescription pd = new GeoPolygonFactory.PolygonDescription(points);
|
||||||
|
|
||||||
|
for (int i = 0; i < points.size(); i++) {
|
||||||
|
System.out.println("Point "+i+": "+points.get(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
final GeoPoint unquantized = new GeoPoint(PlanetModel.WGS84, 2.4457272005608357E-47, -3.1404077424936307);
|
||||||
|
final GeoPoint quantized = new GeoPoint(-1.0011181510675629, -0.001186236379718708, 2.3309121299774915E-10);
|
||||||
|
|
||||||
|
// Is the north pole in set, or out of set?
|
||||||
|
final GeoPoint northPole = new GeoPoint(PlanetModel.WGS84, Math.PI * 0.5, 0.0);
|
||||||
|
final GeoPoint negativeX = new GeoPoint(PlanetModel.WGS84, 0.0, Math.PI);
|
||||||
|
final GeoPoint negativeY = new GeoPoint(PlanetModel.WGS84, 0.0, -Math.PI * 0.5);
|
||||||
|
final GeoPoint positiveY = new GeoPoint(PlanetModel.WGS84, 0.0, Math.PI * 0.5);
|
||||||
|
final GeoPoint testPoint = new GeoPoint(-0.07416172733314662, 0.5686488061136892, 0.8178445379402641);
|
||||||
|
|
||||||
|
// Construct a standard polygon first to see what that does. This winds up being a large polygon under the covers.
|
||||||
|
GeoPolygon standard = GeoPolygonFactory.makeGeoPolygon(PlanetModel.WGS84, pd);
|
||||||
|
|
||||||
|
System.out.println("Shape = "+standard);
|
||||||
|
|
||||||
|
// This should be true, by inspection, but is false. That's the cause for the failure.
|
||||||
|
assertTrue(standard.isWithin(negativeX));
|
||||||
|
System.out.println("Negative x pole in set? "+standard.isWithin(negativeX));
|
||||||
|
|
||||||
|
System.out.println("Test point in set? "+standard.isWithin(testPoint));
|
||||||
|
assertTrue(standard.isWithin(testPoint));
|
||||||
|
|
||||||
|
// This is in-set because it's on an edge
|
||||||
|
System.out.println("North pole in set? "+standard.isWithin(northPole));
|
||||||
|
assertTrue(standard.isWithin(northPole));
|
||||||
|
|
||||||
|
// This is in-set
|
||||||
|
System.out.println("Plus-Y pole in set? "+standard.isWithin(positiveY));
|
||||||
|
assertTrue(standard.isWithin(positiveY));
|
||||||
|
|
||||||
|
|
||||||
|
final XYZBounds standardBounds = new XYZBounds();
|
||||||
|
standard.getBounds(standardBounds);
|
||||||
|
System.out.println("Bounds = "+standardBounds);
|
||||||
|
final XYZSolid standardSolid = XYZSolidFactory.makeXYZSolid(PlanetModel.WGS84, standardBounds);
|
||||||
|
|
||||||
|
// If within shape, should be within bounds
|
||||||
|
assertTrue(standard.isWithin(unquantized)?standardSolid.isWithin(unquantized):true);
|
||||||
|
assertTrue(standard.isWithin(quantized)?standardSolid.isWithin(quantized):true);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue