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 [3/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/Plane.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6487/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/Plane.java?rev=1681907&r1=1681906&r2=1681907&view=diff
==============================================================================
--- lucene/dev/branches/lucene6487/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/Plane.java (original)
+++ lucene/dev/branches/lucene6487/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/Plane.java Wed May 27 04:54:50 2015
@@ -51,11 +51,12 @@ public class Plane extends Vector {
   /**
    * Construct a horizontal plane at a specified Z.
    *
-   * @param height is the specified Z coordinate.
+   * @param planetModel is the planet model.
+   * @param sinLat is the sin(latitude).
    */
-  public Plane(final double height) {
+  public Plane(final PlanetModel planetModel, final double sinLat) {
     super(0.0, 0.0, 1.0);
-    D = -height;
+    D = -sinLat * computeMagnitude(planetModel, sinLat);
   }
 
   /**
@@ -81,6 +82,15 @@ public class Plane extends Vector {
     this.D = D;
   }
 
+  /** Construct a normalized, vertical plane through an x-y point.  If the x-y point is at (0,0), return null.
+  */
+  public static Plane constructNormalizedVerticalPlane(final double x, final double y) {
+    if (Math.abs(x) < MINIMUM_RESOLUTION && Math.abs(y) < MINIMUM_RESOLUTION)
+      return null;
+    final double denom = 1.0 / Math.sqrt(x*x + y*y);
+    return new Plane(x * denom, y * denom);
+  }
+  
   /**
    * Evaluate the plane equation for a given point, as represented
    * by a vector.
@@ -290,14 +300,26 @@ public class Plane extends Vector {
   }
 
   /**
+   * Public version of findIntersections.
+   */
+  public GeoPoint[] findIntersections(final PlanetModel planetModel, final Plane q, final Membership... bounds) {
+    if (isNumericallyIdentical(q)) {
+      return null;
+    }
+    return findIntersections(planetModel, q, bounds, NO_BOUNDS);
+  }
+  
+  /**
    * Find the intersection points between two planes, given a set of bounds.
    *
+   * @param planetModel is the planet model to use in finding points.
    * @param q          is the plane to intersect with.
    * @param bounds     is the set of bounds.
    * @param moreBounds is another set of bounds.
    * @return the intersection point(s) on the unit sphere, if there are any.
    */
-  protected GeoPoint[] findIntersections(final Plane q, final Membership[] bounds, final Membership[] moreBounds) {
+  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);
     if (Math.abs(lineVector.x) < MINIMUM_RESOLUTION && Math.abs(lineVector.y) < MINIMUM_RESOLUTION && Math.abs(lineVector.z) < MINIMUM_RESOLUTION) {
       // Degenerate case: parallel planes
@@ -363,16 +385,18 @@ public class Plane extends Vector {
       z0 = 0.0;
     }
 
-    // Once an intersecting line is determined, the next step is to intersect that line with the unit sphere, which
+    // Once an intersecting line is determined, the next step is to intersect that line with the ellipsoid, which
     // will yield zero, one, or two points.
-    // The equation of the sphere is: 1.0 = x^2 + y^2 + z^2.  Plugging in the parameterized line values yields:
-    // 1.0 = (At+A0)^2 + (Bt+B0)^2 + (Ct+C0)^2
-    // A^2 t^2 + 2AA0t + A0^2 + B^2 t^2 + 2BB0t + B0^2 + C^2 t^2 + 2CC0t + C0^2 - 1,0 = 0.0
-    // [A^2 + B^2 + C^2] t^2 + [2AA0 + 2BB0 + 2CC0] t + [A0^2 + B0^2 + C0^2 - 1,0] = 0.0
+    // The ellipsoid equation: 1,0 = x^2/a^2 + y^2/b^2 + z^2/c^2
+    // 1.0 = (At+A0)^2/a^2 + (Bt+B0)^2/b^2 + (Ct+C0)^2/c^2
+    // A^2 t^2 / a^2 + 2AA0t / a^2 + A0^2 / a^2 + B^2 t^2 / b^2 + 2BB0t / b^2 + B0^2 / b^2 + C^2 t^2 / c^2 + 2CC0t / c^2 + C0^2 / c^2  - 1,0 = 0.0
+    // [A^2 / a^2 + B^2 / b^2 + C^2 / c^2] t^2 + [2AA0 / a^2 + 2BB0 / b^2 + 2CC0 / c^2] t + [A0^2 / a^2 + B0^2 / b^2 + C0^2 / c^2 - 1,0] = 0.0
     // Use the quadratic formula to determine t values and candidate point(s)
-    final double A = lineVector.x * lineVector.x + lineVector.y * lineVector.y + lineVector.z * lineVector.z;
-    final double B = 2.0 * (lineVector.x * x0 + lineVector.y * y0 + lineVector.z * z0);
-    final double C = x0 * x0 + y0 * y0 + z0 * z0 - 1.0;
+    final double A = lineVector.x * lineVector.x * planetModel.inverseAbSquared +
+      lineVector.y * lineVector.y * planetModel.inverseAbSquared +
+      lineVector.z * lineVector.z * planetModel.inverseCSquared;
+    final double B = 2.0 * (lineVector.x * x0 * planetModel.inverseAbSquared + lineVector.y * y0 * planetModel.inverseAbSquared + lineVector.z * z0 * planetModel.inverseCSquared);
+    final double C = x0 * x0 * planetModel.inverseAbSquared + y0 * y0 * planetModel.inverseAbSquared + z0 * z0 * planetModel.inverseCSquared - 1.0;
 
     final double BsquaredMinus = B * B - 4.0 * A * C;
     if (Math.abs(BsquaredMinus) < MINIMUM_RESOLUTION_SQUARED) {
@@ -381,6 +405,8 @@ public class Plane extends Vector {
       // One solution only
       final double t = -B * inverse2A;
       GeoPoint point = new GeoPoint(lineVector.x * t + x0, lineVector.y * t + y0, lineVector.z * t + z0);
+      //System.err.println("  point: "+point);
+      //verifyPoint(planetModel, point, q);
       if (point.isWithin(bounds, moreBounds))
         return new GeoPoint[]{point};
       return NO_POINTS;
@@ -393,6 +419,8 @@ public class Plane extends Vector {
       final double t2 = (-B - sqrtTerm) * inverse2A;
       GeoPoint point1 = new GeoPoint(lineVector.x * t1 + x0, lineVector.y * t1 + y0, lineVector.z * t1 + z0);
       GeoPoint point2 = new GeoPoint(lineVector.x * t2 + x0, lineVector.y * t2 + y0, lineVector.z * t2 + z0);
+      //verifyPoint(planetModel, point1, q);
+      //verifyPoint(planetModel, point2, q);
       //System.err.println("  "+point1+" and "+point2);
       if (point1.isWithin(bounds, moreBounds)) {
         if (point2.isWithin(bounds, moreBounds))
@@ -408,18 +436,30 @@ public class Plane extends Vector {
     }
   }
 
+  /*
+  protected void verifyPoint(final PlanetModel planetModel, final GeoPoint point, final Plane q) {
+    if (!evaluateIsZero(point))
+      throw new RuntimeException("Intersection point not on original plane; point="+point+", plane="+this);
+    if (!q.evaluateIsZero(point))
+      throw new RuntimeException("Intersection point not on intersected plane; point="+point+", plane="+q);
+    if (Math.abs(point.x * point.x * planetModel.inverseASquared + point.y * point.y * planetModel.inverseBSquared + point.z * point.z * planetModel.inverseCSquared - 1.0) >= MINIMUM_RESOLUTION) 
+      throw new RuntimeException("Intersection point not on ellipsoid; point="+point);
+  }
+  */
+  
   /**
    * Accumulate bounds information for this plane, intersected with another plane
    * and with the unit sphere.
    * Updates both latitude and longitude information, using max/min points found
    * within the specified bounds.
    *
+   * @param planetModel is the planet model to use to determine bounding points
    * @param q          is the plane to intersect with.
    * @param boundsInfo is the info to update with additional bounding information.
    * @param bounds     are the surfaces delineating what's inside the shape.
    */
-  public void recordBounds(final Plane q, final Bounds boundsInfo, final Membership... bounds) {
-    final GeoPoint[] intersectionPoints = findIntersections(q, bounds, NO_BOUNDS);
+  public void recordBounds(final PlanetModel planetModel, final Plane q, final Bounds boundsInfo, final Membership... bounds) {
+    final GeoPoint[] intersectionPoints = findIntersections(planetModel, q, bounds, NO_BOUNDS);
     for (GeoPoint intersectionPoint : intersectionPoints) {
       boundsInfo.addPoint(intersectionPoint);
     }
@@ -430,10 +470,11 @@ public class Plane extends Vector {
    * Updates both latitude and longitude information, using max/min points found
    * within the specified bounds.
    *
+   * @param planetModel is the planet model to use in determining bounds.
    * @param boundsInfo is the info to update with additional bounding information.
    * @param bounds     are the surfaces delineating what's inside the shape.
    */
-  public void recordBounds(final Bounds boundsInfo, final Membership... bounds) {
+  public void recordBounds(final PlanetModel planetModel, final Bounds boundsInfo, final Membership... bounds) {
     // For clarity, load local variables with good names
     final double A = this.x;
     final double B = this.y;
@@ -442,236 +483,27 @@ public class Plane extends Vector {
     // Now compute latitude min/max points
     if (!boundsInfo.checkNoTopLatitudeBound() || !boundsInfo.checkNoBottomLatitudeBound()) {
       //System.err.println("Looking at latitude for plane "+this);
+      // With ellipsoids, we really have only one viable way to do this computation.
+      // Specifically, we compute an appropriate vertical plane, based on the current plane's x-y orientation, and
+      // then intersect it with this one and with the ellipsoid.  This gives us zero, one, or two points to use
+      // as bounds.
+      // There is one special case: horizontal circles.  These require TWO vertical planes: one for the x, and one for
+      // the y, and we use all four resulting points in the bounds computation.
       if ((Math.abs(A) >= MINIMUM_RESOLUTION || Math.abs(B) >= MINIMUM_RESOLUTION)) {
-        //System.out.println("A = "+A+" B = "+B+" C = "+C+" D = "+D);
-        // sin (phi) = z
-        // cos (theta - phi) = D
-        // sin (theta) = C  (the dot product of (0,0,1) and (A,B,C) )
-        // Q: what is z?
-        //
-        // cos (theta-phi) = cos(theta)cos(phi) + sin(theta)sin(phi) = D
-
-        if (Math.abs(C) < MINIMUM_RESOLUTION) {
-          // Special case: circle is vertical.
-          //System.err.println(" Degenerate case; it's vertical circle");
-          // cos(phi) = D, and we want sin(phi) = z
-          // There are two solutions for phi given cos(phi) = D: a positive solution and a negative solution.
-          // So, when we compute z = sqrt(1-D^2), it's really z = +/- sqrt(1-D^2) .
-
-          double z;
-          double x;
-          double y;
-
-          final double denom = 1.0 / (A * A + B * B);
-
-          z = Math.sqrt(1.0 - D * D);
-          y = -B * D * denom;
-          x = -A * D * denom;
-          addPoint(boundsInfo, bounds, x, y, z);
-
-          z = -z;
-          addPoint(boundsInfo, bounds, x, y, z);
-        } else if (Math.abs(D) < MINIMUM_RESOLUTION) {
-          //System.err.println(" Plane through origin case");
-          // The general case is degenerate when the plane goes through the origin.
-          // Luckily there's a pretty good way to figure out the max and min for that case though.
-          // We find the two z values by computing the angle of the plane's inclination with the normal.
-          // E.g., if this.z == 1, then our z value is 0, and if this.z == 0, our z value is 1.
-          // Also if this.z == -1, then z value is 0 again.
-          // Another way of putting this is that our z = sqrt(this.x^2 + this.y^2).
-          //
-          // The only tricky part is computing x and y.
-          double z;
-          double x;
-          double y;
-
-          final double denom = 1.0 / (A * A + B * B);
-
-          z = Math.sqrt((A * A + B * B) / (A * A + B * B + C * C));
-          y = -B * (C * z) * denom;
-          x = -A * (C * z) * denom;
-          addPoint(boundsInfo, bounds, x, y, z);
-
-          z = -z;
-          y = -B * (C * z) * denom;
-          x = -A * (C * z) * denom;
-          addPoint(boundsInfo, bounds, x, y, z);
-
-        } else {
-          //System.err.println(" General latitude case");
-          // We might be able to identify a specific new latitude maximum or minimum.
-          //
-          // cos (theta-phi) = cos(theta)cos(phi) + sin(theta)sin(phi) = D
-          //
-          // This is tricky.  If cos(phi) = something, and we want to figure out
-          // what sin(phi) is, in order to capture all solutions we need to recognize
-          // that sin(phi) = +/- sqrt(1 - cos(phi)^2).  Basically, this means that
-          // whatever solution we find we have to mirror it across the x-y plane,
-          // and include both +z and -z solutions.
-          //
-          // cos (phi) = +/- sqrt(1-sin(phi)^2) = +/- sqrt(1-z^2)
-          // cos (theta) = +/- sqrt(1-sin(theta)^2) = +/- sqrt(1-C^2)
-          //
-          // D = cos(theta)cos(phi) + sin(theta)sin(phi)
-          // Substitute:
-          // D = sqrt(1-C^2) * sqrt(1-z^2) -/+ C * z
-          // Solve for z...
-          // D +/- Cz = sqrt(1-C^2)*sqrt(1-z^2) = sqrt(1 - z^2 - C^2 + z^2*C^2)
-          // Square both sides.
-          // (D +/- Cz)^2 = 1 - z^2 - C^2 + z^2*C^2
-          // D^2 +/- 2DCz + C^2*z^2 = 1 - z^2 - C^2 + z^2*C^2
-          // D^2 +/- 2DCz  = 1 - C^2 - z^2
-          // 0 = z^2 +/- 2DCz + (C^2 +D^2-1) = 0
-          //
-          // z = (+/- 2DC +/- sqrt(4*D^2*C^2 - 4*(C^2+D^2-1))) / (2)
-          // z  = +/- DC +/- sqrt(D^2*C^2 + 1 - C^2 - D^2 )
-          //    = +/- DC +/- sqrt(D^2*C^2 + 1 - C^2 - D^2)
-          //
-          // NOTE WELL: The above is clearly degenerate when D = 0.  So we'll have to
-          // code a different solution for that case!
-
-          // To get x and y, we need to plug z into the equations, as follows:
-          //
-          // Ax + By = -Cz - D
-          // x^2 + y^2 = 1 - z^2
-          //
-          // x = (-Cz -D -By) /A
-          // y = (-Cz -D -Ax) /B
-          //
-          // [(-Cz -D -By) /A]^2 + y^2 = 1 - z^2
-          // [-Cz -D -By]^2 + A^2*y^2 = A^2 - A^2*z^2
-          // C^2*z^2 + D^2 + B^2*y^2 + 2CDz + 2CBzy + 2DBy + A^2*y^2 - A^2 + A^2*z^2 = 0
-          // y^2 [A^2 + B^2]  + y [2DB + 2CBz] + [C^2*z^2 + D^2 + 2CDz - A^2 + A^2*z^2] = 0
-          //
-          //
-          // Use quadratic formula, where:
-          // a = [A^2 + B^2]
-          // b = [2BD + 2CBz]
-          // c = [C^2*z^2 + D^2 + 2CDz - A^2 + A^2*z^2]
-          //
-          // y = (-[2BD + 2CBz] +/- sqrt([2BD + 2CBz]^2 - 4 * [A^2 + B^2] * [C^2*z^2 + D^2 + 2CDz - A^2 + A^2*z^2]) ) / (2 * [A^2 + B^2])
-          // Take out a 2:
-          // y = (-[DB +CBz] +/- sqrt([DB + CBz]^2 - [A^2 + B^2] * [C^2*z^2 + D^2 + 2CDz - A^2 + A^2*z^2]) ) / [A^2 + B^2]
-          //
-          // The sqrt term simplifies:
-          //
-          // B^2*D^2 + C^2*B^2*z^2 + 2C*D*B^2*z - [A^2 + B^2] * [C^2*z^2 + D^2 + 2CDz - A^2 + A^2*z^2] = ?
-          // B^2*D^2 + C^2*B^2*z^2 + 2C*D*B^2*z - [A^2 * C^2 * z^2 + A^2 * D^2 + 2 * A^2 * CDz - A^4 + A^4*z^2
-          //                  + B^2 * C^2 * z^2 + B^2 * D^2 + 2 * B^2 * CDz - A^2 * B^2 + B^2 * A^2 * z^2] =?
-          // C^2*B^2*z^2 + 2C*D*B^2*z - [A^2 * C^2 * z^2 + A^2 * D^2 + 2 * A^2 * CDz - A^4 + A^4*z^2
-          //                  + B^2 * C^2 * z^2 + 2 * B^2 * CDz - A^2 * B^2 + B^2 * A^2 * z^2] =?
-          // 2C*D*B^2*z - [A^2 * C^2 * z^2 + A^2 * D^2 + 2 * A^2 * CDz - A^4 + A^4*z^2
-          //                  + 2 * B^2 * CDz - A^2 * B^2 + B^2 * A^2 * z^2] =?
-          // - [A^2 * C^2 * z^2 + A^2 * D^2 + 2 * A^2 * CDz - A^4 + A^4*z^2
-          //                  - A^2 * B^2 + B^2 * A^2 * z^2] =?
-          // - A^2 * [C^2 * z^2 + D^2 + 2 * CDz - A^2 + A^2*z^2
-          //                  - B^2 + B^2 * z^2] =?
-          // - A^2 * [z^2[A^2 + B^2 + C^2] - [A^2 + B^2 - D^2] + 2CDz] =?
-          // - A^2 * [z^2 - [A^2 + B^2 - D^2] + 2CDz] =?
-          //
-          // y = (-[DB +CBz] +/- A*sqrt([A^2 + B^2 - D^2] - z^2 - 2CDz) ) / [A^2 + B^2]
-          //
-          // correspondingly:
-          // x = (-[DA +CAz] +/- B*sqrt([A^2 + B^2 - D^2] - z^2 - 2CDz) ) / [A^2 + B^2]
-          //
-          // However, for the maximum or minimum we seek, the clause inside the sqrt should be zero.  If
-          // it is NOT zero, then we aren't looking at the right z value.
-
-          double z;
-          double x;
-          double y;
-
-          double sqrtValue = D * D * C * C + 1.0 - C * C - D * D;
-          double denom = 1.0 / (A * A + B * B);
-          if (Math.abs(sqrtValue) < MINIMUM_RESOLUTION_SQUARED) {
-            //System.err.println(" One latitude solution");
-            double insideValue;
-            double sqrtTerm;
-
-            z = D * C;
-            // Since we squared both sides of the equation, we may have introduced spurious solutions, so we have to check.
-            // But the same check applies to BOTH solutions -- the +z one as well as the -z one.
-            insideValue = A * A + B * B - D * D - z * z - 2.0 * C * D * z;
-            if (Math.abs(insideValue) < MINIMUM_RESOLUTION) {
-              y = -B * (D + C * z) * denom;
-              x = -A * (D + C * z) * denom;
-              if (evaluateIsZero(x, y, z)) {
-                addPoint(boundsInfo, bounds, x, y, z);
-              }
-            }
-            // Check the solution on the other side of the x-y plane
-            z = -z;
-            insideValue = A * A + B * B - D * D - z * z - 2.0 * C * D * z;
-            if (Math.abs(insideValue) < MINIMUM_RESOLUTION) {
-              y = -B * (D + C * z) * denom;
-              x = -A * (D + C * z) * denom;
-              if (evaluateIsZero(x, y, z)) {
-                addPoint(boundsInfo, bounds, x, y, z);
-              }
-            }
-          } else if (sqrtValue > 0.0) {
-            //System.err.println(" Two latitude solutions");
-            double sqrtResult = Math.sqrt(sqrtValue);
-
-            double insideValue;
-            double sqrtTerm;
-
-            z = D * C + sqrtResult;
-            //System.out.println("z= "+z+" D-C*z = " + (D-C*z) + " Math.sqrt(1.0 - z*z - C*C + z*z*C*C) = "+(Math.sqrt(1.0 - z*z - C*C + z*z*C*C)));
-            // Since we squared both sides of the equation, we may have introduced spurios solutions, so we have to check.
-            // But the same check applies to BOTH solutions -- the +z one as well as the -z one.
-            insideValue = A * A + B * B - D * D - z * z - 2.0 * C * D * z;
-            //System.err.println(" z="+z+" C="+C+" D="+D+" inside value "+insideValue);
-            if (Math.abs(insideValue) < MINIMUM_RESOLUTION) {
-              y = -B * (D + C * z) * denom;
-              x = -A * (D + C * z) * denom;
-              if (evaluateIsZero(x, y, z)) {
-                addPoint(boundsInfo, bounds, x, y, z);
-              }
-            }
-            // Check the solution on the other side of the x-y plane
-            z = -z;
-            insideValue = A * A + B * B - D * D - z * z - 2.0 * C * D * z;
-            //System.err.println(" z="+z+" C="+C+" D="+D+" inside value "+insideValue);
-            if (Math.abs(insideValue) < MINIMUM_RESOLUTION) {
-              y = -B * (D + C * z) * denom;
-              x = -A * (D + C * z) * denom;
-              if (evaluateIsZero(x, y, z)) {
-                addPoint(boundsInfo, bounds, x, y, z);
-              }
-            }
-            z = D * C - sqrtResult;
-            //System.out.println("z= "+z+" D-C*z = " + (D-C*z) + " Math.sqrt(1.0 - z*z - C*C + z*z*C*C) = "+(Math.sqrt(1.0 - z*z - C*C + z*z*C*C)));
-            // Since we squared both sides of the equation, we may have introduced spurios solutions, so we have to check.
-            // But the same check applies to BOTH solutions -- the +z one as well as the -z one.
-            insideValue = A * A + B * B - D * D - z * z - 2.0 * C * D * z;
-            //System.err.println(" z="+z+" C="+C+" D="+D+" inside value "+insideValue);
-            if (Math.abs(insideValue) < MINIMUM_RESOLUTION) {
-              y = -B * (D + C * z) * denom;
-              x = -A * (D + C * z) * denom;
-              if (evaluateIsZero(x, y, z)) {
-                addPoint(boundsInfo, bounds, x, y, z);
-              }
-            }
-            // Check the solution on the other side of the x-y plane
-            z = -z;
-            insideValue = A * A + B * B - D * D - z * z - 2.0 * C * D * z;
-            //System.err.println(" z="+z+" C="+C+" D="+D+" inside value "+insideValue);
-            if (Math.abs(insideValue) < MINIMUM_RESOLUTION) {
-              y = -B * (D + C * z) * denom;
-              x = -A * (D + C * z) * denom;
-              if (evaluateIsZero(x, y, z)) {
-                addPoint(boundsInfo, bounds, x, y, z);
-              }
-            }
-          }
+        // NOT a horizontal circle!
+        //System.err.println(" Not a horizontal circle");
+        final Plane verticalPlane = constructNormalizedVerticalPlane(A,B);
+        final GeoPoint[] points = findIntersections(planetModel, verticalPlane, NO_BOUNDS, NO_BOUNDS);
+        for (final GeoPoint point : points) {
+          addPoint(boundsInfo, bounds, point.x, point.y, point.z);
         }
       } else {
-        // Horizontal circle.
-        // Since the recordBounds() method will be called ONLY for planes that constitute edges of a shape,
-        // we can be sure that some part of the horizontal circle will be part of the boundary, so we don't need
-        // to check Membership objects.
-        boundsInfo.addHorizontalCircle(-D * C);
+        // Horizontal circle.  Since a==b, one vertical plane suffices.
+        final Plane verticalPlane = new Plane(1.0,0.0);
+        final GeoPoint[] points = findIntersections(planetModel, verticalPlane, NO_BOUNDS, NO_BOUNDS);
+        // There will always be two points; we only need one.
+        final GeoPoint point = points[0];
+        boundsInfo.addHorizontalCircle(point.z/Math.sqrt(point.x * point.x + point.y * point.y + point.z * point.z));
       }
       //System.err.println("Done latitude bounds");
     }
@@ -697,8 +529,8 @@ public class Plane extends Vector {
             // Geometrically, we have a line segment in x-y space.  We need to locate the endpoints
             // of that line.  But luckily, we know some things: specifically, since it is a
             // degenerate situation in projection, the C value had to have been 0.  That
-            // means that our line's endpoints will coincide with the unit circle.  All we
-            // need to do then is to find the intersection of the unit circle and the line
+            // means that our line's endpoints will coincide with the projected ellipse.  All we
+            // need to do then is to find the intersection of the projected ellipse and the line
             // equation:
             //
             // A x + B y + D = 0
@@ -706,20 +538,20 @@ public class Plane extends Vector {
             // Since A != 0:
             // x = (-By - D)/A
             //
-            // The unit circle:
-            // x^2 + y^2 - 1 = 0
+            // The projected ellipse:
+            // x^2/a^2 + y^2/b^2 - 1 = 0
             // Substitute:
-            // [(-By-D)/A]^2 + y^2 -1 = 0
+            // [(-By-D)/A]^2/a^2 + y^2/b^2 -1 = 0
             // Multiply through by A^2:
-            // [-By - D]^2 + A^2*y^2 - A^2 = 0
+            // [-By - D]^2/a^2 + A^2*y^2/b^2 - A^2 = 0
             // Multiply out:
-            // B^2*y^2 + 2BDy + D^2 + A^2*y^2 - A^2 = 0
+            // B^2*y^2/a^2 + 2BDy/a^2 + D^2/a^2 + A^2*y^2/b^2 - A^2 = 0
             // Group:
-            // y^2 * [B^2 + A^2] + y [2BD] + [D^2-A^2] = 0
+            // y^2 * [B^2/a^2 + A^2/b^2] + y [2BD/a^2] + [D^2/a^2-A^2] = 0
 
-            a = B * B + A * A;
-            b = 2.0 * B * D;
-            c = D * D - A * A;
+            a = B * B * planetModel.inverseAbSquared + A * A * planetModel.inverseAbSquared;
+            b = 2.0 * B * D * planetModel.inverseAbSquared;
+            c = D * D * planetModel.inverseAbSquared - A * A;
 
             double sqrtClause = b * b - 4.0 * a * c;
 
@@ -750,9 +582,9 @@ public class Plane extends Vector {
             // Use equation suitable for B != 0
             // Since I != 0, we rewrite:
             // y = (-Ax - D)/B
-            a = B * B + A * A;
-            b = 2.0 * A * D;
-            c = D * D - B * B;
+            a = B * B * planetModel.inverseAbSquared + A * A * planetModel.inverseAbSquared;
+            b = 2.0 * A * D * planetModel.inverseAbSquared;
+            c = D * D * planetModel.inverseAbSquared - B * B;
 
             double sqrtClause = b * b - 4.0 * a * c;
 
@@ -786,25 +618,25 @@ public class Plane extends Vector {
         // They are for lat/lon calculation purposes only.  x-y is meant to be used for longitude determination,
         // and z for latitude, and that's all the values are good for.
 
-        // (1) Intersect the plane and the unit sphere, and project the results into the x-y plane:
+        // (1) Intersect the plane and the ellipsoid, and project the results into the x-y plane:
         // From plane:
         // z = (-Ax - By - D) / C
-        // From unit sphere:
-        // x^2 + y^2 + [(-Ax - By - D) / C]^2 = 1
+        // From ellipsoid:
+        // x^2/a^2 + y^2/b^2 + [(-Ax - By - D) / C]^2/c^2 = 1
         // Simplify/expand:
-        // C^2*x^2 + C^2*y^2 + (-Ax - By - D)^2 = C^2
+        // C^2*x^2/a^2 + C^2*y^2/b^2 + (-Ax - By - D)^2/c^2 = C^2
         //
-        // x^2 * C^2 + y^2 * C^2 + x^2 * (A^2 + ABxy + ADx) + (ABxy + y^2 * B^2 + BDy) + (ADx + BDy + D^2) = C^2
+        // x^2 * C^2/a^2 + y^2 * C^2/b^2 + x^2 * A^2/c^2 + ABxy/c^2 + ADx/c^2 + ABxy/c^2 + y^2 * B^2/c^2 + BDy/c^2 + ADx/c^2 + BDy/c^2 + D^2/c^2 = C^2
         // Group:
-        // [A^2 + C^2] x^2 + [B^2 + C^2] y^2 + [2AB]xy + [2AD]x + [2BD]y + [D^2-C^2] = 0
+        // [A^2/c^2 + C^2/a^2] x^2 + [B^2/c^2 + C^2/b^2] y^2 + [2AB/c^2]xy + [2AD/c^2]x + [2BD/c^2]y + [D^2/c^2-C^2] = 0
         // For convenience, introduce post-projection coefficient variables to make life easier.
         // E x^2 + F y^2 + G xy + H x + I y + J = 0
-        double E = A * A + C * C;
-        double F = B * B + C * C;
-        double G = 2.0 * A * B;
-        double H = 2.0 * A * D;
-        double I = 2.0 * B * D;
-        double J = D * D - C * C;
+        double E = A * A * planetModel.inverseCSquared + C * C * planetModel.inverseAbSquared;
+        double F = B * B * planetModel.inverseCSquared + C * C * planetModel.inverseAbSquared;
+        double G = 2.0 * A * B * planetModel.inverseCSquared;
+        double H = 2.0 * A * D * planetModel.inverseCSquared;
+        double I = 2.0 * B * D * planetModel.inverseCSquared;
+        double J = D * D * planetModel.inverseCSquared - C * C;
 
         //System.err.println("E = " + E + " F = " + F + " G = " + G + " H = "+ H + " I = " + I + " J = " + J);
 
@@ -962,6 +794,7 @@ public class Plane extends Vector {
    * Determine whether the plane intersects another plane within the
    * bounds provided.
    *
+   * @param planetModel is the planet model to use in determining intersection.
    * @param q                 is the other plane.
    * @param notablePoints     are points to look at to disambiguate cases when the two planes are identical.
    * @param moreNotablePoints are additional points to look at to disambiguate cases when the two planes are identical.
@@ -969,7 +802,7 @@ public class Plane extends Vector {
    * @param moreBounds        are more bounds.
    * @return true if there's an intersection.
    */
-  public boolean intersects(final Plane q, final GeoPoint[] notablePoints, final GeoPoint[] moreNotablePoints, final Membership[] bounds, final Membership... moreBounds) {
+  public boolean intersects(final PlanetModel planetModel, final Plane q, final GeoPoint[] notablePoints, final GeoPoint[] moreNotablePoints, final Membership[] bounds, final Membership... moreBounds) {
     //System.err.println("Does plane "+this+" intersect with plane "+q);
     // If the two planes are identical, then the math will find no points of intersection.
     // So a special case of this is to check for plane equality.  But that is not enough, because
@@ -994,7 +827,7 @@ public class Plane extends Vector {
       //System.err.println("  no notable points inside found; no intersection");
       return false;
     }
-    return findIntersections(q, bounds, moreBounds).length > 0;
+    return findIntersections(planetModel, q, bounds, moreBounds).length > 0;
   }
 
   /**
@@ -1042,8 +875,8 @@ public class Plane extends Vector {
   /**
    * Find a sample point on the intersection between two planes and the unit sphere.
    */
-  public GeoPoint getSampleIntersectionPoint(final Plane q) {
-    final GeoPoint[] intersections = findIntersections(q, NO_BOUNDS, NO_BOUNDS);
+  public GeoPoint getSampleIntersectionPoint(final PlanetModel planetModel, final Plane q) {
+    final GeoPoint[] intersections = findIntersections(planetModel, q, NO_BOUNDS, NO_BOUNDS);
     if (intersections.length == 0)
       return null;
     return intersections[0];

Added: lucene/dev/branches/lucene6487/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/PlanetModel.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6487/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/PlanetModel.java?rev=1681907&view=auto
==============================================================================
--- lucene/dev/branches/lucene6487/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/PlanetModel.java (added)
+++ lucene/dev/branches/lucene6487/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/PlanetModel.java Wed May 27 04:54:50 2015
@@ -0,0 +1,102 @@
+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.
+ */
+
+/**
+ * Holds mathematical constants associated with the model of a planet.
+ * @lucene.experimental
+ */
+public class PlanetModel {
+  
+  /** Planet model corresponding to sphere. */
+  public static final PlanetModel SPHERE = new PlanetModel(1.0,1.0);
+
+  /** Mean radius */
+  public static final double WGS84_MEAN = 6371009.0;
+  /** Polar radius */
+  public static final double WGS84_POLAR = 6356752.3;
+  /** Equatorial radius */
+  public static final double WGS84_EQUATORIAL = 6378137.0;
+  /** Planet model corresponding to WGS84 */
+  public static final PlanetModel WGS84 = new PlanetModel(WGS84_EQUATORIAL/WGS84_MEAN,
+    WGS84_POLAR/WGS84_MEAN);
+
+  // Surface of the planet:
+  // x^2/a^2 + y^2/b^2 + z^2/c^2 = 1.0
+  // Scaling factors are a,b,c.  geo3d can only support models where a==b, so use ab instead.
+  public final double ab;
+  public final double c;
+  public final double inverseAb;
+  public final double inverseC;
+  public final double inverseAbSquared;
+  public final double inverseCSquared;
+  // We do NOT include radius, because all computations in geo3d are in radians, not meters.
+  
+  // Compute north and south pole for planet model, since these are commonly used.
+  public final GeoPoint NORTH_POLE;
+  public final GeoPoint SOUTH_POLE;
+  
+  public PlanetModel(final double ab, final double c) {
+    this.ab = ab;
+    this.c = c;
+    this.inverseAb = 1.0 / ab;
+    this.inverseC = 1.0 / c;
+    this.inverseAbSquared = inverseAb * inverseAb;
+    this.inverseCSquared = inverseC * inverseC;
+    this.NORTH_POLE = new GeoPoint(c, 0.0, 0.0, 1.0);
+    this.SOUTH_POLE = new GeoPoint(c, 0.0, 0.0, -1.0);
+  }
+  
+  /** Find the minimum magnitude of all points on the ellipsoid.
+   */
+  public double getMinimumMagnitude() {
+    return Math.min(this.ab, this.c);
+  }
+
+  /** Find the maximum magnitude of all points on the ellipsoid.
+   */
+  public double getMaximumMagnitude() {
+    return Math.max(this.ab, this.c);
+  }
+  
+  @Override
+  public boolean equals(final Object o) {
+    if (!(o instanceof PlanetModel))
+      return false;
+    final PlanetModel other = (PlanetModel)o;
+    return ab == other.ab && c == other.c;
+  }
+  
+  @Override
+  public int hashCode() {
+    return Double.hashCode(ab) + Double.hashCode(c);
+  }
+  
+  @Override
+  public String toString() {
+    if (this.equals(SPHERE)) {
+      return "PlanetModel.SPHERE";
+    } else if (this.equals(WGS84)) {
+      return "PlanetModel.WGS84";
+    } else {
+      return "PlanetModel(ab="+ab+" c="+c+")";
+    }
+  }
+}
+
+

Modified: lucene/dev/branches/lucene6487/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/SidedPlane.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6487/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/SidedPlane.java?rev=1681907&r1=1681906&r2=1681907&view=diff
==============================================================================
--- lucene/dev/branches/lucene6487/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/SidedPlane.java (original)
+++ lucene/dev/branches/lucene6487/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/SidedPlane.java Wed May 27 04:54:50 2015
@@ -53,10 +53,11 @@ public class SidedPlane extends Plane im
    * Construct a sided plane from a point and a Z coordinate.
    *
    * @param p      point to evaluate.
-   * @param height is the Z coordinate of the plane.
+   * @param planetModel is the planet model.
+   * @param sinLat is the sin of the latitude of the plane.
    */
-  public SidedPlane(Vector p, double height) {
-    super(height);
+  public SidedPlane(Vector p, final PlanetModel planetModel, double sinLat) {
+    super(planetModel, sinLat);
     sigNum = Math.signum(evaluate(p));
   }
 
@@ -84,6 +85,28 @@ public class SidedPlane extends Plane im
     sigNum = Math.signum(evaluate(p));
   }
 
+  /** Construct a sided plane from two points and a third normal vector.
+   */
+  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();
+    // 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)
+      return null;
+    return new SidedPlane(insidePoint, planeNormal, -planeNormal.dotProduct(point2));
+  }
+
   /**
    * Check if a point is within this shape.
    *

Modified: lucene/dev/branches/lucene6487/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/Vector.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6487/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/Vector.java?rev=1681907&r1=1681906&r2=1681907&view=diff
==============================================================================
--- lucene/dev/branches/lucene6487/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/Vector.java (original)
+++ lucene/dev/branches/lucene6487/lucene/spatial/src/java/org/apache/lucene/spatial/spatial4j/geo3d/Vector.java Wed May 27 04:54:50 2015
@@ -114,14 +114,20 @@ public class Vector {
    */
   public boolean isWithin(final Membership[] bounds, final Membership[] moreBounds) {
     // Return true if the point described is within all provided bounds
+    //System.err.println("  checking if "+this+" is within bounds");
     for (Membership bound : bounds) {
-      if (bound != null && !bound.isWithin(this))
+      if (bound != null && !bound.isWithin(this)) {
+        //System.err.println("    NOT within "+bound);
         return false;
+      }
     }
     for (Membership bound : moreBounds) {
-      if (bound != null && !bound.isWithin(this))
+      if (bound != null && !bound.isWithin(this)) {
+        //System.err.println("    NOT within "+bound);
         return false;
+      }
     }
+    //System.err.println("    is within");
     return true;
   }
 
@@ -301,6 +307,20 @@ public class Vector {
     return Math.sqrt(x * x + y * y + z * z);
   }
 
+  /** Compute the magnitude of a vector projected to a given
+   * planet model.
+   */
+  protected static double computeMagnitude(final PlanetModel planetModel, final double x, final double y, final double z) {
+    return 1.0 / Math.sqrt(x*x*planetModel.inverseAbSquared + y*y*planetModel.inverseAbSquared + z*z*planetModel.inverseCSquared);
+  }
+
+  /** Compute the magnitude of a vector projected to a given
+   * planet model.
+   */
+  protected static double computeMagnitude(final PlanetModel planetModel, final double z) {
+    return 1.0 / Math.sqrt((1.0-z*z)*planetModel.inverseAbSquared + z*z*planetModel.inverseCSquared);
+  }
+  
   @Override
   public boolean equals(Object o) {
     if (!(o instanceof Vector))

Modified: lucene/dev/branches/lucene6487/lucene/spatial/src/test/org/apache/lucene/spatial/spatial4j/Geo3dRptTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6487/lucene/spatial/src/test/org/apache/lucene/spatial/spatial4j/Geo3dRptTest.java?rev=1681907&r1=1681906&r2=1681907&view=diff
==============================================================================
--- lucene/dev/branches/lucene6487/lucene/spatial/src/test/org/apache/lucene/spatial/spatial4j/Geo3dRptTest.java (original)
+++ lucene/dev/branches/lucene6487/lucene/spatial/src/test/org/apache/lucene/spatial/spatial4j/Geo3dRptTest.java Wed May 27 04:54:50 2015
@@ -39,6 +39,7 @@ import org.apache.lucene.spatial.spatial
 import org.apache.lucene.spatial.spatial4j.geo3d.GeoPoint;
 import org.apache.lucene.spatial.spatial4j.geo3d.GeoPolygonFactory;
 import org.apache.lucene.spatial.spatial4j.geo3d.GeoShape;
+import org.apache.lucene.spatial.spatial4j.geo3d.PlanetModel;
 import org.junit.Test;
 
 import static com.spatial4j.core.distance.DistanceUtils.DEGREES_TO_RADIANS;
@@ -81,12 +82,12 @@ public class Geo3dRptTest extends Random
   public void testFailure1() throws IOException {
     setupStrategy();
     final List<GeoPoint> points = new ArrayList<GeoPoint>();
-    points.add(new GeoPoint(18 * DEGREES_TO_RADIANS, -27 * DEGREES_TO_RADIANS));
-    points.add(new GeoPoint(-57 * DEGREES_TO_RADIANS, 146 * DEGREES_TO_RADIANS));
-    points.add(new GeoPoint(14 * DEGREES_TO_RADIANS, -180 * DEGREES_TO_RADIANS));
-    points.add(new GeoPoint(-15 * DEGREES_TO_RADIANS, 153 * DEGREES_TO_RADIANS));
+    points.add(new GeoPoint(PlanetModel.SPHERE, 18 * DEGREES_TO_RADIANS, -27 * DEGREES_TO_RADIANS));
+    points.add(new GeoPoint(PlanetModel.SPHERE, -57 * DEGREES_TO_RADIANS, 146 * DEGREES_TO_RADIANS));
+    points.add(new GeoPoint(PlanetModel.SPHERE, 14 * DEGREES_TO_RADIANS, -180 * DEGREES_TO_RADIANS));
+    points.add(new GeoPoint(PlanetModel.SPHERE, -15 * DEGREES_TO_RADIANS, 153 * DEGREES_TO_RADIANS));
     
-    final Shape triangle = new Geo3dShape(GeoPolygonFactory.makeGeoPolygon(points,0),ctx);
+    final Shape triangle = new Geo3dShape(GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, points,0),ctx);
     final Rectangle rect = ctx.makeRectangle(-49, -45, 73, 86);
     testOperation(rect,SpatialOperation.Intersects,triangle, false);
   }
@@ -101,11 +102,11 @@ public class Geo3dRptTest extends Random
 
   private Shape makeTriangle(double x1, double y1, double x2, double y2, double x3, double y3) {
     final List<GeoPoint> geoPoints = new ArrayList<>();
-    geoPoints.add(new GeoPoint(y1 * DEGREES_TO_RADIANS, x1 * DEGREES_TO_RADIANS));
-    geoPoints.add(new GeoPoint(y2 * DEGREES_TO_RADIANS, x2 * DEGREES_TO_RADIANS));
-    geoPoints.add(new GeoPoint(y3 * DEGREES_TO_RADIANS, x3 * DEGREES_TO_RADIANS));
+    geoPoints.add(new GeoPoint(PlanetModel.SPHERE, y1 * DEGREES_TO_RADIANS, x1 * DEGREES_TO_RADIANS));
+    geoPoints.add(new GeoPoint(PlanetModel.SPHERE, y2 * DEGREES_TO_RADIANS, x2 * DEGREES_TO_RADIANS));
+    geoPoints.add(new GeoPoint(PlanetModel.SPHERE, y3 * DEGREES_TO_RADIANS, x3 * DEGREES_TO_RADIANS));
     final int convexPointIndex = 0;
-    final GeoShape shape = GeoPolygonFactory.makeGeoPolygon(geoPoints, convexPointIndex);
+    final GeoShape shape = GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, geoPoints, convexPointIndex);
     return new Geo3dShape(shape, ctx);
   }
 
@@ -125,12 +126,12 @@ public class Geo3dRptTest extends Random
           final List<GeoPoint> geoPoints = new ArrayList<>();
           while (geoPoints.size() < vertexCount) {
             final Point point = randomPoint();
-            final GeoPoint gPt = new GeoPoint(point.getY() * DEGREES_TO_RADIANS, point.getX() * DEGREES_TO_RADIANS);
+            final GeoPoint gPt = new GeoPoint(PlanetModel.SPHERE, point.getY() * DEGREES_TO_RADIANS, point.getX() * DEGREES_TO_RADIANS);
             geoPoints.add(gPt);
           }
           final int convexPointIndex = random().nextInt(vertexCount);       //If we get this wrong, hopefully we get IllegalArgumentException
           try {
-            final GeoShape shape = GeoPolygonFactory.makeGeoPolygon(geoPoints, convexPointIndex);
+            final GeoShape shape = GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, geoPoints, convexPointIndex);
             return new Geo3dShape(shape, ctx);
           } catch (IllegalArgumentException e) {
             // This is what happens when we create a shape that is invalid.  Although it is conceivable that there are cases where
@@ -145,7 +146,7 @@ public class Geo3dRptTest extends Random
           final int circleRadius = random().nextInt(179) + 1;
           final Point point = randomPoint();
           try {
-            final GeoShape shape = new GeoCircle(point.getY() * DEGREES_TO_RADIANS, point.getX() * DEGREES_TO_RADIANS,
+            final GeoShape shape = new GeoCircle(PlanetModel.SPHERE, point.getY() * DEGREES_TO_RADIANS, point.getX() * DEGREES_TO_RADIANS,
               circleRadius * DEGREES_TO_RADIANS);
             return new Geo3dShape(shape, ctx);
           } catch (IllegalArgumentException e) {
@@ -167,7 +168,7 @@ public class Geo3dRptTest extends Random
             lrhcPoint = temp;
           }
           try {
-            final GeoShape shape = GeoBBoxFactory.makeGeoBBox(ulhcPoint.getY() * DEGREES_TO_RADIANS,
+            final GeoShape shape = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, ulhcPoint.getY() * DEGREES_TO_RADIANS,
               lrhcPoint.getY() * DEGREES_TO_RADIANS,
               ulhcPoint.getX() * DEGREES_TO_RADIANS,
               lrhcPoint.getX() * DEGREES_TO_RADIANS);
@@ -186,7 +187,7 @@ public class Geo3dRptTest extends Random
         final double width = (random().nextInt(89)+1) * DEGREES_TO_RADIANS;
         while (true) {
           try {
-            final GeoPath path = new GeoPath(width);
+            final GeoPath path = new GeoPath(PlanetModel.SPHERE, width);
             for (int i = 0; i < pointCount; i++) {
               final Point nextPoint = randomPoint();
               path.addPoint(nextPoint.getY() * DEGREES_TO_RADIANS, nextPoint.getX() * DEGREES_TO_RADIANS);

Added: lucene/dev/branches/lucene6487/lucene/spatial/src/test/org/apache/lucene/spatial/spatial4j/Geo3dShapeRectRelationTestCase.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6487/lucene/spatial/src/test/org/apache/lucene/spatial/spatial4j/Geo3dShapeRectRelationTestCase.java?rev=1681907&view=auto
==============================================================================
--- lucene/dev/branches/lucene6487/lucene/spatial/src/test/org/apache/lucene/spatial/spatial4j/Geo3dShapeRectRelationTestCase.java (added)
+++ lucene/dev/branches/lucene6487/lucene/spatial/src/test/org/apache/lucene/spatial/spatial4j/Geo3dShapeRectRelationTestCase.java Wed May 27 04:54:50 2015
@@ -0,0 +1,243 @@
+package org.apache.lucene.spatial.spatial4j;
+
+/*
+ * 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.
+ */
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+
+import com.carrotsearch.randomizedtesting.RandomizedContext;
+import com.spatial4j.core.context.SpatialContext;
+import com.spatial4j.core.distance.DistanceUtils;
+import com.spatial4j.core.shape.Point;
+import org.apache.lucene.spatial.spatial4j.geo3d.Bounds;
+import org.apache.lucene.spatial.spatial4j.geo3d.GeoBBox;
+import org.apache.lucene.spatial.spatial4j.geo3d.GeoBBoxFactory;
+import org.apache.lucene.spatial.spatial4j.geo3d.GeoCircle;
+import org.apache.lucene.spatial.spatial4j.geo3d.GeoPath;
+import org.apache.lucene.spatial.spatial4j.geo3d.GeoPoint;
+import org.apache.lucene.spatial.spatial4j.geo3d.GeoPolygonFactory;
+import org.apache.lucene.spatial.spatial4j.geo3d.GeoShape;
+import org.apache.lucene.spatial.spatial4j.geo3d.PlanetModel;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static com.spatial4j.core.distance.DistanceUtils.DEGREES_TO_RADIANS;
+
+public abstract class Geo3dShapeRectRelationTestCase extends RandomizedShapeTestCase {
+  protected final static double RADIANS_PER_DEGREE = Math.PI/180.0;
+
+  @Rule
+  public final LogRule testLog = LogRule.instance;
+
+  protected static Random random() {
+    return RandomizedContext.current().getRandom();
+  }
+
+  protected final PlanetModel planetModel;
+
+  public Geo3dShapeRectRelationTestCase(PlanetModel planetModel) {
+    super(SpatialContext.GEO);
+    this.planetModel = planetModel;
+  }
+
+  protected GeoBBox getBoundingBox(final GeoShape path) {
+      Bounds bounds = path.getBounds(null);
+
+      double leftLon;
+      double rightLon;
+      if (bounds.checkNoLongitudeBound()) {
+        leftLon = -Math.PI;
+        rightLon = Math.PI;
+      } else {
+        leftLon = bounds.getLeftLongitude().doubleValue();
+        rightLon = bounds.getRightLongitude().doubleValue();
+      }
+      double minLat;
+      if (bounds.checkNoBottomLatitudeBound()) {
+        minLat = -Math.PI * 0.5;
+      } else {
+        minLat = bounds.getMinLatitude().doubleValue();
+      }
+      double maxLat;
+      if (bounds.checkNoTopLatitudeBound()) {
+        maxLat = Math.PI * 0.5;
+      } else {
+        maxLat = bounds.getMaxLatitude().doubleValue();
+      }
+      return GeoBBoxFactory.makeGeoBBox(planetModel, maxLat, minLat, leftLon, rightLon);
+  }
+
+  @Test
+  public void testGeoCircleRect() {
+    new RectIntersectionTestHelper<Geo3dShape>(ctx) {
+
+      @Override
+      protected Geo3dShape generateRandomShape(Point nearP) {
+        while (true) {
+          final int circleRadius = random().nextInt(179) + 1;//no 0-radius
+          final Point point = nearP;
+          try {
+            final GeoShape shape = new GeoCircle(planetModel, point.getY() * DEGREES_TO_RADIANS, point.getX() * DEGREES_TO_RADIANS,
+                circleRadius * DEGREES_TO_RADIANS);
+            return new Geo3dShape(planetModel, shape, ctx);
+          } catch (IllegalArgumentException e) {
+            // This is what happens when we create a shape that is invalid.  Although it is conceivable that there are cases where
+            // the exception is thrown incorrectly, we aren't going to be able to do that in this random test.
+            continue;
+          }
+        }
+      }
+
+      @Override
+      protected Point randomPointInEmptyShape(Geo3dShape shape) {
+        GeoPoint geoPoint = ((GeoCircle)shape.shape).center;
+        return geoPointToSpatial4jPoint(geoPoint);
+      }
+
+    }.testRelateWithRectangle();
+  }
+
+  @Test
+  public void testGeoBBoxRect() {
+    new RectIntersectionTestHelper<Geo3dShape>(ctx) {
+
+      @Override
+      protected boolean isRandomShapeRectangular() {
+        return true;
+      }
+
+      @Override
+      protected Geo3dShape generateRandomShape(Point nearP) {
+        // (ignoring nearP)
+        Point ulhcPoint = randomPoint();
+        Point lrhcPoint = randomPoint();
+        if (ulhcPoint.getY() < lrhcPoint.getY()) {
+          //swap
+          Point temp = ulhcPoint;
+          ulhcPoint = lrhcPoint;
+          lrhcPoint = temp;
+        }
+        final GeoShape shape = GeoBBoxFactory.makeGeoBBox(planetModel, ulhcPoint.getY() * DEGREES_TO_RADIANS,
+            lrhcPoint.getY() * DEGREES_TO_RADIANS,
+            ulhcPoint.getX() * DEGREES_TO_RADIANS,
+            lrhcPoint.getX() * DEGREES_TO_RADIANS);
+        return new Geo3dShape(planetModel, shape, ctx);
+      }
+
+      @Override
+      protected Point randomPointInEmptyShape(Geo3dShape shape) {
+        return shape.getBoundingBox().getCenter();
+      }
+    }.testRelateWithRectangle();
+  }
+
+  @Test
+  public void testGeoPolygonRect() {
+    new RectIntersectionTestHelper<Geo3dShape>(ctx) {
+
+      @Override
+      protected Geo3dShape generateRandomShape(Point nearP) {
+        final Point centerPoint = randomPoint();
+        final int maxDistance = random().nextInt(160) + 20;
+        final int vertexCount = random().nextInt(3) + 3;
+        while (true) {
+          final List<GeoPoint> geoPoints = new ArrayList<>();
+          while (geoPoints.size() < vertexCount) {
+            final Point point = randomPoint();
+            if (ctx.getDistCalc().distance(point,centerPoint) > maxDistance)
+              continue;
+            final GeoPoint gPt = new GeoPoint(planetModel, point.getY() * DEGREES_TO_RADIANS, point.getX() * DEGREES_TO_RADIANS);
+            geoPoints.add(gPt);
+          }
+          final int convexPointIndex = random().nextInt(vertexCount);       //If we get this wrong, hopefully we get IllegalArgumentException
+          try {
+            final GeoShape shape = GeoPolygonFactory.makeGeoPolygon(planetModel, geoPoints, convexPointIndex);
+            return new Geo3dShape(planetModel, shape, ctx);
+          } catch (IllegalArgumentException e) {
+            // This is what happens when we create a shape that is invalid.  Although it is conceivable that there are cases where
+            // the exception is thrown incorrectly, we aren't going to be able to do that in this random test.
+            continue;
+          }
+        }
+      }
+
+      @Override
+      protected Point randomPointInEmptyShape(Geo3dShape shape) {
+        throw new IllegalStateException("unexpected; need to finish test code");
+      }
+
+      @Override
+      protected int getWithinMinimum(int laps) {
+        // Long/thin so only 10% of the usual figure
+        return laps/10000;
+      }
+
+    }.testRelateWithRectangle();
+  }
+
+  @Test
+  public void testGeoPathRect() {
+    new RectIntersectionTestHelper<Geo3dShape>(ctx) {
+
+      @Override
+      protected Geo3dShape generateRandomShape(Point nearP) {
+        final Point centerPoint = randomPoint();
+        final int maxDistance = random().nextInt(160) + 20;
+        final int pointCount = random().nextInt(5) + 1;
+        final double width = (random().nextInt(89)+1) * DEGREES_TO_RADIANS;
+        while (true) {
+          try {
+            final GeoPath path = new GeoPath(planetModel, width);
+            int i = 0;
+            while (i < pointCount) {
+              final Point nextPoint = randomPoint();
+              if (ctx.getDistCalc().distance(nextPoint,centerPoint) > maxDistance)
+                continue;
+              path.addPoint(nextPoint.getY() * DEGREES_TO_RADIANS, nextPoint.getX() * DEGREES_TO_RADIANS);
+              i++;
+            }
+            path.done();
+            return new Geo3dShape(planetModel, path, ctx);
+          } catch (IllegalArgumentException e) {
+            // This is what happens when we create a shape that is invalid.  Although it is conceivable that there are cases where
+            // the exception is thrown incorrectly, we aren't going to be able to do that in this random test.
+            continue;
+          }
+        }
+      }
+
+      @Override
+      protected Point randomPointInEmptyShape(Geo3dShape shape) {
+        throw new IllegalStateException("unexpected; need to finish test code");
+      }
+
+      @Override
+      protected int getWithinMinimum(int laps) {
+        // Long/thin so only 10% of the usual figure
+        return laps/10000;
+      }
+
+    }.testRelateWithRectangle();
+  }
+
+  private Point geoPointToSpatial4jPoint(GeoPoint geoPoint) {
+    return ctx.makePoint(geoPoint.x * DistanceUtils.RADIANS_TO_DEGREES,
+        geoPoint.y * DistanceUtils.RADIANS_TO_DEGREES);
+  }
+}

Copied: lucene/dev/branches/lucene6487/lucene/spatial/src/test/org/apache/lucene/spatial/spatial4j/Geo3dShapeSphereModelRectRelationTest.java (from r1681647, lucene/dev/trunk/lucene/spatial/src/test/org/apache/lucene/spatial/spatial4j/Geo3dShapeRectRelationTest.java)
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6487/lucene/spatial/src/test/org/apache/lucene/spatial/spatial4j/Geo3dShapeSphereModelRectRelationTest.java?p2=lucene/dev/branches/lucene6487/lucene/spatial/src/test/org/apache/lucene/spatial/spatial4j/Geo3dShapeSphereModelRectRelationTest.java&p1=lucene/dev/trunk/lucene/spatial/src/test/org/apache/lucene/spatial/spatial4j/Geo3dShapeRectRelationTest.java&r1=1681647&r2=1681907&rev=1681907&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/spatial/src/test/org/apache/lucene/spatial/spatial4j/Geo3dShapeRectRelationTest.java (original)
+++ lucene/dev/branches/lucene6487/lucene/spatial/src/test/org/apache/lucene/spatial/spatial4j/Geo3dShapeSphereModelRectRelationTest.java Wed May 27 04:54:50 2015
@@ -19,236 +19,34 @@ package org.apache.lucene.spatial.spatia
 
 import java.util.ArrayList;
 import java.util.List;
-import java.util.Random;
 
-import com.carrotsearch.randomizedtesting.RandomizedContext;
-import com.spatial4j.core.context.SpatialContext;
-import com.spatial4j.core.distance.DistanceUtils;
-import com.spatial4j.core.shape.Point;
 import com.spatial4j.core.shape.Rectangle;
-import org.apache.lucene.spatial.spatial4j.geo3d.Bounds;
 import org.apache.lucene.spatial.spatial4j.geo3d.GeoArea;
 import org.apache.lucene.spatial.spatial4j.geo3d.GeoBBox;
 import org.apache.lucene.spatial.spatial4j.geo3d.GeoBBoxFactory;
 import org.apache.lucene.spatial.spatial4j.geo3d.GeoCircle;
-import org.apache.lucene.spatial.spatial4j.geo3d.GeoPath;
 import org.apache.lucene.spatial.spatial4j.geo3d.GeoPoint;
 import org.apache.lucene.spatial.spatial4j.geo3d.GeoPolygonFactory;
 import org.apache.lucene.spatial.spatial4j.geo3d.GeoShape;
-import org.junit.Rule;
+import org.apache.lucene.spatial.spatial4j.geo3d.PlanetModel;
 import org.junit.Test;
 
-import static com.spatial4j.core.distance.DistanceUtils.DEGREES_TO_RADIANS;
+public class Geo3dShapeSphereModelRectRelationTest extends Geo3dShapeRectRelationTestCase {
 
-public class Geo3dShapeRectRelationTest extends RandomizedShapeTestCase {
-  @Rule
-  public final LogRule testLog = LogRule.instance;
-
-  static Random random() {
-    return RandomizedContext.current().getRandom();
-  }
-
-  {
-    ctx = SpatialContext.GEO;
-  }
-
-  protected final static double RADIANS_PER_DEGREE = Math.PI/180.0;
-
-  protected static GeoBBox getBoundingBox(final GeoShape path) {
-      Bounds bounds = path.getBounds(null);
-
-      double leftLon;
-      double rightLon;
-      if (bounds.checkNoLongitudeBound()) {
-        leftLon = -Math.PI;
-        rightLon = Math.PI;
-      } else {
-        leftLon = bounds.getLeftLongitude().doubleValue();
-        rightLon = bounds.getRightLongitude().doubleValue();
-      }
-      double minLat;
-      if (bounds.checkNoBottomLatitudeBound()) {
-        minLat = -Math.PI * 0.5;
-      } else {
-        minLat = bounds.getMinLatitude().doubleValue();
-      }
-      double maxLat;
-      if (bounds.checkNoTopLatitudeBound()) {
-        maxLat = Math.PI * 0.5;
-      } else {
-        maxLat = bounds.getMaxLatitude().doubleValue();
-      }
-      return GeoBBoxFactory.makeGeoBBox(maxLat, minLat, leftLon, rightLon);
-  }
-
-  @Test
-  public void testGeoCircleRect() {
-    new RectIntersectionTestHelper<Geo3dShape>(ctx) {
-
-      @Override
-      protected Geo3dShape generateRandomShape(Point nearP) {
-        while (true) {
-          final int circleRadius = random().nextInt(179) + 1;//no 0-radius
-          final Point point = nearP;
-          try {
-            final GeoShape shape = new GeoCircle(point.getY() * DEGREES_TO_RADIANS, point.getX() * DEGREES_TO_RADIANS,
-                circleRadius * DEGREES_TO_RADIANS);
-            return new Geo3dShape(shape, ctx);
-          } catch (IllegalArgumentException e) {
-            // This is what happens when we create a shape that is invalid.  Although it is conceivable that there are cases where
-            // the exception is thrown incorrectly, we aren't going to be able to do that in this random test.
-            continue;
-          }
-        }
-      }
-
-      @Override
-      protected Point randomPointInEmptyShape(Geo3dShape shape) {
-        GeoPoint geoPoint = ((GeoCircle)shape.shape).center;
-        return geoPointToSpatial4jPoint(geoPoint);
-      }
-
-    }.testRelateWithRectangle();
-  }
-
-  @Test
-  public void testGeoBBoxRect() {
-    new RectIntersectionTestHelper<Geo3dShape>(ctx) {
-
-      @Override
-      protected boolean isRandomShapeRectangular() {
-        return true;
-      }
-
-      @Override
-      protected Geo3dShape generateRandomShape(Point nearP) {
-        // (ignoring nearP)
-        Point ulhcPoint = randomPoint();
-        Point lrhcPoint = randomPoint();
-        if (ulhcPoint.getY() < lrhcPoint.getY()) {
-          //swap
-          Point temp = ulhcPoint;
-          ulhcPoint = lrhcPoint;
-          lrhcPoint = temp;
-        }
-        final GeoShape shape = GeoBBoxFactory.makeGeoBBox(ulhcPoint.getY() * DEGREES_TO_RADIANS,
-            lrhcPoint.getY() * DEGREES_TO_RADIANS,
-            ulhcPoint.getX() * DEGREES_TO_RADIANS,
-            lrhcPoint.getX() * DEGREES_TO_RADIANS);
-        return new Geo3dShape(shape, ctx);
-      }
-
-      @Override
-      protected Point randomPointInEmptyShape(Geo3dShape shape) {
-        return shape.getBoundingBox().getCenter();
-      }
-    }.testRelateWithRectangle();
-  }
-
-  @Test
-  public void testGeoPolygonRect() {
-    new RectIntersectionTestHelper<Geo3dShape>(ctx) {
-
-      @Override
-      protected Geo3dShape generateRandomShape(Point nearP) {
-        final Point centerPoint = randomPoint();
-        final int maxDistance = random().nextInt(160) + 20;
-        final int vertexCount = random().nextInt(3) + 3;
-        while (true) {
-          final List<GeoPoint> geoPoints = new ArrayList<>();
-          while (geoPoints.size() < vertexCount) {
-            final Point point = randomPoint();
-            if (ctx.getDistCalc().distance(point,centerPoint) > maxDistance)
-              continue;
-            final GeoPoint gPt = new GeoPoint(point.getY() * DEGREES_TO_RADIANS, point.getX() * DEGREES_TO_RADIANS);
-            geoPoints.add(gPt);
-          }
-          final int convexPointIndex = random().nextInt(vertexCount);       //If we get this wrong, hopefully we get IllegalArgumentException
-          try {
-            final GeoShape shape = GeoPolygonFactory.makeGeoPolygon(geoPoints, convexPointIndex);
-            return new Geo3dShape(shape, ctx);
-          } catch (IllegalArgumentException e) {
-            // This is what happens when we create a shape that is invalid.  Although it is conceivable that there are cases where
-            // the exception is thrown incorrectly, we aren't going to be able to do that in this random test.
-            continue;
-          }
-        }
-      }
-
-      @Override
-      protected Point randomPointInEmptyShape(Geo3dShape shape) {
-        throw new IllegalStateException("unexpected; need to finish test code");
-      }
-
-      @Override
-      protected int getWithinMinimum(int laps) {
-        // Long/thin so only 10% of the usual figure
-        return laps/10000;
-      }
-
-    }.testRelateWithRectangle();
-  }
-
-  @Test
-  public void testGeoPathRect() {
-    new RectIntersectionTestHelper<Geo3dShape>(ctx) {
-
-      @Override
-      protected Geo3dShape generateRandomShape(Point nearP) {
-        final Point centerPoint = randomPoint();
-        final int maxDistance = random().nextInt(160) + 20;
-        final int pointCount = random().nextInt(5) + 1;
-        final double width = (random().nextInt(89)+1) * DEGREES_TO_RADIANS;
-        while (true) {
-          try {
-            final GeoPath path = new GeoPath(width);
-            int i = 0;
-            while (i < pointCount) {
-              final Point nextPoint = randomPoint();
-              if (ctx.getDistCalc().distance(nextPoint,centerPoint) > maxDistance)
-                continue;
-              path.addPoint(nextPoint.getY() * DEGREES_TO_RADIANS, nextPoint.getX() * DEGREES_TO_RADIANS);
-              i++;
-            }
-            path.done();
-            return new Geo3dShape(path, ctx);
-          } catch (IllegalArgumentException e) {
-            // This is what happens when we create a shape that is invalid.  Although it is conceivable that there are cases where
-            // the exception is thrown incorrectly, we aren't going to be able to do that in this random test.
-            continue;
-          }
-        }
-      }
-
-      @Override
-      protected Point randomPointInEmptyShape(Geo3dShape shape) {
-        throw new IllegalStateException("unexpected; need to finish test code");
-      }
-
-      @Override
-      protected int getWithinMinimum(int laps) {
-        // Long/thin so only 10% of the usual figure
-        return laps/10000;
-      }
-
-    }.testRelateWithRectangle();
-  }
-
-  private Point geoPointToSpatial4jPoint(GeoPoint geoPoint) {
-    return ctx.makePoint(geoPoint.x * DistanceUtils.RADIANS_TO_DEGREES,
-        geoPoint.y * DistanceUtils.RADIANS_TO_DEGREES);
+  public Geo3dShapeSphereModelRectRelationTest() {
+    super(PlanetModel.SPHERE);
   }
 
   @Test
   public void testFailure1() {
-    final GeoBBox rect = GeoBBoxFactory.makeGeoBBox(88 * RADIANS_PER_DEGREE, 30 * RADIANS_PER_DEGREE, -30 * RADIANS_PER_DEGREE, 62 * RADIANS_PER_DEGREE);
-    final List<GeoPoint> points = new ArrayList<GeoPoint>();
-    points.add(new GeoPoint(66.2465299717 * RADIANS_PER_DEGREE, -29.1786158537 * RADIANS_PER_DEGREE));
-    points.add(new GeoPoint(43.684447915 * RADIANS_PER_DEGREE, 46.2210986329 * RADIANS_PER_DEGREE));
-    points.add(new GeoPoint(30.4579218227 * RADIANS_PER_DEGREE, 14.5238410082 * RADIANS_PER_DEGREE));
-    final GeoShape path = GeoPolygonFactory.makeGeoPolygon(points,0);
+    final GeoBBox rect = GeoBBoxFactory.makeGeoBBox(planetModel, 88 * RADIANS_PER_DEGREE, 30 * RADIANS_PER_DEGREE, -30 * RADIANS_PER_DEGREE, 62 * RADIANS_PER_DEGREE);
+    final List<GeoPoint> points = new ArrayList<>();
+    points.add(new GeoPoint(planetModel, 66.2465299717 * RADIANS_PER_DEGREE, -29.1786158537 * RADIANS_PER_DEGREE));
+    points.add(new GeoPoint(planetModel, 43.684447915 * RADIANS_PER_DEGREE, 46.2210986329 * RADIANS_PER_DEGREE));
+    points.add(new GeoPoint(planetModel, 30.4579218227 * RADIANS_PER_DEGREE, 14.5238410082 * RADIANS_PER_DEGREE));
+    final GeoShape path = GeoPolygonFactory.makeGeoPolygon(planetModel, points,0);
 
-    final GeoPoint point = new GeoPoint(34.2730264413182 * RADIANS_PER_DEGREE, 82.75500168892472 * RADIANS_PER_DEGREE);
+    final GeoPoint point = new GeoPoint(planetModel, 34.2730264413182 * RADIANS_PER_DEGREE, 82.75500168892472 * RADIANS_PER_DEGREE);
 
     // Apparently the rectangle thinks the polygon is completely within it... "shape inside rectangle"
     assertTrue(GeoArea.WITHIN == rect.getRelationship(path));
@@ -263,9 +61,9 @@ public class Geo3dShapeRectRelationTest
 
   @Test
   public void testFailure2_LUCENE6475() {
-    GeoShape geo3dCircle = new GeoCircle(1.6282053147165243E-4 * RADIANS_PER_DEGREE,
+    GeoShape geo3dCircle = new GeoCircle(planetModel, 1.6282053147165243E-4 * RADIANS_PER_DEGREE,
         -70.1600629789353 * RADIANS_PER_DEGREE, 86 * RADIANS_PER_DEGREE);
-    Geo3dShape geo3dShape = new Geo3dShape(geo3dCircle, ctx);
+    Geo3dShape geo3dShape = new Geo3dShape(planetModel, geo3dCircle, ctx);
     Rectangle rect = ctx.makeRectangle(-118, -114, -2.0, 32.0);
     assertTrue(geo3dShape.relate(rect).intersects());
     // thus the bounding box must intersect too

Added: lucene/dev/branches/lucene6487/lucene/spatial/src/test/org/apache/lucene/spatial/spatial4j/Geo3dShapeWGS84ModelRectRelationTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6487/lucene/spatial/src/test/org/apache/lucene/spatial/spatial4j/Geo3dShapeWGS84ModelRectRelationTest.java?rev=1681907&view=auto
==============================================================================
--- lucene/dev/branches/lucene6487/lucene/spatial/src/test/org/apache/lucene/spatial/spatial4j/Geo3dShapeWGS84ModelRectRelationTest.java (added)
+++ lucene/dev/branches/lucene6487/lucene/spatial/src/test/org/apache/lucene/spatial/spatial4j/Geo3dShapeWGS84ModelRectRelationTest.java Wed May 27 04:54:50 2015
@@ -0,0 +1,95 @@
+package org.apache.lucene.spatial.spatial4j;
+
+/*
+ * 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.
+ */
+
+import org.apache.lucene.spatial.spatial4j.geo3d.GeoArea;
+import org.apache.lucene.spatial.spatial4j.geo3d.GeoBBox;
+import org.apache.lucene.spatial.spatial4j.geo3d.GeoBBoxFactory;
+import org.apache.lucene.spatial.spatial4j.geo3d.GeoCircle;
+import org.apache.lucene.spatial.spatial4j.geo3d.GeoPath;
+import org.apache.lucene.spatial.spatial4j.geo3d.GeoPoint;
+import org.apache.lucene.spatial.spatial4j.geo3d.PlanetModel;
+import org.junit.Test;
+
+public class Geo3dShapeWGS84ModelRectRelationTest extends Geo3dShapeRectRelationTestCase {
+
+  public Geo3dShapeWGS84ModelRectRelationTest() {
+    super(PlanetModel.WGS84);
+  }
+
+  @Test
+  public void testFailure1() {
+    final GeoBBox rect = GeoBBoxFactory.makeGeoBBox(planetModel, 90 * RADIANS_PER_DEGREE, 74 * RADIANS_PER_DEGREE,
+        40 * RADIANS_PER_DEGREE, 60 * RADIANS_PER_DEGREE);
+    final GeoPath path = new GeoPath(planetModel, 4 * RADIANS_PER_DEGREE);
+    path.addPoint(84.4987594274 * RADIANS_PER_DEGREE, -22.8345484402 * RADIANS_PER_DEGREE);
+    path.done();
+    assertTrue(GeoArea.DISJOINT == rect.getRelationship(path));
+    // This is what the test failure claimed...
+    //assertTrue(GeoArea.CONTAINS == rect.getRelationship(path));
+    //final GeoBBox bbox = getBoundingBox(path);
+    //assertFalse(GeoArea.DISJOINT == rect.getRelationship(bbox));
+  }
+
+  @Test
+  public void testFailure2() {
+    final GeoBBox rect = GeoBBoxFactory.makeGeoBBox(planetModel, -74 * RADIANS_PER_DEGREE, -90 * RADIANS_PER_DEGREE,
+        0 * RADIANS_PER_DEGREE, 26 * RADIANS_PER_DEGREE);
+    final GeoCircle circle = new GeoCircle(planetModel, -87.3647352103 * RADIANS_PER_DEGREE, 52.3769709972 * RADIANS_PER_DEGREE, 1 * RADIANS_PER_DEGREE);
+    assertTrue(GeoArea.DISJOINT == rect.getRelationship(circle));
+    // This is what the test failure claimed...
+    //assertTrue(GeoArea.CONTAINS == rect.getRelationship(circle));
+    //final GeoBBox bbox = getBoundingBox(circle);
+    //assertFalse(GeoArea.DISJOINT == rect.getRelationship(bbox));
+  }
+
+  @Test
+  public void testFailure3() {
+    /*
+   [junit4]   1> S-R Rel: {}, Shape {}, Rectangle {}    lap# {} [CONTAINS, Geo3dShape{planetmodel=PlanetModel: {ab=1.0011188180710464, c=0.9977622539852008}, shape=GeoPath: {planetmodel=PlanetModel: {ab=1.0011188180710464, c=0.9977622539852008}, width=1.53588974175501(87.99999999999999), 
+    points={[[X=0.12097657665150223, Y=-0.6754177666095532, Z=0.7265376136709238], [X=-0.3837892785614207, Y=0.4258049113530899, Z=0.8180007850434892]]}}}, 
+    Rect(minX=4.0,maxX=36.0,minY=16.0,maxY=16.0), 6981](no slf4j subst; sorry)
+   [junit4] FAILURE 0.59s | Geo3dWGS84ShapeRectRelationTest.testGeoPathRect <<<
+   [junit4]    > Throwable #1: java.lang.AssertionError: Geo3dShape{planetmodel=PlanetModel: {ab=1.0011188180710464, c=0.9977622539852008}, shape=GeoPath: {planetmodel=PlanetModel: {ab=1.0011188180710464, c=0.9977622539852008}, width=1.53588974175501(87.99999999999999), 
+    points={[[X=0.12097657665150223, Y=-0.6754177666095532, Z=0.7265376136709238], [X=-0.3837892785614207, Y=0.4258049113530899, Z=0.8180007850434892]]}}} intersect Pt(x=23.81626064835212,y=16.0)
+   [junit4]    >  at __randomizedtesting.SeedInfo.seed([2595268DA3F13FEA:6CC30D8C83453E5D]:0)
+   [junit4]    >  at org.apache.lucene.spatial.spatial4j.RandomizedShapeTestCase._assertIntersect(RandomizedShapeTestCase.java:168)
+   [junit4]    >  at org.apache.lucene.spatial.spatial4j.RandomizedShapeTestCase.assertRelation(RandomizedShapeTestCase.java:153)
+   [junit4]    >  at org.apache.lucene.spatial.spatial4j.RectIntersectionTestHelper.testRelateWithRectangle(RectIntersectionTestHelper.java:128)
+   [junit4]    >  at org.apache.lucene.spatial.spatial4j.Geo3dWGS84ShapeRectRelationTest.testGeoPathRect(Geo3dWGS84ShapeRectRelationTest.java:265)
+  */
+    final GeoBBox rect = GeoBBoxFactory.makeGeoBBox(planetModel, 16 * RADIANS_PER_DEGREE, 16 * RADIANS_PER_DEGREE, 4 * RADIANS_PER_DEGREE, 36 * RADIANS_PER_DEGREE);
+    final GeoPoint pt = new GeoPoint(planetModel, 16 * RADIANS_PER_DEGREE, 23.81626064835212 * RADIANS_PER_DEGREE);
+    final GeoPath path = new GeoPath(planetModel, 88 * RADIANS_PER_DEGREE);
+    path.addPoint(46.6369060853 * RADIANS_PER_DEGREE, -79.8452213228 * RADIANS_PER_DEGREE);
+    path.addPoint(54.9779334519 * RADIANS_PER_DEGREE, 132.029177424 * RADIANS_PER_DEGREE);
+    path.done();
+    System.out.println("rect=" + rect);
+    // Rectangle is within path (this is wrong; it's on the other side.  Should be OVERLAPS)
+    assertTrue(GeoArea.OVERLAPS == rect.getRelationship(path));
+    // Rectangle contains point
+    //assertTrue(rect.isWithin(pt));
+    // Path contains point (THIS FAILS)
+    //assertTrue(path.isWithin(pt));
+    // What happens: (1) The center point of the horizontal line is within the path, in fact within a radius of one of the endpoints.
+    // (2) The point mentioned is NOT inside either SegmentEndpoint.
+    // (3) The point mentioned is NOT inside the path segment, either.  (I think it should be...)
+  }
+
+}
+

Modified: lucene/dev/branches/lucene6487/lucene/spatial/src/test/org/apache/lucene/spatial/spatial4j/geo3d/GeoBBoxTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6487/lucene/spatial/src/test/org/apache/lucene/spatial/spatial4j/geo3d/GeoBBoxTest.java?rev=1681907&r1=1681906&r2=1681907&view=diff
==============================================================================
--- lucene/dev/branches/lucene6487/lucene/spatial/src/test/org/apache/lucene/spatial/spatial4j/geo3d/GeoBBoxTest.java (original)
+++ lucene/dev/branches/lucene6487/lucene/spatial/src/test/org/apache/lucene/spatial/spatial4j/geo3d/GeoBBoxTest.java Wed May 27 04:54:50 2015
@@ -36,14 +36,14 @@ public class GeoBBoxTest {
     GeoConvexPolygon cp;
     int relationship;
     List<GeoPoint> points = new ArrayList<GeoPoint>();
-    points.add(new GeoPoint(24 * DEGREES_TO_RADIANS, -30 * DEGREES_TO_RADIANS));
-    points.add(new GeoPoint(-11 * DEGREES_TO_RADIANS, 101 * DEGREES_TO_RADIANS));
-    points.add(new GeoPoint(-49 * DEGREES_TO_RADIANS, -176 * DEGREES_TO_RADIANS));
-    GeoMembershipShape shape = GeoPolygonFactory.makeGeoPolygon(points, 0);
-    box = GeoBBoxFactory.makeGeoBBox(-64 * DEGREES_TO_RADIANS, -64 * DEGREES_TO_RADIANS, -180 * DEGREES_TO_RADIANS, 180 * DEGREES_TO_RADIANS);
+    points.add(new GeoPoint(PlanetModel.SPHERE, 24 * DEGREES_TO_RADIANS, -30 * DEGREES_TO_RADIANS));
+    points.add(new GeoPoint(PlanetModel.SPHERE, -11 * DEGREES_TO_RADIANS, 101 * DEGREES_TO_RADIANS));
+    points.add(new GeoPoint(PlanetModel.SPHERE, -49 * DEGREES_TO_RADIANS, -176 * DEGREES_TO_RADIANS));
+    GeoMembershipShape shape = GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, points, 0);
+    box = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, -64 * DEGREES_TO_RADIANS, -64 * DEGREES_TO_RADIANS, -180 * DEGREES_TO_RADIANS, 180 * DEGREES_TO_RADIANS);
     relationship = box.getRelationship(shape);
     assertEquals(GeoArea.CONTAINS, relationship);
-    box = GeoBBoxFactory.makeGeoBBox(-61.85 * DEGREES_TO_RADIANS, -67.5 * DEGREES_TO_RADIANS, -180 * DEGREES_TO_RADIANS, -168.75 * DEGREES_TO_RADIANS);
+    box = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, -61.85 * DEGREES_TO_RADIANS, -67.5 * DEGREES_TO_RADIANS, -180 * DEGREES_TO_RADIANS, -168.75 * DEGREES_TO_RADIANS);
     System.out.println("Shape = " + shape + " Rect = " + box);
     relationship = box.getRelationship(shape);
     assertEquals(GeoArea.CONTAINS, relationship);
@@ -54,52 +54,52 @@ public class GeoBBoxTest {
     GeoBBox box;
     GeoPoint gp;
     // Standard normal Rect box, not crossing dateline
-    box = GeoBBoxFactory.makeGeoBBox(0.0, -Math.PI * 0.25, -1.0, 1.0);
-    gp = new GeoPoint(-0.1, 0.0);
+    box = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, 0.0, -Math.PI * 0.25, -1.0, 1.0);
+    gp = new GeoPoint(PlanetModel.SPHERE, -0.1, 0.0);
     assertTrue(box.isWithin(gp));
-    gp = new GeoPoint(0.1, 0.0);
+    gp = new GeoPoint(PlanetModel.SPHERE, 0.1, 0.0);
     assertFalse(box.isWithin(gp));
-    gp = new GeoPoint(-Math.PI * 0.5, 0.0);
+    gp = new GeoPoint(PlanetModel.SPHERE, -Math.PI * 0.5, 0.0);
     assertFalse(box.isWithin(gp));
-    gp = new GeoPoint(-0.1, 1.1);
+    gp = new GeoPoint(PlanetModel.SPHERE, -0.1, 1.1);
     assertFalse(box.isWithin(gp));
-    gp = new GeoPoint(-0.1, -1.1);
+    gp = new GeoPoint(PlanetModel.SPHERE, -0.1, -1.1);
     assertFalse(box.isWithin(gp));
     // Standard normal Rect box, crossing dateline
-    box = GeoBBoxFactory.makeGeoBBox(0.0, -Math.PI * 0.25, Math.PI - 1.0, -Math.PI + 1.0);
-    gp = new GeoPoint(-0.1, -Math.PI);
+    box = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, 0.0, -Math.PI * 0.25, Math.PI - 1.0, -Math.PI + 1.0);
+    gp = new GeoPoint(PlanetModel.SPHERE, -0.1, -Math.PI);
     assertTrue(box.isWithin(gp));
-    gp = new GeoPoint(0.1, -Math.PI);
+    gp = new GeoPoint(PlanetModel.SPHERE, 0.1, -Math.PI);
     assertFalse(box.isWithin(gp));
-    gp = new GeoPoint(-Math.PI * 0.5, -Math.PI);
+    gp = new GeoPoint(PlanetModel.SPHERE, -Math.PI * 0.5, -Math.PI);
     assertFalse(box.isWithin(gp));
-    gp = new GeoPoint(-0.1, -Math.PI + 1.1);
+    gp = new GeoPoint(PlanetModel.SPHERE, -0.1, -Math.PI + 1.1);
     assertFalse(box.isWithin(gp));
-    gp = new GeoPoint(-0.1, -Math.PI - 1.1);
+    gp = new GeoPoint(PlanetModel.SPHERE, -0.1, -Math.PI - 1.1);
     assertFalse(box.isWithin(gp));
     // Latitude zone rectangle
-    box = GeoBBoxFactory.makeGeoBBox(0.0, -Math.PI * 0.25, -Math.PI, Math.PI);
-    gp = new GeoPoint(-0.1, -Math.PI);
+    box = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, 0.0, -Math.PI * 0.25, -Math.PI, Math.PI);
+    gp = new GeoPoint(PlanetModel.SPHERE, -0.1, -Math.PI);
     assertTrue(box.isWithin(gp));
-    gp = new GeoPoint(0.1, -Math.PI);
+    gp = new GeoPoint(PlanetModel.SPHERE, 0.1, -Math.PI);
     assertFalse(box.isWithin(gp));
-    gp = new GeoPoint(-Math.PI * 0.5, -Math.PI);
+    gp = new GeoPoint(PlanetModel.SPHERE, -Math.PI * 0.5, -Math.PI);
     assertFalse(box.isWithin(gp));
-    gp = new GeoPoint(-0.1, -Math.PI + 1.1);
+    gp = new GeoPoint(PlanetModel.SPHERE, -0.1, -Math.PI + 1.1);
     assertTrue(box.isWithin(gp));
-    gp = new GeoPoint(-0.1, -Math.PI - 1.1);
+    gp = new GeoPoint(PlanetModel.SPHERE, -0.1, -Math.PI - 1.1);
     assertTrue(box.isWithin(gp));
     // World
-    box = GeoBBoxFactory.makeGeoBBox(Math.PI * 0.5, -Math.PI * 0.5, -Math.PI, Math.PI);
-    gp = new GeoPoint(-0.1, -Math.PI);
+    box = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, Math.PI * 0.5, -Math.PI * 0.5, -Math.PI, Math.PI);
+    gp = new GeoPoint(PlanetModel.SPHERE, -0.1, -Math.PI);
     assertTrue(box.isWithin(gp));
-    gp = new GeoPoint(0.1, -Math.PI);
+    gp = new GeoPoint(PlanetModel.SPHERE, 0.1, -Math.PI);
     assertTrue(box.isWithin(gp));
-    gp = new GeoPoint(-Math.PI * 0.5, -Math.PI);
+    gp = new GeoPoint(PlanetModel.SPHERE, -Math.PI * 0.5, -Math.PI);
     assertTrue(box.isWithin(gp));
-    gp = new GeoPoint(-0.1, -Math.PI + 1.1);
+    gp = new GeoPoint(PlanetModel.SPHERE, -0.1, -Math.PI + 1.1);
     assertTrue(box.isWithin(gp));
-    gp = new GeoPoint(-0.1, -Math.PI - 1.1);
+    gp = new GeoPoint(PlanetModel.SPHERE, -0.1, -Math.PI - 1.1);
     assertTrue(box.isWithin(gp));
 
   }
@@ -109,23 +109,23 @@ public class GeoBBoxTest {
     GeoBBox box;
     GeoPoint gp;
     // Standard normal Rect box, not crossing dateline
-    box = GeoBBoxFactory.makeGeoBBox(0.0, -Math.PI * 0.25, -1.0, 1.0);
+    box = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, 0.0, -Math.PI * 0.25, -1.0, 1.0);
     box = box.expand(0.1);
-    gp = new GeoPoint(0.05, 0.0);
+    gp = new GeoPoint(PlanetModel.SPHERE, 0.05, 0.0);
     assertTrue(box.isWithin(gp));
-    gp = new GeoPoint(0.15, 0.0);
+    gp = new GeoPoint(PlanetModel.SPHERE, 0.15, 0.0);
     assertFalse(box.isWithin(gp));
-    gp = new GeoPoint(-Math.PI * 0.25 - 0.05, 0.0);
+    gp = new GeoPoint(PlanetModel.SPHERE, -Math.PI * 0.25 - 0.05, 0.0);
     assertTrue(box.isWithin(gp));
-    gp = new GeoPoint(-Math.PI * 0.25 - 0.15, 0.0);
+    gp = new GeoPoint(PlanetModel.SPHERE, -Math.PI * 0.25 - 0.15, 0.0);
     assertFalse(box.isWithin(gp));
-    gp = new GeoPoint(-0.1, -1.05);
+    gp = new GeoPoint(PlanetModel.SPHERE, -0.1, -1.05);
     assertTrue(box.isWithin(gp));
-    gp = new GeoPoint(-0.1, -1.15);
+    gp = new GeoPoint(PlanetModel.SPHERE, -0.1, -1.15);
     assertFalse(box.isWithin(gp));
-    gp = new GeoPoint(-0.1, 1.05);
+    gp = new GeoPoint(PlanetModel.SPHERE, -0.1, 1.05);
     assertTrue(box.isWithin(gp));
-    gp = new GeoPoint(-0.1, 1.15);
+    gp = new GeoPoint(PlanetModel.SPHERE, -0.1, 1.15);
     assertFalse(box.isWithin(gp));
   }
 
@@ -134,7 +134,7 @@ public class GeoBBoxTest {
     GeoBBox c;
     Bounds b;
 
-    c = GeoBBoxFactory.makeGeoBBox(0.0, -Math.PI * 0.25, -1.0, 1.0);
+    c = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, 0.0, -Math.PI * 0.25, -1.0, 1.0);
 
     b = c.getBounds(null);
     assertFalse(b.checkNoLongitudeBound());
@@ -145,7 +145,7 @@ public class GeoBBoxTest {
     assertEquals(-Math.PI * 0.25, b.getMinLatitude(), 0.000001);
     assertEquals(0.0, b.getMaxLatitude(), 0.000001);
 
-    c = GeoBBoxFactory.makeGeoBBox(0.0, -Math.PI * 0.25, 1.0, -1.0);
+    c = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, 0.0, -Math.PI * 0.25, 1.0, -1.0);
 
     b = c.getBounds(null);
     assertTrue(b.checkNoLongitudeBound());
@@ -156,7 +156,7 @@ public class GeoBBoxTest {
     assertEquals(-Math.PI * 0.25, b.getMinLatitude(), 0.000001);
     assertEquals(0.0, b.getMaxLatitude(), 0.000001);
 
-    c = GeoBBoxFactory.makeGeoBBox(Math.PI * 0.5, -Math.PI * 0.5, -1.0, 1.0);
+    c = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, Math.PI * 0.5, -Math.PI * 0.5, -1.0, 1.0);
 
     b = c.getBounds(null);
     assertFalse(b.checkNoLongitudeBound());
@@ -165,7 +165,7 @@ public class GeoBBoxTest {
     assertEquals(-1.0, b.getLeftLongitude(), 0.000001);
     assertEquals(1.0, b.getRightLongitude(), 0.000001);
 
-    c = GeoBBoxFactory.makeGeoBBox(Math.PI * 0.5, -Math.PI * 0.5, 1.0, -1.0);
+    c = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, Math.PI * 0.5, -Math.PI * 0.5, 1.0, -1.0);
 
     b = c.getBounds(null);
     assertTrue(b.checkNoLongitudeBound());
@@ -176,7 +176,7 @@ public class GeoBBoxTest {
 
     // Check wide variants of rectangle and longitude slice
 
-    c = GeoBBoxFactory.makeGeoBBox(0.0, -Math.PI * 0.25, -Math.PI + 0.1, Math.PI - 0.1);
+    c = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, 0.0, -Math.PI * 0.25, -Math.PI + 0.1, Math.PI - 0.1);
 
     b = c.getBounds(null);
     assertTrue(b.checkNoLongitudeBound());
@@ -187,7 +187,7 @@ public class GeoBBoxTest {
     assertEquals(-Math.PI * 0.25, b.getMinLatitude(), 0.000001);
     assertEquals(0.0, b.getMaxLatitude(), 0.000001);
 
-    c = GeoBBoxFactory.makeGeoBBox(0.0, -Math.PI * 0.25, Math.PI - 0.1, -Math.PI + 0.1);
+    c = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, 0.0, -Math.PI * 0.25, Math.PI - 0.1, -Math.PI + 0.1);
 
     b = c.getBounds(null);
     assertFalse(b.checkNoLongitudeBound());
@@ -198,7 +198,7 @@ public class GeoBBoxTest {
     assertEquals(-Math.PI * 0.25, b.getMinLatitude(), 0.000001);
     assertEquals(0.0, b.getMaxLatitude(), 0.000001);
 
-    c = GeoBBoxFactory.makeGeoBBox(Math.PI * 0.5, -Math.PI * 0.5, -Math.PI + 0.1, Math.PI - 0.1);
+    c = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, Math.PI * 0.5, -Math.PI * 0.5, -Math.PI + 0.1, Math.PI - 0.1);
 
     b = c.getBounds(null);
     assertTrue(b.checkNoLongitudeBound());
@@ -207,7 +207,7 @@ public class GeoBBoxTest {
     //assertEquals(-Math.PI+0.1,b.getLeftLongitude(),0.000001);
     //assertEquals(Math.PI-0.1,b.getRightLongitude(),0.000001);
 
-    c = GeoBBoxFactory.makeGeoBBox(Math.PI * 0.5, -Math.PI * 0.5, Math.PI - 0.1, -Math.PI + 0.1);
+    c = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, Math.PI * 0.5, -Math.PI * 0.5, Math.PI - 0.1, -Math.PI + 0.1);
 
     b = c.getBounds(null);
     assertFalse(b.checkNoLongitudeBound());
@@ -217,7 +217,7 @@ public class GeoBBoxTest {
     assertEquals(-Math.PI + 0.1, b.getRightLongitude(), 0.000001);
 
     // Check latitude zone
-    c = GeoBBoxFactory.makeGeoBBox(1.0, -1.0, -Math.PI, Math.PI);
+    c = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, 1.0, -1.0, -Math.PI, Math.PI);
 
     b = c.getBounds(null);
     assertTrue(b.checkNoLongitudeBound());
@@ -230,8 +230,8 @@ public class GeoBBoxTest {
     GeoBBox c1;
     GeoBBox c2;
 
-    c1 = GeoBBoxFactory.makeGeoBBox(Math.PI * 0.5, -Math.PI * 0.5, -Math.PI, 0.0);
-    c2 = GeoBBoxFactory.makeGeoBBox(Math.PI * 0.5, -Math.PI * 0.5, 0.0, Math.PI);
+    c1 = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, Math.PI * 0.5, -Math.PI * 0.5, -Math.PI, 0.0);
+    c2 = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, Math.PI * 0.5, -Math.PI * 0.5, 0.0, Math.PI);
 
     b = new Bounds();
     b = c1.getBounds(b);
@@ -240,8 +240,8 @@ public class GeoBBoxTest {
     assertTrue(b.checkNoTopLatitudeBound());
     assertTrue(b.checkNoBottomLatitudeBound());
 
-    c1 = GeoBBoxFactory.makeGeoBBox(Math.PI * 0.5, -Math.PI * 0.5, -Math.PI, 0.0);
-    c2 = GeoBBoxFactory.makeGeoBBox(Math.PI * 0.5, -Math.PI * 0.5, 0.0, Math.PI * 0.5);
+    c1 = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, Math.PI * 0.5, -Math.PI * 0.5, -Math.PI, 0.0);
+    c2 = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, Math.PI * 0.5, -Math.PI * 0.5, 0.0, Math.PI * 0.5);
 
     b = new Bounds();
     b = c1.getBounds(b);
@@ -252,8 +252,8 @@ public class GeoBBoxTest {
     //assertEquals(-Math.PI,b.getLeftLongitude(),0.000001);
     //assertEquals(Math.PI*0.5,b.getRightLongitude(),0.000001);
 
-    c1 = GeoBBoxFactory.makeGeoBBox(Math.PI * 0.5, -Math.PI * 0.5, -Math.PI * 0.5, 0.0);
-    c2 = GeoBBoxFactory.makeGeoBBox(Math.PI * 0.5, -Math.PI * 0.5, 0.0, Math.PI);
+    c1 = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, Math.PI * 0.5, -Math.PI * 0.5, -Math.PI * 0.5, 0.0);
+    c2 = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, Math.PI * 0.5, -Math.PI * 0.5, 0.0, Math.PI);
 
     b = new Bounds();
     b = c1.getBounds(b);