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 2012/09/05 17:37:13 UTC

svn commit: r1381230 - in /lucene/dev/trunk: dev-tools/maven/ lucene/spatial/ lucene/spatial/src/java/org/apache/lucene/spatial/bbox/ lucene/spatial/src/java/org/apache/lucene/spatial/prefix/ lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tre...

Author: dsmiley
Date: Wed Sep  5 15:37:11 2012
New Revision: 1381230

URL: http://svn.apache.org/viewvc?rev=1381230&view=rev
Log:
LUCENE-4351 update to Spatial4j 0.3.  Lucene spatial distances are now all degrees based (0-180).  Also, improved TestRecursivePrefixTreeStrategy.geohashRecursiveRandom() to use circle index clusters.

Modified:
    lucene/dev/trunk/dev-tools/maven/pom.xml.template
    lucene/dev/trunk/lucene/spatial/build.xml
    lucene/dev/trunk/lucene/spatial/ivy.xml
    lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/bbox/AreaSimilarity.java
    lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/bbox/BBoxSimilarityValueSource.java
    lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/PrefixTreeStrategy.java
    lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/RecursivePrefixTreeFilter.java
    lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/GeohashPrefixTree.java
    lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/Node.java
    lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/QuadPrefixTree.java
    lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/SpatialPrefixTree.java
    lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/SpatialPrefixTreeFactory.java
    lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/query/SpatialArgs.java
    lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/query/SpatialArgsParser.java
    lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/query/SpatialOperation.java
    lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/vector/TwoDoublesStrategy.java
    lucene/dev/trunk/lucene/spatial/src/test/org/apache/lucene/spatial/PortedSolr3Test.java
    lucene/dev/trunk/lucene/spatial/src/test/org/apache/lucene/spatial/SpatialExample.java
    lucene/dev/trunk/lucene/spatial/src/test/org/apache/lucene/spatial/StrategyTestCase.java
    lucene/dev/trunk/lucene/spatial/src/test/org/apache/lucene/spatial/TestTestFramework.java
    lucene/dev/trunk/lucene/spatial/src/test/org/apache/lucene/spatial/bbox/TestBBoxStrategy.java
    lucene/dev/trunk/lucene/spatial/src/test/org/apache/lucene/spatial/prefix/TestRecursivePrefixTreeStrategy.java
    lucene/dev/trunk/lucene/spatial/src/test/org/apache/lucene/spatial/prefix/TestTermQueryPrefixGridStrategy.java
    lucene/dev/trunk/lucene/spatial/src/test/org/apache/lucene/spatial/prefix/tree/SpatialPrefixTreeTest.java
    lucene/dev/trunk/lucene/spatial/src/test/org/apache/lucene/spatial/query/SpatialArgsParserTest.java
    lucene/dev/trunk/lucene/spatial/src/test/org/apache/lucene/spatial/vector/TestTwoDoublesStrategy.java
    lucene/dev/trunk/solr/core/ivy.xml
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/schema/GeoHashField.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/schema/LatLonType.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/schema/PointType.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/SpatialFilterQParser.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/SpatialOptions.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/ValueSourceParser.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/function/distance/GeohashFunction.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/function/distance/GeohashHaversineFunction.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/function/distance/HaversineConstFunction.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/function/distance/HaversineFunction.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/search/function/distance/DistanceFunctionTest.java

Modified: lucene/dev/trunk/dev-tools/maven/pom.xml.template
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/dev-tools/maven/pom.xml.template?rev=1381230&r1=1381229&r2=1381230&view=diff
==============================================================================
--- lucene/dev/trunk/dev-tools/maven/pom.xml.template (original)
+++ lucene/dev/trunk/dev-tools/maven/pom.xml.template Wed Sep  5 15:37:11 2012
@@ -418,7 +418,7 @@
       <dependency>
         <groupId>com.spatial4j</groupId>
         <artifactId>spatial4j</artifactId>
-        <version>0.2</version>
+        <version>0.3</version>
       </dependency>
       <dependency>
         <groupId>xerces</groupId>

Modified: lucene/dev/trunk/lucene/spatial/build.xml
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/spatial/build.xml?rev=1381230&r1=1381229&r2=1381230&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/spatial/build.xml (original)
+++ lucene/dev/trunk/lucene/spatial/build.xml Wed Sep  5 15:37:11 2012
@@ -7,7 +7,7 @@
   <import file="../module-build.xml"/>
 
   <path id="spatialjar">
-     <pathelement path="lib/spatial4j-0.2.jar"/>
+     <pathelement path="lib/spatial4j-0.3.jar"/>
   </path>
 
   <path id="classpath">

Modified: lucene/dev/trunk/lucene/spatial/ivy.xml
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/spatial/ivy.xml?rev=1381230&r1=1381229&r2=1381230&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/spatial/ivy.xml (original)
+++ lucene/dev/trunk/lucene/spatial/ivy.xml Wed Sep  5 15:37:11 2012
@@ -19,7 +19,7 @@
 <ivy-module version="2.0">
     <info organisation="org.apache.lucene" module="spatial"/>
     <dependencies>
-      <dependency org="com.spatial4j" name="spatial4j" rev="0.2" transitive="false"/>
+      <dependency org="com.spatial4j" name="spatial4j" rev="0.3" transitive="false"/>
       <exclude org="*" ext="*" matcher="regexp" type="${ivy.exclude.types}"/> 
     </dependencies>
 </ivy-module>

