diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoDegeneratePath.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoDegeneratePath.java
index b13bbfe50ff..472dedb158f 100644
--- a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoDegeneratePath.java
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoDegeneratePath.java
@@ -21,9 +21,9 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collections;
-import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
/**
* GeoShape representing a path across the surface of the globe, with a specified half-width. Path
@@ -109,7 +109,7 @@ class GeoDegeneratePath extends GeoBasePath {
// Simple circle
final GeoPoint point = points.get(0);
- final SegmentEndpoint onlyEndpoint = new SegmentEndpoint(point);
+ final SegmentEndpoint onlyEndpoint = new SegmentEndpoint(planetModel, point);
endPoints.add(onlyEndpoint);
this.edgePoints = new GeoPoint[] {point};
return;
@@ -122,7 +122,7 @@ class GeoDegeneratePath extends GeoBasePath {
if (i == 0) {
// Starting endpoint
final SegmentEndpoint startEndpoint =
- new SegmentEndpoint(currentSegment.start, currentSegment.startCutoffPlane);
+ new SegmentEndpoint(planetModel, currentSegment.start, currentSegment.startCutoffPlane);
endPoints.add(startEndpoint);
this.edgePoints = new GeoPoint[] {currentSegment.start};
continue;
@@ -130,13 +130,14 @@ class GeoDegeneratePath extends GeoBasePath {
endPoints.add(
new SegmentEndpoint(
+ planetModel,
currentSegment.start,
segments.get(i - 1).endCutoffPlane,
currentSegment.startCutoffPlane));
}
// Do final endpoint
final PathSegment lastSegment = segments.get(segments.size() - 1);
- endPoints.add(new SegmentEndpoint(lastSegment.end, lastSegment.endCutoffPlane));
+ endPoints.add(new SegmentEndpoint(planetModel, lastSegment.end, lastSegment.endCutoffPlane));
}
/**
@@ -162,8 +163,7 @@ class GeoDegeneratePath extends GeoBasePath {
double closestDistance = Double.POSITIVE_INFINITY;
// Segments first
for (PathSegment segment : segments) {
- final double segmentDistance =
- segment.pathCenterDistance(planetModel, distanceStyle, x, y, z);
+ final double segmentDistance = segment.pathCenterDistance(distanceStyle, x, y, z);
if (segmentDistance < closestDistance) {
closestDistance = segmentDistance;
}
@@ -196,14 +196,12 @@ class GeoDegeneratePath extends GeoBasePath {
// Look at the following segment, if any
if (segmentIndex < segments.size()) {
final PathSegment segment = segments.get(segmentIndex++);
- final double segmentPathCenterDistance =
- segment.pathCenterDistance(planetModel, distanceStyle, x, y, z);
+ final double segmentPathCenterDistance = segment.pathCenterDistance(distanceStyle, x, y, z);
if (segmentPathCenterDistance < minPathCenterDistance) {
minPathCenterDistance = segmentPathCenterDistance;
bestDistance =
distanceStyle.aggregateDistances(
- currentDistance,
- segment.nearestPathDistance(planetModel, distanceStyle, x, y, z));
+ currentDistance, segment.nearestPathDistance(distanceStyle, x, y, z));
}
currentDistance =
distanceStyle.aggregateDistances(
@@ -221,7 +219,7 @@ class GeoDegeneratePath extends GeoBasePath {
// (2) If the point is within any of the segment end circles along the path, return that value.
double currentDistance = 0.0;
for (PathSegment segment : segments) {
- double distance = segment.pathDistance(planetModel, distanceStyle, x, y, z);
+ double distance = segment.pathDistance(distanceStyle, x, y, z);
if (distance != Double.POSITIVE_INFINITY)
return distanceStyle.fromAggregationForm(
distanceStyle.aggregateDistances(currentDistance, distance));
@@ -272,7 +270,7 @@ class GeoDegeneratePath extends GeoBasePath {
}
}
for (final PathSegment segment : segments) {
- final double newDistance = segment.outsideDistance(planetModel, distanceStyle, x, y, z);
+ final double newDistance = segment.outsideDistance(distanceStyle, x, y, z);
if (newDistance < minDistance) {
minDistance = newDistance;
}
@@ -317,11 +315,11 @@ class GeoDegeneratePath extends GeoBasePath {
// Since the endpoints are included in the path segments, we only need to do this if there are
// no path segments
if (endPoints.size() == 1) {
- return endPoints.get(0).intersects(planetModel, plane, notablePoints, bounds);
+ return endPoints.get(0).intersects(plane, notablePoints, bounds);
}
for (final PathSegment pathSegment : segments) {
- if (pathSegment.intersects(planetModel, plane, notablePoints, bounds)) {
+ if (pathSegment.intersects(plane, notablePoints, bounds)) {
return true;
}
}
@@ -353,10 +351,10 @@ class GeoDegeneratePath extends GeoBasePath {
// never more than 180 degrees longitude at a pop or we risk having the
// bounds object get itself inverted. So do the edges first.
for (PathSegment pathSegment : segments) {
- pathSegment.getBounds(planetModel, bounds);
+ pathSegment.getBounds(bounds);
}
if (endPoints.size() == 1) {
- endPoints.get(0).getBounds(planetModel, bounds);
+ endPoints.get(0).getBounds(bounds);
}
}
@@ -396,7 +394,7 @@ class GeoDegeneratePath extends GeoBasePath {
*
Intersection. There are two cutoff planes, one for each end of the intersection.
*
*/
- private static class SegmentEndpoint {
+ private static class SegmentEndpoint extends GeoBaseBounds {
/** The center point of the endpoint */
public final GeoPoint point;
/** Pertinent cutoff planes from adjoining segments */
@@ -407,9 +405,11 @@ class GeoDegeneratePath extends GeoBasePath {
/**
* Constructor for case (1).
*
+ * @param planetModel is the planet model.
* @param point is the center point.
*/
- public SegmentEndpoint(final GeoPoint point) {
+ public SegmentEndpoint(final PlanetModel planetModel, final GeoPoint point) {
+ super(planetModel);
this.point = point;
this.cutoffPlanes = NO_MEMBERSHIP;
}
@@ -422,7 +422,9 @@ class GeoDegeneratePath extends GeoBasePath {
* @param cutoffPlane is the plane from the adjoining path segment marking the boundary between
* this endpoint and that segment.
*/
- public SegmentEndpoint(final GeoPoint point, final SidedPlane cutoffPlane) {
+ public SegmentEndpoint(
+ final PlanetModel planetModel, final GeoPoint point, final SidedPlane cutoffPlane) {
+ super(planetModel);
this.point = point;
this.cutoffPlanes = new Membership[] {new SidedPlane(cutoffPlane)};
}
@@ -430,12 +432,17 @@ class GeoDegeneratePath extends GeoBasePath {
/**
* Constructor for case (3). Generate an endpoint, given two cutoff planes.
*
+ * @param planetModel is the planet model.
* @param point is the center.
* @param cutoffPlane1 is one adjoining path segment cutoff plane.
* @param cutoffPlane2 is another adjoining path segment cutoff plane.
*/
public SegmentEndpoint(
- final GeoPoint point, final SidedPlane cutoffPlane1, final SidedPlane cutoffPlane2) {
+ final PlanetModel planetModel,
+ final GeoPoint point,
+ final SidedPlane cutoffPlane1,
+ final SidedPlane cutoffPlane2) {
+ super(planetModel);
this.point = point;
this.cutoffPlanes =
new Membership[] {new SidedPlane(cutoffPlane1), new SidedPlane(cutoffPlane2)};
@@ -507,17 +514,13 @@ class GeoDegeneratePath extends GeoBasePath {
/**
* Determine if this endpoint intersects a specified plane.
*
- * @param planetModel is the planet model.
* @param p is the plane.
* @param notablePoints are the points associated with the plane.
* @param bounds are any bounds which the intersection must lie within.
* @return true if there is a matching intersection.
*/
public boolean intersects(
- final PlanetModel planetModel,
- final Plane p,
- final GeoPoint[] notablePoints,
- final Membership[] bounds) {
+ final Plane p, final GeoPoint[] notablePoints, final Membership[] bounds) {
// If not on the plane, no intersection
if (!p.evaluateIsZero(point)) {
return false;
@@ -572,13 +575,13 @@ class GeoDegeneratePath extends GeoBasePath {
}
/** This is the pre-calculated data for a path segment. */
- private static class PathSegment {
+ private static class PathSegment extends GeoBaseBounds {
/** Starting point of the segment */
public final GeoPoint start;
/** End point of the segment */
public final GeoPoint end;
/** Place to keep any complete segment distances we've calculated so far */
- public final Map fullDistanceCache = new HashMap<>();
+ public final Map fullDistanceCache = new ConcurrentHashMap<>(1);
/** Normalized plane connecting the two points and going through world center */
public final Plane normalizedConnectingPlane;
/** Plane going through the center and start point, marking the start edge of the segment */
@@ -601,6 +604,7 @@ class GeoDegeneratePath extends GeoBasePath {
final GeoPoint start,
final GeoPoint end,
final Plane normalizedConnectingPlane) {
+ super(planetModel);
this.start = start;
this.end = end;
this.normalizedConnectingPlane = normalizedConnectingPlane;
@@ -618,16 +622,14 @@ class GeoDegeneratePath extends GeoBasePath {
* @return the distance metric, in aggregation form.
*/
public double fullPathDistance(final DistanceStyle distanceStyle) {
- synchronized (fullDistanceCache) {
- Double dist = fullDistanceCache.get(distanceStyle);
- if (dist == null) {
- dist =
- distanceStyle.toAggregationForm(
- distanceStyle.computeDistance(start, end.x, end.y, end.z));
- fullDistanceCache.put(distanceStyle, dist);
- }
- return dist.doubleValue();
+ Double dist = fullDistanceCache.get(distanceStyle);
+ if (dist == null) {
+ dist =
+ distanceStyle.toAggregationForm(
+ distanceStyle.computeDistance(start, end.x, end.y, end.z));
+ fullDistanceCache.put(distanceStyle, dist);
}
+ return dist.doubleValue();
}
/**
@@ -638,6 +640,7 @@ class GeoDegeneratePath extends GeoBasePath {
* @param z is the point z.
* @return true of within.
*/
+ @Override
public boolean isWithin(final double x, final double y, final double z) {
return startCutoffPlane.isWithin(x, y, z)
&& endCutoffPlane.isWithin(x, y, z)
@@ -645,9 +648,8 @@ class GeoDegeneratePath extends GeoBasePath {
}
/**
- * Compute path center distance.
+ * Compute path center distance (distance from path to current point).
*
- * @param planetModel is the planet model.
* @param distanceStyle is the distance style.
* @param x is the point x.
* @param y is the point y.
@@ -655,11 +657,7 @@ class GeoDegeneratePath extends GeoBasePath {
* @return the distance metric, or Double.POSITIVE_INFINITY if outside this segment
*/
public double pathCenterDistance(
- final PlanetModel planetModel,
- final DistanceStyle distanceStyle,
- final double x,
- final double y,
- final double z) {
+ final DistanceStyle distanceStyle, final double x, final double y, final double z) {
// First, if this point is outside the endplanes of the segment, return POSITIVE_INFINITY.
if (!startCutoffPlane.isWithin(x, y, z) || !endCutoffPlane.isWithin(x, y, z)) {
return Double.POSITIVE_INFINITY;
@@ -704,9 +702,8 @@ class GeoDegeneratePath extends GeoBasePath {
}
/**
- * Compute nearest path distance.
+ * Compute nearest path distance (distance from start of segment to center line point adjacent).
*
- * @param planetModel is the planet model.
* @param distanceStyle is the distance style.
* @param x is the point x.
* @param y is the point y.
@@ -715,11 +712,7 @@ class GeoDegeneratePath extends GeoBasePath {
* segment
*/
public double nearestPathDistance(
- final PlanetModel planetModel,
- final DistanceStyle distanceStyle,
- final double x,
- final double y,
- final double z) {
+ final DistanceStyle distanceStyle, final double x, final double y, final double z) {
// First, if this point is outside the endplanes of the segment, return POSITIVE_INFINITY.
if (!startCutoffPlane.isWithin(x, y, z) || !endCutoffPlane.isWithin(x, y, z)) {
return Double.POSITIVE_INFINITY;
@@ -775,11 +768,7 @@ class GeoDegeneratePath extends GeoBasePath {
* @return the distance metric, in aggregation form.
*/
public double pathDistance(
- final PlanetModel planetModel,
- final DistanceStyle distanceStyle,
- final double x,
- final double y,
- final double z) {
+ final DistanceStyle distanceStyle, final double x, final double y, final double z) {
if (!isWithin(x, y, z)) return Double.POSITIVE_INFINITY;
// (1) Compute normalizedPerpPlane. If degenerate, then return point distance from start to
@@ -839,11 +828,7 @@ class GeoDegeneratePath extends GeoBasePath {
* @return the distance metric.
*/
public double outsideDistance(
- final PlanetModel planetModel,
- final DistanceStyle distanceStyle,
- final double x,
- final double y,
- final double z) {
+ final DistanceStyle distanceStyle, final double x, final double y, final double z) {
final double distance =
distanceStyle.computeDistance(
planetModel, normalizedConnectingPlane, x, y, z, startCutoffPlane, endCutoffPlane);
@@ -862,10 +847,7 @@ class GeoDegeneratePath extends GeoBasePath {
* @return true if there is a matching intersection.
*/
public boolean intersects(
- final PlanetModel planetModel,
- final Plane p,
- final GeoPoint[] notablePoints,
- final Membership[] bounds) {
+ final Plane p, final GeoPoint[] notablePoints, final Membership[] bounds) {
return normalizedConnectingPlane.intersects(
planetModel,
p,
@@ -893,7 +875,9 @@ class GeoDegeneratePath extends GeoBasePath {
* @param planetModel is the planet model.
* @param bounds are the bounds to be modified.
*/
- public void getBounds(final PlanetModel planetModel, Bounds bounds) {
+ @Override
+ public void getBounds(final Bounds bounds) {
+ super.getBounds(bounds);
// We need to do all bounding planes as well as corner points
bounds
.addPoint(start)
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 4d711a1efa3..072b276cd4a 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
@@ -108,7 +108,7 @@ class GeoStandardPath extends GeoBasePath {
final List endPoints = new ArrayList<>(points.size());
final List segments = new ArrayList<>(points.size());
-
+
// Compute an offset to use for all segments. This will be based on the minimum magnitude of
// the entire ellipsoid.
final double cutoffOffset = this.sinAngle * planetModel.getMinimumMagnitude();
@@ -351,7 +351,11 @@ class GeoStandardPath extends GeoBasePath {
if (rootComponent == null) {
return false;
}
- return rootComponent.intersects(plane, notablePoints, bounds);
+ final boolean rval = rootComponent.intersects(plane, notablePoints, bounds);
+ if (rval) {
+ System.out.println("Plane " + plane + " within its bounds intersects " + rootComponent);
+ }
+ return rval;
}
@Override
@@ -359,7 +363,11 @@ class GeoStandardPath extends GeoBasePath {
if (rootComponent == null) {
return false;
}
- return rootComponent.intersects(geoShape);
+ final boolean rval = rootComponent.intersects(geoShape);
+ if (rval) {
+ System.out.println("Shape " + geoShape + " intersects " + rootComponent);
+ }
+ return rval;
}
@Override
@@ -430,6 +438,12 @@ class GeoStandardPath extends GeoBasePath {
*/
boolean isWithin(final double x, final double y, final double z);
+ /** Check if point is within this section (within cutoff planes). */
+ boolean isWithinSection(final Vector point);
+
+ /** Check if point is within this section (within cutoff planes). */
+ boolean isWithinSection(final double x, final double y, final double z);
+
/**
* Retrieve the starting distance along the path for this path element.
*
@@ -498,28 +512,28 @@ class GeoStandardPath extends GeoBasePath {
final DistanceStyle distanceStyle, final double x, final double y, final double z);
/**
- * Compute nearest path distance.
+ * Compute nearest path distance (distance from start of segment to point adjacent the one
+ * specitied, if reachable by this segment).
*
* @param distanceStyle is the distance style.
* @param x is the point x.
* @param y is the point y.
* @param z is the point z.
- * @return the distance metric (always value zero), in aggregation form, or POSITIVE_INFINITY if
- * the point is not within the bounds of the endpoint.
+ * @return the distance metric, in aggregation form.
*/
double nearestPathDistance(
final DistanceStyle distanceStyle, final double x, final double y, final double z);
/**
- * Compute path center distance. Returns POSITIVE_INFINITY if the point is outside of the
- * bounds.
+ * Compute path center distance (distance from the point to center of the path, if reachable by
+ * this segment).
*
* @param distanceStyle is the distance style.
* @param x is the point x.
* @param y is the point y.
* @param z is the point z.
* @return the distance metric, or POSITIVE_INFINITY if the point is not within the bounds of
- * the endpoint.
+ * the path segment.
*/
double pathCenterDistance(
final DistanceStyle distanceStyle, final double x, final double y, final double z);
@@ -611,6 +625,16 @@ class GeoStandardPath extends GeoBasePath {
return child1.isWithin(x, y, z) || child2.isWithin(x, y, z);
}
+ @Override
+ public boolean isWithinSection(final Vector point) {
+ return child1.isWithinSection(point) || child2.isWithinSection(point);
+ }
+
+ @Override
+ public boolean isWithinSection(final double x, final double y, final double z) {
+ return child1.isWithinSection(x, y, z) || child2.isWithinSection(x, y, z);
+ }
+
@Override
public double getStartingDistance(final DistanceStyle distanceStyle) {
return child1.getStartingDistance(distanceStyle);
@@ -632,7 +656,7 @@ class GeoStandardPath extends GeoBasePath {
@Override
public double nearestDistance(
final DistanceStyle distanceStyle, final double x, final double y, final double z) {
- if (!isWithin(x, y, z)) {
+ if (!isWithinSection(x, y, z)) {
return Double.POSITIVE_INFINITY;
}
return Math.min(
@@ -672,7 +696,7 @@ class GeoStandardPath extends GeoBasePath {
@Override
public double nearestPathDistance(
final DistanceStyle distanceStyle, final double x, final double y, final double z) {
- if (!isWithin(x, y, z)) {
+ if (!isWithinSection(x, y, z)) {
return Double.POSITIVE_INFINITY;
}
return Math.min(
@@ -683,7 +707,7 @@ class GeoStandardPath extends GeoBasePath {
@Override
public double pathCenterDistance(
final DistanceStyle distanceStyle, final double x, final double y, final double z) {
- if (!isWithin(x, y, z)) {
+ if (!isWithinSection(x, y, z)) {
return Double.POSITIVE_INFINITY;
}
return Math.min(
@@ -703,8 +727,17 @@ class GeoStandardPath extends GeoBasePath {
@Override
public boolean intersects(
final Plane p, final GeoPoint[] notablePoints, final Membership[] bounds) {
- return child1.intersects(p, notablePoints, bounds)
- || child2.intersects(p, notablePoints, bounds);
+ final boolean rval =
+ child1.intersects(p, notablePoints, bounds)
+ || child2.intersects(p, notablePoints, bounds);
+ if (rval) {
+ if (child1.intersects(p, notablePoints, bounds)) {
+ System.out.println("Plane " + p + " intersected " + child1);
+ } else if (child2.intersects(p, notablePoints, bounds)) {
+ System.out.println("Plane " + p + " intersected " + child2);
+ }
+ }
+ return rval;
}
@Override
@@ -769,6 +802,16 @@ class GeoStandardPath extends GeoBasePath {
return false;
}
+ @Override
+ public boolean isWithinSection(final double x, final double y, final double z) {
+ return true;
+ }
+
+ @Override
+ public boolean isWithinSection(final Vector point) {
+ return true;
+ }
+
@Override
public double getStartingDistance(DistanceStyle distanceStyle) {
if (previous == null) {
@@ -793,7 +836,7 @@ class GeoStandardPath extends GeoBasePath {
@Override
public double nearestDistance(
final DistanceStyle distanceStyle, final double x, final double y, final double z) {
- if (!isWithin(x, y, z)) {
+ if (!isWithinSection(x, y, z)) {
return Double.POSITIVE_INFINITY;
}
return distanceStyle.fromAggregationForm(getStartingDistance(distanceStyle));
@@ -827,16 +870,16 @@ class GeoStandardPath extends GeoBasePath {
@Override
public double nearestPathDistance(
final DistanceStyle distanceStyle, final double x, final double y, final double z) {
- if (!isWithin(x, y, z)) {
+ if (!isWithinSection(x, y, z)) {
return Double.POSITIVE_INFINITY;
}
- return distanceStyle.toAggregationForm(0.0);
+ return distanceStyle.toAggregationForm(distanceStyle.computeDistance(this.point, x, y, z));
}
@Override
public double pathCenterDistance(
final DistanceStyle distanceStyle, final double x, final double y, final double z) {
- if (!isWithin(x, y, z)) {
+ if (!isWithinSection(x, y, z)) {
return Double.POSITIVE_INFINITY;
}
return distanceStyle.computeDistance(this.point, x, y, z);
@@ -1023,6 +1066,16 @@ class GeoStandardPath extends GeoBasePath {
return cutoffPlane.isWithin(x, y, z) && super.isWithin(x, y, z);
}
+ @Override
+ public boolean isWithinSection(final Vector point) {
+ return cutoffPlane.isWithin(point);
+ }
+
+ @Override
+ public boolean isWithinSection(final double x, final double y, final double z) {
+ return cutoffPlane.isWithin(x, y, z);
+ }
+
@Override
public boolean intersects(
final Plane p, final GeoPoint[] notablePoints, final Membership[] bounds) {
@@ -1035,6 +1088,28 @@ class GeoStandardPath extends GeoBasePath {
return geoShape.intersects(circlePlane, this.notablePoints, this.cutoffPlanes);
}
+ @Override
+ public double nearestPathDistance(
+ final DistanceStyle distanceStyle, final double x, final double y, final double z) {
+ for (final Membership cutoff : cutoffPlanes) {
+ if (!cutoff.isWithin(x, y, z)) {
+ return Double.POSITIVE_INFINITY;
+ }
+ }
+ return super.nearestPathDistance(distanceStyle, x, y, z);
+ }
+
+ @Override
+ public double pathCenterDistance(
+ final DistanceStyle distanceStyle, final double x, final double y, final double z) {
+ for (final Membership cutoff : cutoffPlanes) {
+ if (!cutoff.isWithin(x, y, z)) {
+ return Double.POSITIVE_INFINITY;
+ }
+ }
+ return super.pathCenterDistance(distanceStyle, x, y, z);
+ }
+
@Override
public void getBounds(final Bounds bounds) {
super.getBounds(bounds);
@@ -1144,6 +1219,26 @@ class GeoStandardPath extends GeoBasePath {
return circlePlane1.isWithin(x, y, z) || circlePlane2.isWithin(x, y, z);
}
+ @Override
+ public boolean isWithinSection(final Vector point) {
+ for (final Membership m : cutoffPlanes) {
+ if (!m.isWithin(point)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public boolean isWithinSection(final double x, final double y, final double z) {
+ for (final Membership m : cutoffPlanes) {
+ if (!m.isWithin(x, y, z)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
@Override
public boolean intersects(
final Plane p, final GeoPoint[] notablePoints, final Membership[] bounds) {
@@ -1159,6 +1254,28 @@ class GeoStandardPath extends GeoBasePath {
|| geoShape.intersects(circlePlane2, this.notablePoints2, this.cutoffPlanes);
}
+ @Override
+ public double nearestPathDistance(
+ final DistanceStyle distanceStyle, final double x, final double y, final double z) {
+ for (final Membership cutoff : cutoffPlanes) {
+ if (!cutoff.isWithin(x, y, z)) {
+ return Double.POSITIVE_INFINITY;
+ }
+ }
+ return super.nearestPathDistance(distanceStyle, x, y, z);
+ }
+
+ @Override
+ public double pathCenterDistance(
+ final DistanceStyle distanceStyle, final double x, final double y, final double z) {
+ for (final Membership cutoff : cutoffPlanes) {
+ if (!cutoff.isWithin(x, y, z)) {
+ return Double.POSITIVE_INFINITY;
+ }
+ }
+ return super.pathCenterDistance(distanceStyle, x, y, z);
+ }
+
@Override
public void getBounds(final Bounds bounds) {
super.getBounds(bounds);
@@ -1311,6 +1428,16 @@ class GeoStandardPath extends GeoBasePath {
return isWithin(v.x, v.y, v.z);
}
+ @Override
+ public boolean isWithinSection(final Vector point) {
+ return startCutoffPlane.isWithin(point) && endCutoffPlane.isWithin(point);
+ }
+
+ @Override
+ public boolean isWithinSection(final double x, final double y, final double z) {
+ return startCutoffPlane.isWithin(x, y, z) && endCutoffPlane.isWithin(x, y, z);
+ }
+
@Override
public double getStartingDistance(final DistanceStyle distanceStyle) {
Double dist = startDistanceCache.get(distanceStyle);
@@ -1338,12 +1465,14 @@ class GeoStandardPath extends GeoBasePath {
@Override
public double nearestDistance(
final DistanceStyle distanceStyle, final double x, final double y, final double z) {
- if (!isWithin(x, y, z)) {
+ if (!isWithinSection(x, y, z)) {
return Double.POSITIVE_INFINITY;
}
return distanceStyle.fromAggregationForm(
distanceStyle.aggregateDistances(
- getStartingDistance(distanceStyle), nearestPathDistance(distanceStyle, x, y, z)));
+ distanceStyle.aggregateDistances(
+ getStartingDistance(distanceStyle), nearestPathDistance(distanceStyle, x, y, z)),
+ pathCenterDistance(distanceStyle, x, y, z)));
}
private double computeStartingDistance(final DistanceStyle distanceStyle) {
@@ -1358,10 +1487,10 @@ class GeoStandardPath extends GeoBasePath {
public double pathCenterDistance(
final DistanceStyle distanceStyle, final double x, final double y, final double z) {
// Computes the distance to the path center from the specified point, or returns
- // POSITIVE_INFINITY if the point is outside the path.
+ // POSITIVE_INFINITY if the point is outside the path section.
// First, if this point is outside the endplanes of the segment, return POSITIVE_INFINITY.
- if (!startCutoffPlane.isWithin(x, y, z) || !endCutoffPlane.isWithin(x, y, z)) {
+ if (!isWithinSection(x, y, z)) {
return Double.POSITIVE_INFINITY;
}
// (1) Compute normalizedPerpPlane. If degenerate, then there is no such plane, which means
@@ -1400,7 +1529,7 @@ class GeoStandardPath extends GeoBasePath {
"Can't find world intersection for point x=" + x + " y=" + y + " z=" + z);
}
}
- return distanceStyle.computeDistance(thePoint, x, y, z);
+ return distanceStyle.toAggregationForm(distanceStyle.computeDistance(thePoint, x, y, z));
}
@Override
@@ -1408,7 +1537,10 @@ class GeoStandardPath extends GeoBasePath {
final DistanceStyle distanceStyle, final double x, final double y, final double z) {
// Computes the distance along the path to a point on the path where a perpendicular plane
// goes through the specified point.
-
+ // First, if this point is outside the endplanes of the segment, return POSITIVE_INFINITY.
+ if (!isWithinSection(x, y, z)) {
+ return Double.POSITIVE_INFINITY;
+ }
// (1) Compute normalizedPerpPlane. If degenerate, then there is no such plane, which means
// that the point given is insufficient to distinguish between a family of such planes.
// This can happen only if the point is one of the "poles", imagining the normalized plane
@@ -1452,7 +1584,7 @@ class GeoStandardPath extends GeoBasePath {
@Override
public double pathDeltaDistance(
final DistanceStyle distanceStyle, final double x, final double y, final double z) {
- // Returns 2x the pathCenterDistance. Represents the cost of an "excursion" to and
+ // Represents the cost of an "excursion" to and
// from the path.
if (!isWithin(x, y, z)) {
diff --git a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestGeoPath.java b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestGeoPath.java
index f547ee86227..72d86c07b58 100755
--- a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestGeoPath.java
+++ b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/TestGeoPath.java
@@ -431,6 +431,52 @@ public class TestGeoPath extends LuceneTestCase {
}
+ @Test
+ public void testInterpolation2() {
+ final double lat = 52.5665;
+ final double lon = 13.3076;
+ final double[] pathLats =
+ new double[] {
+ 52.5355, 52.54, 52.5626, 52.5665, 52.6007, 52.6135, 52.6303, 52.6651, 52.7074
+ };
+ final double[] pathLons =
+ new double[] {
+ 13.3634, 13.3704, 13.3307, 13.3076, 13.2806, 13.2484, 13.2406, 13.241, 13.1926
+ };
+
+ final GeoPoint carPoint =
+ new GeoPoint(PlanetModel.SPHERE, Math.toRadians(lat), Math.toRadians(lon));
+ final GeoPoint[] pathPoints = new GeoPoint[pathLats.length];
+ for (int i = 0; i < pathPoints.length; i++) {
+ pathPoints[i] =
+ new GeoPoint(
+ PlanetModel.SPHERE, Math.toRadians(pathLats[i]), Math.toRadians(pathLons[i]));
+ }
+
+ // Construct a path with no width
+ final GeoPath thisPath = GeoPathFactory.makeGeoPath(PlanetModel.SPHERE, 0.0, pathPoints);
+ // Construct a path with a width
+ final GeoPath legacyPath = GeoPathFactory.makeGeoPath(PlanetModel.SPHERE, 1e-6, pathPoints);
+
+ // Compute the inside distance to the atPoint using zero-width path
+ final double distance = thisPath.computeNearestDistance(DistanceStyle.ARC, carPoint);
+ // Compute the inside distance using legacy path
+ final double legacyDistance = legacyPath.computeNearestDistance(DistanceStyle.ARC, carPoint);
+
+ // Compute the inside distance using the legacy formula
+ final double oldFormulaDistance = thisPath.computeDistance(DistanceStyle.ARC, carPoint);
+ // Compute the inside distance using the legacy formula with the legacy shape
+ final double oldFormulaLegacyDistance = legacyPath.computeDistance(DistanceStyle.ARC, carPoint);
+
+ // These should be about the same
+ assertEquals(legacyDistance, distance, 1e-12);
+
+ assertEquals(oldFormulaLegacyDistance, oldFormulaDistance, 1e-12);
+
+ // Since the point we picked is actually on the path, this should also be true
+ assertEquals(oldFormulaDistance, distance, 1e-12);
+ }
+
@Test
public void testIdenticalPoints() {
PlanetModel planetModel = PlanetModel.WGS84;