You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by ds...@apache.org on 2015/07/01 04:03:44 UTC
svn commit: r1688545 [2/2] - in /lucene/dev/trunk/lucene: ./
spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/
spatial/src/test/org/apache/lucene/spatial/spatial4j/geo3d/
Modified: lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoPath.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoPath.java?rev=1688545&r1=1688544&r2=1688545&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoPath.java (original)
+++ lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoPath.java Wed Jul 1 02:03:43 2015
@@ -19,17 +19,19 @@ package org.apache.lucene.spatial.spatia
import java.util.ArrayList;
import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
/**
- * GeoSearchableShape representing a path across the surface of the globe,
+ * GeoShape representing a path across the surface of the globe,
* with a specified half-width. Path is described by a series of points.
* Distances are measured from the starting point along the path, and then at right
* angles to the path.
*
* @lucene.experimental
*/
-public class GeoPath extends GeoBaseExtendedShape implements GeoDistanceShape {
+public class GeoPath extends GeoBaseDistanceShape {
public final double cutoffAngle;
@@ -83,7 +85,7 @@ public class GeoPath extends GeoBaseExte
GeoPoint lastPoint = null;
for (final GeoPoint end : points) {
if (lastPoint != null) {
- final Plane normalizedConnectingPlane = new Plane(lastPoint, end).normalize();
+ final Plane normalizedConnectingPlane = new Plane(lastPoint, end);
if (normalizedConnectingPlane == null) {
continue;
}
@@ -166,173 +168,46 @@ public class GeoPath extends GeoBaseExte
}
- /**
- * Compute an estimate of "distance" to the GeoPoint.
- * A return value of Double.MAX_VALUE should be returned for
- * points outside of the shape.
- */
- @Override
- public double computeNormalDistance(final GeoPoint point) {
- // Algorithm:
- // (1) If the point is within any of the segments along the path, return that value.
- // (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.pathNormalDistance(point);
- if (distance != Double.MAX_VALUE)
- return currentDistance + distance;
- currentDistance += segment.fullNormalDistance;
- }
-
- int segmentIndex = 0;
- currentDistance = 0.0;
- for (SegmentEndpoint endpoint : endPoints) {
- double distance = endpoint.pathNormalDistance(point);
- if (distance != Double.MAX_VALUE)
- return currentDistance + distance;
- if (segmentIndex < segments.size())
- currentDistance += segments.get(segmentIndex++).fullNormalDistance;
- }
-
- return Double.MAX_VALUE;
- }
-
- /**
- * Compute an estimate of "distance" to the GeoPoint.
- * A return value of Double.MAX_VALUE should be returned for
- * points outside of the shape.
- */
- @Override
- public double computeNormalDistance(final double x, final double y, final double z) {
- return computeNormalDistance(new GeoPoint(x, y, z));
- }
-
- /**
- * Compute a squared estimate of the "distance" to the
- * GeoPoint. Double.MAX_VALUE indicates a point outside of the
- * shape.
- */
- @Override
- public double computeSquaredNormalDistance(final GeoPoint point) {
- double pd = computeNormalDistance(point);
- if (pd == Double.MAX_VALUE)
- return pd;
- return pd * pd;
- }
-
- /**
- * Compute a squared estimate of the "distance" to the
- * GeoPoint. Double.MAX_VALUE indicates a point outside of the
- * shape.
- */
- @Override
- public double computeSquaredNormalDistance(final double x, final double y, final double z) {
- return computeSquaredNormalDistance(new GeoPoint(x, y, z));
- }
-
- /**
- * Compute a linear distance to the point.
- */
- @Override
- public double computeLinearDistance(final GeoPoint point) {
- // Algorithm:
- // (1) If the point is within any of the segments along the path, return that value.
- // (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.pathLinearDistance(point);
- if (distance != Double.MAX_VALUE)
- return currentDistance + distance;
- currentDistance += segment.fullLinearDistance;
- }
-
- int segmentIndex = 0;
- currentDistance = 0.0;
- for (SegmentEndpoint endpoint : endPoints) {
- double distance = endpoint.pathLinearDistance(point);
- if (distance != Double.MAX_VALUE)
- return currentDistance + distance;
- if (segmentIndex < segments.size())
- currentDistance += segments.get(segmentIndex++).fullLinearDistance;
- }
-
- return Double.MAX_VALUE;
- }
-
- /**
- * Compute a linear distance to the point.
- */
- @Override
- public double computeLinearDistance(final double x, final double y, final double z) {
- return computeLinearDistance(new GeoPoint(x, y, z));
- }
-
- /**
- * Compute a squared linear distance to the vector.
- */
- @Override
- public double computeSquaredLinearDistance(final GeoPoint point) {
- double pd = computeLinearDistance(point);
- if (pd == Double.MAX_VALUE)
- return pd;
- return pd * pd;
- }
-
- /**
- * Compute a squared linear distance to the vector.
- */
- @Override
- public double computeSquaredLinearDistance(final double x, final double y, final double z) {
- return computeSquaredLinearDistance(new GeoPoint(x, y, z));
- }
-
- /**
- * Compute a true, accurate, great-circle distance.
- * Double.MAX_VALUE indicates a point is outside of the shape.
- */
@Override
- public double computeArcDistance(final GeoPoint point) {
+ protected double distance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
// Algorithm:
// (1) If the point is within any of the segments along the path, return that value.
// (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(point);
+ double distance = segment.pathDistance(planetModel, distanceStyle, x,y,z);
if (distance != Double.MAX_VALUE)
return currentDistance + distance;
- currentDistance += segment.fullDistance;
+ currentDistance += segment.fullPathDistance(distanceStyle);
}
int segmentIndex = 0;
currentDistance = 0.0;
for (SegmentEndpoint endpoint : endPoints) {
- double distance = endpoint.pathDistance(point);
+ double distance = endpoint.pathDistance(distanceStyle, x, y, z);
if (distance != Double.MAX_VALUE)
return currentDistance + distance;
if (segmentIndex < segments.size())
- currentDistance += segments.get(segmentIndex++).fullDistance;
+ currentDistance += segments.get(segmentIndex++).fullPathDistance(distanceStyle);
}
return Double.MAX_VALUE;
}
@Override
- public boolean isWithin(final Vector point) {
- //System.err.println("Assessing whether point "+point+" is within geopath "+this);
- for (SegmentEndpoint pathPoint : endPoints) {
- if (pathPoint.isWithin(point)) {
- //System.err.println(" point is within SegmentEndpoint "+pathPoint);
- return true;
- }
- }
- for (PathSegment pathSegment : segments) {
- if (pathSegment.isWithin(point)) {
- //System.err.println(" point is within PathSegment "+pathSegment);
- return true;
- }
+ protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
+ double minDistance = Double.MAX_VALUE;
+ for (final SegmentEndpoint endpoint : endPoints) {
+ final double newDistance = endpoint.outsideDistance(distanceStyle, x,y,z);
+ if (newDistance < minDistance)
+ minDistance = newDistance;
+ }
+ for (final PathSegment segment : segments) {
+ final double newDistance = segment.outsideDistance(planetModel, distanceStyle, x, y, z);
+ if (newDistance < minDistance)
+ minDistance = newDistance;
}
- //System.err.println(" point is not within geopath");
- return false;
+ return minDistance;
}
@Override
@@ -380,15 +255,6 @@ public class GeoPath extends GeoBaseExte
return false;
}
- /**
- * Compute longitude/latitude bounds for the shape.
- *
- * @param bounds is the optional input bounds object. If this is null,
- * a bounds object will be created. Otherwise, the input object will be modified.
- * @return a Bounds object describing the shape's bounds. If the bounds cannot
- * be computed, then return a Bounds object with noLongitudeBound,
- * noTopLatitudeBound, and noBottomLatitudeBound.
- */
@Override
public Bounds getBounds(Bounds bounds) {
bounds = super.getBounds(bounds);
@@ -562,22 +428,14 @@ public class GeoPath extends GeoBaseExte
return circlePlane.isWithin(x, y, z);
}
- public double pathDistance(final GeoPoint point) {
- if (!isWithin(point))
- return Double.MAX_VALUE;
- return this.point.arcDistance(point);
- }
-
- public double pathNormalDistance(final GeoPoint point) {
- if (!isWithin(point))
+ public double pathDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
+ if (!isWithin(x,y,z))
return Double.MAX_VALUE;
- return this.point.normalDistance(point);
+ return distanceStyle.computeDistance(this.point, x, y, z);
}
- public double pathLinearDistance(final GeoPoint point) {
- if (!isWithin(point))
- return Double.MAX_VALUE;
- return this.point.linearDistance(point);
+ public double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
+ return distanceStyle.computeDistance(this.point, x, y, z);
}
public boolean intersects(final PlanetModel planetModel, final Plane p, final GeoPoint[] notablePoints, final Membership[] bounds) {
@@ -614,14 +472,12 @@ public class GeoPath extends GeoBaseExte
}
/**
- * This is the precalculated data for a path segment.
+ * This is the pre-calculated data for a path segment.
*/
public static class PathSegment {
public final GeoPoint start;
public final GeoPoint end;
- public final double fullDistance;
- public final double fullNormalDistance;
- public final double fullLinearDistance;
+ public final Map<DistanceStyle,Double> fullDistanceCache = new HashMap<DistanceStyle,Double>();
public final Plane normalizedConnectingPlane;
public final SidedPlane upperConnectingPlane;
public final SidedPlane lowerConnectingPlane;
@@ -644,9 +500,6 @@ public class GeoPath extends GeoBaseExte
this.normalizedConnectingPlane = normalizedConnectingPlane;
this.planeBoundingOffset = planeBoundingOffset;
- fullDistance = start.arcDistance(end);
- fullNormalDistance = start.normalDistance(end);
- fullLinearDistance = start.linearDistance(end);
// Either start or end should be on the correct side
upperConnectingPlane = new SidedPlane(start, normalizedConnectingPlane, -planeBoundingOffset);
lowerConnectingPlane = new SidedPlane(start, normalizedConnectingPlane, planeBoundingOffset);
@@ -684,6 +537,17 @@ public class GeoPath extends GeoBaseExte
endCutoffPlanePoints = new GeoPoint[]{URHC, LRHC};
}
+ public double fullPathDistance(final DistanceStyle distanceStyle) {
+ synchronized (fullDistanceCache) {
+ Double dist = fullDistanceCache.get(distanceStyle);
+ if (dist == null) {
+ dist = new Double(distanceStyle.computeDistance(start, end.x, end.y, end.z));
+ fullDistanceCache.put(distanceStyle, dist);
+ }
+ return dist.doubleValue();
+ }
+ }
+
public boolean isWithin(final Vector point) {
//System.err.println(" assessing whether point "+point+" is within path segment "+this);
//System.err.println(" within "+startCutoffPlane+": "+startCutoffPlane.isWithin(point));
@@ -704,74 +568,58 @@ public class GeoPath extends GeoBaseExte
lowerConnectingPlane.isWithin(x, y, z);
}
- public double pathDistance(final GeoPoint point) {
- if (!isWithin(point))
- return Double.MAX_VALUE;
-
- // Compute the distance, filling in both components.
- final double perpDistance = Math.PI * 0.5 - Tools.safeAcos(Math.abs(normalizedConnectingPlane.evaluate(point)));
- final Plane normalizedPerpPlane = new Plane(normalizedConnectingPlane, point).normalize();
- final double pathDistance = Math.PI * 0.5 - Tools.safeAcos(Math.abs(normalizedPerpPlane.evaluate(start)));
- return perpDistance + pathDistance;
- }
-
- public double pathNormalDistance(final GeoPoint point) {
- if (!isWithin(point))
- return Double.MAX_VALUE;
-
- final double pointEval = Math.abs(normalizedConnectingPlane.evaluate(point));
-
- // Want no allocations or expensive operations! so we do this the hard way
- final double perpX = normalizedConnectingPlane.y * point.z - normalizedConnectingPlane.z * point.y;
- final double perpY = normalizedConnectingPlane.z * point.x - normalizedConnectingPlane.x * point.z;
- final double perpZ = normalizedConnectingPlane.x * point.y - normalizedConnectingPlane.y * point.x;
-
- // If we have a degenerate line, then just compute the normal distance from point x to the start
- if (Math.abs(perpX) < Vector.MINIMUM_RESOLUTION && Math.abs(perpY) < Vector.MINIMUM_RESOLUTION && Math.abs(perpZ) < Vector.MINIMUM_RESOLUTION)
- return point.normalDistance(start);
-
- final double normFactor = 1.0 / Math.sqrt(perpX * perpX + perpY * perpY + perpZ * perpZ);
- final double perpEval = Math.abs(perpX * start.x + perpY * start.y + perpZ * start.z);
- return perpEval * normFactor + pointEval;
- }
-
- public double pathLinearDistance(final GeoPoint point) {
- if (!isWithin(point))
+ public double pathDistance(final PlanetModel planetModel, final DistanceStyle distanceStyle, final double x, final double y, final double z) {
+ if (!isWithin(x,y,z))
return Double.MAX_VALUE;
- // We have a normalized connecting plane.
- // First, compute the perpendicular plane.
+ // (1) Compute normalizedPerpPlane. If degenerate, then return point distance from start to point.
// Want no allocations or expensive operations! so we do this the hard way
- final double perpX = normalizedConnectingPlane.y * point.z - normalizedConnectingPlane.z * point.y;
- final double perpY = normalizedConnectingPlane.z * point.x - normalizedConnectingPlane.x * point.z;
- final double perpZ = normalizedConnectingPlane.x * point.y - normalizedConnectingPlane.y * point.x;
-
- // If we have a degenerate line, then just compute the normal distance from point x to the start
- if (Math.abs(perpX) < Vector.MINIMUM_RESOLUTION && Math.abs(perpY) < Vector.MINIMUM_RESOLUTION && Math.abs(perpZ) < Vector.MINIMUM_RESOLUTION)
- return point.linearDistance(start);
-
- // Next, we need the vector of the line, which is the cross product of the normalized connecting plane
- // and the perpendicular plane that we just calculated.
- final double lineX = normalizedConnectingPlane.y * perpZ - normalizedConnectingPlane.z * perpY;
- final double lineY = normalizedConnectingPlane.z * perpX - normalizedConnectingPlane.x * perpZ;
- final double lineZ = normalizedConnectingPlane.x * perpY - normalizedConnectingPlane.y * perpX;
-
- // Now, compute a normalization factor
- final double normalizer = 1.0 / Math.sqrt(lineX * lineX + lineY * lineY + lineZ * lineZ);
-
- // Pick which point by using bounding planes
- double normLineX = lineX * normalizer;
- double normLineY = lineY * normalizer;
- double normLineZ = lineZ * normalizer;
- if (!startCutoffPlane.isWithin(normLineX, normLineY, normLineZ) ||
- !endCutoffPlane.isWithin(normLineX, normLineY, normLineZ)) {
- normLineX = -normLineX;
- normLineY = -normLineY;
- normLineZ = -normLineZ;
- }
-
- // Compute linear distance for the two points
- return point.linearDistance(normLineX, normLineY, normLineZ) + start.linearDistance(normLineX, normLineY, normLineZ);
+ final double perpX = normalizedConnectingPlane.y * z - normalizedConnectingPlane.z * y;
+ final double perpY = normalizedConnectingPlane.z * x - normalizedConnectingPlane.x * z;
+ final double perpZ = normalizedConnectingPlane.x * y - normalizedConnectingPlane.y * x;
+ final double magnitude = Math.sqrt(perpX * perpX + perpY * perpY + perpZ * perpZ);
+ if (Math.abs(magnitude) < Vector.MINIMUM_RESOLUTION)
+ return distanceStyle.computeDistance(start, x,y,z);
+ final double normFactor = 1.0/magnitude;
+ final Plane normalizedPerpPlane = new Plane(perpX * normFactor, perpY * normFactor, perpZ * normFactor, 0.0);
+
+ // Old computation: too expensive, because it calculates the intersection point twice.
+ //return distanceStyle.computeDistance(planetModel, normalizedConnectingPlane, x, y, z, startCutoffPlane, endCutoffPlane) +
+ // distanceStyle.computeDistance(planetModel, normalizedPerpPlane, start.x, start.y, start.z, upperConnectingPlane, lowerConnectingPlane);
+
+ final GeoPoint[] intersectionPoints = normalizedConnectingPlane.findIntersections(planetModel, normalizedPerpPlane);
+ GeoPoint thePoint;
+ if (intersectionPoints.length == 0)
+ throw new RuntimeException("Can't find world intersection for point x="+x+" y="+y+" z="+z);
+ else if (intersectionPoints.length == 1)
+ thePoint = intersectionPoints[0];
+ else {
+ if (startCutoffPlane.isWithin(intersectionPoints[0]) && endCutoffPlane.isWithin(intersectionPoints[0]))
+ thePoint = intersectionPoints[0];
+ else if (startCutoffPlane.isWithin(intersectionPoints[1]) && endCutoffPlane.isWithin(intersectionPoints[1]))
+ thePoint = intersectionPoints[1];
+ else
+ throw new RuntimeException("Can't find world intersection for point x="+x+" y="+y+" z="+z);
+ }
+ return distanceStyle.computeDistance(thePoint, x, y, z) + distanceStyle.computeDistance(start, thePoint.x, thePoint.y, thePoint.z);
+ }
+
+ public double outsideDistance(final PlanetModel planetModel, final DistanceStyle distanceStyle, final double x, final double y, final double z) {
+ final double upperDistance = distanceStyle.computeDistance(planetModel, upperConnectingPlane, x,y,z, lowerConnectingPlane, startCutoffPlane, endCutoffPlane);
+ final double lowerDistance = distanceStyle.computeDistance(planetModel, lowerConnectingPlane, x,y,z, upperConnectingPlane, startCutoffPlane, endCutoffPlane);
+ final double startDistance = distanceStyle.computeDistance(planetModel, startCutoffPlane, x,y,z, endCutoffPlane, lowerConnectingPlane, upperConnectingPlane);
+ final double endDistance = distanceStyle.computeDistance(planetModel, endCutoffPlane, x,y,z, startCutoffPlane, lowerConnectingPlane, upperConnectingPlane);
+ final double ULHCDistance = distanceStyle.computeDistance(ULHC, x,y,z);
+ final double URHCDistance = distanceStyle.computeDistance(URHC, x,y,z);
+ final double LLHCDistance = distanceStyle.computeDistance(LLHC, x,y,z);
+ final double LRHCDistance = distanceStyle.computeDistance(LRHC, x,y,z);
+ return Math.min(
+ Math.min(
+ Math.min(upperDistance,lowerDistance),
+ Math.min(startDistance,endDistance)),
+ Math.min(
+ Math.min(ULHCDistance, URHCDistance),
+ Math.min(LLHCDistance, LRHCDistance)));
}
public boolean intersects(final PlanetModel planetModel, final Plane p, final GeoPoint[] notablePoints, final Membership[] bounds) {
@@ -790,12 +638,6 @@ public class GeoPath extends GeoBaseExte
lowerConnectingPlane.recordBounds(planetModel, bounds, upperConnectingPlane, startCutoffPlane, endCutoffPlane);
startCutoffPlane.recordBounds(planetModel, bounds, endCutoffPlane, upperConnectingPlane, lowerConnectingPlane);
endCutoffPlane.recordBounds(planetModel, bounds, startCutoffPlane, upperConnectingPlane, lowerConnectingPlane);
- if (fullDistance >= Math.PI) {
- // Too large a segment basically means that we can confuse the Bounds object. Specifically, if our span exceeds 180 degrees
- // in longitude (which even a segment whose actual length is less than that might if it goes close to a pole).
- // Unfortunately, we can get arbitrarily close to the pole, so this may still not work in all cases.
- bounds.noLongitudeBound();
- }
}
}
Modified: lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoPoint.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoPoint.java?rev=1688545&r1=1688544&r2=1688545&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoPoint.java (original)
+++ lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoPoint.java Wed Jul 1 02:03:43 2015
@@ -18,7 +18,7 @@ package org.apache.lucene.spatial.spatia
*/
/**
- * This class represents a point on the surface of a unit sphere.
+ * This class represents a point on the surface of a sphere or ellipsoid.
*
* @lucene.experimental
*/
@@ -124,6 +124,16 @@ public class GeoPoint extends Vector {
return Tools.safeAcos(dotProduct(v)/(magnitude() * v.magnitude()));
}
+ /** Compute an arc distance between two points.
+ * @param x is the x part of the second point.
+ * @param y is the y part of the second point.
+ * @param z is the z part of the second point.
+ * @return the angle, in radians, between the two points.
+ */
+ public double arcDistance(final double x, final double y, final double z) {
+ return Tools.safeAcos(dotProduct(x,y,z)/(magnitude() * Vector.magnitude(x,y,z)));
+ }
+
/** Compute the latitude for the point.
* @return the latitude.
*/
Modified: lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoRectangle.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoRectangle.java?rev=1688545&r1=1688544&r2=1688545&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoRectangle.java (original)
+++ lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoRectangle.java Wed Jul 1 02:03:43 2015
@@ -138,14 +138,6 @@ public class GeoRectangle extends GeoBas
}
@Override
- public boolean isWithin(final Vector point) {
- return topPlane.isWithin(point) &&
- bottomPlane.isWithin(point) &&
- leftPlane.isWithin(point) &&
- rightPlane.isWithin(point);
- }
-
- @Override
public boolean isWithin(final double x, final double y, final double z) {
return topPlane.isWithin(x, y, z) &&
bottomPlane.isWithin(x, y, z) &&
@@ -169,11 +161,6 @@ public class GeoRectangle extends GeoBas
return edgePoints;
}
- /**
- * Returns the center of a circle into which the area will be inscribed.
- *
- * @return the center.
- */
@Override
public GeoPoint getCenter() {
return centerPoint;
@@ -187,15 +174,6 @@ public class GeoRectangle extends GeoBas
p.intersects(planetModel, rightPlane, notablePoints, rightPlanePoints, bounds, leftPlane, topPlane, bottomPlane);
}
- /**
- * Compute longitude/latitude bounds for the shape.
- *
- * @param bounds is the optional input bounds object. If this is null,
- * a bounds object will be created. Otherwise, the input object will be modified.
- * @return a Bounds object describing the shape's bounds. If the bounds cannot
- * be computed, then return a Bounds object with noLongitudeBound,
- * noTopLatitudeBound, and noBottomLatitudeBound.
- */
@Override
public Bounds getBounds(Bounds bounds) {
if (bounds == null)
@@ -243,6 +221,27 @@ public class GeoRectangle extends GeoBas
}
@Override
+ protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
+ final double topDistance = distanceStyle.computeDistance(planetModel, topPlane, x,y,z, bottomPlane, leftPlane, rightPlane);
+ final double bottomDistance = distanceStyle.computeDistance(planetModel, bottomPlane, x,y,z, topPlane, leftPlane, rightPlane);
+ final double leftDistance = distanceStyle.computeDistance(planetModel, leftPlane, x,y,z, rightPlane, topPlane, bottomPlane);
+ final double rightDistance = distanceStyle.computeDistance(planetModel, rightPlane, x,y,z, leftPlane, topPlane, bottomPlane);
+
+ final double ULHCDistance = distanceStyle.computeDistance(ULHC, x,y,z);
+ final double URHCDistance = distanceStyle.computeDistance(URHC, x,y,z);
+ final double LRHCDistance = distanceStyle.computeDistance(LRHC, x,y,z);
+ final double LLHCDistance = distanceStyle.computeDistance(LLHC, x,y,z);
+
+ return Math.min(
+ Math.min(
+ Math.min(topDistance, bottomDistance),
+ Math.min(leftDistance, rightDistance)),
+ Math.min(
+ Math.min(ULHCDistance, URHCDistance),
+ Math.min(LRHCDistance, LLHCDistance)));
+ }
+
+ @Override
public boolean equals(Object o) {
if (!(o instanceof GeoRectangle))
return false;
Modified: lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoShape.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoShape.java?rev=1688545&r1=1688544&r2=1688545&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoShape.java (original)
+++ lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoShape.java Wed Jul 1 02:03:43 2015
@@ -64,8 +64,4 @@ public interface GeoShape extends Member
*/
public Bounds getBounds(final Bounds bounds);
- /**
- * Equals
- */
- public boolean equals(Object o);
}
Modified: lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoSouthLatitudeZone.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoSouthLatitudeZone.java?rev=1688545&r1=1688544&r2=1688545&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoSouthLatitudeZone.java (original)
+++ lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoSouthLatitudeZone.java Wed Jul 1 02:03:43 2015
@@ -60,11 +60,6 @@ public class GeoSouthLatitudeZone extend
}
@Override
- public boolean isWithin(final Vector point) {
- return topPlane.isWithin(point);
- }
-
- @Override
public boolean isWithin(final double x, final double y, final double z) {
return topPlane.isWithin(x, y, z);
}
@@ -149,6 +144,11 @@ public class GeoSouthLatitudeZone extend
}
@Override
+ protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
+ return distanceStyle.computeDistance(planetModel, topPlane, x,y,z);
+ }
+
+ @Override
public boolean equals(Object o) {
if (!(o instanceof GeoSouthLatitudeZone))
return false;
Modified: lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoSouthRectangle.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoSouthRectangle.java?rev=1688545&r1=1688544&r2=1688545&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoSouthRectangle.java (original)
+++ lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoSouthRectangle.java Wed Jul 1 02:03:43 2015
@@ -21,7 +21,7 @@ package org.apache.lucene.spatial.spatia
* Bounding box limited on three sides (top lat, left lon, right lon). The
* other corner is the south pole.
* The left-right maximum extent for this shape is PI; for anything larger, use
- * GeoWideSouthRectangle.
+ * {@link GeoWideSouthRectangle}.
*
* @lucene.internal
*/
@@ -124,13 +124,6 @@ public class GeoSouthRectangle extends G
}
@Override
- public boolean isWithin(final Vector point) {
- return topPlane.isWithin(point) &&
- leftPlane.isWithin(point) &&
- rightPlane.isWithin(point);
- }
-
- @Override
public boolean isWithin(final double x, final double y, final double z) {
return topPlane.isWithin(x, y, z) &&
leftPlane.isWithin(x, y, z) &&
@@ -152,11 +145,6 @@ public class GeoSouthRectangle extends G
return edgePoints;
}
- /**
- * Returns the center of a circle into which the area will be inscribed.
- *
- * @return the center.
- */
@Override
public GeoPoint getCenter() {
return centerPoint;
@@ -169,15 +157,6 @@ public class GeoSouthRectangle extends G
p.intersects(planetModel, rightPlane, notablePoints, rightPlanePoints, bounds, leftPlane, topPlane);
}
- /**
- * Compute longitude/latitude bounds for the shape.
- *
- * @param bounds is the optional input bounds object. If this is null,
- * a bounds object will be created. Otherwise, the input object will be modified.
- * @return a Bounds object describing the shape's bounds. If the bounds cannot
- * be computed, then return a Bounds object with noLongitudeBound,
- * noTopLatitudeBound, and noBottomLatitudeBound.
- */
@Override
public Bounds getBounds(Bounds bounds) {
if (bounds == null)
@@ -224,6 +203,22 @@ public class GeoSouthRectangle extends G
}
@Override
+ protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
+ final double topDistance = distanceStyle.computeDistance(planetModel, topPlane, x,y,z, leftPlane, rightPlane);
+ final double leftDistance = distanceStyle.computeDistance(planetModel, leftPlane, x,y,z, rightPlane, topPlane);
+ final double rightDistance = distanceStyle.computeDistance(planetModel, rightPlane, x,y,z, leftPlane, topPlane);
+
+ final double ULHCDistance = distanceStyle.computeDistance(ULHC, x,y,z);
+ final double URHCDistance = distanceStyle.computeDistance(URHC, x,y,z);
+
+ return Math.min(
+ Math.min(
+ topDistance,
+ Math.min(leftDistance, rightDistance)),
+ Math.min(ULHCDistance, URHCDistance));
+ }
+
+ @Override
public boolean equals(Object o) {
if (!(o instanceof GeoSouthRectangle))
return false;
Modified: lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWideDegenerateHorizontalLine.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWideDegenerateHorizontalLine.java?rev=1688545&r1=1688544&r2=1688545&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWideDegenerateHorizontalLine.java (original)
+++ lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWideDegenerateHorizontalLine.java Wed Jul 1 02:03:43 2015
@@ -117,15 +117,6 @@ public class GeoWideDegenerateHorizontal
}
@Override
- public boolean isWithin(final Vector point) {
- if (point == null)
- return false;
- return plane.evaluateIsZero(point) &&
- (leftPlane.isWithin(point) ||
- rightPlane.isWithin(point));
- }
-
- @Override
public boolean isWithin(final double x, final double y, final double z) {
return plane.evaluateIsZero(x, y, z) &&
(leftPlane.isWithin(x, y, z) ||
@@ -142,11 +133,6 @@ public class GeoWideDegenerateHorizontal
return Math.max(topAngle, bottomAngle);
}
- /**
- * Returns the center of a circle into which the area will be inscribed.
- *
- * @return the center.
- */
@Override
public GeoPoint getCenter() {
return centerPoint;
@@ -164,15 +150,6 @@ public class GeoWideDegenerateHorizontal
return p.intersects(planetModel, plane, notablePoints, planePoints, bounds, eitherBound);
}
- /**
- * Compute longitude/latitude bounds for the shape.
- *
- * @param bounds is the optional input bounds object. If this is null,
- * a bounds object will be created. Otherwise, the input object will be modified.
- * @return a Bounds object describing the shape's bounds. If the bounds cannot
- * be computed, then return a Bounds object with noLongitudeBound,
- * noTopLatitudeBound, and noBottomLatitudeBound.
- */
@Override
public Bounds getBounds(Bounds bounds) {
if (bounds == null)
@@ -196,6 +173,18 @@ public class GeoWideDegenerateHorizontal
}
@Override
+ protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
+ final double distance = distanceStyle.computeDistance(planetModel, plane, x,y,z, eitherBound);
+
+ final double LHCDistance = distanceStyle.computeDistance(LHC, x,y,z);
+ final double RHCDistance = distanceStyle.computeDistance(RHC, x,y,z);
+
+ return Math.min(
+ distance,
+ Math.min(LHCDistance, RHCDistance));
+ }
+
+ @Override
public boolean equals(Object o) {
if (!(o instanceof GeoWideDegenerateHorizontalLine))
return false;
@@ -221,11 +210,6 @@ public class GeoWideDegenerateHorizontal
}
@Override
- public boolean isWithin(final Vector v) {
- return leftPlane.isWithin(v) || rightPlane.isWithin(v);
- }
-
- @Override
public boolean isWithin(final double x, final double y, final double z) {
return leftPlane.isWithin(x, y, z) || rightPlane.isWithin(x, y, z);
}
Modified: lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWideLongitudeSlice.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWideLongitudeSlice.java?rev=1688545&r1=1688544&r2=1688545&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWideLongitudeSlice.java (original)
+++ lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWideLongitudeSlice.java Wed Jul 1 02:03:43 2015
@@ -92,12 +92,6 @@ public class GeoWideLongitudeSlice exten
}
@Override
- public boolean isWithin(final Vector point) {
- return leftPlane.isWithin(point) ||
- rightPlane.isWithin(point);
- }
-
- @Override
public boolean isWithin(final double x, final double y, final double z) {
return leftPlane.isWithin(x, y, z) ||
rightPlane.isWithin(x, y, z);
@@ -112,11 +106,6 @@ public class GeoWideLongitudeSlice exten
return Math.max(Math.PI * 0.5, extent * 0.5);
}
- /**
- * Returns the center of a circle into which the area will be inscribed.
- *
- * @return the center.
- */
@Override
public GeoPoint getCenter() {
return centerPoint;
@@ -135,15 +124,6 @@ public class GeoWideLongitudeSlice exten
p.intersects(planetModel, rightPlane, notablePoints, planePoints, bounds);
}
- /**
- * Compute longitude/latitude bounds for the shape.
- *
- * @param bounds is the optional input bounds object. If this is null,
- * a bounds object will be created. Otherwise, the input object will be modified.
- * @return a Bounds object describing the shape's bounds. If the bounds cannot
- * be computed, then return a Bounds object with noLongitudeBound,
- * noTopLatitudeBound, and noBottomLatitudeBound.
- */
@Override
public Bounds getBounds(Bounds bounds) {
if (bounds == null)
@@ -178,6 +158,21 @@ public class GeoWideLongitudeSlice exten
}
@Override
+ protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
+ // Because the rectangle exceeds 180 degrees, it is safe to compute the horizontally
+ // unbounded distance to both the left and the right and only take the minimum of the two.
+ final double leftDistance = distanceStyle.computeDistance(planetModel, leftPlane, x,y,z);
+ final double rightDistance = distanceStyle.computeDistance(planetModel, rightPlane, x,y,z);
+
+ final double northDistance = distanceStyle.computeDistance(planetModel.NORTH_POLE, x,y,z);
+ final double southDistance = distanceStyle.computeDistance(planetModel.SOUTH_POLE, x,y,z);
+
+ return Math.min(
+ Math.min(leftDistance, rightDistance),
+ Math.min(northDistance, southDistance));
+ }
+
+ @Override
public boolean equals(Object o) {
if (!(o instanceof GeoWideLongitudeSlice))
return false;
Modified: lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWideNorthRectangle.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWideNorthRectangle.java?rev=1688545&r1=1688544&r2=1688545&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWideNorthRectangle.java (original)
+++ lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWideNorthRectangle.java Wed Jul 1 02:03:43 2015
@@ -125,14 +125,6 @@ public class GeoWideNorthRectangle exten
}
@Override
- public boolean isWithin(final Vector point) {
- return
- bottomPlane.isWithin(point) &&
- (leftPlane.isWithin(point) ||
- rightPlane.isWithin(point));
- }
-
- @Override
public boolean isWithin(final double x, final double y, final double z) {
return
bottomPlane.isWithin(x, y, z) &&
@@ -150,11 +142,6 @@ public class GeoWideNorthRectangle exten
return Math.max(centerAngle, bottomAngle);
}
- /**
- * Returns the center of a circle into which the area will be inscribed.
- *
- * @return the center.
- */
@Override
public GeoPoint getCenter() {
return centerPoint;
@@ -175,15 +162,6 @@ public class GeoWideNorthRectangle exten
p.intersects(planetModel, rightPlane, notablePoints, rightPlanePoints, bounds, bottomPlane);
}
- /**
- * Compute longitude/latitude bounds for the shape.
- *
- * @param bounds is the optional input bounds object. If this is null,
- * a bounds object will be created. Otherwise, the input object will be modified.
- * @return a Bounds object describing the shape's bounds. If the bounds cannot
- * be computed, then return a Bounds object with noLongitudeBound,
- * noTopLatitudeBound, and noBottomLatitudeBound.
- */
@Override
public Bounds getBounds(Bounds bounds) {
if (bounds == null)
@@ -232,6 +210,24 @@ public class GeoWideNorthRectangle exten
}
@Override
+ protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
+ final double bottomDistance = distanceStyle.computeDistance(planetModel, bottomPlane, x,y,z, eitherBound);
+ // Because the rectangle exceeds 180 degrees, it is safe to compute the horizontally
+ // unbounded distance to both the left and the right and only take the minimum of the two.
+ final double leftDistance = distanceStyle.computeDistance(planetModel, leftPlane, x,y,z, bottomPlane);
+ final double rightDistance = distanceStyle.computeDistance(planetModel, rightPlane, x,y,z, bottomPlane);
+
+ final double LRHCDistance = distanceStyle.computeDistance(LRHC, x,y,z);
+ final double LLHCDistance = distanceStyle.computeDistance(LLHC, x,y,z);
+
+ return Math.min(
+ Math.min(
+ bottomDistance,
+ Math.min(leftDistance, rightDistance)),
+ Math.min(LRHCDistance, LLHCDistance));
+ }
+
+ @Override
public boolean equals(Object o) {
if (!(o instanceof GeoWideNorthRectangle))
return false;
Modified: lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWideRectangle.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWideRectangle.java?rev=1688545&r1=1688544&r2=1688545&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWideRectangle.java (original)
+++ lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWideRectangle.java Wed Jul 1 02:03:43 2015
@@ -142,14 +142,6 @@ public class GeoWideRectangle extends Ge
}
@Override
- public boolean isWithin(final Vector point) {
- return topPlane.isWithin(point) &&
- bottomPlane.isWithin(point) &&
- (leftPlane.isWithin(point) ||
- rightPlane.isWithin(point));
- }
-
- @Override
public boolean isWithin(final double x, final double y, final double z) {
return topPlane.isWithin(x, y, z) &&
bottomPlane.isWithin(x, y, z) &&
@@ -193,15 +185,6 @@ public class GeoWideRectangle extends Ge
p.intersects(planetModel, rightPlane, notablePoints, rightPlanePoints, bounds, topPlane, bottomPlane);
}
- /**
- * Compute longitude/latitude bounds for the shape.
- *
- * @param bounds is the optional input bounds object. If this is null,
- * a bounds object will be created. Otherwise, the input object will be modified.
- * @return a Bounds object describing the shape's bounds. If the bounds cannot
- * be computed, then return a Bounds object with noLongitudeBound,
- * noTopLatitudeBound, and noBottomLatitudeBound.
- */
@Override
public Bounds getBounds(Bounds bounds) {
if (bounds == null)
@@ -250,6 +233,29 @@ public class GeoWideRectangle extends Ge
}
@Override
+ protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
+ final double topDistance = distanceStyle.computeDistance(planetModel, topPlane, x,y,z, bottomPlane, eitherBound);
+ final double bottomDistance = distanceStyle.computeDistance(planetModel, bottomPlane, x,y,z, topPlane, eitherBound);
+ // Because the rectangle exceeds 180 degrees, it is safe to compute the horizontally
+ // unbounded distance to both the left and the right and only take the minimum of the two.
+ final double leftDistance = distanceStyle.computeDistance(planetModel, leftPlane, x,y,z, topPlane, bottomPlane);
+ final double rightDistance = distanceStyle.computeDistance(planetModel, rightPlane, x,y,z, topPlane, bottomPlane);
+
+ final double ULHCDistance = distanceStyle.computeDistance(ULHC, x,y,z);
+ final double URHCDistance = distanceStyle.computeDistance(URHC, x,y,z);
+ final double LRHCDistance = distanceStyle.computeDistance(LRHC, x,y,z);
+ final double LLHCDistance = distanceStyle.computeDistance(LLHC, x,y,z);
+
+ return Math.min(
+ Math.min(
+ Math.min(topDistance, bottomDistance),
+ Math.min(leftDistance, rightDistance)),
+ Math.min(
+ Math.min(ULHCDistance, URHCDistance),
+ Math.min(LRHCDistance, LLHCDistance)));
+ }
+
+ @Override
public boolean equals(Object o) {
if (!(o instanceof GeoWideRectangle))
return false;
Modified: lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWideSouthRectangle.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWideSouthRectangle.java?rev=1688545&r1=1688544&r2=1688545&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWideSouthRectangle.java (original)
+++ lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWideSouthRectangle.java Wed Jul 1 02:03:43 2015
@@ -126,13 +126,6 @@ public class GeoWideSouthRectangle exten
}
@Override
- public boolean isWithin(final Vector point) {
- return topPlane.isWithin(point) &&
- (leftPlane.isWithin(point) ||
- rightPlane.isWithin(point));
- }
-
- @Override
public boolean isWithin(final double x, final double y, final double z) {
return topPlane.isWithin(x, y, z) &&
(leftPlane.isWithin(x, y, z) ||
@@ -149,11 +142,6 @@ public class GeoWideSouthRectangle exten
return Math.max(centerAngle, topAngle);
}
- /**
- * Returns the center of a circle into which the area will be inscribed.
- *
- * @return the center.
- */
@Override
public GeoPoint getCenter() {
return centerPoint;
@@ -173,15 +161,6 @@ public class GeoWideSouthRectangle exten
p.intersects(planetModel, rightPlane, notablePoints, rightPlanePoints, bounds, topPlane);
}
- /**
- * Compute longitude/latitude bounds for the shape.
- *
- * @param bounds is the optional input bounds object. If this is null,
- * a bounds object will be created. Otherwise, the input object will be modified.
- * @return a Bounds object describing the shape's bounds. If the bounds cannot
- * be computed, then return a Bounds object with noLongitudeBound,
- * noTopLatitudeBound, and noBottomLatitudeBound.
- */
@Override
public Bounds getBounds(Bounds bounds) {
if (bounds == null)
@@ -229,11 +208,29 @@ public class GeoWideSouthRectangle exten
}
@Override
+ protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
+ final double topDistance = distanceStyle.computeDistance(planetModel, topPlane, x,y,z, eitherBound);
+ // Because the rectangle exceeds 180 degrees, it is safe to compute the horizontally
+ // unbounded distance to both the left and the right and only take the minimum of the two.
+ final double leftDistance = distanceStyle.computeDistance(planetModel, leftPlane, x,y,z, topPlane);
+ final double rightDistance = distanceStyle.computeDistance(planetModel, rightPlane, x,y,z, topPlane);
+
+ final double ULHCDistance = distanceStyle.computeDistance(ULHC, x,y,z);
+ final double URHCDistance = distanceStyle.computeDistance(URHC, x,y,z);
+
+ return Math.min(
+ Math.min(
+ topDistance,
+ Math.min(leftDistance, rightDistance)),
+ Math.min(ULHCDistance, URHCDistance));
+ }
+
+ @Override
public boolean equals(Object o) {
if (!(o instanceof GeoWideSouthRectangle))
return false;
GeoWideSouthRectangle other = (GeoWideSouthRectangle) o;
- return super.equals(other) && other.ULHC.equals(ULHC) && other.URHC.equals(URHC);
+ return super.equals(o) && other.ULHC.equals(ULHC) && other.URHC.equals(URHC);
}
@Override
Modified: lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWorld.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWorld.java?rev=1688545&r1=1688544&r2=1688545&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWorld.java (original)
+++ lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWorld.java Wed Jul 1 02:03:43 2015
@@ -41,11 +41,6 @@ public class GeoWorld extends GeoBaseBBo
return Math.PI;
}
- /**
- * Returns the center of a circle into which the area will be inscribed.
- *
- * @return the center.
- */
@Override
public GeoPoint getCenter() {
// Totally arbitrary
@@ -53,11 +48,6 @@ public class GeoWorld extends GeoBaseBBo
}
@Override
- public boolean isWithin(final Vector point) {
- return true;
- }
-
- @Override
public boolean isWithin(final double x, final double y, final double z) {
return true;
}
@@ -72,15 +62,6 @@ public class GeoWorld extends GeoBaseBBo
return false;
}
- /**
- * Compute longitude/latitude bounds for the shape.
- *
- * @param bounds is the optional input bounds object. If this is null,
- * a bounds object will be created. Otherwise, the input object will be modified.
- * @return a Bounds object describing the shape's bounds. If the bounds cannot
- * be computed, then return a Bounds object with noLongitudeBound,
- * noTopLatitudeBound, and noBottomLatitudeBound.
- */
@Override
public Bounds getBounds(Bounds bounds) {
if (bounds == null)
@@ -99,6 +80,11 @@ public class GeoWorld extends GeoBaseBBo
}
@Override
+ protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
+ return 0.0;
+ }
+
+ @Override
public boolean equals(Object o) {
if (!(o instanceof GeoWorld))
return false;
Added: lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/LinearDistance.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/LinearDistance.java?rev=1688545&view=auto
==============================================================================
--- lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/LinearDistance.java (added)
+++ lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/LinearDistance.java Wed Jul 1 02:03:43 2015
@@ -0,0 +1,51 @@
+package org.apache.lucene.spatial.spatial4j.geo3d;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Linear distance computation style.
+ *
+ * @lucene.experimental
+ */
+public class LinearDistance implements DistanceStyle {
+
+ public final static LinearDistance INSTANCE = new LinearDistance();
+
+ @Override
+ public double computeDistance(final GeoPoint point1, final GeoPoint point2) {
+ return point1.linearDistance(point2);
+ }
+
+ @Override
+ public double computeDistance(final GeoPoint point1, final double x2, final double y2, final double z2) {
+ return point1.linearDistance(x2,y2,z2);
+ }
+
+ @Override
+ public double computeDistance(final PlanetModel planetModel, final Plane plane, final GeoPoint point, final Membership... bounds) {
+ return plane.linearDistance(planetModel, point, bounds);
+ }
+
+ @Override
+ public double computeDistance(final PlanetModel planetModel, final Plane plane, final double x, final double y, final double z, final Membership... bounds) {
+ return plane.linearDistance(planetModel, x,y,z, bounds);
+ }
+
+}
+
+
Added: lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/LinearSquaredDistance.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/LinearSquaredDistance.java?rev=1688545&view=auto
==============================================================================
--- lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/LinearSquaredDistance.java (added)
+++ lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/LinearSquaredDistance.java Wed Jul 1 02:03:43 2015
@@ -0,0 +1,51 @@
+package org.apache.lucene.spatial.spatial4j.geo3d;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Linear squared distance computation style.
+ *
+ * @lucene.experimental
+ */
+public class LinearSquaredDistance implements DistanceStyle {
+
+ public final static LinearSquaredDistance INSTANCE = new LinearSquaredDistance();
+
+ @Override
+ public double computeDistance(final GeoPoint point1, final GeoPoint point2) {
+ return point1.linearDistanceSquared(point2);
+ }
+
+ @Override
+ public double computeDistance(final GeoPoint point1, final double x2, final double y2, final double z2) {
+ return point1.linearDistanceSquared(x2,y2,z2);
+ }
+
+ @Override
+ public double computeDistance(final PlanetModel planetModel, final Plane plane, final GeoPoint point, final Membership... bounds) {
+ return plane.linearDistanceSquared(planetModel, point, bounds);
+ }
+
+ @Override
+ public double computeDistance(final PlanetModel planetModel, final Plane plane, final double x, final double y, final double z, final Membership... bounds) {
+ return plane.linearDistanceSquared(planetModel, x,y,z, bounds);
+ }
+
+}
+
+
Modified: lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/Membership.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/Membership.java?rev=1688545&r1=1688544&r2=1688545&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/Membership.java (original)
+++ lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/Membership.java Wed Jul 1 02:03:43 2015
@@ -18,7 +18,7 @@ package org.apache.lucene.spatial.spatia
*/
/**
- * Interface describing 3d shape membership methods.
+ * Implemented by Geo3D shapes that can calculate if a point is within it or not.
*
* @lucene.experimental
*/
@@ -30,7 +30,9 @@ public interface Membership {
* @param point is the point to check.
* @return true if the point is within this shape
*/
- public boolean isWithin(final Vector point);
+ public default boolean isWithin(final Vector point) {
+ return isWithin(point.x, point.y, point.z);
+ }
/**
* Check if a point is within this shape.
Added: lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/NormalDistance.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/NormalDistance.java?rev=1688545&view=auto
==============================================================================
--- lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/NormalDistance.java (added)
+++ lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/NormalDistance.java Wed Jul 1 02:03:43 2015
@@ -0,0 +1,51 @@
+package org.apache.lucene.spatial.spatial4j.geo3d;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Normal distance computation style.
+ *
+ * @lucene.experimental
+ */
+public class NormalDistance implements DistanceStyle {
+
+ public final static NormalDistance INSTANCE = new NormalDistance();
+
+ @Override
+ public double computeDistance(final GeoPoint point1, final GeoPoint point2) {
+ return point1.normalDistance(point2);
+ }
+
+ @Override
+ public double computeDistance(final GeoPoint point1, final double x2, final double y2, final double z2) {
+ return point1.normalDistance(x2,y2,z2);
+ }
+
+ @Override
+ public double computeDistance(final PlanetModel planetModel, final Plane plane, final GeoPoint point, final Membership... bounds) {
+ return plane.normalDistance(point, bounds);
+ }
+
+ @Override
+ public double computeDistance(final PlanetModel planetModel, final Plane plane, final double x, final double y, final double z, final Membership... bounds) {
+ return plane.normalDistance(x,y,z, bounds);
+ }
+
+}
+
+
Added: lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/NormalSquaredDistance.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/NormalSquaredDistance.java?rev=1688545&view=auto
==============================================================================
--- lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/NormalSquaredDistance.java (added)
+++ lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/NormalSquaredDistance.java Wed Jul 1 02:03:43 2015
@@ -0,0 +1,51 @@
+package org.apache.lucene.spatial.spatial4j.geo3d;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Normal squared distance computation style.
+ *
+ * @lucene.experimental
+ */
+public class NormalSquaredDistance implements DistanceStyle {
+
+ public final static NormalSquaredDistance INSTANCE = new NormalSquaredDistance();
+
+ @Override
+ public double computeDistance(final GeoPoint point1, final GeoPoint point2) {
+ return point1.normalDistanceSquared(point2);
+ }
+
+ @Override
+ public double computeDistance(final GeoPoint point1, final double x2, final double y2, final double z2) {
+ return point1.normalDistanceSquared(x2,y2,z2);
+ }
+
+ @Override
+ public double computeDistance(final PlanetModel planetModel, final Plane plane, final GeoPoint point, final Membership... bounds) {
+ return plane.normalDistanceSquared(point, bounds);
+ }
+
+ @Override
+ public double computeDistance(final PlanetModel planetModel, final Plane plane, final double x, final double y, final double z, final Membership... bounds) {
+ return plane.normalDistanceSquared(x,y,z, bounds);
+ }
+
+}
+
+
Modified: lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/Plane.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/Plane.java?rev=1688545&r1=1688544&r2=1688545&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/Plane.java (original)
+++ lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/Plane.java Wed Jul 1 02:03:43 2015
@@ -143,6 +143,178 @@ public class Plane extends Vector {
return new Plane(normVect, this.D);
}
+ /** @see #arcDistance(PlanetModel, double, double, double, Membership...) */
+ public double arcDistance(final PlanetModel planetModel, final GeoPoint v, final Membership... bounds) {
+ return arcDistance(planetModel, v.x, v.y, v.z, bounds);
+ }
+
+ /**
+ * Compute arc distance from plane to a vector.
+ * @param x is the x vector value.
+ * @param y is the y vector value.
+ * @param z is the z vector value.
+ * @return the arc distance.
+ */
+ public double arcDistance(final PlanetModel planetModel, final double x, final double y, final double z, final Membership... bounds) {
+
+ if (evaluateIsZero(x,y,z)) {
+ if (meetsAllBounds(x,y,z, bounds))
+ return 0.0;
+ return Double.MAX_VALUE;
+ }
+
+ // First, compute the perpendicular plane.
+ final Plane perpPlane = new Plane(this.y * z - this.z * y, this.z * x - this.x * z, this.x * y - this.y * x, 0.0);
+
+ // We need to compute the intersection of two planes on the geo surface: this one, and its perpendicular.
+ // Then, we need to choose which of the two points we want to compute the distance to. We pick the
+ // shorter distance always.
+
+ final GeoPoint[] intersectionPoints = findIntersections(planetModel, perpPlane);
+
+ // For each point, compute a linear distance, and take the minimum of them
+ double minDistance = Double.MAX_VALUE;
+
+ for (final GeoPoint intersectionPoint : intersectionPoints) {
+ if (meetsAllBounds(intersectionPoint, bounds)) {
+ final double theDistance = intersectionPoint.arcDistance(x,y,z);
+ if (theDistance < minDistance) {
+ minDistance = theDistance;
+ }
+ }
+ }
+ return minDistance;
+
+ }
+
+ /**
+ * Compute normal distance from plane to a vector.
+ * @param v is the vector.
+ * @return the normal distance.
+ */
+ public double normalDistance(final Vector v, final Membership... bounds) {
+ return normalDistance(v.x, v.y, v.z, bounds);
+ }
+
+ /**
+ * Compute normal distance from plane to a vector.
+ * @param x is the vector x.
+ * @param y is the vector y.
+ * @param z is the vector z.
+ * @return the normal distance.
+ */
+ public double normalDistance(final double x, final double y, final double z, final Membership... bounds) {
+
+ final double dist = evaluate(x,y,z);
+ final double perpX = x - dist * this.x;
+ final double perpY = y - dist * this.y;
+ final double perpZ = z - dist * this.z;
+
+ if (!meetsAllBounds(perpX, perpY, perpZ, bounds)) {
+ return Double.MAX_VALUE;
+ }
+
+ return Math.abs(dist);
+ }
+
+ /**
+ * Compute normal distance squared from plane to a vector.
+ * @param v is the vector.
+ * @return the normal distance squared.
+ */
+ public double normalDistanceSquared(final Vector v, final Membership... bounds) {
+ return normalDistanceSquared(v.x, v.y, v.z, bounds);
+ }
+
+ /**
+ * Compute normal distance squared from plane to a vector.
+ * @param x is the vector x.
+ * @param y is the vector y.
+ * @param z is the vector z.
+ * @return the normal distance squared.
+ */
+ public double normalDistanceSquared(final double x, final double y, final double z, final Membership... bounds) {
+ final double normal = normalDistance(x,y,z,bounds);
+ if (normal == Double.MAX_VALUE)
+ return normal;
+ return normal * normal;
+ }
+
+ /**
+ * Compute linear distance from plane to a vector. This is defined
+ * as the distance from the given point to the nearest intersection of
+ * this plane with the planet surface.
+ * @param v is the vector.
+ * @return the linear distance.
+ */
+ public double linearDistance(final PlanetModel planetModel, final GeoPoint v, final Membership... bounds) {
+ return linearDistance(planetModel, v.x, v.y, v.z, bounds);
+ }
+
+ /**
+ * Compute linear distance from plane to a vector. This is defined
+ * as the distance from the given point to the nearest intersection of
+ * this plane with the planet surface.
+ * @param x is the vector x.
+ * @param y is the vector y.
+ * @param z is the vector z.
+ * @return the linear distance.
+ */
+ public double linearDistance(final PlanetModel planetModel, final double x, final double y, final double z, final Membership... bounds) {
+ if (evaluateIsZero(x,y,z)) {
+ if (meetsAllBounds(x,y,z, bounds))
+ return 0.0;
+ return Double.MAX_VALUE;
+ }
+
+ // First, compute the perpendicular plane.
+ final Plane perpPlane = new Plane(this.y * z - this.z * y, this.z * x - this.x * z, this.x * y - this.y * x, 0.0);
+
+ // We need to compute the intersection of two planes on the geo surface: this one, and its perpendicular.
+ // Then, we need to choose which of the two points we want to compute the distance to. We pick the
+ // shorter distance always.
+
+ final GeoPoint[] intersectionPoints = findIntersections(planetModel, perpPlane);
+
+ // For each point, compute a linear distance, and take the minimum of them
+ double minDistance = Double.MAX_VALUE;
+
+ for (final GeoPoint intersectionPoint : intersectionPoints) {
+ if (meetsAllBounds(intersectionPoint, bounds)) {
+ final double theDistance = intersectionPoint.linearDistance(x,y,z);
+ if (theDistance < minDistance) {
+ minDistance = theDistance;
+ }
+ }
+ }
+ return minDistance;
+ }
+
+ /**
+ * Compute linear distance squared from plane to a vector. This is defined
+ * as the distance from the given point to the nearest intersection of
+ * this plane with the planet surface.
+ * @param v is the vector.
+ * @return the linear distance squared.
+ */
+ public double linearDistanceSquared(final PlanetModel planetModel, final GeoPoint v, final Membership... bounds) {
+ return linearDistanceSquared(planetModel, v.x, v.y, v.z, bounds);
+ }
+
+ /**
+ * Compute linear distance squared from plane to a vector. This is defined
+ * as the distance from the given point to the nearest intersection of
+ * this plane with the planet surface.
+ * @param x is the vector x.
+ * @param y is the vector y.
+ * @param z is the vector z.
+ * @return the linear distance squared.
+ */
+ public double linearDistanceSquared(final PlanetModel planetModel, final double x, final double y, final double z, final Membership... bounds) {
+ final double linearDistance = linearDistance(planetModel, x, y, z, bounds);
+ return linearDistance * linearDistance;
+ }
+
/**
* Find points on the boundary of the intersection of a plane and the unit sphere,
* given a starting point, and ending point, and a list of proportions of the arc (e.g. 0.25, 0.5, 0.75).
@@ -320,7 +492,8 @@ public class Plane extends Vector {
*/
protected GeoPoint[] findIntersections(final PlanetModel planetModel, final Plane q, final Membership[] bounds, final Membership[] moreBounds) {
//System.err.println("Looking for intersection between plane "+this+" and plane "+q+" within bounds");
- final Vector lineVector = new Vector(this, q);
+ // Unnormalized, unchecked...
+ final Vector lineVector = new Vector(y * q.z - z * q.y, z * q.x - x * q.z, x * q.y - y * q.x);
if (Math.abs(lineVector.x) < MINIMUM_RESOLUTION && Math.abs(lineVector.y) < MINIMUM_RESOLUTION && Math.abs(lineVector.z) < MINIMUM_RESOLUTION) {
// Degenerate case: parallel planes
//System.err.println(" planes are parallel - no intersection");
@@ -860,18 +1033,27 @@ public class Plane extends Vector {
return evaluateIsZero(-p.x * p.D * denom, -p.y * p.D * denom, -p.z * p.D * denom);
}
- protected static boolean meetsAllBounds(final GeoPoint p, final Membership[] bounds, final Membership[] moreBounds) {
+ protected static boolean meetsAllBounds(final Vector p, final Membership[] bounds) {
+ return meetsAllBounds(p.x, p.y, p.z, bounds);
+ }
+
+ protected static boolean meetsAllBounds(final double x, final double y, final double z, final Membership[] bounds) {
for (final Membership bound : bounds) {
- if (!bound.isWithin(p))
- return false;
- }
- for (final Membership bound : moreBounds) {
- if (!bound.isWithin(p))
+ if (!bound.isWithin(x,y,z))
return false;
}
return true;
}
+ protected static boolean meetsAllBounds(final Vector p, final Membership[] bounds, final Membership[] moreBounds) {
+ return meetsAllBounds(p.x, p.y, p.z, bounds, moreBounds);
+ }
+
+ protected static boolean meetsAllBounds(final double x, final double y, final double z, final Membership[] bounds,
+ final Membership[] moreBounds) {
+ return meetsAllBounds(x,y,z, bounds) && meetsAllBounds(x,y,z, moreBounds);
+ }
+
/**
* Find a sample point on the intersection between two planes and the unit sphere.
*/
Modified: lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/SidedPlane.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/SidedPlane.java?rev=1688545&r1=1688544&r2=1688545&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/SidedPlane.java (original)
+++ lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/SidedPlane.java Wed Jul 1 02:03:43 2015
@@ -90,57 +90,58 @@ public class SidedPlane extends Plane im
public static SidedPlane constructNormalizedPerpendicularSidedPlane(final Vector insidePoint,
final Vector normalVector, final Vector point1, final Vector point2) {
final Vector pointsVector = new Vector(point1.x - point2.x, point1.y - point2.y, point1.z - point2.z);
- final Vector newNormalVector = new Vector(normalVector, pointsVector).normalize();
- if (newNormalVector == null)
+ final Vector newNormalVector = new Vector(normalVector, pointsVector);
+ try {
+ // To construct the plane, we now just need D, which is simply the negative of the evaluation of the circle normal vector at one of the points.
+ return new SidedPlane(insidePoint, newNormalVector, -newNormalVector.dotProduct(point1));
+ } catch (IllegalArgumentException e) {
return null;
- // To construct the plane, we now just need D, which is simply the negative of the evaluation of the circle normal vector at one of the points.
- return new SidedPlane(insidePoint, newNormalVector, -newNormalVector.dotProduct(point1));
+ }
}
/** Construct a sided plane from three points.
*/
public static SidedPlane constructNormalizedThreePointSidedPlane(final Vector insidePoint,
final Vector point1, final Vector point2, final Vector point3) {
- final Vector planeNormal = new Vector(
- new Vector(point1.x - point2.x, point1.y - point2.y, point1.z - point2.z),
- new Vector(point2.x - point3.x, point2.y - point3.y, point2.z - point3.z)).normalize();
- if (planeNormal == null)
+ try {
+ final Vector planeNormal = new Vector(
+ new Vector(point1.x - point2.x, point1.y - point2.y, point1.z - point2.z),
+ new Vector(point2.x - point3.x, point2.y - point3.y, point2.z - point3.z));
+ return new SidedPlane(insidePoint, planeNormal, -planeNormal.dotProduct(point2));
+ } catch (IllegalArgumentException e) {
return null;
- return new SidedPlane(insidePoint, planeNormal, -planeNormal.dotProduct(point2));
+ }
}
- /**
- * Check if a point is within this shape.
- *
- * @param point is the point to check.
- * @return true if the point is within this shape
- */
@Override
- public boolean isWithin(Vector point) {
- double evalResult = evaluate(point);
+ public boolean isWithin(double x, double y, double z) {
+ double evalResult = evaluate(x, y, z);
if (Math.abs(evalResult) < MINIMUM_RESOLUTION)
return true;
double sigNum = Math.signum(evalResult);
return sigNum == this.sigNum;
}
- /**
- * Check if a point is within this shape.
- *
- * @param x is x coordinate of point to check.
- * @param y is y coordinate of point to check.
- * @param z is z coordinate of point to check.
- * @return true if the point is within this shape
- */
@Override
- public boolean isWithin(double x, double y, double z) {
- double evalResult = evaluate(x, y, z);
- if (Math.abs(evalResult) < MINIMUM_RESOLUTION)
- return true;
- double sigNum = Math.signum(evalResult);
- return sigNum == this.sigNum;
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof SidedPlane)) return false;
+ if (!super.equals(o)) return false;
+
+ SidedPlane that = (SidedPlane) o;
+
+ return Double.compare(that.sigNum, sigNum) == 0;
+
}
+ @Override
+ public int hashCode() {
+ int result = super.hashCode();
+ long temp;
+ temp = Double.doubleToLongBits(sigNum);
+ result = 31 * result + (int) (temp ^ (temp >>> 32));
+ return result;
+ }
@Override
public String toString() {
Modified: lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/Vector.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/Vector.java?rev=1688545&r1=1688544&r2=1688545&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/Vector.java (original)
+++ lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/Vector.java Wed Jul 1 02:03:43 2015
@@ -52,7 +52,8 @@ public class Vector {
/**
* Construct a vector that is perpendicular to
* two other (non-zero) vectors. If the vectors are parallel,
- * the result vector will have magnitude 0.
+ * IllegalArgumentException will be thrown.
+ * Produces a normalized final vector.
*
* @param A is the first vector
* @param B is the second
@@ -61,12 +62,25 @@ public class Vector {
// x = u2v3 - u3v2
// y = u3v1 - u1v3
// z = u1v2 - u2v1
-
- this(A.y * B.z - A.z * B.y,
- A.z * B.x - A.x * B.z,
- A.x * B.y - A.y * B.x);
+ final double thisX = A.y * B.z - A.z * B.y;
+ final double thisY = A.z * B.x - A.x * B.z;
+ final double thisZ = A.x * B.y - A.y * B.x;
+ final double magnitude = magnitude(thisX, thisY, thisZ);
+ if (Math.abs(magnitude) < MINIMUM_RESOLUTION) {
+ throw new IllegalArgumentException("Degenerate/parallel vector constructed");
+ }
+ final double inverseMagnitude = 1.0 / magnitude;
+ this.x = thisX * inverseMagnitude;
+ this.y = thisY * inverseMagnitude;
+ this.z = thisZ * inverseMagnitude;
}
+ /** Compute a magnitude of an x,y,z value.
+ */
+ public static double magnitude(final double x, final double y, final double z) {
+ return Math.sqrt(x*x + y*y + z*z);
+ }
+
/**
* Compute a normalized unit vector based on the current vector.
*
@@ -304,7 +318,7 @@ public class Vector {
* @return the magnitude.
*/
public double magnitude() {
- return Math.sqrt(x * x + y * y + z * z);
+ return magnitude(x,y,z);
}
/** Compute the desired magnitude of a unit vector projected to a given
Modified: lucene/dev/trunk/lucene/spatial/src/test/org/apache/lucene/spatial/spatial4j/geo3d/GeoBBoxTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/spatial/src/test/org/apache/lucene/spatial/spatial4j/geo3d/GeoBBoxTest.java?rev=1688545&r1=1688544&r2=1688545&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/spatial/src/test/org/apache/lucene/spatial/spatial4j/geo3d/GeoBBoxTest.java (original)
+++ lucene/dev/trunk/lucene/spatial/src/test/org/apache/lucene/spatial/spatial4j/geo3d/GeoBBoxTest.java Wed Jul 1 02:03:43 2015
@@ -66,6 +66,9 @@ public class GeoBBoxTest {
assertFalse(box.isWithin(gp));
gp = new GeoPoint(PlanetModel.SPHERE, -0.1, -1.1);
assertFalse(box.isWithin(gp));
+ assertEquals(0.1,box.computeOutsideDistance(DistanceStyle.ARC,gp),1e-2);
+ assertEquals(0.1,box.computeOutsideDistance(DistanceStyle.NORMAL,gp),1e-2);
+ assertEquals(0.1,box.computeOutsideDistance(DistanceStyle.NORMAL,gp),1e-2);
// Standard normal Rect box, crossing dateline
box = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, 0.0, -Math.PI * 0.25, Math.PI - 1.0, -Math.PI + 1.0);
@@ -77,8 +80,8 @@ public class GeoBBoxTest {
assertFalse(box.isWithin(gp));
gp = new GeoPoint(PlanetModel.SPHERE, -0.1, -Math.PI + 1.1);
assertFalse(box.isWithin(gp));
- //bad lon: gp = new GeoPoint(PlanetModel.SPHERE, -0.1, -Math.PI - 1.1);
- //assertFalse(box.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, -0.1, (-Math.PI - 1.1) + Math.PI * 2.0);
+ assertFalse(box.isWithin(gp));
// Latitude zone rectangle
box = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, 0.0, -Math.PI * 0.25, -Math.PI, Math.PI);
@@ -90,8 +93,8 @@ public class GeoBBoxTest {
assertFalse(box.isWithin(gp));
gp = new GeoPoint(PlanetModel.SPHERE, -0.1, -Math.PI + 1.1);
assertTrue(box.isWithin(gp));
- //bad lon: gp = new GeoPoint(PlanetModel.SPHERE, -0.1, -Math.PI - 1.1);
- //assertTrue(box.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, -0.1, (-Math.PI - 1.1) + Math.PI * 2.0);
+ assertTrue(box.isWithin(gp));
// World
box = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, Math.PI * 0.5, -Math.PI * 0.5, -Math.PI, Math.PI);
@@ -103,8 +106,8 @@ public class GeoBBoxTest {
assertTrue(box.isWithin(gp));
gp = new GeoPoint(PlanetModel.SPHERE, -0.1, -Math.PI + 1.1);
assertTrue(box.isWithin(gp));
- //bad lat: gp = new GeoPoint(PlanetModel.SPHERE, -0.1, -Math.PI - 1.1);
- //assertTrue(box.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, -0.1, (-Math.PI - 1.1) + Math.PI * 2.0);
+ assertTrue(box.isWithin(gp));
}
Modified: lucene/dev/trunk/lucene/spatial/src/test/org/apache/lucene/spatial/spatial4j/geo3d/GeoCircleTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/spatial/src/test/org/apache/lucene/spatial/spatial4j/geo3d/GeoCircleTest.java?rev=1688545&r1=1688544&r2=1688545&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/spatial/src/test/org/apache/lucene/spatial/spatial4j/geo3d/GeoCircleTest.java (original)
+++ lucene/dev/trunk/lucene/spatial/src/test/org/apache/lucene/spatial/spatial4j/geo3d/GeoCircleTest.java Wed Jul 1 02:03:43 2015
@@ -32,17 +32,17 @@ public class GeoCircleTest {
GeoPoint gp;
c = new GeoCircle(PlanetModel.SPHERE, 0.0, -0.5, 0.1);
gp = new GeoPoint(PlanetModel.SPHERE, 0.0, 0.0);
- assertEquals(Double.MAX_VALUE, c.computeArcDistance(gp), 0.0);
- assertEquals(Double.MAX_VALUE, c.computeLinearDistance(gp), 0.0);
- assertEquals(Double.MAX_VALUE, c.computeNormalDistance(gp), 0.0);
+ assertEquals(Double.MAX_VALUE, c.computeDistance(DistanceStyle.ARC,gp), 0.0);
+ assertEquals(Double.MAX_VALUE, c.computeDistance(DistanceStyle.NORMAL,gp), 0.0);
+ assertEquals(Double.MAX_VALUE, c.computeDistance(DistanceStyle.NORMAL,gp), 0.0);
gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.5);
- assertEquals(0.0, c.computeArcDistance(gp), 0.000001);
- assertEquals(0.0, c.computeLinearDistance(gp), 0.000001);
- assertEquals(0.0, c.computeNormalDistance(gp), 0.000001);
+ assertEquals(0.0, c.computeDistance(DistanceStyle.ARC,gp), 0.000001);
+ assertEquals(0.0, c.computeDistance(DistanceStyle.NORMAL,gp), 0.000001);
+ assertEquals(0.0, c.computeDistance(DistanceStyle.NORMAL,gp), 0.000001);
gp = new GeoPoint(PlanetModel.SPHERE, 0.05, -0.5);
- assertEquals(0.05, c.computeArcDistance(gp), 0.000001);
- assertEquals(0.049995, c.computeLinearDistance(gp), 0.000001);
- assertEquals(0.049979, c.computeNormalDistance(gp), 0.000001);
+ assertEquals(0.05, c.computeDistance(DistanceStyle.ARC,gp), 0.000001);
+ assertEquals(0.049995, c.computeDistance(DistanceStyle.LINEAR,gp), 0.000001);
+ assertEquals(0.049979, c.computeDistance(DistanceStyle.NORMAL,gp), 0.000001);
}
@Test
@@ -75,6 +75,9 @@ public class GeoCircleTest {
c = new GeoCircle(PlanetModel.SPHERE, 0.0, -0.5, 0.1);
gp = new GeoPoint(PlanetModel.SPHERE, 0.0, 0.0);
assertFalse(c.isWithin(gp));
+ assertEquals(0.4,c.computeOutsideDistance(DistanceStyle.ARC,gp),1e-12);
+ assertEquals(0.12,c.computeOutsideDistance(DistanceStyle.NORMAL,gp),0.01);
+ assertEquals(0.4,c.computeOutsideDistance(DistanceStyle.LINEAR,gp),0.01);
gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.5);
assertTrue(c.isWithin(gp));
gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.55);
Modified: lucene/dev/trunk/lucene/spatial/src/test/org/apache/lucene/spatial/spatial4j/geo3d/GeoConvexPolygonTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/spatial/src/test/org/apache/lucene/spatial/spatial4j/geo3d/GeoConvexPolygonTest.java?rev=1688545&r1=1688544&r2=1688545&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/spatial/src/test/org/apache/lucene/spatial/spatial4j/geo3d/GeoConvexPolygonTest.java (original)
+++ lucene/dev/trunk/lucene/spatial/src/test/org/apache/lucene/spatial/spatial4j/geo3d/GeoConvexPolygonTest.java Wed Jul 1 02:03:43 2015
@@ -46,9 +46,12 @@ public class GeoConvexPolygonTest {
assertTrue(c.isWithin(gp));
gp = new GeoPoint(PlanetModel.SPHERE, 0.05, -0.5);
assertTrue(c.isWithin(gp));
- // Sample some nearby points outside
+ // Sample some nearby points outside, and compute distance-to-shape for them as well
gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.65);
assertFalse(c.isWithin(gp));
+ assertEquals(0.05,c.computeOutsideDistance(DistanceStyle.ARC,gp),1e-12);
+ assertEquals(0.05,c.computeOutsideDistance(DistanceStyle.NORMAL,gp),1e-3);
+ assertEquals(0.05,c.computeOutsideDistance(DistanceStyle.LINEAR,gp),1e-3);
gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.35);
assertFalse(c.isWithin(gp));
gp = new GeoPoint(PlanetModel.SPHERE, -0.15, -0.5);
Modified: lucene/dev/trunk/lucene/spatial/src/test/org/apache/lucene/spatial/spatial4j/geo3d/GeoPathTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/spatial/src/test/org/apache/lucene/spatial/spatial4j/geo3d/GeoPathTest.java?rev=1688545&r1=1688544&r2=1688545&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/spatial/src/test/org/apache/lucene/spatial/spatial4j/geo3d/GeoPathTest.java (original)
+++ lucene/dev/trunk/lucene/spatial/src/test/org/apache/lucene/spatial/spatial4j/geo3d/GeoPathTest.java Wed Jul 1 02:03:43 2015
@@ -37,17 +37,17 @@ public class GeoPathTest {
p.addPoint(0.0, 0.2);
p.done();
gp = new GeoPoint(PlanetModel.SPHERE, Math.PI * 0.5, 0.15);
- assertEquals(Double.MAX_VALUE, p.computeArcDistance(gp), 0.0);
+ assertEquals(Double.MAX_VALUE, p.computeDistance(DistanceStyle.ARC,gp), 0.0);
gp = new GeoPoint(PlanetModel.SPHERE, 0.05, 0.15);
- assertEquals(0.15 + 0.05, p.computeArcDistance(gp), 0.000001);
+ assertEquals(0.15 + 0.05, p.computeDistance(DistanceStyle.ARC,gp), 0.000001);
gp = new GeoPoint(PlanetModel.SPHERE, 0.0, 0.12);
- assertEquals(0.12 + 0.0, p.computeArcDistance(gp), 0.000001);
+ assertEquals(0.12 + 0.0, p.computeDistance(DistanceStyle.ARC,gp), 0.000001);
gp = new GeoPoint(PlanetModel.SPHERE, -0.15, 0.05);
- assertEquals(Double.MAX_VALUE, p.computeArcDistance(gp), 0.000001);
+ assertEquals(Double.MAX_VALUE, p.computeDistance(DistanceStyle.ARC,gp), 0.000001);
gp = new GeoPoint(PlanetModel.SPHERE, 0.0, 0.25);
- assertEquals(0.20 + 0.05, p.computeArcDistance(gp), 0.000001);
+ assertEquals(0.20 + 0.05, p.computeDistance(DistanceStyle.ARC,gp), 0.000001);
gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.05);
- assertEquals(0.0 + 0.05, p.computeArcDistance(gp), 0.000001);
+ assertEquals(0.0 + 0.05, p.computeDistance(DistanceStyle.ARC,gp), 0.000001);
// Compute path distances now
p = new GeoPath(PlanetModel.SPHERE, 0.1);
@@ -56,9 +56,9 @@ public class GeoPathTest {
p.addPoint(0.0, 0.2);
p.done();
gp = new GeoPoint(PlanetModel.SPHERE, 0.05, 0.15);
- assertEquals(0.15 + 0.05, p.computeArcDistance(gp), 0.000001);
+ assertEquals(0.15 + 0.05, p.computeDistance(DistanceStyle.ARC,gp), 0.000001);
gp = new GeoPoint(PlanetModel.SPHERE, 0.0, 0.12);
- assertEquals(0.12, p.computeArcDistance(gp), 0.000001);
+ assertEquals(0.12, p.computeDistance(DistanceStyle.ARC,gp), 0.000001);
// Now try a vertical path, and make sure distances are as expected
p = new GeoPath(PlanetModel.SPHERE, 0.1);
@@ -66,13 +66,13 @@ public class GeoPathTest {
p.addPoint(Math.PI * 0.25, -0.5);
p.done();
gp = new GeoPoint(PlanetModel.SPHERE, 0.0, 0.0);
- assertEquals(Double.MAX_VALUE, p.computeArcDistance(gp), 0.0);
+ assertEquals(Double.MAX_VALUE, p.computeDistance(DistanceStyle.ARC,gp), 0.0);
gp = new GeoPoint(PlanetModel.SPHERE, -0.1, -1.0);
- assertEquals(Double.MAX_VALUE, p.computeArcDistance(gp), 0.0);
+ assertEquals(Double.MAX_VALUE, p.computeDistance(DistanceStyle.ARC,gp), 0.0);
gp = new GeoPoint(PlanetModel.SPHERE, Math.PI * 0.25 + 0.05, -0.5);
- assertEquals(Math.PI * 0.5 + 0.05, p.computeArcDistance(gp), 0.000001);
+ assertEquals(Math.PI * 0.5 + 0.05, p.computeDistance(DistanceStyle.ARC,gp), 0.000001);
gp = new GeoPoint(PlanetModel.SPHERE, -Math.PI * 0.25 - 0.05, -0.5);
- assertEquals(0.0 + 0.05, p.computeArcDistance(gp), 0.000001);
+ assertEquals(0.0 + 0.05, p.computeDistance(DistanceStyle.ARC,gp), 0.000001);
}
@Test