Modified: lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/bbox/AreaSimilarity.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/bbox/AreaSimilarity.java?rev=1381230&r1=1381229&r2=1381230&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/bbox/AreaSimilarity.java (original)
+++ lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/bbox/AreaSimilarity.java Wed Sep  5 15:37:11 2012
@@ -57,7 +57,7 @@ public class AreaSimilarity implements B
 
   public AreaSimilarity(Rectangle queryExtent, double queryPower, double targetPower) {
     this.queryExtent = queryExtent;
-    this.queryArea = queryExtent.getArea();
+    this.queryArea = queryExtent.getArea(null);
 
     this.queryPower = queryPower;
     this.targetPower = targetPower;
@@ -84,7 +84,7 @@ public class AreaSimilarity implements B
     if (target == null || queryArea <= 0) {
       return 0;
     }
-    double targetArea = target.getArea();
+    double targetArea = target.getArea(null);
     if (targetArea <= 0) {
       return 0;
     }

Modified: lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/bbox/BBoxSimilarityValueSource.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/bbox/BBoxSimilarityValueSource.java?rev=1381230&r1=1381229&r2=1381230&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/bbox/BBoxSimilarityValueSource.java (original)
+++ lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/bbox/BBoxSimilarityValueSource.java Wed Sep  5 15:37:11 2012
@@ -18,7 +18,6 @@ package org.apache.lucene.spatial.bbox;
  */
 
 import com.spatial4j.core.shape.Rectangle;
-import com.spatial4j.core.shape.simple.RectangleImpl;
 import org.apache.lucene.index.AtomicReader;
 import org.apache.lucene.index.AtomicReaderContext;
 import org.apache.lucene.queries.function.FunctionValues;
@@ -74,11 +73,14 @@ public class BBoxSimilarityValueSource e
     final Bits validMaxX = FieldCache.DEFAULT.getDocsWithField(reader, strategy.field_maxX);
 
     return new FunctionValues() {
+      //reused
+      Rectangle rect = strategy.getSpatialContext().makeRectangle(0,0,0,0);
+
       @Override
       public float floatVal(int doc) {
         // make sure it has minX and area
         if (validMinX.get(doc) && validMaxX.get(doc)) {
-          Rectangle rect = new RectangleImpl(
+          rect.reset(
               minX[doc], maxX[doc],
               minY[doc], maxY[doc]);
           return (float) similarity.score(rect, null);
@@ -89,7 +91,7 @@ public class BBoxSimilarityValueSource e
       public Explanation explain(int doc) {
         // make sure it has minX and area
         if (validMinX.get(doc) && validMaxX.get(doc)) {
-          Rectangle rect = new RectangleImpl(
+          rect.reset(
               minX[doc], maxX[doc],
               minY[doc], maxY[doc]);
           Explanation exp = new Explanation();

Modified: lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/PrefixTreeStrategy.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/PrefixTreeStrategy.java?rev=1381230&r1=1381229&r2=1381230&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/PrefixTreeStrategy.java (original)
+++ lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/PrefixTreeStrategy.java Wed Sep  5 15:37:11 2012
@@ -25,7 +25,6 @@ import org.apache.lucene.analysis.tokena
 import org.apache.lucene.document.Field;
 import org.apache.lucene.document.FieldType;
 import org.apache.lucene.index.FieldInfo;
-import org.apache.lucene.index.IndexableField;
 import org.apache.lucene.queries.function.ValueSource;
 import org.apache.lucene.spatial.SpatialStrategy;
 import org.apache.lucene.spatial.prefix.tree.Node;

Modified: lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/RecursivePrefixTreeFilter.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/RecursivePrefixTreeFilter.java?rev=1381230&r1=1381229&r2=1381230&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/RecursivePrefixTreeFilter.java (original)
+++ lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/RecursivePrefixTreeFilter.java Wed Sep  5 15:37:11 2012
@@ -142,7 +142,7 @@ RE "scan" threshold:
             if (termLevel == detailLevel || scanCell.isLeaf()) {
               //TODO should put more thought into implications of box vs point
               Shape cShape = termLevel == grid.getMaxLevels() ? scanCell.getCenter() : scanCell.getShape();
-              if(queryShape.relate(cShape, grid.getSpatialContext()) == SpatialRelation.DISJOINT)
+              if(queryShape.relate(cShape) == SpatialRelation.DISJOINT)
                 continue;
 
               docsEnum = termsEnum.docs(acceptDocs, docsEnum, 0);

Modified: lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/GeohashPrefixTree.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/GeohashPrefixTree.java?rev=1381230&r1=1381229&r2=1381230&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/GeohashPrefixTree.java (original)
+++ lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/GeohashPrefixTree.java Wed Sep  5 15:37:11 2012
@@ -21,7 +21,7 @@ import com.spatial4j.core.context.Spatia
 import com.spatial4j.core.shape.Point;
 import com.spatial4j.core.shape.Rectangle;
 import com.spatial4j.core.shape.Shape;
-import com.spatial4j.core.util.GeohashUtils;
+import com.spatial4j.core.io.GeohashUtils;
 
 import java.util.ArrayList;
 import java.util.Collection;
@@ -67,41 +67,10 @@ public class GeohashPrefixTree extends S
 
   @Override
   public int getLevelForDistance(double dist) {
-    final int level = lookupHashLenForWidthHeight(dist, dist);
+    final int level = GeohashUtils.lookupHashLenForWidthHeight(dist, dist);
     return Math.max(Math.min(level, maxLevels), 1);
   }
 
-  /* TODO temporarily in-lined GeoHashUtils.lookupHashLenForWidthHeight() is fixed in Spatial4j 0.3 */
-
-  /**
-   * Return the longest geohash length that will have a width & height >= specified arguments.
-   */
-  private static int lookupHashLenForWidthHeight(double lonErr, double latErr) {
-    //loop through hash length arrays from beginning till we find one.
-    for(int len = 1; len <= GeohashUtils.MAX_PRECISION; len++) {
-      double latHeight = hashLenToLatHeight[len];
-      double lonWidth = hashLenToLonWidth[len];
-      if (latHeight < latErr && lonWidth < lonErr)
-        return len;
-    }
-    return GeohashUtils.MAX_PRECISION;
-  }
-
-  /** See the table at http://en.wikipedia.org/wiki/Geohash */
-  private static final double[] hashLenToLatHeight, hashLenToLonWidth;
-  static {
-    hashLenToLatHeight = new double[GeohashUtils.MAX_PRECISION +1];
-    hashLenToLonWidth = new double[GeohashUtils.MAX_PRECISION +1];
-    hashLenToLatHeight[0] = 90*2;
-    hashLenToLonWidth[0] = 180*2;
-    boolean even = false;
-    for(int i = 1; i <= GeohashUtils.MAX_PRECISION; i++) {
-      hashLenToLatHeight[i] = hashLenToLatHeight[i-1]/(even?8:4);
-      hashLenToLonWidth[i] = hashLenToLonWidth[i-1]/(even?4:8);
-      even = ! even;
-    }
-  }
-
   @Override
   public Node getNode(Point p, int level) {
     return new GhCell(GeohashUtils.encodeLatLon(p.getY(), p.getX(), level));//args are lat,lon (y,x)

Modified: lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/Node.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/Node.java?rev=1381230&r1=1381229&r2=1381230&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/Node.java (original)
+++ lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/Node.java Wed Sep  5 15:37:11 2012
@@ -152,7 +152,7 @@ public abstract class Node implements Co
     }
     List<Node> copy = new ArrayList<Node>(cells.size());//copy since cells contractually isn't modifiable
     for (Node cell : cells) {
-      SpatialRelation rel = cell.getShape().relate(shapeFilter, spatialPrefixTree.ctx);
+      SpatialRelation rel = cell.getShape().relate(shapeFilter);
       if (rel == SpatialRelation.DISJOINT)
         continue;
       cell.shapeRel = rel;

Modified: lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/QuadPrefixTree.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/QuadPrefixTree.java?rev=1381230&r1=1381229&r2=1381230&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/QuadPrefixTree.java (original)
+++ lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/QuadPrefixTree.java Wed Sep  5 15:37:11 2012
@@ -22,7 +22,6 @@ import com.spatial4j.core.shape.Point;
 import com.spatial4j.core.shape.Rectangle;
 import com.spatial4j.core.shape.Shape;
 import com.spatial4j.core.shape.SpatialRelation;
-import com.spatial4j.core.shape.simple.PointImpl;
 
 import java.io.PrintStream;
 import java.text.NumberFormat;
@@ -134,7 +133,7 @@ public class QuadPrefixTree extends Spat
   @Override
   public Node getNode(Point p, int level) {
     List<Node> cells = new ArrayList<Node>(1);
-    build(xmid, ymid, 0, cells, new StringBuilder(), new PointImpl(p.getX(),p.getY()), level);
+    build(xmid, ymid, 0, cells, new StringBuilder(), ctx.makePoint(p.getX(),p.getY()), level);
     return cells.get(0);//note cells could be longer if p on edge
   }
 
@@ -195,8 +194,8 @@ public class QuadPrefixTree extends Spat
     double h = levelH[level] / 2;
 
     int strlen = str.length();
-    Rectangle rectangle = ctx.makeRect(cx - w, cx + w, cy - h, cy + h);
-    SpatialRelation v = shape.relate(rectangle, ctx);
+    Rectangle rectangle = ctx.makeRectangle(cx - w, cx + w, cy - h, cy + h);
+    SpatialRelation v = shape.relate(rectangle);
     if (SpatialRelation.CONTAINS == v) {
       str.append(c);
       //str.append(SpatialPrefixGrid.COVER);
@@ -297,7 +296,7 @@ public class QuadPrefixTree extends Spat
         width = gridW;
         height = gridH;
       }
-      return ctx.makeRect(xmin, xmin + width, ymin, ymin + height);
+      return ctx.makeRectangle(xmin, xmin + width, ymin, ymin + height);
     }
   }//QuadCell
 }

Modified: lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/SpatialPrefixTree.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/SpatialPrefixTree.java?rev=1381230&r1=1381229&r2=1381230&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/SpatialPrefixTree.java (original)
+++ lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/SpatialPrefixTree.java Wed Sep  5 15:37:11 2012
@@ -83,8 +83,6 @@ public abstract class SpatialPrefixTree 
     // and this is the longest distance that might be occurring within the shape.
     double diagonalDist = ctx.getDistCalc().distance(
         ctx.makePoint(bbox.getMinX(), bbox.getMinY()), bbox.getMaxX(), bbox.getMaxY());
-    //convert to degrees    //TODO not needed in Spatial4j 0.3
-    diagonalDist = ctx.getDistCalc().distanceToDegrees(diagonalDist);
     return getLevelForDistance(diagonalDist * 0.5 * precision);
   }
 

Modified: lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/SpatialPrefixTreeFactory.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/SpatialPrefixTreeFactory.java?rev=1381230&r1=1381229&r2=1381230&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/SpatialPrefixTreeFactory.java (original)
+++ lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/prefix/tree/SpatialPrefixTreeFactory.java Wed Sep  5 15:37:11 2012
@@ -18,7 +18,6 @@
 package org.apache.lucene.spatial.prefix.tree;
 
 import com.spatial4j.core.context.SpatialContext;
-import com.spatial4j.core.distance.DistanceUnits;
 import com.spatial4j.core.distance.DistanceUtils;
 
 import java.util.Map;
@@ -78,11 +77,14 @@ public abstract class SpatialPrefixTreeF
       if (!ctx.isGeo()) {
         return;//let default to max
       }
-      degrees = DistanceUtils.dist2Degrees(DEFAULT_GEO_MAX_DETAIL_KM, DistanceUnits.KILOMETERS.earthRadius());
+      degrees = DistanceUtils.dist2Degrees(DEFAULT_GEO_MAX_DETAIL_KM, DistanceUtils.EARTH_MEAN_RADIUS_KM);
     } else {
-      degrees = DistanceUtils.dist2Degrees(Double.parseDouble(maxDetailDistStr), ctx.getUnits().earthRadius());
+      degrees = Double.parseDouble(maxDetailDistStr);
+      if (ctx.isGeo()) {
+        degrees = DistanceUtils.dist2Degrees(Double.parseDouble(maxDetailDistStr), DistanceUtils.EARTH_MEAN_RADIUS_KM);
+      }
     }
-    maxLevels = getLevelForDistance(degrees) + 1;//returns 1 greater
+    maxLevels = getLevelForDistance(degrees);
   }
 
   /** Calls {@link SpatialPrefixTree#getLevelForDistance(double)}. */

Modified: lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/query/SpatialArgs.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/query/SpatialArgs.java?rev=1381230&r1=1381229&r2=1381230&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/query/SpatialArgs.java (original)
+++ lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/query/SpatialArgs.java Wed Sep  5 15:37:11 2012
@@ -19,7 +19,6 @@ package org.apache.lucene.spatial.query;
 
 import java.util.Locale;
 
-import com.spatial4j.core.exception.InvalidSpatialArgument;
 import com.spatial4j.core.shape.Shape;
 
 /**
@@ -45,9 +44,9 @@ public class SpatialArgs {
   }
 
   /** Check if the arguments make sense -- throw an exception if not */
-  public void validate() throws InvalidSpatialArgument {
+  public void validate() throws IllegalArgumentException {
     if (operation.isTargetNeedsArea() && !shape.hasArea()) {
-      throw new InvalidSpatialArgument(operation + " only supports geometry with area");
+      throw new IllegalArgumentException(operation + " only supports geometry with area");
     }
   }
 

Modified: lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/query/SpatialArgsParser.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/query/SpatialArgsParser.java?rev=1381230&r1=1381229&r2=1381230&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/query/SpatialArgsParser.java (original)
+++ lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/query/SpatialArgsParser.java Wed Sep  5 15:37:11 2012
@@ -19,7 +19,7 @@ package org.apache.lucene.spatial.query;
 
 import com.spatial4j.core.context.SpatialContext;
 import com.spatial4j.core.exception.InvalidShapeException;
-import com.spatial4j.core.exception.InvalidSpatialArgument;
+import com.spatial4j.core.io.ShapeReadWriter;
 import com.spatial4j.core.shape.Shape;
 
 import java.util.HashMap;
@@ -30,7 +30,7 @@ import java.util.StringTokenizer;
  * Parses a string that usually looks like "OPERATION(SHAPE)" into a {@link SpatialArgs}
  * object. The set of operations supported are defined in {@link SpatialOperation}, such
  * as "Intersects" being a common one. The shape portion is defined by {@link
- * SpatialContext#readShape(String)}. There are some optional name-value pair parameters
+ * ShapeReadWriter#readShape(String)}. There are some optional name-value pair parameters
  * that follow the closing parenthesis.  Example:
  * <pre>
  *   Intersects(-10,20,-8,22) distPec=0.025
@@ -50,25 +50,25 @@ public class SpatialArgsParser {
    * @param v   The string to parse. Mandatory.
    * @param ctx The spatial context. Mandatory.
    * @return Not null.
-   * @throws InvalidSpatialArgument If there is a problem parsing the string.
-   * @throws InvalidShapeException  Thrown from {@link SpatialContext#readShape(String)}
+   * @throws IllegalArgumentException If there is a problem parsing the string.
+   * @throws InvalidShapeException  Thrown from {@link ShapeReadWriter#readShape(String)}
    */
-  public SpatialArgs parse(String v, SpatialContext ctx) throws InvalidSpatialArgument, InvalidShapeException {
+  public SpatialArgs parse(String v, SpatialContext ctx) throws IllegalArgumentException, InvalidShapeException {
     int idx = v.indexOf('(');
     int edx = v.lastIndexOf(')');
 
     if (idx < 0 || idx > edx) {
-      throw new InvalidSpatialArgument("missing parens: " + v, null);
+      throw new IllegalArgumentException("missing parens: " + v, null);
     }
 
     SpatialOperation op = SpatialOperation.get(v.substring(0, idx).trim());
 
     String body = v.substring(idx + 1, edx).trim();
     if (body.length() < 1) {
-      throw new InvalidSpatialArgument("missing body : " + v, null);
+      throw new IllegalArgumentException("missing body : " + v, null);
     }
 
-    Shape shape = ctx.readShape(body);
+    Shape shape = new ShapeReadWriter(ctx).readShape(body);
     SpatialArgs args = new SpatialArgs(op, shape);
 
     if (v.length() > (edx + 1)) {
@@ -77,7 +77,7 @@ public class SpatialArgsParser {
         Map<String, String> aa = parseMap(body);
         args.setDistPrecision(readDouble(aa.remove("distPrec")));
         if (!aa.isEmpty()) {
-          throw new InvalidSpatialArgument("unused parameters: " + aa, null);
+          throw new IllegalArgumentException("unused parameters: " + aa, null);
         }
       }
     }

Modified: lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/query/SpatialOperation.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/query/SpatialOperation.java?rev=1381230&r1=1381229&r2=1381230&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/query/SpatialOperation.java (original)
+++ lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/query/SpatialOperation.java Wed Sep  5 15:37:11 2012
@@ -17,8 +17,6 @@ package org.apache.lucene.spatial.query;
  * limitations under the License.
  */
 
-import com.spatial4j.core.exception.InvalidSpatialArgument;
-
 import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -71,7 +69,7 @@ public class SpatialOperation implements
       op = registry.get(v.toUpperCase(Locale.ROOT));
     }
     if( op == null ) {
-      throw new InvalidSpatialArgument("Unknown Operation: " + v );
+      throw new IllegalArgumentException("Unknown Operation: " + v );
     }
     return op;
   }

Modified: lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/vector/TwoDoublesStrategy.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/vector/TwoDoublesStrategy.java?rev=1381230&r1=1381229&r2=1381230&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/vector/TwoDoublesStrategy.java (original)
+++ lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/vector/TwoDoublesStrategy.java Wed Sep  5 15:37:11 2012
@@ -113,7 +113,7 @@ public class TwoDoublesStrategy extends 
         ValueSource valueSource = makeValueSource(args);
 
         return new ValueSourceFilter(
-            new QueryWrapperFilter( bbox ), valueSource, 0, circle.getDistance() );
+            new QueryWrapperFilter( bbox ), valueSource, 0, circle.getRadius() );
       }
     }
     return new QueryWrapperFilter( makeQuery(args) );
@@ -155,7 +155,7 @@ public class TwoDoublesStrategy extends 
         valueSource = makeValueSource(args);
 
         ValueSourceFilter vsf = new ValueSourceFilter(
-            new QueryWrapperFilter( spatial ), valueSource, 0, circle.getDistance() );
+            new QueryWrapperFilter( spatial ), valueSource, 0, circle.getRadius() );
 
         spatial = new FilteredQuery( new MatchAllDocsQuery(), vsf );
       }

Modified: lucene/dev/trunk/lucene/spatial/src/test/org/apache/lucene/spatial/PortedSolr3Test.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/spatial/src/test/org/apache/lucene/spatial/PortedSolr3Test.java?rev=1381230&r1=1381229&r2=1381230&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/spatial/src/test/org/apache/lucene/spatial/PortedSolr3Test.java (original)
+++ lucene/dev/trunk/lucene/spatial/src/test/org/apache/lucene/spatial/PortedSolr3Test.java Wed Sep  5 15:37:11 2012
@@ -20,14 +20,14 @@ package org.apache.lucene.spatial;
 import com.carrotsearch.randomizedtesting.annotations.Name;
 import com.carrotsearch.randomizedtesting.annotations.ParametersFactory;
 import com.spatial4j.core.context.SpatialContext;
-import com.spatial4j.core.context.simple.SimpleSpatialContext;
+import com.spatial4j.core.distance.DistanceUtils;
+import com.spatial4j.core.io.ShapeReadWriter;
 import com.spatial4j.core.shape.Point;
 import com.spatial4j.core.shape.Shape;
 import org.apache.lucene.document.Document;
 import org.apache.lucene.document.Field;
 import org.apache.lucene.document.StoredField;
 import org.apache.lucene.document.StringField;
-import org.apache.lucene.index.IndexableField;
 import org.apache.lucene.search.FilteredQuery;
 import org.apache.lucene.search.MatchAllDocsQuery;
 import org.apache.lucene.search.Query;
@@ -55,7 +55,7 @@ public class PortedSolr3Test extends Str
   public static Iterable<Object[]> parameters() {
     List<Object[]> ctorArgs = new ArrayList<Object[]>();
 
-    SpatialContext ctx = SimpleSpatialContext.GEO_KM;
+    SpatialContext ctx = SpatialContext.GEO;
     SpatialPrefixTree grid;
     SpatialStrategy strategy;
 
@@ -121,6 +121,7 @@ public class PortedSolr3Test extends Str
   public void testIntersections() throws Exception {
     setupDocs();
     //Try some edge cases
+      //NOTE: 2nd arg is distance in kilometers
     checkHitsCircle("1,1", 175, 3, 5, 6, 7);
     checkHitsCircle("0,179.8", 200, 2, 8, 9);
     checkHitsCircle("89.8, 50", 200, 2, 10, 11);//this goes over the north pole
@@ -164,11 +165,12 @@ public class PortedSolr3Test extends Str
     adoc("100","1,2");
     adoc("101","4,-1");
     commit();
+    double km1000inDeg = DistanceUtils.dist2Degrees(1000, DistanceUtils.EARTH_MEAN_RADIUS_KM);
 
     //query closer to #100
-    checkHitsOrdered("Intersects(Circle(3,4 d=1000))", "101", "100");
+    checkHitsOrdered("Intersects(Circle(3,4 d="+km1000inDeg+"))", "101", "100");
     //query closer to #101
-    checkHitsOrdered("Intersects(Circle(4,0 d=1000))", "100", "101");
+    checkHitsOrdered("Intersects(Circle(4,0 d="+km1000inDeg+"))", "100", "101");
   }
 
   private void checkHitsOrdered(String spatialQ, String... ids) {
@@ -186,7 +188,7 @@ public class PortedSolr3Test extends Str
   //---- these are similar to Solr test methods
   
   private void adoc(String idStr, String shapeStr) throws IOException {
-    Shape shape = ctx.readShape(shapeStr);
+    Shape shape = new ShapeReadWriter(ctx).readShape(shapeStr);
     addDocument(newDoc(idStr,shape));
   }
 
@@ -202,17 +204,18 @@ public class PortedSolr3Test extends Str
     return doc;
   }
 
-  private void checkHitsCircle(String ptStr, double dist, int assertNumFound, int... assertIds) {
-    _checkHits(SpatialOperation.Intersects, ptStr, dist, assertNumFound, assertIds);
+  private void checkHitsCircle(String ptStr, double distKM, int assertNumFound, int... assertIds) {
+    _checkHits(SpatialOperation.Intersects, ptStr, distKM, assertNumFound, assertIds);
   }
-  private void checkHitsBBox(String ptStr, double dist, int assertNumFound, int... assertIds) {
-    _checkHits(SpatialOperation.BBoxIntersects, ptStr, dist, assertNumFound, assertIds);
+  private void checkHitsBBox(String ptStr, double distKM, int assertNumFound, int... assertIds) {
+    _checkHits(SpatialOperation.BBoxIntersects, ptStr, distKM, assertNumFound, assertIds);
   }
 
   @SuppressWarnings("unchecked")
-  private void _checkHits(SpatialOperation op, String ptStr, double dist, int assertNumFound, int... assertIds) {
-    Point pt = (Point) ctx.readShape(ptStr);
-    Shape shape = ctx.makeCircle(pt,dist);
+  private void _checkHits(SpatialOperation op, String ptStr, double distKM, int assertNumFound, int... assertIds) {
+    Point pt = (Point) new ShapeReadWriter(ctx).readShape(ptStr);
+    double distDEG = DistanceUtils.dist2Degrees(distKM, DistanceUtils.EARTH_MEAN_RADIUS_KM);
+    Shape shape = ctx.makeCircle(pt, distDEG);
 
     SpatialArgs args = new SpatialArgs(op,shape);
     //args.setDistPrecision(0.025);

Modified: lucene/dev/trunk/lucene/spatial/src/test/org/apache/lucene/spatial/SpatialExample.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/spatial/src/test/org/apache/lucene/spatial/SpatialExample.java?rev=1381230&r1=1381229&r2=1381230&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/spatial/src/test/org/apache/lucene/spatial/SpatialExample.java (original)
+++ lucene/dev/trunk/lucene/spatial/src/test/org/apache/lucene/spatial/SpatialExample.java Wed Sep  5 15:37:11 2012
@@ -18,7 +18,8 @@ package org.apache.lucene.spatial;
  */
 
 import com.spatial4j.core.context.SpatialContext;
-import com.spatial4j.core.context.simple.SimpleSpatialContext;
+import com.spatial4j.core.distance.DistanceUtils;
+import com.spatial4j.core.io.ShapeReadWriter;
 import com.spatial4j.core.shape.Shape;
 import org.apache.lucene.document.Document;
 import org.apache.lucene.document.Field;
@@ -28,7 +29,6 @@ import org.apache.lucene.index.Directory
 import org.apache.lucene.index.IndexReader;
 import org.apache.lucene.index.IndexWriter;
 import org.apache.lucene.index.IndexWriterConfig;
-import org.apache.lucene.index.IndexableField;
 import org.apache.lucene.queries.function.ValueSource;
 import org.apache.lucene.search.Filter;
 import org.apache.lucene.search.IndexSearcher;
@@ -87,7 +87,7 @@ public class SpatialExample extends Luce
   protected void init() {
     //Typical geospatial context with kilometer units.
     //  These can also be constructed from a factory: SpatialContextFactory
-    this.ctx = SimpleSpatialContext.GEO_KM;
+    this.ctx = SpatialContext.GEO;
 
     int maxLevels = 10;//results in sub-meter precision for geohash
     //TODO demo lookup by detail distance
@@ -110,7 +110,7 @@ public class SpatialExample extends Luce
     //When parsing a string to a shape, the presence of a comma means it's y-x
     // order (lon, lat)
     indexWriter.addDocument(newSampleDocument(
-        4, ctx.readShape("-50.7693246, 60.9289094")));
+        4, new ShapeReadWriter(ctx).readShape("-50.7693246, 60.9289094")));
 
     indexWriter.addDocument(newSampleDocument(
         20, ctx.makePoint(0.1,0.1), ctx.makePoint(0, 0)));
@@ -144,7 +144,7 @@ public class SpatialExample extends Luce
       //Search with circle
       //note: SpatialArgs can be parsed from a string
       SpatialArgs args = new SpatialArgs(SpatialOperation.Intersects,
-          ctx.makeCircle(-80.0, 33.0, 200));//200km (since km == ctx.getDistanceUnits
+          ctx.makeCircle(-80.0, 33.0, DistanceUtils.dist2Degrees(200, DistanceUtils.EARTH_MEAN_RADIUS_KM)));
       Filter filter = strategy.makeFilter(args);
       TopDocs docs = indexSearcher.search(new MatchAllDocsQuery(), filter, 10, idSort);
       assertDocMatchedIds(indexSearcher, docs, 2);
@@ -153,7 +153,7 @@ public class SpatialExample extends Luce
     {
       SpatialArgs args = new SpatialArgs(SpatialOperation.Intersects,//doesn't matter
           ctx.makePoint(60, -50));
-      ValueSource valueSource = strategy.makeValueSource(args);//the distance
+      ValueSource valueSource = strategy.makeValueSource(args);//the distance (in degrees)
       Sort reverseDistSort = new Sort(valueSource.getSortField(false)).rewrite(indexSearcher);//true=asc dist
       TopDocs docs = indexSearcher.search(new MatchAllDocsQuery(), 10, reverseDistSort);
       assertDocMatchedIds(indexSearcher, docs, 4, 20, 2);
@@ -161,8 +161,8 @@ public class SpatialExample extends Luce
     //demo arg parsing
     {
       SpatialArgs args = new SpatialArgs(SpatialOperation.Intersects,
-          ctx.makeCircle(-80.0, 33.0, 200));
-      SpatialArgs args2 = new SpatialArgsParser().parse("Intersects(Circle(33,-80 d=200))", ctx);
+          ctx.makeCircle(-80.0, 33.0, 1));
+      SpatialArgs args2 = new SpatialArgsParser().parse("Intersects(Circle(33,-80 d=1))", ctx);
       assertEquals(args.toString(),args2.toString());
     }
 

Modified: lucene/dev/trunk/lucene/spatial/src/test/org/apache/lucene/spatial/StrategyTestCase.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/spatial/src/test/org/apache/lucene/spatial/StrategyTestCase.java?rev=1381230&r1=1381229&r2=1381230&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/spatial/src/test/org/apache/lucene/spatial/StrategyTestCase.java (original)
+++ lucene/dev/trunk/lucene/spatial/src/test/org/apache/lucene/spatial/StrategyTestCase.java Wed Sep  5 15:37:11 2012
@@ -19,6 +19,7 @@ package org.apache.lucene.spatial;
  */
 
 import com.spatial4j.core.context.SpatialContext;
+import com.spatial4j.core.io.ShapeReadWriter;
 import com.spatial4j.core.io.sample.SampleData;
 import com.spatial4j.core.io.sample.SampleDataReader;
 import com.spatial4j.core.shape.Shape;
@@ -84,7 +85,7 @@ public abstract class StrategyTestCase e
       Document document = new Document();
       document.add(new StringField("id", data.id, Field.Store.YES));
       document.add(new StringField("name", data.name, Field.Store.YES));
-      Shape shape = ctx.readShape(data.shape);
+      Shape shape = new ShapeReadWriter(ctx).readShape(data.shape);
       for (Field f : strategy.createIndexableFields(shape)) {
         document.add(f);
       }
@@ -117,7 +118,7 @@ public abstract class StrategyTestCase e
       SearchResults got = executeQuery(strategy.makeQuery(q.args), 100);
       if (storeShape && got.numFound > 0) {
         //check stored value is there & parses
-        assertNotNull(ctx.readShape(got.results.get(0).document.get(strategy.getFieldName())));
+        assertNotNull(new ShapeReadWriter(ctx).readShape(got.results.get(0).document.get(strategy.getFieldName())));
       }
       if (concern.orderIsImportant) {
         Iterator<String> ids = q.ids.iterator();

Modified: lucene/dev/trunk/lucene/spatial/src/test/org/apache/lucene/spatial/TestTestFramework.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/spatial/src/test/org/apache/lucene/spatial/TestTestFramework.java?rev=1381230&r1=1381229&r2=1381230&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/spatial/src/test/org/apache/lucene/spatial/TestTestFramework.java (original)
+++ lucene/dev/trunk/lucene/spatial/src/test/org/apache/lucene/spatial/TestTestFramework.java Wed Sep  5 15:37:11 2012
@@ -18,7 +18,7 @@ package org.apache.lucene.spatial;
  */
 
 import com.spatial4j.core.context.SpatialContext;
-import com.spatial4j.core.context.simple.SimpleSpatialContext;
+import com.spatial4j.core.context.SpatialContext;
 import com.spatial4j.core.shape.Rectangle;
 import org.apache.lucene.spatial.query.SpatialArgsParser;
 import org.apache.lucene.spatial.query.SpatialOperation;
@@ -43,7 +43,7 @@ public class TestTestFramework extends L
     String name = StrategyTestCase.QTEST_Cities_IsWithin_BBox;
 
     InputStream in = getClass().getClassLoader().getResourceAsStream(name);
-    SpatialContext ctx = SimpleSpatialContext.GEO_KM;
+    SpatialContext ctx = SpatialContext.GEO;
     Iterator<SpatialTestQuery> iter = SpatialTestQuery.getTestQueries(
         new SpatialArgsParser(), ctx, name, in );
     List<SpatialTestQuery> tests = new ArrayList<SpatialTestQuery>();

Modified: lucene/dev/trunk/lucene/spatial/src/test/org/apache/lucene/spatial/bbox/TestBBoxStrategy.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/spatial/src/test/org/apache/lucene/spatial/bbox/TestBBoxStrategy.java?rev=1381230&r1=1381229&r2=1381230&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/spatial/src/test/org/apache/lucene/spatial/bbox/TestBBoxStrategy.java (original)
+++ lucene/dev/trunk/lucene/spatial/src/test/org/apache/lucene/spatial/bbox/TestBBoxStrategy.java Wed Sep  5 15:37:11 2012
@@ -17,7 +17,7 @@ package org.apache.lucene.spatial.bbox;
  * limitations under the License.
  */
 
-import com.spatial4j.core.context.simple.SimpleSpatialContext;
+import com.spatial4j.core.context.SpatialContext;
 import org.apache.lucene.spatial.SpatialMatchConcern;
 import org.apache.lucene.spatial.StrategyTestCase;
 import org.junit.Before;
@@ -31,7 +31,7 @@ public class TestBBoxStrategy extends St
   @Override
   public void setUp() throws Exception {
     super.setUp();
-    this.ctx = SimpleSpatialContext.GEO_KM;
+    this.ctx = SpatialContext.GEO;
     this.strategy = new BBoxStrategy(ctx, "bbox");
   }
 

Modified: lucene/dev/trunk/lucene/spatial/src/test/org/apache/lucene/spatial/prefix/TestRecursivePrefixTreeStrategy.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/spatial/src/test/org/apache/lucene/spatial/prefix/TestRecursivePrefixTreeStrategy.java?rev=1381230&r1=1381229&r2=1381230&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/spatial/src/test/org/apache/lucene/spatial/prefix/TestRecursivePrefixTreeStrategy.java (original)
+++ lucene/dev/trunk/lucene/spatial/src/test/org/apache/lucene/spatial/prefix/TestRecursivePrefixTreeStrategy.java Wed Sep  5 15:37:11 2012
@@ -17,18 +17,16 @@ package org.apache.lucene.spatial.prefix
  * limitations under the License.
  */
 
-import com.spatial4j.core.context.simple.SimpleSpatialContext;
+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 com.spatial4j.core.shape.Shape;
-import com.spatial4j.core.shape.simple.PointImpl;
-import com.spatial4j.core.util.GeohashUtils;
+import com.spatial4j.core.io.GeohashUtils;
 import org.apache.lucene.document.Document;
 import org.apache.lucene.document.Field;
 import org.apache.lucene.document.StoredField;
 import org.apache.lucene.document.StringField;
-import org.apache.lucene.index.IndexableField;
 import org.apache.lucene.spatial.SpatialMatchConcern;
 import org.apache.lucene.spatial.StrategyTestCase;
 import org.apache.lucene.spatial.prefix.tree.GeohashPrefixTree;
@@ -43,8 +41,6 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 
-import static java.lang.Math.toRadians;
-
 public class TestRecursivePrefixTreeStrategy extends StrategyTestCase {
 
   private int maxLength;
@@ -52,7 +48,7 @@ public class TestRecursivePrefixTreeStra
   //Tests should call this first.
   private void init(int maxLength) {
     this.maxLength = maxLength;
-    this.ctx = SimpleSpatialContext.GEO_KM;
+    this.ctx = SpatialContext.GEO;
     GeohashPrefixTree grid = new GeohashPrefixTree(ctx, maxLength);
     this.strategy = new RecursivePrefixTreeStrategy(grid, getClass().getSimpleName());
   }
@@ -74,7 +70,8 @@ public class TestRecursivePrefixTreeStra
     init(GeohashPrefixTree.getMaxLevelsPossible());
     GeohashPrefixTree grid = (GeohashPrefixTree) ((RecursivePrefixTreeStrategy) strategy).getGrid();
     //DWS: I know this to be true.  11 is needed for one meter
-    assertEquals(11, grid.getLevelForDistance(ctx.getDistCalc().distanceToDegrees(0.001)));
+    double degrees = DistanceUtils.dist2Degrees(0.001, DistanceUtils.EARTH_MEAN_RADIUS_KM);
+    assertEquals(11, grid.getLevelForDistance(degrees));
   }
 
   @Test
@@ -87,8 +84,11 @@ public class TestRecursivePrefixTreeStra
 
     Point qPt = ctx.makePoint(2.4632387000000335, 48.6003516);
 
+    final double KM2DEG = DistanceUtils.dist2Degrees(1, DistanceUtils.EARTH_MEAN_RADIUS_KM);
+    final double DEG2KM = 1 / KM2DEG;
+
     final double DIST = 35.75;//35.7499...
-    assertEquals(DIST, ctx.getDistCalc().distance(iPt, qPt), 0.001);
+    assertEquals(DIST, ctx.getDistCalc().distance(iPt, qPt) * DEG2KM, 0.001);
 
     //distPrec will affect the query shape precision. The indexed precision
     // was set to nearly zilch via init(GeohashPrefixTree.getMaxLevelsPossible());
@@ -96,16 +96,16 @@ public class TestRecursivePrefixTreeStra
     final double distMult = 1+distPrec;
 
     assertTrue(35.74*distMult >= DIST);
-    checkHits(q(qPt, 35.74, distPrec), 1, null);
+    checkHits(q(qPt, 35.74 * KM2DEG, distPrec), 1, null);
 
     assertTrue(30*distMult < DIST);
-    checkHits(q(qPt, 30, distPrec), 0, null);
+    checkHits(q(qPt, 30 * KM2DEG, distPrec), 0, null);
 
     assertTrue(33*distMult < DIST);
-    checkHits(q(qPt, 33, distPrec), 0, null);
+    checkHits(q(qPt, 33 * KM2DEG, distPrec), 0, null);
 
     assertTrue(34*distMult < DIST);
-    checkHits(q(qPt, 34, distPrec), 0, null);
+    checkHits(q(qPt, 34 * KM2DEG, distPrec), 0, null);
   }
 
   @Test
@@ -113,70 +113,72 @@ public class TestRecursivePrefixTreeStra
     init(12);
 
     //1. Iterate test with the cluster at some worldly point of interest
-    Point[] clusterCenters = new Point[]{new PointImpl(0,0), new PointImpl(0,90),new PointImpl(0,-90)};
+    Point[] clusterCenters = new Point[]{ctx.makePoint(0,0), ctx.makePoint(0,90), ctx.makePoint(0,-90)};
     for (Point clusterCenter : clusterCenters) {
       //2. Iterate on size of cluster (a really small one and a large one)
       String hashCenter = GeohashUtils.encodeLatLon(clusterCenter.getY(), clusterCenter.getX(), maxLength);
       //calculate the number of degrees in the smallest grid box size (use for both lat & lon)
       String smallBox = hashCenter.substring(0,hashCenter.length()-1);//chop off leaf precision
       Rectangle clusterDims = GeohashUtils.decodeBoundary(smallBox,ctx);
-      double smallDegrees = Math.max(clusterDims.getMaxX()-clusterDims.getMinX(),clusterDims.getMaxY()-clusterDims.getMinY());
-      assert smallDegrees < 1;
-      double largeDegrees = 20d;//good large size; don't use >=45 for this test code to work
-      double[] sideDegrees = {largeDegrees,smallDegrees};
-      for (double sideDegree : sideDegrees) {
-        //3. Index random points in this cluster box
+      double smallRadius = Math.max(clusterDims.getMaxX()-clusterDims.getMinX(),clusterDims.getMaxY()-clusterDims.getMinY());
+      assert smallRadius < 1;
+      double largeRadius = 20d;//good large size; don't use >=45 for this test code to work
+      double[] radiusDegs = {largeRadius,smallRadius};
+      for (double radiusDeg : radiusDegs) {
+        //3. Index random points in this cluster circle
         deleteAll();
         List<Point> points = new ArrayList<Point>();
         for(int i = 0; i < 20; i++) {
-          double x = random().nextDouble()*sideDegree - sideDegree/2 + clusterCenter.getX();
-          double y = random().nextDouble()*sideDegree - sideDegree/2 + clusterCenter.getY();
-          final Point pt = normPointXY(x, y);
+          //Note that this will not result in randomly distributed points in the
+          // circle, they will be concentrated towards the center a little. But
+          // it's good enough.
+          Point pt = ctx.getDistCalc().pointOnBearing(clusterCenter,
+              random().nextDouble() * radiusDeg, random().nextInt() * 360, ctx, null);
+          pt = alignGeohash(pt);
           points.add(pt);
           addDocument(newDoc("" + i, pt));
         }
         commit();
 
-        //3. Use 4 query centers. Each is radially out from each corner of cluster box by twice distance to box edge.
-        for(double qcXoff : new double[]{sideDegree,-sideDegree}) {//query-center X offset from cluster center
-          for(double qcYoff : new double[]{sideDegree,-sideDegree}) {//query-center Y offset from cluster center
-            Point queryCenter = normPointXY(qcXoff + clusterCenter.getX(),
-                qcYoff + clusterCenter.getY());
-            double[] distRange = calcDistRange(queryCenter,clusterCenter,sideDegree);
-            //4.1 query a small box getting nothing
-            checkHits(q(queryCenter, distRange[0]*0.99), 0, null);
-            //4.2 Query a large box enclosing the cluster, getting everything
-            checkHits(q(queryCenter, distRange[1]*1.01), points.size(), null);
-            //4.3 Query a medium box getting some (calculate the correct solution and verify)
-            double queryDist = distRange[0] + (distRange[1]-distRange[0])/2;//average
-
-            //Find matching points.  Put into int[] of doc ids which is the same thing as the index into points list.
-            int[] ids = new int[points.size()];
-            int ids_sz = 0;
-            for (int i = 0; i < points.size(); i++) {
-              Point point = points.get(i);
-              if (ctx.getDistCalc().distance(queryCenter, point) <= queryDist)
-                ids[ids_sz++] = i;
-            }
-            ids = Arrays.copyOf(ids, ids_sz);
-            //assert ids_sz > 0 (can't because randomness keeps us from being able to)
-
-            checkHits(q(queryCenter, queryDist), ids.length, ids);
+        //3. Use some query centers. Each is twice the cluster's radius away.
+        for(int ri = 0; ri < 4; ri++) {
+          Point queryCenter = ctx.getDistCalc().pointOnBearing(clusterCenter,
+              radiusDeg*2, random().nextInt() * 360, ctx, null);
+          queryCenter = alignGeohash(queryCenter);
+          //4.1 Query a small box getting nothing
+          checkHits(q(queryCenter, radiusDeg*0.99), 0, null);
+          //4.2 Query a large box enclosing the cluster, getting everything
+          checkHits(q(queryCenter, radiusDeg*3*1.01), points.size(), null);
+          //4.3 Query a medium box getting some (calculate the correct solution and verify)
+          double queryDist = radiusDeg * 2;
+
+          //Find matching points.  Put into int[] of doc ids which is the same thing as the index into points list.
+          int[] ids = new int[points.size()];
+          int ids_sz = 0;
+          for (int i = 0; i < points.size(); i++) {
+            Point point = points.get(i);
+            if (ctx.getDistCalc().distance(queryCenter, point) <= queryDist)
+              ids[ids_sz++] = i;
           }
+          ids = Arrays.copyOf(ids, ids_sz);
+          //assert ids_sz > 0 (can't because randomness keeps us from being able to)
+
+          checkHits(q(queryCenter, queryDist), ids.length, ids);
         }
 
-      }//for sideDegree
+      }//for radiusDeg
 
     }//for clusterCenter
 
   }//randomTest()
 
-  private SpatialArgs q(Point pt, double dist) {
-    return q(pt, dist, 0.0);
+  /** Query point-distance (in degrees) with zero error percent. */
+  private SpatialArgs q(Point pt, double distDEG) {
+    return q(pt, distDEG, 0.0);
   }
 
-  private SpatialArgs q(Point pt, double dist, double distPrec) {
-    Shape shape = ctx.makeCircle(pt,dist);
+  private SpatialArgs q(Point pt, double distDEG, double distPrec) {
+    Shape shape = ctx.makeCircle(pt, distDEG);
     SpatialArgs args = new SpatialArgs(SpatialOperation.Intersects,shape);
     args.setDistPrecision(distPrec);
     return args;
@@ -207,30 +209,8 @@ public class TestRecursivePrefixTreeStra
     return doc;
   }
 
-  private double[] calcDistRange(Point startPoint, Point targetCenter, double targetSideDegrees) {
-    double min = Double.MAX_VALUE;
-    double max = Double.MIN_VALUE;
-    for(double xLen : new double[]{targetSideDegrees,-targetSideDegrees}) {
-      for(double yLen : new double[]{targetSideDegrees,-targetSideDegrees}) {
-        Point p2 = normPointXY(targetCenter.getX() + xLen / 2, targetCenter.getY() + yLen / 2);
-        double d = ctx.getDistCalc().distance(startPoint, p2);
-        min = Math.min(min,d);
-        max = Math.max(max,d);
-      }
-    }
-    return new double[]{min,max};
-  }
-
-  /** Normalize x & y (put in lon-lat ranges) & ensure geohash round-trip for given precision. */
-  private Point normPointXY(double x, double y) {
-    //put x,y as degrees into double[] as radians
-    double[] latLon = {y*DistanceUtils.DEG_180_AS_RADS, toRadians(x)};
-    DistanceUtils.normLatRAD(latLon);
-    DistanceUtils.normLatRAD(latLon);
-    double x2 = Math.toDegrees(latLon[1]);
-    double y2 = Math.toDegrees(latLon[0]);
-    //overwrite latLon, units is now degrees
-
-    return GeohashUtils.decode(GeohashUtils.encodeLatLon(y2, x2, maxLength),ctx);
+  /** NGeohash round-trip for given precision. */
+  private Point alignGeohash(Point p) {
+    return GeohashUtils.decode(GeohashUtils.encodeLatLon(p.getY(), p.getX(), maxLength), ctx);
   }
 }

Modified: lucene/dev/trunk/lucene/spatial/src/test/org/apache/lucene/spatial/prefix/TestTermQueryPrefixGridStrategy.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/spatial/src/test/org/apache/lucene/spatial/prefix/TestTermQueryPrefixGridStrategy.java?rev=1381230&r1=1381229&r2=1381230&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/spatial/src/test/org/apache/lucene/spatial/prefix/TestTermQueryPrefixGridStrategy.java (original)
+++ lucene/dev/trunk/lucene/spatial/src/test/org/apache/lucene/spatial/prefix/TestTermQueryPrefixGridStrategy.java Wed Sep  5 15:37:11 2012
@@ -18,14 +18,12 @@ package org.apache.lucene.spatial.prefix
  */
 
 import com.spatial4j.core.context.SpatialContext;
-import com.spatial4j.core.context.simple.SimpleSpatialContext;
+import com.spatial4j.core.context.SpatialContext;
 import com.spatial4j.core.shape.Shape;
-import com.spatial4j.core.shape.simple.PointImpl;
 import org.apache.lucene.document.Document;
 import org.apache.lucene.document.Field;
 import org.apache.lucene.document.StoredField;
 import org.apache.lucene.document.StringField;
-import org.apache.lucene.index.IndexableField;
 import org.apache.lucene.spatial.SpatialTestCase;
 import org.apache.lucene.spatial.prefix.tree.QuadPrefixTree;
 import org.apache.lucene.spatial.query.SpatialArgsParser;
@@ -39,10 +37,10 @@ public class TestTermQueryPrefixGridStra
 
   @Test
   public void testNGramPrefixGridLosAngeles() throws IOException {
-    SpatialContext ctx = SimpleSpatialContext.GEO_KM;
+    SpatialContext ctx = SpatialContext.GEO;
     TermQueryPrefixTreeStrategy prefixGridStrategy = new TermQueryPrefixTreeStrategy(new QuadPrefixTree(ctx), "geo");
 
-    Shape point = new PointImpl(-118.243680, 34.052230);
+    Shape point = ctx.makePoint(-118.243680, 34.052230);
 
     Document losAngeles = new Document();
     losAngeles.add(new StringField("name", "Los Angeles", Field.Store.YES));

Modified: lucene/dev/trunk/lucene/spatial/src/test/org/apache/lucene/spatial/prefix/tree/SpatialPrefixTreeTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/spatial/src/test/org/apache/lucene/spatial/prefix/tree/SpatialPrefixTreeTest.java?rev=1381230&r1=1381229&r2=1381230&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/spatial/src/test/org/apache/lucene/spatial/prefix/tree/SpatialPrefixTreeTest.java (original)
+++ lucene/dev/trunk/lucene/spatial/src/test/org/apache/lucene/spatial/prefix/tree/SpatialPrefixTreeTest.java Wed Sep  5 15:37:11 2012
@@ -17,7 +17,7 @@
 
 package org.apache.lucene.spatial.prefix.tree;
 
-import com.spatial4j.core.context.simple.SimpleSpatialContext;
+import com.spatial4j.core.context.SpatialContext;
 import com.spatial4j.core.shape.Rectangle;
 import com.spatial4j.core.shape.Shape;
 
@@ -28,13 +28,13 @@ import org.junit.Test;
 public class SpatialPrefixTreeTest extends LuceneTestCase {
 
   //TODO plug in others and test them
-  private SimpleSpatialContext ctx;
+  private SpatialContext ctx;
   private SpatialPrefixTree trie;
 
   @Before
   public void setUp() throws Exception {
     super.setUp();
-    ctx = SimpleSpatialContext.GEO_KM;
+    ctx = SpatialContext.GEO;
     trie = new GeohashPrefixTree(ctx,4);
   }
 

Modified: lucene/dev/trunk/lucene/spatial/src/test/org/apache/lucene/spatial/query/SpatialArgsParserTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/spatial/src/test/org/apache/lucene/spatial/query/SpatialArgsParserTest.java?rev=1381230&r1=1381229&r2=1381230&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/spatial/src/test/org/apache/lucene/spatial/query/SpatialArgsParserTest.java (original)
+++ lucene/dev/trunk/lucene/spatial/src/test/org/apache/lucene/spatial/query/SpatialArgsParserTest.java Wed Sep  5 15:37:11 2012
@@ -18,7 +18,6 @@ package org.apache.lucene.spatial.query;
  */
 
 import com.spatial4j.core.context.SpatialContext;
-import com.spatial4j.core.context.simple.SimpleSpatialContext;
 import com.spatial4j.core.shape.Rectangle;
 import org.apache.lucene.util.LuceneTestCase;
 import org.junit.Test;
@@ -26,7 +25,7 @@ import org.junit.Test;
 
 public class SpatialArgsParserTest extends LuceneTestCase {
 
-  private SpatialContext ctx = SimpleSpatialContext.GEO_KM;
+  private SpatialContext ctx = SpatialContext.GEO;
 
   //The args parser is only dependent on the ctx for IO so I don't care to test
   // with other implementations.

Modified: lucene/dev/trunk/lucene/spatial/src/test/org/apache/lucene/spatial/vector/TestTwoDoublesStrategy.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/spatial/src/test/org/apache/lucene/spatial/vector/TestTwoDoublesStrategy.java?rev=1381230&r1=1381229&r2=1381230&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/spatial/src/test/org/apache/lucene/spatial/vector/TestTwoDoublesStrategy.java (original)
+++ lucene/dev/trunk/lucene/spatial/src/test/org/apache/lucene/spatial/vector/TestTwoDoublesStrategy.java Wed Sep  5 15:37:11 2012
@@ -17,12 +17,10 @@ package org.apache.lucene.spatial.vector
  * limitations under the License.
  */
 
-import com.spatial4j.core.context.simple.SimpleSpatialContext;
+import com.spatial4j.core.context.SpatialContext;
 import com.spatial4j.core.exception.InvalidShapeException;
 import com.spatial4j.core.shape.Circle;
 import com.spatial4j.core.shape.Point;
-import com.spatial4j.core.shape.simple.CircleImpl;
-import com.spatial4j.core.shape.simple.PointImpl;
 import org.apache.lucene.search.Query;
 import org.apache.lucene.spatial.SpatialMatchConcern;
 import org.apache.lucene.spatial.StrategyTestCase;
@@ -39,13 +37,13 @@ public class TestTwoDoublesStrategy exte
   @Override
   public void setUp() throws Exception {
     super.setUp();
-    this.ctx = SimpleSpatialContext.GEO_KM;
+    this.ctx = SpatialContext.GEO;
     this.strategy = new TwoDoublesStrategy(ctx, getClass().getSimpleName());
   }
 
   @Test
   public void testCircleShapeSupport() {
-    Circle circle = new CircleImpl(new PointImpl(0, 0), 10, this.ctx);
+    Circle circle = ctx.makeCircle(ctx.makePoint(0, 0), 10);
     SpatialArgs args = new SpatialArgs(SpatialOperation.Intersects, circle);
     Query query = this.strategy.makeQuery(args);
 
@@ -54,7 +52,7 @@ public class TestTwoDoublesStrategy exte
 
   @Test(expected = InvalidShapeException.class)
   public void testInvalidQueryShape() {
-    Point point = new PointImpl(0, 0);
+    Point point = ctx.makePoint(0, 0);
     SpatialArgs args = new SpatialArgs(SpatialOperation.Intersects, point);
     this.strategy.makeQuery(args);
   }

Modified: lucene/dev/trunk/solr/core/ivy.xml
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/ivy.xml?rev=1381230&r1=1381229&r2=1381230&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/ivy.xml (original)
+++ lucene/dev/trunk/solr/core/ivy.xml Wed Sep  5 15:37:11 2012
@@ -34,7 +34,7 @@
       <dependency org="org.easymock" name="easymock" rev="2.2" transitive="false"/>
       <dependency org="org.slf4j" name="slf4j-api" rev="1.6.4" transitive="false"/>
       <dependency org="org.slf4j" name="slf4j-jdk14" rev="1.6.4" transitive="false"/>
-      <dependency org="com.spatial4j" name="spatial4j" rev="0.2" transitive="false"/>
+      <dependency org="com.spatial4j" name="spatial4j" rev="0.3" transitive="false"/>
       <dependency org="javax.servlet" name="javax.servlet-api" rev="3.0.1" transitive="false"/>
       <exclude org="*" ext="*" matcher="regexp" type="${ivy.exclude.types}"/> 
     </dependencies>

Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/schema/GeoHashField.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/schema/GeoHashField.java?rev=1381230&r1=1381229&r2=1381230&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/schema/GeoHashField.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/schema/GeoHashField.java Wed Sep  5 15:37:11 2012
@@ -19,16 +19,13 @@ package org.apache.solr.schema;
 
 import org.apache.lucene.queries.function.ValueSource;
 import org.apache.lucene.queries.function.valuesource.LiteralValueSource;
-import org.apache.lucene.index.GeneralField;
-import org.apache.lucene.index.IndexableField;
 import org.apache.lucene.index.StorableField;
 import org.apache.lucene.search.Query;
 import org.apache.lucene.search.SortField;
-import com.spatial4j.core.context.ParseUtils;
+import com.spatial4j.core.io.ParseUtils;
 import com.spatial4j.core.context.SpatialContext;
-import com.spatial4j.core.context.simple.SimpleSpatialContext;
 import com.spatial4j.core.exception.InvalidShapeException;
-import com.spatial4j.core.util.GeohashUtils;
+import com.spatial4j.core.io.GeohashUtils;
 import com.spatial4j.core.shape.Point;
 import org.apache.solr.common.SolrException;
 import org.apache.solr.response.TextResponseWriter;
@@ -46,12 +43,12 @@ import java.io.IOException;
  * href="http://en.wikipedia.org/wiki/Geohash">Geohash</a> field. The field is
  * provided as a lat/lon pair and is internally represented as a string.
  *
- * @see com.spatial4j.core.context.ParseUtils#parseLatitudeLongitude(double[], String) 
+ * @see com.spatial4j.core.io.ParseUtils#parseLatitudeLongitude(double[], String)
  */
 public class GeoHashField extends FieldType implements SpatialQueryable {
 
 
-  private final SpatialContext ctx = SimpleSpatialContext.GEO_KM;
+  private final SpatialContext ctx = SpatialContext.GEO;
 
   @Override
   public SortField getSortField(SchemaField field, boolean top) {

Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/schema/LatLonType.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/schema/LatLonType.java?rev=1381230&r1=1381229&r2=1381230&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/schema/LatLonType.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/schema/LatLonType.java Wed Sep  5 15:37:11 2012
@@ -17,8 +17,6 @@ package org.apache.solr.schema;
  */
 
 import org.apache.lucene.document.FieldType;
-import org.apache.lucene.index.GeneralField;
-import org.apache.lucene.index.IndexableField;
 import org.apache.lucene.index.IndexReader;
 import org.apache.lucene.index.AtomicReaderContext;
 import org.apache.lucene.index.StorableField;
@@ -26,12 +24,9 @@ import org.apache.lucene.queries.functio
 import org.apache.lucene.queries.function.ValueSource;
 import org.apache.lucene.queries.function.valuesource.VectorValueSource;
 import org.apache.lucene.search.*;
-import com.spatial4j.core.context.ParseUtils;
+import com.spatial4j.core.io.ParseUtils;
 import com.spatial4j.core.context.SpatialContext;
-import com.spatial4j.core.context.simple.SimpleSpatialContext;
-import com.spatial4j.core.distance.DistanceCalculator;
 import com.spatial4j.core.distance.DistanceUtils;
-import com.spatial4j.core.distance.GeodesicSphereDistCalc;
 import com.spatial4j.core.exception.InvalidShapeException;
 import com.spatial4j.core.shape.Rectangle;
 import org.apache.lucene.util.Bits;
@@ -149,9 +144,8 @@ public class LatLonType extends Abstract
     double latCenter = point[LAT];
     double lonCenter = point[LON];
     
-    DistanceCalculator distCalc = new GeodesicSphereDistCalc.Haversine(options.units.earthRadius());
-    SpatialContext ctx = new SimpleSpatialContext(options.units,distCalc,null);
-    Rectangle bbox = DistanceUtils.calcBoxByDistFromPtDEG(latCenter, lonCenter, options.distance, ctx);
+    double distDeg = DistanceUtils.dist2Degrees(options.distance, options.radius);
+    Rectangle bbox = DistanceUtils.calcBoxByDistFromPtDEG(latCenter, lonCenter, distDeg, SpatialContext.GEO, null);
     double latMin = bbox.getMinY();
     double latMax = bbox.getMaxY();
     double lonMin, lonMax, lon2Min, lon2Max;
@@ -403,8 +397,8 @@ class SpatialDistanceQuery extends Exten
       this.lon2 = SpatialDistanceQuery.this.lon2;
       this.calcDist = SpatialDistanceQuery.this.calcDist;
 
-      this.latCenterRad = SpatialDistanceQuery.this.latCenter * HaversineConstFunction.DEGREES_TO_RADIANS;
-      this.lonCenterRad = SpatialDistanceQuery.this.lonCenter * HaversineConstFunction.DEGREES_TO_RADIANS;
+      this.latCenterRad = SpatialDistanceQuery.this.latCenter * DistanceUtils.DEGREES_TO_RADIANS;
+      this.lonCenterRad = SpatialDistanceQuery.this.lonCenter * DistanceUtils.DEGREES_TO_RADIANS;
       this.latCenterRad_cos = this.calcDist ? Math.cos(latCenterRad) : 0;
       this.dist = SpatialDistanceQuery.this.dist;
       this.planetRadius = SpatialDistanceQuery.this.planetRadius;
@@ -433,8 +427,8 @@ class SpatialDistanceQuery extends Exten
     }
 
     double dist(double lat, double lon) {
-      double latRad = lat * HaversineConstFunction.DEGREES_TO_RADIANS;
-      double lonRad = lon * HaversineConstFunction.DEGREES_TO_RADIANS;
+      double latRad = lat * DistanceUtils.DEGREES_TO_RADIANS;
+      double lonRad = lon * DistanceUtils.DEGREES_TO_RADIANS;
       
       // haversine, specialized to avoid a cos() call on latCenterRad
       double diffX = latCenterRad - latRad;
@@ -599,7 +593,7 @@ class SpatialDistanceQuery extends Exten
   /** Returns a hash code value for this object. */
   @Override
   public int hashCode() {
-    // don't bother making the hash expensive - the center latitude + min longitude will be very uinque 
+    // don't bother making the hash expensive - the center latitude + min longitude will be very unique
     long hash = Double.doubleToLongBits(latCenter);
     hash = hash * 31 + Double.doubleToLongBits(lonMin);
     hash = hash * 31 + (long)super.hashCode();

Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/schema/PointType.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/schema/PointType.java?rev=1381230&r1=1381229&r2=1381230&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/schema/PointType.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/schema/PointType.java Wed Sep  5 15:37:11 2012
@@ -20,14 +20,12 @@ package org.apache.solr.schema;
 import org.apache.lucene.document.FieldType;
 import org.apache.lucene.queries.function.ValueSource;
 import org.apache.lucene.queries.function.valuesource.VectorValueSource;
-import org.apache.lucene.index.GeneralField;
-import org.apache.lucene.index.IndexableField;
 import org.apache.lucene.index.StorableField;
 import org.apache.lucene.search.BooleanClause;
 import org.apache.lucene.search.BooleanQuery;
 import org.apache.lucene.search.Query;
 import org.apache.lucene.search.SortField;
-import com.spatial4j.core.context.ParseUtils;
+import com.spatial4j.core.io.ParseUtils;
 import com.spatial4j.core.distance.DistanceUtils;
 import com.spatial4j.core.exception.InvalidShapeException;
 import org.apache.solr.common.SolrException;

Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/SpatialFilterQParser.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/SpatialFilterQParser.java?rev=1381230&r1=1381229&r2=1381230&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/SpatialFilterQParser.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/SpatialFilterQParser.java Wed Sep  5 15:37:11 2012
@@ -19,7 +19,6 @@ package org.apache.solr.search;
 
 import org.apache.lucene.queryparser.classic.ParseException;
 import org.apache.lucene.search.Query;
-import com.spatial4j.core.distance.DistanceUnits;
 import com.spatial4j.core.distance.DistanceUtils;
 import org.apache.solr.common.SolrException;
 import org.apache.solr.common.params.SolrParams;
@@ -79,7 +78,7 @@ public class SpatialFilterQParser extend
 
       if (type instanceof SpatialQueryable) {
         double radius = localParams.getDouble(SpatialParams.SPHERE_RADIUS, DistanceUtils.EARTH_MEAN_RADIUS_KM);
-        SpatialOptions opts = new SpatialOptions(pointStr, dist, sf, measStr, radius, DistanceUnits.KILOMETERS);
+        SpatialOptions opts = new SpatialOptions(pointStr, dist, sf, measStr, radius);
         opts.bbox = bbox;
         result = ((SpatialQueryable)type).createSpatialQuery(this, opts);
       } else {

Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/SpatialOptions.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/SpatialOptions.java?rev=1381230&r1=1381229&r2=1381230&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/SpatialOptions.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/SpatialOptions.java Wed Sep  5 15:37:11 2012
@@ -16,7 +16,6 @@ package org.apache.solr.search;
  * limitations under the License.
  */
 
-import com.spatial4j.core.distance.DistanceUnits;
 import org.apache.solr.schema.SchemaField;
 
 /**
@@ -28,8 +27,7 @@ public class SpatialOptions {
   public double distance;
   public SchemaField field;
   public String measStr;
-  public double radius;
-  public DistanceUnits units;
+  public double radius;//(planetRadius) effectively establishes the units
 
   /** Just do a "bounding box" - or any other quicker method / shape that
    * still encompasses all of the points of interest, but may also encompass
@@ -40,19 +38,11 @@ public class SpatialOptions {
   public SpatialOptions() {
   }
 
-
   public SpatialOptions(String pointStr, double dist, SchemaField sf, String measStr, double radius) {
-    this(pointStr, dist, sf, measStr, radius, DistanceUnits.MILES);
-
-  }
-
-
-  public SpatialOptions(String pointStr, double dist, SchemaField sf, String measStr, double radius, DistanceUnits units) {
     this.pointStr = pointStr;
     this.distance = dist;
     this.field = sf;
     this.measStr = measStr;
     this.radius = radius;
-    this.units = units;
   }
 }

Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/ValueSourceParser.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/ValueSourceParser.java?rev=1381230&r1=1381229&r2=1381230&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/ValueSourceParser.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/ValueSourceParser.java Wed Sep  5 15:37:11 2012
@@ -16,6 +16,7 @@
  */
 package org.apache.solr.search;
 
+import com.spatial4j.core.distance.DistanceUtils;
 import org.apache.lucene.index.AtomicReaderContext;
 import org.apache.lucene.index.Term;
 import org.apache.lucene.queries.function.BoostedQuery;
@@ -398,13 +399,13 @@ public abstract class ValueSourceParser 
     addParser(new DoubleParser("rad") {
       @Override
       public double func(int doc, FunctionValues vals) {
-        return vals.doubleVal(doc) * HaversineConstFunction.DEGREES_TO_RADIANS;
+        return vals.doubleVal(doc) * DistanceUtils.DEGREES_TO_RADIANS;
       }
     });
     addParser(new DoubleParser("deg") {
       @Override
       public double func(int doc, FunctionValues vals) {
-        return vals.doubleVal(doc) * HaversineConstFunction.RADIANS_TO_DEGREES;
+        return vals.doubleVal(doc) * DistanceUtils.RADIANS_TO_DEGREES;
       }
     });
     addParser(new DoubleParser("sqrt") {

Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/function/distance/GeohashFunction.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/function/distance/GeohashFunction.java?rev=1381230&r1=1381229&r2=1381230&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/function/distance/GeohashFunction.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/function/distance/GeohashFunction.java Wed Sep  5 15:37:11 2012
@@ -19,7 +19,7 @@ package org.apache.solr.search.function.
 import org.apache.lucene.index.AtomicReaderContext;
 import org.apache.lucene.queries.function.FunctionValues;
 import org.apache.lucene.queries.function.ValueSource;
-import com.spatial4j.core.util.GeohashUtils;
+import com.spatial4j.core.io.GeohashUtils;
 
 import java.util.Map;
 import java.io.IOException;

Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/function/distance/GeohashHaversineFunction.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/function/distance/GeohashHaversineFunction.java?rev=1381230&r1=1381229&r2=1381230&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/function/distance/GeohashHaversineFunction.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/function/distance/GeohashHaversineFunction.java Wed Sep  5 15:37:11 2012
@@ -17,21 +17,19 @@ package org.apache.solr.search.function.
  */
 
 
+import com.spatial4j.core.context.SpatialContext;
+import com.spatial4j.core.distance.DistanceUtils;
+import com.spatial4j.core.distance.GeodesicSphereDistCalc;
+import com.spatial4j.core.io.GeohashUtils;
+import com.spatial4j.core.shape.Point;
+import org.apache.lucene.index.AtomicReaderContext;
 import org.apache.lucene.queries.function.FunctionValues;
 import org.apache.lucene.queries.function.ValueSource;
 import org.apache.lucene.queries.function.docvalues.DoubleDocValues;
-import org.apache.lucene.index.AtomicReaderContext;
 import org.apache.lucene.search.IndexSearcher;
-import com.spatial4j.core.context.SpatialContext;
-import com.spatial4j.core.context.simple.SimpleSpatialContext;
-import com.spatial4j.core.distance.DistanceCalculator;
-import com.spatial4j.core.distance.DistanceUnits;
-import com.spatial4j.core.distance.GeodesicSphereDistCalc;
-import com.spatial4j.core.util.GeohashUtils;
-import com.spatial4j.core.shape.Point;
 
-import java.util.Map;
 import java.io.IOException;
+import java.util.Map;
 
 
 /**
@@ -46,16 +44,16 @@ import java.io.IOException;
  **/
 public class GeohashHaversineFunction extends ValueSource {
 
-  private ValueSource geoHash1, geoHash2;
-  private double radius;
+  private final ValueSource geoHash1, geoHash2;
   private final SpatialContext ctx;
+  private final double degreesToDist;
 
   public GeohashHaversineFunction(ValueSource geoHash1, ValueSource geoHash2, double radius) {
     this.geoHash1 = geoHash1;
     this.geoHash2 = geoHash2;
-    this.radius = radius;
-    DistanceCalculator distCalc = new GeodesicSphereDistCalc.Haversine(radius);
-    this.ctx = new SimpleSpatialContext(DistanceUnits.KILOMETERS,distCalc,null);
+    this.degreesToDist = DistanceUtils.degrees2Dist(1, radius);
+    this.ctx = SpatialContext.GEO;
+    assert this.ctx.getDistCalc() instanceof GeodesicSphereDistCalc.Haversine;
   }
 
   protected String name() {
@@ -92,7 +90,7 @@ public class GeohashHaversineFunction ex
       //and avoid decoding every time
       Point p1 = GeohashUtils.decode(h1,ctx);
       Point p2 = GeohashUtils.decode(h2,ctx);
-      result = ctx.getDistCalc().distance(p1, p2);
+      result = ctx.getDistCalc().distance(p1, p2) * degreesToDist;
     } else if (h1 == null || h2 == null){
       result = Double.MAX_VALUE;
     }
@@ -112,7 +110,7 @@ public class GeohashHaversineFunction ex
     return this.name().equals(other.name())
             && geoHash1.equals(other.geoHash1) &&
             geoHash2.equals(other.geoHash2) &&
-            radius == other.radius;
+            degreesToDist == other.degreesToDist;
   }
 
   @Override
@@ -121,7 +119,7 @@ public class GeohashHaversineFunction ex
     result = geoHash1.hashCode();
     result = 31 * result + geoHash2.hashCode();
     result = 31 * result + name().hashCode();
-    long temp =Double.doubleToRawLongBits(radius);
+    long temp =Double.doubleToRawLongBits(degreesToDist);
     result = 31 * result + (int) (temp ^ (temp >>> 32));
     return result;
   }

Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/function/distance/HaversineConstFunction.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/function/distance/HaversineConstFunction.java?rev=1381230&r1=1381229&r2=1381230&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/function/distance/HaversineConstFunction.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/function/distance/HaversineConstFunction.java Wed Sep  5 15:37:11 2012
@@ -26,7 +26,7 @@ import org.apache.lucene.queries.functio
 import org.apache.lucene.queries.function.valuesource.VectorValueSource;
 import org.apache.lucene.queryparser.classic.ParseException;
 import org.apache.lucene.search.IndexSearcher;
-import com.spatial4j.core.context.ParseUtils;
+import com.spatial4j.core.io.ParseUtils;
 import com.spatial4j.core.distance.DistanceUtils;
 import com.spatial4j.core.exception.InvalidShapeException;
 import org.apache.solr.common.params.SpatialParams;
@@ -39,20 +39,18 @@ import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
 
+import static com.spatial4j.core.distance.DistanceUtils.DEGREES_TO_RADIANS;
 
 /**
  * Haversine function with one point constant
  */
 public class HaversineConstFunction extends ValueSource {
-  // TODO: these could go in spatial4j somewhere
-  public static final double DEGREES_TO_RADIANS = Math.PI / 180.0;
-  public static final double RADIANS_TO_DEGREES =  180.0 / Math.PI;
 
   public static ValueSourceParser parser = new ValueSourceParser() {
     @Override
     public ValueSource parse(FunctionQParser fp) throws ParseException
     {
-      // TODO: dispatch through SpatialQueriable in the future?
+      // TODO: dispatch through SpatialQueryable in the future?
       List<ValueSource> sources = fp.parseValueSourceList();
 
       // "m" is a multi-value source, "x" is a single-value source

Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/function/distance/HaversineFunction.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/function/distance/HaversineFunction.java?rev=1381230&r1=1381229&r2=1381230&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/function/distance/HaversineFunction.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/function/distance/HaversineFunction.java Wed Sep  5 15:37:11 2012
@@ -81,10 +81,10 @@ public class HaversineFunction extends V
     double y2;
     double x2;
     if (convertToRadians) {
-      y1 = p1D[0] * HaversineConstFunction.DEGREES_TO_RADIANS;
-      x1 = p1D[1] * HaversineConstFunction.DEGREES_TO_RADIANS;
-      y2 = p2D[0] * HaversineConstFunction.DEGREES_TO_RADIANS;
-      x2 = p2D[1] * HaversineConstFunction.DEGREES_TO_RADIANS;
+      y1 = p1D[0] * DistanceUtils.DEGREES_TO_RADIANS;
+      x1 = p1D[1] * DistanceUtils.DEGREES_TO_RADIANS;
+      y2 = p2D[0] * DistanceUtils.DEGREES_TO_RADIANS;
+      x2 = p2D[1] * DistanceUtils.DEGREES_TO_RADIANS;
     } else {
       y1 = p1D[0];
       x1 = p1D[1];

Modified: lucene/dev/trunk/solr/core/src/test/org/apache/solr/search/function/distance/DistanceFunctionTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/test/org/apache/solr/search/function/distance/DistanceFunctionTest.java?rev=1381230&r1=1381229&r2=1381230&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/test/org/apache/solr/search/function/distance/DistanceFunctionTest.java (original)
+++ lucene/dev/trunk/solr/core/src/test/org/apache/solr/search/function/distance/DistanceFunctionTest.java Wed Sep  5 15:37:11 2012
@@ -17,7 +17,7 @@ package org.apache.solr.search.function.
  */
 
 import com.spatial4j.core.distance.DistanceUtils;
-import com.spatial4j.core.util.GeohashUtils;
+import com.spatial4j.core.io.GeohashUtils;
 import org.apache.solr.SolrTestCaseJ4;
 import org.apache.solr.common.SolrException;
 import org.junit.BeforeClass;