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/05/27 06:54:51 UTC

svn commit: r1681907 [2/4] - in /lucene/dev/branches/lucene6487/lucene/spatial/src: java/org/apache/lucene/spatial/spatial4j/ java/org/apache/lucene/spatial/spatial4j/geo3d/ test/org/apache/lucene/spatial/spatial4j/ test/org/apache/lucene/spatial/spati...

Modified: lucene/dev/branches/lucene6487/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoPath.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6487/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoPath.java?rev=1681907&r1=1681906&r2=1681907&view=diff
==============================================================================
--- lucene/dev/branches/lucene6487/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoPath.java (original)
+++ lucene/dev/branches/lucene6487/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoPath.java Wed May 27 04:54:50 2015
@@ -29,29 +29,25 @@ import java.util.List;
  * @lucene.experimental
  */
 public class GeoPath extends GeoBaseExtendedShape implements GeoDistanceShape {
+  
   public final double cutoffAngle;
-  public final double cutoffOffset;
-  public final double originDistance;
-  public final double chordDistance;
+  public final double sinAngle;
+  public final double cosAngle;
 
-  public final List<SegmentEndpoint> points = new ArrayList<SegmentEndpoint>();
+  public final List<GeoPoint> points = new ArrayList<GeoPoint>();
+  
+  public final List<SegmentEndpoint> endPoints = new ArrayList<SegmentEndpoint>();
   public final List<PathSegment> segments = new ArrayList<PathSegment>();
 
   public GeoPoint[] edgePoints = null;
 
-  public GeoPath(final double cutoffAngle) {
-    super();
-    if (cutoffAngle <= 0.0 || cutoffAngle > Math.PI * 0.5)
+  public GeoPath(final PlanetModel planetModel, final double maxCutoffAngle) {
+    super(planetModel);
+    if (maxCutoffAngle <= 0.0 || maxCutoffAngle > Math.PI * 0.5)
       throw new IllegalArgumentException("Cutoff angle out of bounds");
-    this.cutoffAngle = cutoffAngle;
-    final double cosAngle = Math.cos(cutoffAngle);
-    final double sinAngle = Math.sin(cutoffAngle);
-    // Cutoff offset is the linear distance given the angle
-    this.cutoffOffset = sinAngle;
-    this.originDistance = cosAngle;
-    // Compute chord distance
-    double xDiff = 1.0 - cosAngle;
-    this.chordDistance = Math.sqrt(xDiff * xDiff + sinAngle * sinAngle);
+    this.cutoffAngle = maxCutoffAngle;
+    this.cosAngle = Math.cos(maxCutoffAngle);
+    this.sinAngle = Math.sin(maxCutoffAngle);
   }
 
   public void addPoint(double lat, double lon) {
@@ -59,57 +55,80 @@ public class GeoPath extends GeoBaseExte
       throw new IllegalArgumentException("Latitude out of range");
     if (lon < -Math.PI || lon > Math.PI)
       throw new IllegalArgumentException("Longitude out of range");
-    final GeoPoint end = new GeoPoint(lat, lon);
-    if (points.size() > 0) {
-      final GeoPoint start = points.get(points.size() - 1).point;
-      final PathSegment ps = new PathSegment(start, end, cutoffOffset, cutoffAngle, chordDistance);
-      // Check for degeneracy; if the segment is degenerate, don't include the point
-      if (ps.isDegenerate())
-        return;
-      segments.add(ps);
-    } else {
-      // First point.  We compute the basic set of edgepoints here because we've got the lat and lon available.
-      // Move from center only in latitude.  Then, if we go past the north pole, adjust the longitude also.
-      double newLat = lat + cutoffAngle;
-      double newLon = lon;
-      if (newLat > Math.PI * 0.5) {
-        newLat = Math.PI - newLat;
-        newLon += Math.PI;
-      }
-      while (newLon > Math.PI) {
-        newLon -= Math.PI * 2.0;
-      }
-      final GeoPoint edgePoint = new GeoPoint(newLat, newLon);
-      this.edgePoints = new GeoPoint[]{edgePoint};
-    }
-    final SegmentEndpoint se = new SegmentEndpoint(end, originDistance, cutoffOffset, cutoffAngle, chordDistance);
-    points.add(se);
+    points.add(new GeoPoint(planetModel, lat, lon));
   }
-
+  
   public void done() {
     if (points.size() == 0)
       throw new IllegalArgumentException("Path must have at least one point");
-    if (segments.size() > 0) {
-      edgePoints = new GeoPoint[]{points.get(0).circlePlane.getSampleIntersectionPoint(segments.get(0).invertedStartCutoffPlane)};
+    // 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();
+    
+    // First, build all segments.  We'll then go back and build corresponding segment endpoints.
+    GeoPoint lastPoint = null;
+    for (final GeoPoint end : points) {
+      if (lastPoint != null) {
+        final Plane normalizedConnectingPlane = new Plane(lastPoint, end).normalize();
+        if (normalizedConnectingPlane == null) {
+          continue;
+        }
+        segments.add(new PathSegment(planetModel, lastPoint, end, normalizedConnectingPlane, cutoffOffset));
+      }
+      lastPoint = end;
+    }
+    
+    if (segments.size() == 0) {
+      // Simple circle
+      final SegmentEndpoint onlyEndpoint = new SegmentEndpoint(points.get(0), cutoffOffset);
+      endPoints.add(onlyEndpoint);
+      // Find an edgepoint
+      // We already have circle plane, which is the definitive determination of the edge of the "circle".
+      // Next, compute vertical plane going through origin and the center point (C = 0, D = 0).
+      Plane verticalPlane = Plane.constructNormalizedVerticalPlane(onlyEndpoint.point.x, onlyEndpoint.point.y);
+      if (verticalPlane == null) {
+        verticalPlane = new Plane(1.0,0.0);
+      }
+      // Finally, use Plane.findIntersections() to find the intersection points.
+      final GeoPoint edgePoint = onlyEndpoint.circlePlane.getSampleIntersectionPoint(planetModel, verticalPlane);
+      if (edgePoint == null) {
+        throw new RuntimeException("Could not find edge point for path endpoint="+onlyEndpoint.point+" cutoffOffset="+cutoffOffset+" planetModel="+planetModel);
+      }
+      this.edgePoints = new GeoPoint[]{edgePoint};
+      return;
     }
-    for (int i = 0; i < points.size(); i++) {
-      final SegmentEndpoint pathPoint = points.get(i);
-      Membership previousEndBound = null;
-      GeoPoint[] previousEndNotablePoints = null;
-      Membership nextStartBound = null;
-      GeoPoint[] nextStartNotablePoints = null;
-      if (i > 0) {
-        final PathSegment previousSegment = segments.get(i - 1);
-        previousEndBound = previousSegment.invertedEndCutoffPlane;
-        previousEndNotablePoints = previousSegment.endCutoffPlanePoints;
-      }
-      if (i < segments.size()) {
-        final PathSegment nextSegment = segments.get(i);
-        nextStartBound = nextSegment.invertedStartCutoffPlane;
-        nextStartNotablePoints = nextSegment.startCutoffPlanePoints;
+    
+    // Create segment endpoints.  Use an appropriate constructor for the start and end of the path.
+    for (int i = 0; i < segments.size(); i++) {
+      final PathSegment currentSegment = segments.get(i);
+      
+      if (i == 0) {
+        // Starting endpoint
+        final SegmentEndpoint startEndpoint = new SegmentEndpoint(currentSegment.start, 
+          currentSegment.startCutoffPlane, currentSegment.ULHC, currentSegment.LLHC);
+        endPoints.add(startEndpoint);
+        this.edgePoints = new GeoPoint[]{currentSegment.ULHC};
+        continue;
+      }
+      
+      // General intersection case
+      final PathSegment prevSegment = segments.get(i-1);
+      if (prevSegment.upperConnectingPlane.isNumericallyIdentical(currentSegment.upperConnectingPlane) &&
+          prevSegment.lowerConnectingPlane.isNumericallyIdentical(currentSegment.lowerConnectingPlane)) {
+        // The planes are identical.  We don't need a circle at all.  Special constructor...
+        endPoints.add(new SegmentEndpoint(currentSegment.start));
+      } else {
+        endPoints.add(new SegmentEndpoint(currentSegment.start,
+          prevSegment.endCutoffPlane, currentSegment.startCutoffPlane,
+          prevSegment.URHC, prevSegment.LRHC,
+          currentSegment.ULHC, currentSegment.LLHC));
       }
-      pathPoint.setCutoffPlanes(previousEndNotablePoints, previousEndBound, nextStartNotablePoints, nextStartBound);
     }
+    // Do final endpoint
+    final PathSegment lastSegment = segments.get(segments.size()-1);
+    endPoints.add(new SegmentEndpoint(lastSegment.end,
+      lastSegment.endCutoffPlane, lastSegment.URHC, lastSegment.LRHC));
+
   }
 
   /**
@@ -132,7 +151,7 @@ public class GeoPath extends GeoBaseExte
 
     int segmentIndex = 0;
     currentDistance = 0.0;
-    for (SegmentEndpoint endpoint : points) {
+    for (SegmentEndpoint endpoint : endPoints) {
       double distance = endpoint.pathNormalDistance(point);
       if (distance != Double.MAX_VALUE)
         return currentDistance + distance;
@@ -194,7 +213,7 @@ public class GeoPath extends GeoBaseExte
 
     int segmentIndex = 0;
     currentDistance = 0.0;
-    for (SegmentEndpoint endpoint : points) {
+    for (SegmentEndpoint endpoint : endPoints) {
       double distance = endpoint.pathLinearDistance(point);
       if (distance != Double.MAX_VALUE)
         return currentDistance + distance;
@@ -251,7 +270,7 @@ public class GeoPath extends GeoBaseExte
 
     int segmentIndex = 0;
     currentDistance = 0.0;
-    for (SegmentEndpoint endpoint : points) {
+    for (SegmentEndpoint endpoint : endPoints) {
       double distance = endpoint.pathDistance(point);
       if (distance != Double.MAX_VALUE)
         return currentDistance + distance;
@@ -264,20 +283,26 @@ public class GeoPath extends GeoBaseExte
 
   @Override
   public boolean isWithin(final Vector point) {
-    for (SegmentEndpoint pathPoint : points) {
-      if (pathPoint.isWithin(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))
+      if (pathSegment.isWithin(point)) {
+        //System.err.println(" point is within PathSegment "+pathSegment);
         return true;
+      }
     }
+    //System.err.println(" point is not within geopath");
     return false;
   }
 
   @Override
   public boolean isWithin(final double x, final double y, final double z) {
-    for (SegmentEndpoint pathPoint : points) {
+    for (SegmentEndpoint pathPoint : endPoints) {
       if (pathPoint.isWithin(x, y, z))
         return true;
     }
@@ -304,15 +329,15 @@ public class GeoPath extends GeoBaseExte
     // any of the intersection points are within the bounds, then we've detected an intersection.
     // Well, sort of.  We can detect intersections also due to overlap of segments with each other.
     // But that's an edge case and we won't be optimizing for it.
-
-    for (final SegmentEndpoint pathPoint : points) {
-      if (pathPoint.intersects(plane, notablePoints, bounds)) {
+    //System.err.println(" Looking for intersection of plane "+plane+" with path "+this);
+    for (final SegmentEndpoint pathPoint : endPoints) {
+      if (pathPoint.intersects(planetModel, plane, notablePoints, bounds)) {
         return true;
       }
     }
 
     for (final PathSegment pathSegment : segments) {
-      if (pathSegment.intersects(plane, notablePoints, bounds)) {
+      if (pathSegment.intersects(planetModel, plane, notablePoints, bounds)) {
         return true;
       }
     }
@@ -336,10 +361,10 @@ public class GeoPath extends GeoBaseExte
     // 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(bounds);
+      pathSegment.getBounds(planetModel, bounds);
     }
-    for (SegmentEndpoint pathPoint : points) {
-      pathPoint.getBounds(bounds);
+    for (SegmentEndpoint pathPoint : endPoints) {
+      pathPoint.getBounds(planetModel, bounds);
     }
     return bounds;
   }
@@ -349,13 +374,15 @@ public class GeoPath extends GeoBaseExte
     if (!(o instanceof GeoPath))
       return false;
     GeoPath p = (GeoPath) o;
-    if (points.size() != p.points.size())
+    if (!super.equals(p))
+      return false;
+    if (endPoints.size() != p.endPoints.size())
       return false;
     if (cutoffAngle != p.cutoffAngle)
       return false;
-    for (int i = 0; i < points.size(); i++) {
-      SegmentEndpoint point = points.get(i);
-      SegmentEndpoint point2 = p.points.get(i);
+    for (int i = 0; i < endPoints.size(); i++) {
+      SegmentEndpoint point = endPoints.get(i);
+      SegmentEndpoint point2 = p.endPoints.get(i);
       if (!point.equals(point2))
         return false;
     }
@@ -364,101 +391,168 @@ public class GeoPath extends GeoBaseExte
 
   @Override
   public int hashCode() {
-    int result;
-    long temp;
-    temp = Double.doubleToLongBits(cutoffAngle);
-    result = (int) (temp ^ (temp >>> 32));
-    result = 31 * result + points.hashCode();
+    int result = super.hashCode();
+    long temp = Double.doubleToLongBits(cutoffAngle);
+    result = 31 * result + (int) (temp ^ (temp >>> 32));
+    result = 31 * result + endPoints.hashCode();
     return result;
   }
 
   @Override
   public String toString() {
-    return "GeoPath: {width=" + cutoffAngle + "(" + cutoffAngle * 180.0 / Math.PI + "), points={" + points + "}}";
+    return "GeoPath: {planetmodel=" + planetModel+", width=" + cutoffAngle + "(" + cutoffAngle * 180.0 / Math.PI + "), points={" + points + "}}";
   }
 
   /**
    * This is precalculated data for segment endpoint.
+   * Note well: This is not necessarily a circle.  There are four cases:
+   * (1) The path consists of a single endpoint.  In this case, we build a simple circle with the proper cutoff offset.
+   * (2) This is the end of a path.  The circle plane must be constructed to go through two supplied points and be perpendicular to a connecting plane.
+   * (3) This is an intersection in a path.  We are supplied FOUR planes.  If there are intersections within bounds for both upper and lower, then
+   *    we generate no circle at all.  If there is one intersection only, then we generate a plane that includes that intersection, as well as the remaining
+   *    cutoff plane/edge plane points.
    */
   public static class SegmentEndpoint {
     public final GeoPoint point;
     public final SidedPlane circlePlane;
-    public final double cutoffNormalDistance;
-    public final double cutoffAngle;
-    public final double chordDistance;
-    public Membership[] cutoffPlanes = null;
-    public GeoPoint[] notablePoints = null;
+    public final Membership[] cutoffPlanes;
+    public final GeoPoint[] notablePoints;
 
     public final static GeoPoint[] circlePoints = new GeoPoint[0];
 
-    public SegmentEndpoint(final GeoPoint point, final double originDistance, final double cutoffOffset, final double cutoffAngle, final double chordDistance) {
+    /** Base case.  Does nothing at all.
+     */
+    public SegmentEndpoint(final GeoPoint point) {
+      this.point = point;
+      this.circlePlane = null;
+      this.cutoffPlanes = null;
+      this.notablePoints = null;
+    }
+    
+    /** Constructor for case (1).
+     * Generate a simple circle cutoff plane.
+     */
+    public SegmentEndpoint(final GeoPoint point, final double cutoffOffset) {
       this.point = point;
-      this.cutoffNormalDistance = cutoffOffset;
-      this.cutoffAngle = cutoffAngle;
-      this.chordDistance = chordDistance;
-      this.circlePlane = new SidedPlane(point, point, -originDistance);
-    }
-
-    public void setCutoffPlanes(final GeoPoint[] previousEndNotablePoints, final Membership previousEndPlane,
-                                final GeoPoint[] nextStartNotablePoints, final Membership nextStartPlane) {
-      if (previousEndNotablePoints == null && nextStartNotablePoints == null) {
-        cutoffPlanes = new Membership[0];
-        notablePoints = new GeoPoint[0];
-      } else if (previousEndNotablePoints != null && nextStartNotablePoints == null) {
-        cutoffPlanes = new Membership[]{previousEndPlane};
-        notablePoints = previousEndNotablePoints;
-      } else if (previousEndNotablePoints == null && nextStartNotablePoints != null) {
-        cutoffPlanes = new Membership[]{nextStartPlane};
-        notablePoints = nextStartNotablePoints;
+      final double magnitude = point.magnitude();
+      // Normalize vector to make D value correct
+      this.circlePlane = new SidedPlane(point, point.normalize(), -Math.sqrt(magnitude * magnitude - cutoffOffset * cutoffOffset));
+      this.cutoffPlanes = new Membership[0];
+      this.notablePoints = new GeoPoint[0];
+    }
+    
+    /** Constructor for case (2).
+     * Generate an endpoint, given a single cutoff plane plus upper and lower edge points.
+     */
+    public SegmentEndpoint(final GeoPoint point,
+      final SidedPlane cutoffPlane, final GeoPoint topEdgePoint, final GeoPoint bottomEdgePoint) {
+      this.point = point;
+      this.cutoffPlanes = new Membership[]{new SidedPlane(cutoffPlane)};
+      this.notablePoints = new GeoPoint[]{topEdgePoint, bottomEdgePoint};
+      // 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.
+      this.circlePlane = SidedPlane.constructNormalizedPerpendicularSidedPlane(point, cutoffPlane, topEdgePoint, bottomEdgePoint);
+    }
+    
+    /** Constructor for case (3).
+     * Generate an endpoint for an intersection, given four points.
+     */
+    public SegmentEndpoint(final GeoPoint point,
+      final SidedPlane prevCutoffPlane, final SidedPlane nextCutoffPlane,
+      final GeoPoint prevUpperGeoPoint, final GeoPoint prevLowerGeoPoint,
+      final GeoPoint nextUpperGeoPoint, final GeoPoint nextLowerGeoPoint) {
+      // Note: What we really need is a single plane that goes through all four points.
+      // Since that's not possible in the ellipsoid case (because three points determine a plane, not four), we
+      // need an approximation that at least creates a boundary that has no interruptions.
+      // There are three obvious choices for the third point: either (a) one of the two remaining points, or (b) the top or bottom edge
+      // intersection point.  (a) has no guarantee of continuity, while (b) is capable of producing something very far from a circle if
+      // the angle between segments is acute.
+      // The solution is to look for the side (top or bottom) that has an intersection within the shape.  We use the two points from
+      // the opposite side to determine the plane, AND we pick the third to be either of the two points on the intersecting side
+      // PROVIDED that the other point is within the final circle we come up with.
+      this.point = point;
+      
+      // We construct four separate planes, and evaluate which one includes all interior points with least overlap
+      final SidedPlane candidate1 = SidedPlane.constructNormalizedThreePointSidedPlane(point, prevUpperGeoPoint, nextUpperGeoPoint, nextLowerGeoPoint);
+      final SidedPlane candidate2 = SidedPlane.constructNormalizedThreePointSidedPlane(point, nextUpperGeoPoint, nextLowerGeoPoint, prevLowerGeoPoint);
+      final SidedPlane candidate3 = SidedPlane.constructNormalizedThreePointSidedPlane(point, nextLowerGeoPoint, prevLowerGeoPoint, prevUpperGeoPoint);
+      final SidedPlane candidate4 = SidedPlane.constructNormalizedThreePointSidedPlane(point, prevLowerGeoPoint, prevUpperGeoPoint, nextUpperGeoPoint);
+
+      final boolean cand1IsOtherWithin = candidate1.isWithin(prevLowerGeoPoint);
+      final boolean cand2IsOtherWithin = candidate2.isWithin(prevUpperGeoPoint);
+      final boolean cand3IsOtherWithin = candidate3.isWithin(nextUpperGeoPoint);
+      final boolean cand4IsOtherWithin = candidate4.isWithin(nextLowerGeoPoint);
+      
+      if (cand1IsOtherWithin && cand2IsOtherWithin && cand3IsOtherWithin && cand4IsOtherWithin) {
+        // The only way we should see both within is if all four points are coplanar.  In that case, we default to the simplest treatment.
+        this.circlePlane = candidate1;  // doesn't matter which
+        this.notablePoints = new GeoPoint[]{prevUpperGeoPoint, nextUpperGeoPoint, prevLowerGeoPoint, nextLowerGeoPoint};
+        this.cutoffPlanes = new Membership[]{new SidedPlane(prevCutoffPlane), new SidedPlane(nextCutoffPlane)};
+      } else if (cand1IsOtherWithin) {
+        // Use candidate1, and DON'T include prevCutoffPlane in the cutoff planes list
+        this.circlePlane = candidate1;
+        this.notablePoints = new GeoPoint[]{prevUpperGeoPoint, nextUpperGeoPoint, nextLowerGeoPoint};
+        this.cutoffPlanes = new Membership[]{new SidedPlane(nextCutoffPlane)};
+      } else if (cand2IsOtherWithin) {
+        // Use candidate2
+        this.circlePlane = candidate2;
+        this.notablePoints = new GeoPoint[]{nextUpperGeoPoint, nextLowerGeoPoint, prevLowerGeoPoint};
+        this.cutoffPlanes = new Membership[]{new SidedPlane(nextCutoffPlane)};
+      } else if (cand3IsOtherWithin) {
+        this.circlePlane = candidate3;
+        this.notablePoints = new GeoPoint[]{nextLowerGeoPoint, prevLowerGeoPoint, prevUpperGeoPoint};
+        this.cutoffPlanes = new Membership[]{new SidedPlane(prevCutoffPlane)};
+      } else if (cand4IsOtherWithin) {
+        this.circlePlane = candidate4;
+        this.notablePoints = new GeoPoint[]{prevLowerGeoPoint, prevUpperGeoPoint, nextUpperGeoPoint};
+        this.cutoffPlanes = new Membership[]{new SidedPlane(prevCutoffPlane)};
       } else {
-        cutoffPlanes = new Membership[]{previousEndPlane, nextStartPlane};
-        notablePoints = new GeoPoint[previousEndNotablePoints.length + nextStartNotablePoints.length];
-        int i = 0;
-        for (GeoPoint p : previousEndNotablePoints) {
-          notablePoints[i++] = p;
-        }
-        for (GeoPoint p : nextStartNotablePoints) {
-          notablePoints[i++] = p;
-        }
+        // dunno what happened
+        throw new RuntimeException("Couldn't come up with a plane through three points that included the fourth");
       }
     }
 
     public boolean isWithin(final Vector point) {
+      if (circlePlane == null)
+        return false;
       return circlePlane.isWithin(point);
     }
 
     public boolean isWithin(final double x, final double y, final double z) {
+      if (circlePlane == null)
+        return false;
       return circlePlane.isWithin(x, y, z);
     }
 
     public double pathDistance(final GeoPoint point) {
-      double dist = this.point.arcDistance(point);
-      if (dist > cutoffAngle)
+      if (!isWithin(point))
         return Double.MAX_VALUE;
-      return dist;
+      return this.point.arcDistance(point);
     }
 
     public double pathNormalDistance(final GeoPoint point) {
-      double dist = this.point.normalDistance(point);
-      if (dist > cutoffNormalDistance)
+      if (!isWithin(point))
         return Double.MAX_VALUE;
-      return dist;
+      return this.point.normalDistance(point);
     }
 
     public double pathLinearDistance(final GeoPoint point) {
-      double dist = this.point.linearDistance(point);
-      if (dist > chordDistance)
+      if (!isWithin(point))
         return Double.MAX_VALUE;
-      return dist;
+      return this.point.linearDistance(point);
     }
 
-    public boolean intersects(final Plane p, final GeoPoint[] notablePoints, final Membership[] bounds) {
-      return circlePlane.intersects(p, notablePoints, this.notablePoints, bounds, this.cutoffPlanes);
+    public boolean intersects(final PlanetModel planetModel, final Plane p, final GeoPoint[] notablePoints, final Membership[] bounds) {
+      //System.err.println("  looking for intersection between plane "+p+" and circle "+circlePlane+" on proper side of "+cutoffPlanes+" within "+bounds);
+      if (circlePlane == null)
+        return false;
+      return circlePlane.intersects(planetModel, p, notablePoints, this.notablePoints, bounds, this.cutoffPlanes);
     }
 
-    public void getBounds(Bounds bounds) {
+    public void getBounds(final PlanetModel planetModel, Bounds bounds) {
       bounds.addPoint(point);
-      circlePlane.recordBounds(bounds);
+      if (circlePlane == null)
+        return;
+      circlePlane.recordBounds(planetModel, bounds);
     }
 
     @Override
@@ -494,69 +588,70 @@ public class GeoPath extends GeoBaseExte
     public final SidedPlane lowerConnectingPlane;
     public final SidedPlane startCutoffPlane;
     public final SidedPlane endCutoffPlane;
+    public final GeoPoint URHC;
+    public final GeoPoint LRHC;
+    public final GeoPoint ULHC;
+    public final GeoPoint LLHC;
     public final GeoPoint[] upperConnectingPlanePoints;
     public final GeoPoint[] lowerConnectingPlanePoints;
     public final GeoPoint[] startCutoffPlanePoints;
     public final GeoPoint[] endCutoffPlanePoints;
     public final double planeBoundingOffset;
-    public final double arcWidth;
-    public final double chordDistance;
-
-    // For the adjoining SegmentEndpoint...
-    public final SidedPlane invertedStartCutoffPlane;
-    public final SidedPlane invertedEndCutoffPlane;
 
-    public PathSegment(final GeoPoint start, final GeoPoint end, final double planeBoundingOffset, final double arcWidth, final double chordDistance) {
+    public PathSegment(final PlanetModel planetModel, final GeoPoint start, final GeoPoint end,
+      final Plane normalizedConnectingPlane, final double planeBoundingOffset) {
       this.start = start;
       this.end = end;
+      this.normalizedConnectingPlane = normalizedConnectingPlane;
       this.planeBoundingOffset = planeBoundingOffset;
-      this.arcWidth = arcWidth;
-      this.chordDistance = chordDistance;
 
       fullDistance = start.arcDistance(end);
       fullNormalDistance = start.normalDistance(end);
       fullLinearDistance = start.linearDistance(end);
-      normalizedConnectingPlane = new Plane(start, end).normalize();
-      if (normalizedConnectingPlane == null) {
-        upperConnectingPlane = null;
-        lowerConnectingPlane = null;
-        startCutoffPlane = null;
-        endCutoffPlane = null;
-        upperConnectingPlanePoints = null;
-        lowerConnectingPlanePoints = null;
-        startCutoffPlanePoints = null;
-        endCutoffPlanePoints = null;
-        invertedStartCutoffPlane = null;
-        invertedEndCutoffPlane = null;
-      } else {
-        // Either start or end should be on the correct side
-        upperConnectingPlane = new SidedPlane(start, normalizedConnectingPlane, -planeBoundingOffset);
-        lowerConnectingPlane = new SidedPlane(start, normalizedConnectingPlane, planeBoundingOffset);
-        // Cutoff planes use opposite endpoints as correct side examples
-        startCutoffPlane = new SidedPlane(end, normalizedConnectingPlane, start);
-        endCutoffPlane = new SidedPlane(start, normalizedConnectingPlane, end);
-        final Membership[] upperSide = new Membership[]{upperConnectingPlane};
-        final Membership[] lowerSide = new Membership[]{lowerConnectingPlane};
-        final Membership[] startSide = new Membership[]{startCutoffPlane};
-        final Membership[] endSide = new Membership[]{endCutoffPlane};
-        final GeoPoint ULHC = upperConnectingPlane.findIntersections(startCutoffPlane, lowerSide, endSide)[0];
-        final GeoPoint URHC = upperConnectingPlane.findIntersections(endCutoffPlane, lowerSide, startSide)[0];
-        final GeoPoint LLHC = lowerConnectingPlane.findIntersections(startCutoffPlane, upperSide, endSide)[0];
-        final GeoPoint LRHC = lowerConnectingPlane.findIntersections(endCutoffPlane, upperSide, startSide)[0];
-        upperConnectingPlanePoints = new GeoPoint[]{ULHC, URHC};
-        lowerConnectingPlanePoints = new GeoPoint[]{LLHC, LRHC};
-        startCutoffPlanePoints = new GeoPoint[]{ULHC, LLHC};
-        endCutoffPlanePoints = new GeoPoint[]{URHC, LRHC};
-        invertedStartCutoffPlane = new SidedPlane(startCutoffPlane);
-        invertedEndCutoffPlane = new SidedPlane(endCutoffPlane);
+      // Either start or end should be on the correct side
+      upperConnectingPlane = new SidedPlane(start, normalizedConnectingPlane, -planeBoundingOffset);
+      lowerConnectingPlane = new SidedPlane(start, normalizedConnectingPlane, planeBoundingOffset);
+      // Cutoff planes use opposite endpoints as correct side examples
+      startCutoffPlane = new SidedPlane(end, normalizedConnectingPlane, start);
+      endCutoffPlane = new SidedPlane(start, normalizedConnectingPlane, end);
+      final Membership[] upperSide = new Membership[]{upperConnectingPlane};
+      final Membership[] lowerSide = new Membership[]{lowerConnectingPlane};
+      final Membership[] startSide = new Membership[]{startCutoffPlane};
+      final Membership[] endSide = new Membership[]{endCutoffPlane};
+      GeoPoint[] points;
+      points = upperConnectingPlane.findIntersections(planetModel, startCutoffPlane, lowerSide, endSide);
+      if (points.length == 0) {
+        throw new IllegalArgumentException("Some segment boundary points are off the ellipsoid; path too wide");
       }
-    }
-
-    public boolean isDegenerate() {
-      return normalizedConnectingPlane == null;
+      this.ULHC = points[0];
+      points = upperConnectingPlane.findIntersections(planetModel, endCutoffPlane, lowerSide, startSide);
+      if (points.length == 0) {
+        throw new IllegalArgumentException("Some segment boundary points are off the ellipsoid; path too wide");
+      }
+      this.URHC = points[0];
+      points = lowerConnectingPlane.findIntersections(planetModel, startCutoffPlane, upperSide, endSide);
+      if (points.length == 0) {
+        throw new IllegalArgumentException("Some segment boundary points are off the ellipsoid; path too wide");
+      }
+      this.LLHC = points[0];
+      points = lowerConnectingPlane.findIntersections(planetModel, endCutoffPlane, upperSide, startSide);
+      if (points.length == 0) {
+        throw new IllegalArgumentException("Some segment boundary points are off the ellipsoid; path too wide");
+      }
+      this.LRHC = points[0];
+      upperConnectingPlanePoints = new GeoPoint[]{ULHC, URHC};
+      lowerConnectingPlanePoints = new GeoPoint[]{LLHC, LRHC};
+      startCutoffPlanePoints = new GeoPoint[]{ULHC, LLHC};
+      endCutoffPlanePoints = new GeoPoint[]{URHC, LRHC};
     }
 
     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));
+      //System.err.println("  within "+endCutoffPlane+": "+endCutoffPlane.isWithin(point));
+      //System.err.println("  within "+upperConnectingPlane+": "+upperConnectingPlane.isWithin(point));
+      //System.err.println("  within "+lowerConnectingPlane+": "+lowerConnectingPlane.isWithin(point));
+
       return startCutoffPlane.isWithin(point) &&
           endCutoffPlane.isWithin(point) &&
           upperConnectingPlane.isWithin(point) &&
@@ -640,22 +735,22 @@ public class GeoPath extends GeoBaseExte
       return point.linearDistance(normLineX, normLineY, normLineZ) + start.linearDistance(normLineX, normLineY, normLineZ);
     }
 
-    public boolean intersects(final Plane p, final GeoPoint[] notablePoints, final Membership[] bounds) {
-      return upperConnectingPlane.intersects(p, notablePoints, upperConnectingPlanePoints, bounds, lowerConnectingPlane, startCutoffPlane, endCutoffPlane) ||
-          lowerConnectingPlane.intersects(p, notablePoints, lowerConnectingPlanePoints, bounds, upperConnectingPlane, startCutoffPlane, endCutoffPlane);
+    public boolean intersects(final PlanetModel planetModel, final Plane p, final GeoPoint[] notablePoints, final Membership[] bounds) {
+      return upperConnectingPlane.intersects(planetModel, p, notablePoints, upperConnectingPlanePoints, bounds, lowerConnectingPlane, startCutoffPlane, endCutoffPlane) ||
+          lowerConnectingPlane.intersects(planetModel, p, notablePoints, lowerConnectingPlanePoints, bounds, upperConnectingPlane, startCutoffPlane, endCutoffPlane);
     }
 
-    public void getBounds(Bounds bounds) {
+    public void getBounds(final PlanetModel planetModel, Bounds bounds) {
       // We need to do all bounding planes as well as corner points
       bounds.addPoint(start).addPoint(end);
-      upperConnectingPlane.recordBounds(startCutoffPlane, bounds, lowerConnectingPlane, endCutoffPlane);
-      startCutoffPlane.recordBounds(lowerConnectingPlane, bounds, endCutoffPlane, upperConnectingPlane);
-      lowerConnectingPlane.recordBounds(endCutoffPlane, bounds, upperConnectingPlane, startCutoffPlane);
-      endCutoffPlane.recordBounds(upperConnectingPlane, bounds, startCutoffPlane, lowerConnectingPlane);
-      upperConnectingPlane.recordBounds(bounds, lowerConnectingPlane, startCutoffPlane, endCutoffPlane);
-      lowerConnectingPlane.recordBounds(bounds, upperConnectingPlane, startCutoffPlane, endCutoffPlane);
-      startCutoffPlane.recordBounds(bounds, endCutoffPlane, upperConnectingPlane, lowerConnectingPlane);
-      endCutoffPlane.recordBounds(bounds, startCutoffPlane, upperConnectingPlane, lowerConnectingPlane);
+      upperConnectingPlane.recordBounds(planetModel, startCutoffPlane, bounds, lowerConnectingPlane, endCutoffPlane);
+      startCutoffPlane.recordBounds(planetModel, lowerConnectingPlane, bounds, endCutoffPlane, upperConnectingPlane);
+      lowerConnectingPlane.recordBounds(planetModel, endCutoffPlane, bounds, upperConnectingPlane, startCutoffPlane);
+      endCutoffPlane.recordBounds(planetModel, upperConnectingPlane, bounds, startCutoffPlane, lowerConnectingPlane);
+      upperConnectingPlane.recordBounds(planetModel, bounds, lowerConnectingPlane, startCutoffPlane, endCutoffPlane);
+      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).

Modified: lucene/dev/branches/lucene6487/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoPoint.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6487/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoPoint.java?rev=1681907&r1=1681906&r2=1681907&view=diff
==============================================================================
--- lucene/dev/branches/lucene6487/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoPoint.java (original)
+++ lucene/dev/branches/lucene6487/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoPoint.java Wed May 27 04:54:50 2015
@@ -23,20 +23,36 @@ package org.apache.lucene.spatial.spatia
  * @lucene.experimental
  */
 public class GeoPoint extends Vector {
-  public GeoPoint(final double sinLat, final double sinLon, final double cosLat, final double cosLon) {
-    super(cosLat * cosLon, cosLat * sinLon, sinLat);
+  
+  protected double magnitude = Double.NEGATIVE_INFINITY;
+  
+  public GeoPoint(final PlanetModel planetModel, final double sinLat, final double sinLon, final double cosLat, final double cosLon) {
+    this(computeMagnitude(planetModel, cosLat * cosLon, cosLat * sinLon, sinLat),
+      cosLat * cosLon, cosLat * sinLon, sinLat);
   }
 
-  public GeoPoint(final double lat, final double lon) {
-    this(Math.sin(lat), Math.sin(lon), Math.cos(lat), Math.cos(lon));
+  public GeoPoint(final PlanetModel planetModel, final double lat, final double lon) {
+    this(planetModel, Math.sin(lat), Math.sin(lon), Math.cos(lat), Math.cos(lon));
   }
 
+  public GeoPoint(final double magnitude, final double x, final double y, final double z) {
+    super(x * magnitude, y * magnitude, z * magnitude);
+    this.magnitude = magnitude;
+  }
+  
   public GeoPoint(final double x, final double y, final double z) {
     super(x, y, z);
   }
 
   public double arcDistance(final GeoPoint v) {
-    return Tools.safeAcos(dotProduct(v));
+    return Tools.safeAcos(dotProduct(v)/(magnitude() * v.magnitude()));
   }
 
+  @Override
+  public double magnitude() {
+    if (this.magnitude == Double.NEGATIVE_INFINITY) {
+      this.magnitude = super.magnitude();
+    }
+    return magnitude;
+  }
 }

Modified: lucene/dev/branches/lucene6487/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoPolygonFactory.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6487/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoPolygonFactory.java?rev=1681907&r1=1681906&r2=1681907&view=diff
==============================================================================
--- lucene/dev/branches/lucene6487/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoPolygonFactory.java (original)
+++ lucene/dev/branches/lucene6487/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoPolygonFactory.java Wed May 27 04:54:50 2015
@@ -38,16 +38,16 @@ public class GeoPolygonFactory {
    *                         its neighbors determines inside/outside for the entire polygon.
    * @return a GeoMembershipShape corresponding to what was specified.
    */
-  public static GeoMembershipShape makeGeoPolygon(List<GeoPoint> pointList, int convexPointIndex) {
+  public static GeoMembershipShape makeGeoPolygon(final PlanetModel planetModel, final List<GeoPoint> pointList, final int convexPointIndex) {
     // The basic operation uses a set of points, two points determining one particular edge, and a sided plane
     // describing membership.
-    return buildPolygonShape(pointList, convexPointIndex, getLegalIndex(convexPointIndex + 1, pointList.size()),
+    return buildPolygonShape(planetModel, pointList, convexPointIndex, getLegalIndex(convexPointIndex + 1, pointList.size()),
         new SidedPlane(pointList.get(getLegalIndex(convexPointIndex - 1, pointList.size())),
             pointList.get(convexPointIndex), pointList.get(getLegalIndex(convexPointIndex + 1, pointList.size()))),
         false);
   }
 
-  public static GeoMembershipShape buildPolygonShape(List<GeoPoint> pointsList, int startPointIndex, int endPointIndex, SidedPlane startingEdge, boolean isInternalEdge) {
+  public static GeoMembershipShape buildPolygonShape(final PlanetModel planetModel, final List<GeoPoint> pointsList, final int startPointIndex, final int endPointIndex, final SidedPlane startingEdge, final boolean isInternalEdge) {
     // Algorithm as follows:
     // Start with sided edge.  Go through all points in some order.  For each new point, determine if the point is within all edges considered so far.
     // If not, put it into a list of points for recursion.  If it is within, add new edge and keep going.
@@ -112,7 +112,7 @@ public class GeoPolygonFactory {
             }
             // We want the other side for the recursion
             SidedPlane otherSideNewBoundary = new SidedPlane(newBoundary);
-            rval.addShape(buildPolygonShape(recursionList, recursionList.size() - 2, recursionList.size() - 1, otherSideNewBoundary, true));
+            rval.addShape(buildPolygonShape(planetModel, recursionList, recursionList.size() - 2, recursionList.size() - 1, otherSideNewBoundary, true));
             recursionList.clear();
           }
           currentList.add(newPoint);
@@ -140,11 +140,11 @@ public class GeoPolygonFactory {
       SidedPlane newBoundary = new SidedPlane(currentList.get(currentList.size() - 2), currentList.get(0), currentList.get(currentList.size() - 1));
       // We want the other side for the recursion
       SidedPlane otherSideNewBoundary = new SidedPlane(newBoundary);
-      rval.addShape(buildPolygonShape(recursionList, recursionList.size() - 2, recursionList.size() - 1, otherSideNewBoundary, true));
+      rval.addShape(buildPolygonShape(planetModel, recursionList, recursionList.size() - 2, recursionList.size() - 1, otherSideNewBoundary, true));
       recursionList.clear();
     }
     // Now, add in the current shape.
-    rval.addShape(new GeoConvexPolygon(currentList, internalEdgeList, returnEdgeInternalBoundary));
+    rval.addShape(new GeoConvexPolygon(planetModel, currentList, internalEdgeList, returnEdgeInternalBoundary));
     //System.out.println("Done creating polygon");
     return rval;
   }

Modified: lucene/dev/branches/lucene6487/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoRectangle.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6487/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoRectangle.java?rev=1681907&r1=1681906&r2=1681907&view=diff
==============================================================================
--- lucene/dev/branches/lucene6487/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoRectangle.java (original)
+++ lucene/dev/branches/lucene6487/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoRectangle.java Wed May 27 04:54:50 2015
@@ -24,7 +24,7 @@ package org.apache.lucene.spatial.spatia
  *
  * @lucene.internal
  */
-public class GeoRectangle extends GeoBBoxBase {
+public class GeoRectangle extends GeoBaseBBox {
   public final double topLat;
   public final double bottomLat;
   public final double leftLon;
@@ -54,7 +54,8 @@ public class GeoRectangle extends GeoBBo
   /**
    * Accepts only values in the following ranges: lat: {@code -PI/2 -> PI/2}, lon: {@code -PI -> PI}
    */
-  public GeoRectangle(final double topLat, final double bottomLat, final double leftLon, double rightLon) {
+  public GeoRectangle(final PlanetModel planetModel, final double topLat, final double bottomLat, final double leftLon, double rightLon) {
+    super(planetModel);
     // Argument checking
     if (topLat > Math.PI * 0.5 || topLat < -Math.PI * 0.5)
       throw new IllegalArgumentException("Top latitude out of range");
@@ -88,10 +89,10 @@ public class GeoRectangle extends GeoBBo
     final double cosRightLon = Math.cos(rightLon);
 
     // Now build the four points
-    this.ULHC = new GeoPoint(sinTopLat, sinLeftLon, cosTopLat, cosLeftLon);
-    this.URHC = new GeoPoint(sinTopLat, sinRightLon, cosTopLat, cosRightLon);
-    this.LRHC = new GeoPoint(sinBottomLat, sinRightLon, cosBottomLat, cosRightLon);
-    this.LLHC = new GeoPoint(sinBottomLat, sinLeftLon, cosBottomLat, cosLeftLon);
+    this.ULHC = new GeoPoint(planetModel, sinTopLat, sinLeftLon, cosTopLat, cosLeftLon);
+    this.URHC = new GeoPoint(planetModel, sinTopLat, sinRightLon, cosTopLat, cosRightLon);
+    this.LRHC = new GeoPoint(planetModel, sinBottomLat, sinRightLon, cosBottomLat, cosRightLon);
+    this.LLHC = new GeoPoint(planetModel, sinBottomLat, sinLeftLon, cosBottomLat, cosLeftLon);
 
     final double middleLat = (topLat + bottomLat) * 0.5;
     final double sinMiddleLat = Math.sin(middleLat);
@@ -104,10 +105,10 @@ public class GeoRectangle extends GeoBBo
     final double sinMiddleLon = Math.sin(middleLon);
     final double cosMiddleLon = Math.cos(middleLon);
 
-    this.centerPoint = new GeoPoint(sinMiddleLat, sinMiddleLon, cosMiddleLat, cosMiddleLon);
+    this.centerPoint = new GeoPoint(planetModel, sinMiddleLat, sinMiddleLon, cosMiddleLat, cosMiddleLon);
 
-    this.topPlane = new SidedPlane(centerPoint, sinTopLat);
-    this.bottomPlane = new SidedPlane(centerPoint, sinBottomLat);
+    this.topPlane = new SidedPlane(centerPoint, planetModel, sinTopLat);
+    this.bottomPlane = new SidedPlane(centerPoint, planetModel, sinBottomLat);
     this.leftPlane = new SidedPlane(centerPoint, cosLeftLon, sinLeftLon);
     this.rightPlane = new SidedPlane(centerPoint, cosRightLon, sinRightLon);
 
@@ -133,7 +134,7 @@ public class GeoRectangle extends GeoBBo
       newLeftLon = -Math.PI;
       newRightLon = Math.PI;
     }
-    return GeoBBoxFactory.makeGeoBBox(newTopLat, newBottomLat, newLeftLon, newRightLon);
+    return GeoBBoxFactory.makeGeoBBox(planetModel, newTopLat, newBottomLat, newLeftLon, newRightLon);
   }
 
   @Override
@@ -180,10 +181,10 @@ public class GeoRectangle extends GeoBBo
 
   @Override
   public boolean intersects(final Plane p, final GeoPoint[] notablePoints, final Membership... bounds) {
-    return p.intersects(topPlane, notablePoints, topPlanePoints, bounds, bottomPlane, leftPlane, rightPlane) ||
-        p.intersects(bottomPlane, notablePoints, bottomPlanePoints, bounds, topPlane, leftPlane, rightPlane) ||
-        p.intersects(leftPlane, notablePoints, leftPlanePoints, bounds, rightPlane, topPlane, bottomPlane) ||
-        p.intersects(rightPlane, notablePoints, rightPlanePoints, bounds, leftPlane, topPlane, bottomPlane);
+    return p.intersects(planetModel, topPlane, notablePoints, topPlanePoints, bounds, bottomPlane, leftPlane, rightPlane) ||
+        p.intersects(planetModel, bottomPlane, notablePoints, bottomPlanePoints, bounds, topPlane, leftPlane, rightPlane) ||
+        p.intersects(planetModel, leftPlane, notablePoints, leftPlanePoints, bounds, rightPlane, topPlane, bottomPlane) ||
+        p.intersects(planetModel, rightPlane, notablePoints, rightPlanePoints, bounds, leftPlane, topPlane, bottomPlane);
   }
 
   /**
@@ -246,19 +247,20 @@ public class GeoRectangle extends GeoBBo
     if (!(o instanceof GeoRectangle))
       return false;
     GeoRectangle other = (GeoRectangle) o;
-    return other.ULHC.equals(ULHC) && other.LRHC.equals(LRHC);
+    return super.equals(other) && other.ULHC.equals(ULHC) && other.LRHC.equals(LRHC);
   }
 
   @Override
   public int hashCode() {
-    int result = ULHC.hashCode();
-    result = 31 * result + LRHC.hashCode();
+    int result = super.hashCode();
+    result = 31 * result  + ULHC.hashCode();
+    result = 31 * result  + LRHC.hashCode();
     return result;
   }
 
   @Override
   public String toString() {
-    return "GeoRectangle: {toplat=" + topLat + "(" + topLat * 180.0 / Math.PI + "), bottomlat=" + bottomLat + "(" + bottomLat * 180.0 / Math.PI + "), leftlon=" + leftLon + "(" + leftLon * 180.0 / Math.PI + "), rightlon=" + rightLon + "(" + rightLon * 180.0 / Math.PI + ")}";
+    return "GeoRectangle: {planetmodel="+planetModel+", toplat=" + topLat + "(" + topLat * 180.0 / Math.PI + "), bottomlat=" + bottomLat + "(" + bottomLat * 180.0 / Math.PI + "), leftlon=" + leftLon + "(" + leftLon * 180.0 / Math.PI + "), rightlon=" + rightLon + "(" + rightLon * 180.0 / Math.PI + ")}";
   }
 }
   

Modified: lucene/dev/branches/lucene6487/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoSouthLatitudeZone.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6487/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoSouthLatitudeZone.java?rev=1681907&r1=1681906&r2=1681907&view=diff
==============================================================================
--- lucene/dev/branches/lucene6487/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoSouthLatitudeZone.java (original)
+++ lucene/dev/branches/lucene6487/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoSouthLatitudeZone.java Wed May 27 04:54:50 2015
@@ -22,7 +22,7 @@ package org.apache.lucene.spatial.spatia
  *
  * @lucene.internal
  */
-public class GeoSouthLatitudeZone extends GeoBBoxBase {
+public class GeoSouthLatitudeZone extends GeoBaseBBox {
   public final double topLat;
   public final double cosTopLat;
   public final SidedPlane topPlane;
@@ -34,22 +34,20 @@ public class GeoSouthLatitudeZone extend
   // Edge points
   public final GeoPoint[] edgePoints;
 
-  public GeoSouthLatitudeZone(final double topLat) {
+  public GeoSouthLatitudeZone(final PlanetModel planetModel, final double topLat) {
+    super(planetModel);
     this.topLat = topLat;
 
     final double sinTopLat = Math.sin(topLat);
     this.cosTopLat = Math.cos(topLat);
 
-    // Construct sample points, so we get our sidedness right
-    final Vector topPoint = new Vector(0.0, 0.0, sinTopLat);
-
     // Compute an interior point.  Pick one whose lat is between top and bottom.
     final double middleLat = (topLat - Math.PI * 0.5) * 0.5;
     final double sinMiddleLat = Math.sin(middleLat);
-    this.interiorPoint = new GeoPoint(Math.sqrt(1.0 - sinMiddleLat * sinMiddleLat), 0.0, sinMiddleLat);
-    this.topBoundaryPoint = new GeoPoint(Math.sqrt(1.0 - sinTopLat * sinTopLat), 0.0, sinTopLat);
+    this.interiorPoint = new GeoPoint(planetModel, sinMiddleLat, 0.0, Math.sqrt(1.0 - sinMiddleLat * sinMiddleLat), 1.0);
+    this.topBoundaryPoint = new GeoPoint(planetModel, sinTopLat, 0.0, Math.sqrt(1.0 - sinTopLat * sinTopLat), 1.0);
 
-    this.topPlane = new SidedPlane(interiorPoint, sinTopLat);
+    this.topPlane = new SidedPlane(interiorPoint, planetModel, sinTopLat);
 
     this.edgePoints = new GeoPoint[]{topBoundaryPoint};
   }
@@ -58,7 +56,7 @@ public class GeoSouthLatitudeZone extend
   public GeoBBox expand(final double angle) {
     final double newTopLat = topLat + angle;
     final double newBottomLat = -Math.PI * 0.5;
-    return GeoBBoxFactory.makeGeoBBox(newTopLat, newBottomLat, -Math.PI, Math.PI);
+    return GeoBBoxFactory.makeGeoBBox(planetModel, newTopLat, newBottomLat, -Math.PI, Math.PI);
   }
 
   @Override
@@ -98,7 +96,7 @@ public class GeoSouthLatitudeZone extend
 
   @Override
   public boolean intersects(final Plane p, final GeoPoint[] notablePoints, final Membership... bounds) {
-    return p.intersects(topPlane, notablePoints, planePoints, bounds);
+    return p.intersects(planetModel, topPlane, notablePoints, planePoints, bounds);
   }
 
   /**
@@ -155,18 +153,19 @@ public class GeoSouthLatitudeZone extend
     if (!(o instanceof GeoSouthLatitudeZone))
       return false;
     GeoSouthLatitudeZone other = (GeoSouthLatitudeZone) o;
-    return other.topPlane.equals(topPlane);
+    return super.equals(other) && other.topBoundaryPoint.equals(topBoundaryPoint);
   }
 
   @Override
   public int hashCode() {
-    int result = topPlane.hashCode();
+    int result = super.hashCode();
+    result = 31 * result + topBoundaryPoint.hashCode();
     return result;
   }
 
   @Override
   public String toString() {
-    return "GeoSouthLatitudeZone: {toplat=" + topLat + "(" + topLat * 180.0 / Math.PI + ")}";
+    return "GeoSouthLatitudeZone: {planetmodel="+planetModel+", toplat=" + topLat + "(" + topLat * 180.0 / Math.PI + ")}";
   }
 }
 

Modified: lucene/dev/branches/lucene6487/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoSouthRectangle.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6487/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoSouthRectangle.java?rev=1681907&r1=1681906&r2=1681907&view=diff
==============================================================================
--- lucene/dev/branches/lucene6487/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoSouthRectangle.java (original)
+++ lucene/dev/branches/lucene6487/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoSouthRectangle.java Wed May 27 04:54:50 2015
@@ -25,7 +25,7 @@ package org.apache.lucene.spatial.spatia
  *
  * @lucene.internal
  */
-public class GeoSouthRectangle extends GeoBBoxBase {
+public class GeoSouthRectangle extends GeoBaseBBox {
   public final double topLat;
   public final double leftLon;
   public final double rightLon;
@@ -45,12 +45,13 @@ public class GeoSouthRectangle extends G
 
   public final GeoPoint centerPoint;
 
-  public final GeoPoint[] edgePoints = new GeoPoint[]{SOUTH_POLE};
+  public final GeoPoint[] edgePoints;
 
   /**
    * Accepts only values in the following ranges: lat: {@code -PI/2 -> PI/2}, lon: {@code -PI -> PI}
    */
-  public GeoSouthRectangle(final double topLat, final double leftLon, double rightLon) {
+  public GeoSouthRectangle(final PlanetModel planetModel, final double topLat, final double leftLon, double rightLon) {
+    super(planetModel);
     // Argument checking
     if (topLat > Math.PI * 0.5 || topLat < -Math.PI * 0.5)
       throw new IllegalArgumentException("Top latitude out of range");
@@ -77,8 +78,8 @@ public class GeoSouthRectangle extends G
     final double cosRightLon = Math.cos(rightLon);
 
     // Now build the four points
-    this.ULHC = new GeoPoint(sinTopLat, sinLeftLon, cosTopLat, cosLeftLon);
-    this.URHC = new GeoPoint(sinTopLat, sinRightLon, cosTopLat, cosRightLon);
+    this.ULHC = new GeoPoint(planetModel, sinTopLat, sinLeftLon, cosTopLat, cosLeftLon);
+    this.URHC = new GeoPoint(planetModel, sinTopLat, sinRightLon, cosTopLat, cosRightLon);
 
     final double middleLat = (topLat - Math.PI * 0.5) * 0.5;
     final double sinMiddleLat = Math.sin(middleLat);
@@ -91,15 +92,18 @@ public class GeoSouthRectangle extends G
     final double sinMiddleLon = Math.sin(middleLon);
     final double cosMiddleLon = Math.cos(middleLon);
 
-    this.centerPoint = new GeoPoint(sinMiddleLat, sinMiddleLon, cosMiddleLat, cosMiddleLon);
+    this.centerPoint = new GeoPoint(planetModel, sinMiddleLat, sinMiddleLon, cosMiddleLat, cosMiddleLon);
 
-    this.topPlane = new SidedPlane(centerPoint, sinTopLat);
+    this.topPlane = new SidedPlane(centerPoint, planetModel, sinTopLat);
     this.leftPlane = new SidedPlane(centerPoint, cosLeftLon, sinLeftLon);
     this.rightPlane = new SidedPlane(centerPoint, cosRightLon, sinRightLon);
 
     this.topPlanePoints = new GeoPoint[]{ULHC, URHC};
-    this.leftPlanePoints = new GeoPoint[]{ULHC, SOUTH_POLE};
-    this.rightPlanePoints = new GeoPoint[]{URHC, SOUTH_POLE};
+    this.leftPlanePoints = new GeoPoint[]{ULHC, planetModel.SOUTH_POLE};
+    this.rightPlanePoints = new GeoPoint[]{URHC, planetModel.SOUTH_POLE};
+    
+    this.edgePoints = new GeoPoint[]{planetModel.SOUTH_POLE};
+
   }
 
   @Override
@@ -116,7 +120,7 @@ public class GeoSouthRectangle extends G
       newLeftLon = -Math.PI;
       newRightLon = Math.PI;
     }
-    return GeoBBoxFactory.makeGeoBBox(newTopLat, newBottomLat, newLeftLon, newRightLon);
+    return GeoBBoxFactory.makeGeoBBox(planetModel, newTopLat, newBottomLat, newLeftLon, newRightLon);
   }
 
   @Override
@@ -160,9 +164,9 @@ public class GeoSouthRectangle extends G
 
   @Override
   public boolean intersects(final Plane p, final GeoPoint[] notablePoints, final Membership... bounds) {
-    return p.intersects(topPlane, notablePoints, topPlanePoints, bounds, leftPlane, rightPlane) ||
-        p.intersects(leftPlane, notablePoints, leftPlanePoints, bounds, rightPlane, topPlane) ||
-        p.intersects(rightPlane, notablePoints, rightPlanePoints, bounds, leftPlane, topPlane);
+    return p.intersects(planetModel, topPlane, notablePoints, topPlanePoints, bounds, leftPlane, rightPlane) ||
+        p.intersects(planetModel, leftPlane, notablePoints, leftPlanePoints, bounds, rightPlane, topPlane) ||
+        p.intersects(planetModel, rightPlane, notablePoints, rightPlanePoints, bounds, leftPlane, topPlane);
   }
 
   /**
@@ -192,7 +196,7 @@ public class GeoSouthRectangle extends G
       return OVERLAPS;
     }
 
-    final boolean insideShape = path.isWithin(SOUTH_POLE);
+    final boolean insideShape = path.isWithin(planetModel.SOUTH_POLE);
 
     if (insideRectangle == ALL_INSIDE && insideShape) {
       //System.err.println(" inside of each other");
@@ -224,19 +228,20 @@ public class GeoSouthRectangle extends G
     if (!(o instanceof GeoSouthRectangle))
       return false;
     GeoSouthRectangle other = (GeoSouthRectangle) o;
-    return other.ULHC.equals(ULHC) && other.URHC.equals(URHC);
+    return super.equals(other) && other.ULHC.equals(ULHC) && other.URHC.equals(URHC);
   }
 
   @Override
   public int hashCode() {
-    int result = ULHC.hashCode();
+    int result = super.hashCode();
+    result = 31 * result + ULHC.hashCode();
     result = 31 * result + URHC.hashCode();
     return result;
   }
 
   @Override
   public String toString() {
-    return "GeoSouthRectangle: {toplat=" + topLat + "(" + topLat * 180.0 / Math.PI + "), leftlon=" + leftLon + "(" + leftLon * 180.0 / Math.PI + "), rightlon=" + rightLon + "(" + rightLon * 180.0 / Math.PI + ")}";
+    return "GeoSouthRectangle: {planetmodel="+planetModel+", toplat=" + topLat + "(" + topLat * 180.0 / Math.PI + "), leftlon=" + leftLon + "(" + leftLon * 180.0 / Math.PI + "), rightlon=" + rightLon + "(" + rightLon * 180.0 / Math.PI + ")}";
   }
 }
   

Modified: lucene/dev/branches/lucene6487/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWideDegenerateHorizontalLine.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6487/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWideDegenerateHorizontalLine.java?rev=1681907&r1=1681906&r2=1681907&view=diff
==============================================================================
--- lucene/dev/branches/lucene6487/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWideDegenerateHorizontalLine.java (original)
+++ lucene/dev/branches/lucene6487/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWideDegenerateHorizontalLine.java Wed May 27 04:54:50 2015
@@ -22,7 +22,7 @@ package org.apache.lucene.spatial.spatia
  *
  * @lucene.internal
  */
-public class GeoWideDegenerateHorizontalLine extends GeoBBoxBase {
+public class GeoWideDegenerateHorizontalLine extends GeoBaseBBox {
   public final double latitude;
   public final double leftLon;
   public final double rightLon;
@@ -46,7 +46,8 @@ public class GeoWideDegenerateHorizontal
    * Accepts only values in the following ranges: lat: {@code -PI/2 -> PI/2}, lon: {@code -PI -> PI}.
    * Horizontal angle must be greater than or equal to PI.
    */
-  public GeoWideDegenerateHorizontalLine(final double latitude, final double leftLon, double rightLon) {
+  public GeoWideDegenerateHorizontalLine(final PlanetModel planetModel, final double latitude, final double leftLon, double rightLon) {
+    super(planetModel);
     // Argument checking
     if (latitude > Math.PI * 0.5 || latitude < -Math.PI * 0.5)
       throw new IllegalArgumentException("Latitude out of range");
@@ -73,10 +74,10 @@ public class GeoWideDegenerateHorizontal
     final double cosRightLon = Math.cos(rightLon);
 
     // Now build the two points
-    this.LHC = new GeoPoint(sinLatitude, sinLeftLon, cosLatitude, cosLeftLon);
-    this.RHC = new GeoPoint(sinLatitude, sinRightLon, cosLatitude, cosRightLon);
+    this.LHC = new GeoPoint(planetModel, sinLatitude, sinLeftLon, cosLatitude, cosLeftLon);
+    this.RHC = new GeoPoint(planetModel, sinLatitude, sinRightLon, cosLatitude, cosRightLon);
 
-    this.plane = new Plane(sinLatitude);
+    this.plane = new Plane(planetModel, sinLatitude);
 
     // Normalize
     while (leftLon > rightLon) {
@@ -86,7 +87,7 @@ public class GeoWideDegenerateHorizontal
     double sinMiddleLon = Math.sin(middleLon);
     double cosMiddleLon = Math.cos(middleLon);
 
-    this.centerPoint = new GeoPoint(sinLatitude, sinMiddleLon, cosLatitude, cosMiddleLon);
+    this.centerPoint = new GeoPoint(planetModel, sinLatitude, sinMiddleLon, cosLatitude, cosMiddleLon);
 
     this.leftPlane = new SidedPlane(centerPoint, cosLeftLon, sinLeftLon);
     this.rightPlane = new SidedPlane(centerPoint, cosRightLon, sinRightLon);
@@ -112,7 +113,7 @@ public class GeoWideDegenerateHorizontal
       newLeftLon = -Math.PI;
       newRightLon = Math.PI;
     }
-    return GeoBBoxFactory.makeGeoBBox(newTopLat, newBottomLat, newLeftLon, newRightLon);
+    return GeoBBoxFactory.makeGeoBBox(planetModel, newTopLat, newBottomLat, newLeftLon, newRightLon);
   }
 
   @Override
@@ -160,7 +161,7 @@ public class GeoWideDegenerateHorizontal
   public boolean intersects(final Plane p, final GeoPoint[] notablePoints, final Membership... bounds) {
     // Right and left bounds are essentially independent hemispheres; crossing into the wrong part of one
     // requires crossing into the right part of the other.  So intersection can ignore the left/right bounds.
-    return p.intersects(plane, notablePoints, planePoints, bounds, eitherBound);
+    return p.intersects(planetModel, plane, notablePoints, planePoints, bounds, eitherBound);
   }
 
   /**
@@ -199,19 +200,20 @@ public class GeoWideDegenerateHorizontal
     if (!(o instanceof GeoWideDegenerateHorizontalLine))
       return false;
     GeoWideDegenerateHorizontalLine other = (GeoWideDegenerateHorizontalLine) o;
-    return other.LHC.equals(LHC) && other.RHC.equals(RHC);
+    return super.equals(other) && other.LHC.equals(LHC) && other.RHC.equals(RHC);
   }
 
   @Override
   public int hashCode() {
-    int result = LHC.hashCode();
+    int result = super.hashCode();
+    result = 31 * result + LHC.hashCode();
     result = 31 * result + RHC.hashCode();
     return result;
   }
 
   @Override
   public String toString() {
-    return "GeoWideDegenerateHorizontalLine: {latitude=" + latitude + "(" + latitude * 180.0 / Math.PI + "), leftlon=" + leftLon + "(" + leftLon * 180.0 / Math.PI + "), rightLon=" + rightLon + "(" + rightLon * 180.0 / Math.PI + ")}";
+    return "GeoWideDegenerateHorizontalLine: {planetmodel="+planetModel+", latitude=" + latitude + "(" + latitude * 180.0 / Math.PI + "), leftlon=" + leftLon + "(" + leftLon * 180.0 / Math.PI + "), rightLon=" + rightLon + "(" + rightLon * 180.0 / Math.PI + ")}";
   }
 
   protected class EitherBound implements Membership {

Modified: lucene/dev/branches/lucene6487/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWideLongitudeSlice.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6487/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWideLongitudeSlice.java?rev=1681907&r1=1681906&r2=1681907&view=diff
==============================================================================
--- lucene/dev/branches/lucene6487/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWideLongitudeSlice.java (original)
+++ lucene/dev/branches/lucene6487/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWideLongitudeSlice.java Wed May 27 04:54:50 2015
@@ -23,24 +23,25 @@ package org.apache.lucene.spatial.spatia
  *
  * @lucene.internal
  */
-public class GeoWideLongitudeSlice extends GeoBBoxBase {
+public class GeoWideLongitudeSlice extends GeoBaseBBox {
   public final double leftLon;
   public final double rightLon;
 
   public final SidedPlane leftPlane;
   public final SidedPlane rightPlane;
 
-  public final static GeoPoint[] planePoints = new GeoPoint[]{NORTH_POLE, SOUTH_POLE};
+  public final GeoPoint[] planePoints;
 
   public final GeoPoint centerPoint;
 
-  public final static GeoPoint[] edgePoints = new GeoPoint[]{NORTH_POLE};
+  public final GeoPoint[] edgePoints; 
 
   /**
    * Accepts only values in the following ranges: lon: {@code -PI -> PI}.
    * Horizantal angle must be greater than or equal to PI.
    */
-  public GeoWideLongitudeSlice(final double leftLon, double rightLon) {
+  public GeoWideLongitudeSlice(final PlanetModel planetModel, final double leftLon, double rightLon) {
+    super(planetModel);
     // Argument checking
     if (leftLon < -Math.PI || leftLon > Math.PI)
       throw new IllegalArgumentException("Left longitude out of range");
@@ -66,10 +67,13 @@ public class GeoWideLongitudeSlice exten
       rightLon += Math.PI * 2.0;
     }
     final double middleLon = (leftLon + rightLon) * 0.5;
-    this.centerPoint = new GeoPoint(0.0, middleLon);
+    this.centerPoint = new GeoPoint(planetModel, 0.0, middleLon);
 
     this.leftPlane = new SidedPlane(centerPoint, cosLeftLon, sinLeftLon);
     this.rightPlane = new SidedPlane(centerPoint, cosRightLon, sinRightLon);
+    
+    this.planePoints = new GeoPoint[]{planetModel.NORTH_POLE, planetModel.SOUTH_POLE};
+    this.edgePoints = new GeoPoint[]{planetModel.NORTH_POLE};
   }
 
   @Override
@@ -84,7 +88,7 @@ public class GeoWideLongitudeSlice exten
       newLeftLon = -Math.PI;
       newRightLon = Math.PI;
     }
-    return GeoBBoxFactory.makeGeoBBox(Math.PI * 0.5, -Math.PI * 0.5, newLeftLon, newRightLon);
+    return GeoBBoxFactory.makeGeoBBox(planetModel, Math.PI * 0.5, -Math.PI * 0.5, newLeftLon, newRightLon);
   }
 
   @Override
@@ -127,8 +131,8 @@ public class GeoWideLongitudeSlice exten
   public boolean intersects(final Plane p, final GeoPoint[] notablePoints, final Membership... bounds) {
     // Right and left bounds are essentially independent hemispheres; crossing into the wrong part of one
     // requires crossing into the right part of the other.  So intersection can ignore the left/right bounds.
-    return p.intersects(leftPlane, notablePoints, planePoints, bounds) ||
-        p.intersects(rightPlane, notablePoints, planePoints, bounds);
+    return p.intersects(planetModel, leftPlane, notablePoints, planePoints, bounds) ||
+        p.intersects(planetModel, rightPlane, notablePoints, planePoints, bounds);
   }
 
   /**
@@ -155,7 +159,7 @@ public class GeoWideLongitudeSlice exten
     if (insideRectangle == SOME_INSIDE)
       return OVERLAPS;
 
-    final boolean insideShape = path.isWithin(NORTH_POLE);
+    final boolean insideShape = path.isWithin(planetModel.NORTH_POLE);
 
     if (insideRectangle == ALL_INSIDE && insideShape)
       return OVERLAPS;
@@ -178,15 +182,14 @@ public class GeoWideLongitudeSlice exten
     if (!(o instanceof GeoWideLongitudeSlice))
       return false;
     GeoWideLongitudeSlice other = (GeoWideLongitudeSlice) o;
-    return other.leftLon == leftLon && other.rightLon == rightLon;
+    return super.equals(other) && other.leftLon == leftLon && other.rightLon == rightLon;
   }
 
   @Override
   public int hashCode() {
-    int result;
-    long temp;
-    temp = Double.doubleToLongBits(leftLon);
-    result = (int) (temp ^ (temp >>> 32));
+    int result = super.hashCode();
+    long temp = Double.doubleToLongBits(leftLon);
+    result = 31 * result + (int) (temp ^ (temp >>> 32));
     temp = Double.doubleToLongBits(rightLon);
     result = 31 * result + (int) (temp ^ (temp >>> 32));
     return result;
@@ -194,7 +197,7 @@ public class GeoWideLongitudeSlice exten
 
   @Override
   public String toString() {
-    return "GeoWideLongitudeSlice: {leftlon=" + leftLon + "(" + leftLon * 180.0 / Math.PI + "), rightlon=" + rightLon + "(" + rightLon * 180.0 / Math.PI + ")}";
+    return "GeoWideLongitudeSlice: {planetmodel="+planetModel+", leftlon=" + leftLon + "(" + leftLon * 180.0 / Math.PI + "), rightlon=" + rightLon + "(" + rightLon * 180.0 / Math.PI + ")}";
   }
 }
   

Modified: lucene/dev/branches/lucene6487/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWideNorthRectangle.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6487/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWideNorthRectangle.java?rev=1681907&r1=1681906&r2=1681907&view=diff
==============================================================================
--- lucene/dev/branches/lucene6487/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWideNorthRectangle.java (original)
+++ lucene/dev/branches/lucene6487/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWideNorthRectangle.java Wed May 27 04:54:50 2015
@@ -23,7 +23,7 @@ package org.apache.lucene.spatial.spatia
  *
  * @lucene.internal
  */
-public class GeoWideNorthRectangle extends GeoBBoxBase {
+public class GeoWideNorthRectangle extends GeoBaseBBox {
   public final double bottomLat;
   public final double leftLon;
   public final double rightLon;
@@ -45,13 +45,14 @@ public class GeoWideNorthRectangle exten
 
   public final EitherBound eitherBound;
 
-  public final GeoPoint[] edgePoints = new GeoPoint[]{NORTH_POLE};
+  public final GeoPoint[] edgePoints;
 
   /**
    * Accepts only values in the following ranges: lat: {@code -PI/2 -> PI/2}, lon: {@code -PI -> PI}.
    * Horizontal angle must be greater than or equal to PI.
    */
-  public GeoWideNorthRectangle(final double bottomLat, final double leftLon, double rightLon) {
+  public GeoWideNorthRectangle(final PlanetModel planetModel, final double bottomLat, final double leftLon, double rightLon) {
+    super(planetModel);
     // Argument checking
     if (bottomLat > Math.PI * 0.5 || bottomLat < -Math.PI * 0.5)
       throw new IllegalArgumentException("Bottom latitude out of range");
@@ -78,8 +79,8 @@ public class GeoWideNorthRectangle exten
     final double cosRightLon = Math.cos(rightLon);
 
     // Now build the four points
-    this.LRHC = new GeoPoint(sinBottomLat, sinRightLon, cosBottomLat, cosRightLon);
-    this.LLHC = new GeoPoint(sinBottomLat, sinLeftLon, cosBottomLat, cosLeftLon);
+    this.LRHC = new GeoPoint(planetModel, sinBottomLat, sinRightLon, cosBottomLat, cosRightLon);
+    this.LLHC = new GeoPoint(planetModel, sinBottomLat, sinLeftLon, cosBottomLat, cosLeftLon);
 
     final double middleLat = (Math.PI * 0.5 + bottomLat) * 0.5;
     final double sinMiddleLat = Math.sin(middleLat);
@@ -92,17 +93,18 @@ public class GeoWideNorthRectangle exten
     final double sinMiddleLon = Math.sin(middleLon);
     final double cosMiddleLon = Math.cos(middleLon);
 
-    this.centerPoint = new GeoPoint(sinMiddleLat, sinMiddleLon, cosMiddleLat, cosMiddleLon);
+    this.centerPoint = new GeoPoint(planetModel, sinMiddleLat, sinMiddleLon, cosMiddleLat, cosMiddleLon);
 
-    this.bottomPlane = new SidedPlane(centerPoint, sinBottomLat);
+    this.bottomPlane = new SidedPlane(centerPoint, planetModel, sinBottomLat);
     this.leftPlane = new SidedPlane(centerPoint, cosLeftLon, sinLeftLon);
     this.rightPlane = new SidedPlane(centerPoint, cosRightLon, sinRightLon);
 
     this.bottomPlanePoints = new GeoPoint[]{LLHC, LRHC};
-    this.leftPlanePoints = new GeoPoint[]{NORTH_POLE, LLHC};
-    this.rightPlanePoints = new GeoPoint[]{NORTH_POLE, LRHC};
+    this.leftPlanePoints = new GeoPoint[]{planetModel.NORTH_POLE, LLHC};
+    this.rightPlanePoints = new GeoPoint[]{planetModel.NORTH_POLE, LRHC};
 
     this.eitherBound = new EitherBound();
+    this.edgePoints = new GeoPoint[]{planetModel.NORTH_POLE};
   }
 
   @Override
@@ -119,7 +121,7 @@ public class GeoWideNorthRectangle exten
       newLeftLon = -Math.PI;
       newRightLon = Math.PI;
     }
-    return GeoBBoxFactory.makeGeoBBox(newTopLat, newBottomLat, newLeftLon, newRightLon);
+    return GeoBBoxFactory.makeGeoBBox(planetModel, newTopLat, newBottomLat, newLeftLon, newRightLon);
   }
 
   @Override
@@ -168,9 +170,9 @@ public class GeoWideNorthRectangle exten
     // Right and left bounds are essentially independent hemispheres; crossing into the wrong part of one
     // requires crossing into the right part of the other.  So intersection can ignore the left/right bounds.
     return
-        p.intersects(bottomPlane, notablePoints, bottomPlanePoints, bounds, eitherBound) ||
-            p.intersects(leftPlane, notablePoints, leftPlanePoints, bounds, bottomPlane) ||
-            p.intersects(rightPlane, notablePoints, rightPlanePoints, bounds, bottomPlane);
+        p.intersects(planetModel, bottomPlane, notablePoints, bottomPlanePoints, bounds, eitherBound) ||
+            p.intersects(planetModel, leftPlane, notablePoints, leftPlanePoints, bounds, bottomPlane) ||
+            p.intersects(planetModel, rightPlane, notablePoints, rightPlanePoints, bounds, bottomPlane);
   }
 
   /**
@@ -200,7 +202,7 @@ public class GeoWideNorthRectangle exten
       return OVERLAPS;
     }
 
-    final boolean insideShape = path.isWithin(NORTH_POLE);
+    final boolean insideShape = path.isWithin(planetModel.NORTH_POLE);
 
     if (insideRectangle == ALL_INSIDE && insideShape) {
       //System.err.println(" both inside each other");
@@ -234,19 +236,20 @@ public class GeoWideNorthRectangle exten
     if (!(o instanceof GeoWideNorthRectangle))
       return false;
     GeoWideNorthRectangle other = (GeoWideNorthRectangle) o;
-    return other.LLHC.equals(LLHC) && other.LRHC.equals(LRHC);
+    return super.equals(other) && other.LLHC.equals(LLHC) && other.LRHC.equals(LRHC);
   }
 
   @Override
   public int hashCode() {
-    int result = LLHC.hashCode();
+    int result = super.hashCode();
+    result = 31 * result + LLHC.hashCode();
     result = 31 * result + LRHC.hashCode();
     return result;
   }
 
   @Override
   public String toString() {
-    return "GeoWideNorthRectangle: {bottomlat=" + bottomLat + "(" + bottomLat * 180.0 / Math.PI + "), leftlon=" + leftLon + "(" + leftLon * 180.0 / Math.PI + "), rightlon=" + rightLon + "(" + rightLon * 180.0 / Math.PI + ")}";
+    return "GeoWideNorthRectangle: {planetmodel="+planetModel+", bottomlat=" + bottomLat + "(" + bottomLat * 180.0 / Math.PI + "), leftlon=" + leftLon + "(" + leftLon * 180.0 / Math.PI + "), rightlon=" + rightLon + "(" + rightLon * 180.0 / Math.PI + ")}";
   }
 
   protected class EitherBound implements Membership {

Modified: lucene/dev/branches/lucene6487/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWideRectangle.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6487/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWideRectangle.java?rev=1681907&r1=1681906&r2=1681907&view=diff
==============================================================================
--- lucene/dev/branches/lucene6487/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWideRectangle.java (original)
+++ lucene/dev/branches/lucene6487/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWideRectangle.java Wed May 27 04:54:50 2015
@@ -23,7 +23,7 @@ package org.apache.lucene.spatial.spatia
  *
  * @lucene.internal
  */
-public class GeoWideRectangle extends GeoBBoxBase {
+public class GeoWideRectangle extends GeoBaseBBox {
   public final double topLat;
   public final double bottomLat;
   public final double leftLon;
@@ -56,7 +56,8 @@ public class GeoWideRectangle extends Ge
    * Accepts only values in the following ranges: lat: {@code -PI/2 -> PI/2}, lon: {@code -PI -> PI}.
    * Horizontal angle must be greater than or equal to PI.
    */
-  public GeoWideRectangle(final double topLat, final double bottomLat, final double leftLon, double rightLon) {
+  public GeoWideRectangle(final PlanetModel planetModel, final double topLat, final double bottomLat, final double leftLon, double rightLon) {
+    super(planetModel);
     // Argument checking
     if (topLat > Math.PI * 0.5 || topLat < -Math.PI * 0.5)
       throw new IllegalArgumentException("Top latitude out of range");
@@ -90,10 +91,10 @@ public class GeoWideRectangle extends Ge
     final double cosRightLon = Math.cos(rightLon);
 
     // Now build the four points
-    this.ULHC = new GeoPoint(sinTopLat, sinLeftLon, cosTopLat, cosLeftLon);
-    this.URHC = new GeoPoint(sinTopLat, sinRightLon, cosTopLat, cosRightLon);
-    this.LRHC = new GeoPoint(sinBottomLat, sinRightLon, cosBottomLat, cosRightLon);
-    this.LLHC = new GeoPoint(sinBottomLat, sinLeftLon, cosBottomLat, cosLeftLon);
+    this.ULHC = new GeoPoint(planetModel, sinTopLat, sinLeftLon, cosTopLat, cosLeftLon);
+    this.URHC = new GeoPoint(planetModel, sinTopLat, sinRightLon, cosTopLat, cosRightLon);
+    this.LRHC = new GeoPoint(planetModel, sinBottomLat, sinRightLon, cosBottomLat, cosRightLon);
+    this.LLHC = new GeoPoint(planetModel, sinBottomLat, sinLeftLon, cosBottomLat, cosLeftLon);
 
     final double middleLat = (topLat + bottomLat) * 0.5;
     final double sinMiddleLat = Math.sin(middleLat);
@@ -106,10 +107,10 @@ public class GeoWideRectangle extends Ge
     final double sinMiddleLon = Math.sin(middleLon);
     final double cosMiddleLon = Math.cos(middleLon);
 
-    this.centerPoint = new GeoPoint(sinMiddleLat, sinMiddleLon, cosMiddleLat, cosMiddleLon);
+    this.centerPoint = new GeoPoint(planetModel, sinMiddleLat, sinMiddleLon, cosMiddleLat, cosMiddleLon);
 
-    this.topPlane = new SidedPlane(centerPoint, sinTopLat);
-    this.bottomPlane = new SidedPlane(centerPoint, sinBottomLat);
+    this.topPlane = new SidedPlane(centerPoint, planetModel, sinTopLat);
+    this.bottomPlane = new SidedPlane(centerPoint, planetModel, sinBottomLat);
     this.leftPlane = new SidedPlane(centerPoint, cosLeftLon, sinLeftLon);
     this.rightPlane = new SidedPlane(centerPoint, cosRightLon, sinRightLon);
 
@@ -137,7 +138,7 @@ public class GeoWideRectangle extends Ge
       newLeftLon = -Math.PI;
       newRightLon = Math.PI;
     }
-    return GeoBBoxFactory.makeGeoBBox(newTopLat, newBottomLat, newLeftLon, newRightLon);
+    return GeoBBoxFactory.makeGeoBBox(planetModel, newTopLat, newBottomLat, newLeftLon, newRightLon);
   }
 
   @Override
@@ -186,10 +187,10 @@ public class GeoWideRectangle extends Ge
   public boolean intersects(final Plane p, final GeoPoint[] notablePoints, final Membership... bounds) {
     // Right and left bounds are essentially independent hemispheres; crossing into the wrong part of one
     // requires crossing into the right part of the other.  So intersection can ignore the left/right bounds.
-    return p.intersects(topPlane, notablePoints, topPlanePoints, bounds, bottomPlane, eitherBound) ||
-        p.intersects(bottomPlane, notablePoints, bottomPlanePoints, bounds, topPlane, eitherBound) ||
-        p.intersects(leftPlane, notablePoints, leftPlanePoints, bounds, topPlane, bottomPlane) ||
-        p.intersects(rightPlane, notablePoints, rightPlanePoints, bounds, topPlane, bottomPlane);
+    return p.intersects(planetModel, topPlane, notablePoints, topPlanePoints, bounds, bottomPlane, eitherBound) ||
+        p.intersects(planetModel, bottomPlane, notablePoints, bottomPlanePoints, bounds, topPlane, eitherBound) ||
+        p.intersects(planetModel, leftPlane, notablePoints, leftPlanePoints, bounds, topPlane, bottomPlane) ||
+        p.intersects(planetModel, rightPlane, notablePoints, rightPlanePoints, bounds, topPlane, bottomPlane);
   }
 
   /**
@@ -253,19 +254,20 @@ public class GeoWideRectangle extends Ge
     if (!(o instanceof GeoWideRectangle))
       return false;
     GeoWideRectangle other = (GeoWideRectangle) o;
-    return other.ULHC.equals(ULHC) && other.LRHC.equals(LRHC);
+    return super.equals(other) && other.ULHC.equals(ULHC) && other.LRHC.equals(LRHC);
   }
 
   @Override
   public int hashCode() {
-    int result = ULHC.hashCode();
+    int result = super.hashCode();
+    result = 31 * result + ULHC.hashCode();
     result = 31 * result + LRHC.hashCode();
     return result;
   }
 
   @Override
   public String toString() {
-    return "GeoWideRectangle: {toplat=" + topLat + "(" + topLat * 180.0 / Math.PI + "), bottomlat=" + bottomLat + "(" + bottomLat * 180.0 / Math.PI + "), leftlon=" + leftLon + "(" + leftLon * 180.0 / Math.PI + "), rightlon=" + rightLon + "(" + rightLon * 180.0 / Math.PI + ")}";
+    return "GeoWideRectangle: {planetmodel=" + planetModel + ", toplat=" + topLat + "(" + topLat * 180.0 / Math.PI + "), bottomlat=" + bottomLat + "(" + bottomLat * 180.0 / Math.PI + "), leftlon=" + leftLon + "(" + leftLon * 180.0 / Math.PI + "), rightlon=" + rightLon + "(" + rightLon * 180.0 / Math.PI + ")}";
   }
 
   protected class EitherBound implements Membership {

Modified: lucene/dev/branches/lucene6487/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWideSouthRectangle.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6487/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWideSouthRectangle.java?rev=1681907&r1=1681906&r2=1681907&view=diff
==============================================================================
--- lucene/dev/branches/lucene6487/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWideSouthRectangle.java (original)
+++ lucene/dev/branches/lucene6487/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWideSouthRectangle.java Wed May 27 04:54:50 2015
@@ -23,7 +23,7 @@ package org.apache.lucene.spatial.spatia
  *
  * @lucene.internal
  */
-public class GeoWideSouthRectangle extends GeoBBoxBase {
+public class GeoWideSouthRectangle extends GeoBaseBBox {
   public final double topLat;
   public final double leftLon;
   public final double rightLon;
@@ -45,13 +45,14 @@ public class GeoWideSouthRectangle exten
 
   public final EitherBound eitherBound;
 
-  public final GeoPoint[] edgePoints = new GeoPoint[]{SOUTH_POLE};
+  public final GeoPoint[] edgePoints;
 
   /**
    * Accepts only values in the following ranges: lat: {@code -PI/2 -> PI/2}, lon: {@code -PI -> PI}.
    * Horizontal angle must be greater than or equal to PI.
    */
-  public GeoWideSouthRectangle(final double topLat, final double leftLon, double rightLon) {
+  public GeoWideSouthRectangle(final PlanetModel planetModel, final double topLat, final double leftLon, double rightLon) {
+    super(planetModel);
     // Argument checking
     if (topLat > Math.PI * 0.5 || topLat < -Math.PI * 0.5)
       throw new IllegalArgumentException("Top latitude out of range");
@@ -78,8 +79,8 @@ public class GeoWideSouthRectangle exten
     final double cosRightLon = Math.cos(rightLon);
 
     // Now build the four points
-    this.ULHC = new GeoPoint(sinTopLat, sinLeftLon, cosTopLat, cosLeftLon);
-    this.URHC = new GeoPoint(sinTopLat, sinRightLon, cosTopLat, cosRightLon);
+    this.ULHC = new GeoPoint(planetModel, sinTopLat, sinLeftLon, cosTopLat, cosLeftLon);
+    this.URHC = new GeoPoint(planetModel, sinTopLat, sinRightLon, cosTopLat, cosRightLon);
 
     final double middleLat = (topLat - Math.PI * 0.5) * 0.5;
     final double sinMiddleLat = Math.sin(middleLat);
@@ -92,17 +93,19 @@ public class GeoWideSouthRectangle exten
     final double sinMiddleLon = Math.sin(middleLon);
     final double cosMiddleLon = Math.cos(middleLon);
 
-    this.centerPoint = new GeoPoint(sinMiddleLat, sinMiddleLon, cosMiddleLat, cosMiddleLon);
+    this.centerPoint = new GeoPoint(planetModel, sinMiddleLat, sinMiddleLon, cosMiddleLat, cosMiddleLon);
 
-    this.topPlane = new SidedPlane(centerPoint, sinTopLat);
+    this.topPlane = new SidedPlane(centerPoint, planetModel, sinTopLat);
     this.leftPlane = new SidedPlane(centerPoint, cosLeftLon, sinLeftLon);
     this.rightPlane = new SidedPlane(centerPoint, cosRightLon, sinRightLon);
 
     this.topPlanePoints = new GeoPoint[]{ULHC, URHC};
-    this.leftPlanePoints = new GeoPoint[]{ULHC, SOUTH_POLE};
-    this.rightPlanePoints = new GeoPoint[]{URHC, SOUTH_POLE};
+    this.leftPlanePoints = new GeoPoint[]{ULHC, planetModel.SOUTH_POLE};
+    this.rightPlanePoints = new GeoPoint[]{URHC, planetModel.SOUTH_POLE};
 
     this.eitherBound = new EitherBound();
+    
+    this.edgePoints = new GeoPoint[]{planetModel.SOUTH_POLE};
   }
 
   @Override
@@ -119,7 +122,7 @@ public class GeoWideSouthRectangle exten
       newLeftLon = -Math.PI;
       newRightLon = Math.PI;
     }
-    return GeoBBoxFactory.makeGeoBBox(newTopLat, newBottomLat, newLeftLon, newRightLon);
+    return GeoBBoxFactory.makeGeoBBox(planetModel, newTopLat, newBottomLat, newLeftLon, newRightLon);
   }
 
   @Override
@@ -165,9 +168,9 @@ public class GeoWideSouthRectangle exten
   public boolean intersects(final Plane p, final GeoPoint[] notablePoints, final Membership... bounds) {
     // Right and left bounds are essentially independent hemispheres; crossing into the wrong part of one
     // requires crossing into the right part of the other.  So intersection can ignore the left/right bounds.
-    return p.intersects(topPlane, notablePoints, topPlanePoints, bounds, eitherBound) ||
-        p.intersects(leftPlane, notablePoints, leftPlanePoints, bounds, topPlane) ||
-        p.intersects(rightPlane, notablePoints, rightPlanePoints, bounds, topPlane);
+    return p.intersects(planetModel, topPlane, notablePoints, topPlanePoints, bounds, eitherBound) ||
+        p.intersects(planetModel, leftPlane, notablePoints, leftPlanePoints, bounds, topPlane) ||
+        p.intersects(planetModel, rightPlane, notablePoints, rightPlanePoints, bounds, topPlane);
   }
 
   /**
@@ -197,7 +200,7 @@ public class GeoWideSouthRectangle exten
       return OVERLAPS;
     }
 
-    final boolean insideShape = path.isWithin(SOUTH_POLE);
+    final boolean insideShape = path.isWithin(planetModel.SOUTH_POLE);
 
     if (insideRectangle == ALL_INSIDE && insideShape) {
       //System.err.println(" both inside each other");
@@ -230,19 +233,20 @@ public class GeoWideSouthRectangle exten
     if (!(o instanceof GeoWideSouthRectangle))
       return false;
     GeoWideSouthRectangle other = (GeoWideSouthRectangle) o;
-    return other.ULHC.equals(ULHC) && other.URHC.equals(URHC);
+    return super.equals(other) && other.ULHC.equals(ULHC) && other.URHC.equals(URHC);
   }
 
   @Override
   public int hashCode() {
-    int result = ULHC.hashCode();
+    int result = super.hashCode();
+    result = 31 * result + ULHC.hashCode();
     result = 31 * result + URHC.hashCode();
     return result;
   }
 
   @Override
   public String toString() {
-    return "GeoWideSouthRectangle: {toplat=" + topLat + "(" + topLat * 180.0 / Math.PI + "), leftlon=" + leftLon + "(" + leftLon * 180.0 / Math.PI + "), rightlon=" + rightLon + "(" + rightLon * 180.0 / Math.PI + ")}";
+    return "GeoWideSouthRectangle: {planetmodel="+planetModel+", toplat=" + topLat + "(" + topLat * 180.0 / Math.PI + "), leftlon=" + leftLon + "(" + leftLon * 180.0 / Math.PI + "), rightlon=" + rightLon + "(" + rightLon * 180.0 / Math.PI + ")}";
   }
 
   protected class EitherBound implements Membership {

Modified: lucene/dev/branches/lucene6487/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWorld.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6487/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWorld.java?rev=1681907&r1=1681906&r2=1681907&view=diff
==============================================================================
--- lucene/dev/branches/lucene6487/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWorld.java (original)
+++ lucene/dev/branches/lucene6487/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/GeoWorld.java Wed May 27 04:54:50 2015
@@ -22,11 +22,13 @@ package org.apache.lucene.spatial.spatia
  *
  * @lucene.internal
  */
-public class GeoWorld extends GeoBBoxBase {
-  protected final static GeoPoint originPoint = new GeoPoint(1.0, 0.0, 0.0);
+public class GeoWorld extends GeoBaseBBox {
   protected final static GeoPoint[] edgePoints = new GeoPoint[0];
-
-  public GeoWorld() {
+  protected final GeoPoint originPoint;
+  
+  public GeoWorld(final PlanetModel planetModel) {
+    super(planetModel);
+    originPoint = new GeoPoint(planetModel.ab, 1.0, 0.0, 0.0);
   }
 
   @Override
@@ -100,16 +102,16 @@ public class GeoWorld extends GeoBBoxBas
   public boolean equals(Object o) {
     if (!(o instanceof GeoWorld))
       return false;
-    return true;
+    return super.equals(o);
   }
 
   @Override
   public int hashCode() {
-    return 0;
+    return super.hashCode();
   }
 
   @Override
   public String toString() {
-    return "GeoWorld";
+    return "GeoWorld: {planetmodel="+planetModel+"}";
   }
 }