diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoStandardPath.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoStandardPath.java index 0f067176b6a..51c507829b8 100755 --- a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoStandardPath.java +++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoStandardPath.java @@ -244,12 +244,14 @@ class GeoStandardPath extends GeoBasePath { @Override public boolean isWithin(final double x, final double y, final double z) { for (SegmentEndpoint pathPoint : endPoints) { - if (pathPoint.isWithin(x, y, z)) + if (pathPoint.isWithin(x, y, z)) { return true; + } } for (PathSegment pathSegment : segments) { - if (pathSegment.isWithin(x, y, z)) + if (pathSegment.isWithin(x, y, z)) { return true; + } } return false; } @@ -626,7 +628,7 @@ class GeoStandardPath extends GeoBasePath { this.start = start; this.end = end; this.normalizedConnectingPlane = normalizedConnectingPlane; - + // Either start or end should be on the correct side upperConnectingPlane = new SidedPlane(start, normalizedConnectingPlane, -planeBoundingOffset); lowerConnectingPlane = new SidedPlane(start, normalizedConnectingPlane, planeBoundingOffset); @@ -642,21 +644,33 @@ class GeoStandardPath extends GeoBasePath { if (points.length == 0) { throw new IllegalArgumentException("Some segment boundary points are off the ellipsoid; path too wide"); } + if (points.length > 1) { + throw new IllegalArgumentException("Ambiguous boundary points; path too short"); + } this.ULHC = points[0]; points = upperConnectingPlane.findIntersections(planetModel, endCutoffPlane, lowerSide, startSide); if (points.length == 0) { throw new IllegalArgumentException("Some segment boundary points are off the ellipsoid; path too wide"); } + if (points.length > 1) { + throw new IllegalArgumentException("Ambiguous boundary points; path too short"); + } this.URHC = points[0]; points = lowerConnectingPlane.findIntersections(planetModel, startCutoffPlane, upperSide, endSide); if (points.length == 0) { throw new IllegalArgumentException("Some segment boundary points are off the ellipsoid; path too wide"); } + if (points.length > 1) { + throw new IllegalArgumentException("Ambiguous boundary points; path too short"); + } this.LLHC = points[0]; points = lowerConnectingPlane.findIntersections(planetModel, endCutoffPlane, upperSide, startSide); if (points.length == 0) { throw new IllegalArgumentException("Some segment boundary points are off the ellipsoid; path too wide"); } + if (points.length > 1) { + throw new IllegalArgumentException("Ambiguous boundary points; path too short"); + } this.LRHC = points[0]; upperConnectingPlanePoints = new GeoPoint[]{ULHC, URHC}; lowerConnectingPlanePoints = new GeoPoint[]{LLHC, LRHC}; @@ -791,11 +805,16 @@ class GeoStandardPath extends GeoBasePath { */ public void getBounds(final PlanetModel planetModel, Bounds bounds) { // We need to do all bounding planes as well as corner points - bounds.addPoint(start).addPoint(end).addPoint(ULHC).addPoint(URHC).addPoint(LRHC).addPoint(LLHC); - bounds.addPlane(planetModel, upperConnectingPlane, lowerConnectingPlane, startCutoffPlane, endCutoffPlane); - bounds.addPlane(planetModel, lowerConnectingPlane, upperConnectingPlane, startCutoffPlane, endCutoffPlane); - bounds.addPlane(planetModel, startCutoffPlane, endCutoffPlane, upperConnectingPlane, lowerConnectingPlane); - bounds.addPlane(planetModel, endCutoffPlane, startCutoffPlane, upperConnectingPlane, lowerConnectingPlane); + bounds.addPoint(start).addPoint(end) + .addPoint(ULHC).addPoint(URHC).addPoint(LRHC).addPoint(LLHC) + .addPlane(planetModel, upperConnectingPlane, lowerConnectingPlane, startCutoffPlane, endCutoffPlane) + .addPlane(planetModel, lowerConnectingPlane, upperConnectingPlane, startCutoffPlane, endCutoffPlane) + .addPlane(planetModel, startCutoffPlane, endCutoffPlane, upperConnectingPlane, lowerConnectingPlane) + .addPlane(planetModel, endCutoffPlane, startCutoffPlane, upperConnectingPlane, lowerConnectingPlane) + .addIntersection(planetModel, upperConnectingPlane, startCutoffPlane, lowerConnectingPlane, endCutoffPlane) + .addIntersection(planetModel, startCutoffPlane, lowerConnectingPlane, endCutoffPlane, upperConnectingPlane) + .addIntersection(planetModel, lowerConnectingPlane, endCutoffPlane, upperConnectingPlane, startCutoffPlane) + .addIntersection(planetModel, endCutoffPlane, upperConnectingPlane, startCutoffPlane, lowerConnectingPlane); } } diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/XYZBounds.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/XYZBounds.java index 9f441570b36..85659ab6cc8 100644 --- a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/XYZBounds.java +++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/XYZBounds.java @@ -30,7 +30,7 @@ public class XYZBounds implements Bounds { * unacceptably large. * Also, see LUCENE-7290 for a description of how geometry can magnify the bounds delta. */ - private static final double FUDGE_FACTOR = Vector.MINIMUM_RESOLUTION * 1000.0; + private static final double FUDGE_FACTOR = Vector.MINIMUM_RESOLUTION * 1e3; /** Minimum x */ private Double minX = null; diff --git a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/GeoPathTest.java b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/GeoPathTest.java index f5dd8b0723b..648854e58bc 100755 --- a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/GeoPathTest.java +++ b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/GeoPathTest.java @@ -267,4 +267,39 @@ public class GeoPathTest { p.done();//at least test this doesn't bomb like it used too -- LUCENE-6520 } + @Test + public void testFailure1() { + /* + GeoStandardPath: {planetmodel=PlanetModel.WGS84, width=1.117010721276371(64.0), points={[ + [lat=2.18531083006635E-12, lon=-3.141592653589793([X=-1.0011188539924791, Y=-1.226017000107956E-16, Z=2.187755873813378E-12])], + [lat=0.0, lon=-3.141592653589793([X=-1.0011188539924791, Y=-1.226017000107956E-16, Z=0.0])]]}} + */ + final GeoPoint[] points = new GeoPoint[]{ + new GeoPoint(PlanetModel.WGS84, 2.18531083006635E-12, -3.141592653589793), + new GeoPoint(PlanetModel.WGS84, 0.0, -3.141592653589793)}; + + final GeoPath path; + try { + path = GeoPathFactory.makeGeoPath(PlanetModel.WGS84, + 1.117010721276371, points); + } catch (IllegalArgumentException e) { + return; + } + assertTrue(false); + + final GeoPoint point = new GeoPoint(PlanetModel.WGS84, -2.848117399637174E-91, -1.1092122135274942); + System.err.println("point = "+point); + + final XYZBounds bounds = new XYZBounds(); + path.getBounds(bounds); + + final XYZSolid solid = XYZSolidFactory.makeXYZSolid(PlanetModel.WGS84, + bounds.getMinimumX(), bounds.getMaximumX(), + bounds.getMinimumY(), bounds.getMaximumY(), + bounds.getMinimumZ(), bounds.getMaximumZ()); + + assertTrue(path.isWithin(point)); + assertTrue(solid.isWithin(point)); + } + }