You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by nk...@apache.org on 2016/04/01 18:05:01 UTC

lucene-solr:master: LUCENE-7152: Refactor GeoUtils from lucene-spatial to core module.

Repository: lucene-solr
Updated Branches:
  refs/heads/master bfc6dcf92 -> 3f217aba6


LUCENE-7152: Refactor GeoUtils from lucene-spatial to core module.


Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/3f217aba
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/3f217aba
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/3f217aba

Branch: refs/heads/master
Commit: 3f217aba6d4422d829be5ad77b02068c130dc7d3
Parents: bfc6dcf
Author: nknize <nk...@apache.org>
Authored: Fri Apr 1 11:03:11 2016 -0500
Committer: nknize <nk...@apache.org>
Committed: Fri Apr 1 11:03:11 2016 -0500

----------------------------------------------------------------------
 lucene/CHANGES.txt                              |   3 +
 .../java/org/apache/lucene/geo/GeoUtils.java    |  94 ++++++++++
 .../org/apache/lucene/geo/package-info.java     |  21 +++
 .../org/apache/lucene/document/LatLonPoint.java |   2 +-
 .../document/LatLonPointDistanceComparator.java |   4 +-
 .../document/LatLonPointDistanceQuery.java      |   8 +-
 .../document/LatLonPointInPolygonQuery.java     |   2 +-
 .../lucene/document/LatLonPointSortField.java   |   2 +-
 .../geopoint/document/GeoPointField.java        |   2 +-
 .../geopoint/search/GeoPointDistanceQuery.java  |   4 +-
 .../search/GeoPointDistanceQueryImpl.java       |   5 +-
 .../geopoint/search/GeoPointInBBoxQuery.java    |   2 +-
 .../geopoint/search/GeoPointInPolygonQuery.java |   2 +-
 .../geopoint/search/GeoPointMultiTermQuery.java |   2 +-
 .../lucene/spatial/util/GeoEncodingUtils.java   |   4 +-
 .../org/apache/lucene/spatial/util/GeoRect.java | 121 +++++++++++++
 .../apache/lucene/spatial/util/GeoUtils.java    | 179 -------------------
 .../org/apache/lucene/spatial/util/Polygon.java |  20 +--
 .../spatial/util/BaseGeoPointTestCase.java      |   1 +
 .../apache/lucene/spatial/util/GeoTestUtil.java |   5 +-
 .../lucene/spatial/util/TestGeoUtils.java       |  31 ++--
 21 files changed, 280 insertions(+), 234 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/3f217aba/lucene/CHANGES.txt
----------------------------------------------------------------------
diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt
index 14a64c8..8e95950 100644
--- a/lucene/CHANGES.txt
+++ b/lucene/CHANGES.txt
@@ -18,6 +18,9 @@ New Features
 
 API Changes
 
+* LUCENE-7152: Refactor GeoUtils from lucene-spatial package to
+  core (Nick Knize)
+
 * LUCENE-7141: Switch OfflineSorter's ByteSequencesReader to
   BytesRefIterator (Mike McCandless)
 

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/3f217aba/lucene/core/src/java/org/apache/lucene/geo/GeoUtils.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/geo/GeoUtils.java b/lucene/core/src/java/org/apache/lucene/geo/GeoUtils.java
new file mode 100644
index 0000000..c11dfe1
--- /dev/null
+++ b/lucene/core/src/java/org/apache/lucene/geo/GeoUtils.java
@@ -0,0 +1,94 @@
+package org.apache.lucene.geo;
+
+import static org.apache.lucene.util.SloppyMath.TO_RADIANS;
+import static org.apache.lucene.util.SloppyMath.cos;
+
+/*
+ * 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.
+ */
+
+/**
+ * Basic reusable geo-spatial utility methods
+ *
+ * @lucene.experimental
+ */
+public final class GeoUtils {
+  /** Minimum longitude value. */
+  public static final double MIN_LON_INCL = -180.0D;
+
+  /** Maximum longitude value. */
+  public static final double MAX_LON_INCL = 180.0D;
+
+  /** Minimum latitude value. */
+  public static final double MIN_LAT_INCL = -90.0D;
+
+  /** Maximum latitude value. */
+  public static final double MAX_LAT_INCL = 90.0D;
+
+  /** min longitude value in radians */
+  public static final double MIN_LON_RADIANS = TO_RADIANS * MIN_LON_INCL;
+  /** min latitude value in radians */
+  public static final double MIN_LAT_RADIANS = TO_RADIANS * MIN_LAT_INCL;
+  /** max longitude value in radians */
+  public static final double MAX_LON_RADIANS = TO_RADIANS * MAX_LON_INCL;
+  /** max latitude value in radians */
+  public static final double MAX_LAT_RADIANS = TO_RADIANS * MAX_LAT_INCL;
+
+  // WGS84 earth-ellipsoid parameters
+  /** mean earth axis in meters */
+  // see http://earth-info.nga.mil/GandG/publications/tr8350.2/wgs84fin.pdf
+  public static final double EARTH_MEAN_RADIUS_METERS = 6_371_008.7714;
+
+  // No instance:
+  private GeoUtils() {
+  }
+
+  /** validates latitude value is within standard +/-90 coordinate bounds */
+  public static void checkLatitude(double latitude) {
+    if (Double.isNaN(latitude) || latitude < MIN_LAT_INCL || latitude > MAX_LAT_INCL) {
+      throw new IllegalArgumentException("invalid latitude " +  latitude + "; must be between " + MIN_LAT_INCL + " and " + MAX_LAT_INCL);
+    }
+  }
+
+  /** validates longitude value is within standard +/-180 coordinate bounds */
+  public static void checkLongitude(double longitude) {
+    if (Double.isNaN(longitude) || longitude < MIN_LON_INCL || longitude > MAX_LON_INCL) {
+      throw new IllegalArgumentException("invalid longitude " +  longitude + "; must be between " + MIN_LON_INCL + " and " + MAX_LON_INCL);
+    }
+  }
+
+  // some sloppyish stuff, do we really need this to be done in a sloppy way?
+  // unless it is performance sensitive, we should try to remove.
+  private static final double PIO2 = Math.PI / 2D;
+
+  /**
+   * Returns the trigonometric sine of an angle converted as a cos operation.
+   * <p>
+   * Note that this is not quite right... e.g. sin(0) != 0
+   * <p>
+   * Special cases:
+   * <ul>
+   *  <li>If the argument is {@code NaN} or an infinity, then the result is {@code NaN}.
+   * </ul>
+   * @param a an angle, in radians.
+   * @return the sine of the argument.
+   * @see Math#sin(double)
+   */
+  // TODO: deprecate/remove this? at least its no longer public.
+  public static double sloppySin(double a) {
+    return cos(a - PIO2);
+  }
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/3f217aba/lucene/core/src/java/org/apache/lucene/geo/package-info.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/geo/package-info.java b/lucene/core/src/java/org/apache/lucene/geo/package-info.java
new file mode 100644
index 0000000..8d9afc9
--- /dev/null
+++ b/lucene/core/src/java/org/apache/lucene/geo/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+
+/**
+ * Geospatial Utility Implementations for Lucene Core
+ */
+package org.apache.lucene.geo;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/3f217aba/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPoint.java
----------------------------------------------------------------------
diff --git a/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPoint.java b/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPoint.java
index 70149b6..af014cb 100644
--- a/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPoint.java
+++ b/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPoint.java
@@ -16,6 +16,7 @@
  */
 package org.apache.lucene.document;
 
+import org.apache.lucene.geo.GeoUtils;
 import org.apache.lucene.util.BytesRef;
 import org.apache.lucene.util.NumericUtils;
 import org.apache.lucene.index.DocValuesType;
@@ -28,7 +29,6 @@ import org.apache.lucene.search.FieldDoc;
 import org.apache.lucene.search.PointRangeQuery;
 import org.apache.lucene.search.Query;
 import org.apache.lucene.search.SortField;
-import org.apache.lucene.spatial.util.GeoUtils;
 import org.apache.lucene.spatial.util.Polygon;
 
 /** 

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/3f217aba/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPointDistanceComparator.java
----------------------------------------------------------------------
diff --git a/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPointDistanceComparator.java b/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPointDistanceComparator.java
index e818e1d..0ed85ad 100644
--- a/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPointDistanceComparator.java
+++ b/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPointDistanceComparator.java
@@ -27,7 +27,7 @@ import org.apache.lucene.search.FieldComparator;
 import org.apache.lucene.search.LeafFieldComparator;
 import org.apache.lucene.search.Scorer;
 import org.apache.lucene.spatial.util.GeoRect;
-import org.apache.lucene.spatial.util.GeoUtils;
+import org.apache.lucene.geo.GeoUtils;
 import org.apache.lucene.util.SloppyMath;
 
 /**
@@ -83,7 +83,7 @@ class LatLonPointDistanceComparator extends FieldComparator<Double> implements L
     // sampling if we get called way too much: don't make gobs of bounding
     // boxes if comparator hits a worst case order (e.g. backwards distance order)
     if (setBottomCounter < 1024 || (setBottomCounter & 0x3F) == 0x3F) {
-      GeoRect box = GeoUtils.circleToBBox(latitude, longitude, haversin2(bottom));
+      GeoRect box = GeoRect.fromPointDistance(latitude, longitude, haversin2(bottom));
       // pre-encode our box to our integer encoding, so we don't have to decode 
       // to double values for uncompetitive hits. This has some cost!
       minLat = LatLonPoint.encodeLatitude(box.minLat);

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/3f217aba/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPointDistanceQuery.java
----------------------------------------------------------------------
diff --git a/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPointDistanceQuery.java b/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPointDistanceQuery.java
index 04d3723..2934718 100644
--- a/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPointDistanceQuery.java
+++ b/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPointDistanceQuery.java
@@ -36,7 +36,7 @@ import org.apache.lucene.search.Scorer;
 import org.apache.lucene.search.TwoPhaseIterator;
 import org.apache.lucene.search.Weight;
 import org.apache.lucene.spatial.util.GeoRect;
-import org.apache.lucene.spatial.util.GeoUtils;
+import org.apache.lucene.geo.GeoUtils;
 import org.apache.lucene.util.BitSet;
 import org.apache.lucene.util.DocIdSetBuilder;
 import org.apache.lucene.util.FixedBitSet;
@@ -71,7 +71,7 @@ final class LatLonPointDistanceQuery extends Query {
 
   @Override
   public Weight createWeight(IndexSearcher searcher, boolean needsScores) throws IOException {
-    GeoRect box = GeoUtils.circleToBBox(latitude, longitude, radiusMeters);
+    GeoRect box = GeoRect.fromPointDistance(latitude, longitude, radiusMeters);
     // create bounding box(es) for the distance range
     // these are pre-encoded with LatLonPoint's encoding
     final byte minLat[] = new byte[Integer.BYTES];
@@ -108,7 +108,7 @@ final class LatLonPointDistanceQuery extends Query {
       maxPartialDistance = Double.POSITIVE_INFINITY;
     }
 
-    final double axisLat = GeoUtils.axisLat(latitude, radiusMeters);
+    final double axisLat = GeoRect.axisLat(latitude, radiusMeters);
 
     return new ConstantScoreWeight(this) {
 
@@ -196,7 +196,7 @@ final class LatLonPointDistanceQuery extends Query {
                              double latMax = LatLonPoint.decodeLatitude(maxPackedValue, 0);
                              double lonMax = LatLonPoint.decodeLongitude(maxPackedValue, Integer.BYTES);
 
-                             if ((longitude < lonMin || longitude > lonMax) && (axisLat+GeoUtils.AXISLAT_ERROR < latMin || axisLat-GeoUtils.AXISLAT_ERROR > latMax)) {
+                             if ((longitude < lonMin || longitude > lonMax) && (axisLat+GeoRect.AXISLAT_ERROR < latMin || axisLat-GeoRect.AXISLAT_ERROR > latMax)) {
                                // circle not fully inside / crossing axis
                                if (SloppyMath.haversinMeters(latitude, longitude, latMin, lonMin) > radiusMeters &&
                                    SloppyMath.haversinMeters(latitude, longitude, latMin, lonMax) > radiusMeters &&

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/3f217aba/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPointInPolygonQuery.java
----------------------------------------------------------------------
diff --git a/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPointInPolygonQuery.java b/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPointInPolygonQuery.java
index 2875e2f..56e906b 100644
--- a/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPointInPolygonQuery.java
+++ b/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPointInPolygonQuery.java
@@ -84,7 +84,7 @@ final class LatLonPointInPolygonQuery extends Query {
     
     // bounding box over all polygons, this can speed up tree intersection/cheaply improve approximation for complex multi-polygons
     // these are pre-encoded with LatLonPoint's encoding
-    final GeoRect box = Polygon.getBoundingBox(polygons);
+    final GeoRect box = GeoRect.fromPolygon(polygons);
     final byte minLat[] = new byte[Integer.BYTES];
     final byte maxLat[] = new byte[Integer.BYTES];
     final byte minLon[] = new byte[Integer.BYTES];

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/3f217aba/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPointSortField.java
----------------------------------------------------------------------
diff --git a/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPointSortField.java b/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPointSortField.java
index 7091229..c886438 100644
--- a/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPointSortField.java
+++ b/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPointSortField.java
@@ -20,7 +20,7 @@ import java.io.IOException;
 
 import org.apache.lucene.search.FieldComparator;
 import org.apache.lucene.search.SortField;
-import org.apache.lucene.spatial.util.GeoUtils;
+import org.apache.lucene.geo.GeoUtils;
 
 /**
  * Sorts by distance from an origin location.

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/3f217aba/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/document/GeoPointField.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/document/GeoPointField.java b/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/document/GeoPointField.java
index 378e513..8b1483a 100644
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/document/GeoPointField.java
+++ b/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/document/GeoPointField.java
@@ -23,7 +23,7 @@ import org.apache.lucene.document.FieldType;
 import org.apache.lucene.index.DocValuesType;
 import org.apache.lucene.index.IndexOptions;
 import org.apache.lucene.spatial.util.GeoEncodingUtils;
-import org.apache.lucene.spatial.util.GeoUtils;
+import org.apache.lucene.geo.GeoUtils;
 
 /**
  * <p>

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/3f217aba/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/search/GeoPointDistanceQuery.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/search/GeoPointDistanceQuery.java b/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/search/GeoPointDistanceQuery.java
index cdd0d6d..c7ac6eb 100644
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/search/GeoPointDistanceQuery.java
+++ b/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/search/GeoPointDistanceQuery.java
@@ -22,7 +22,7 @@ import org.apache.lucene.search.BooleanQuery;
 import org.apache.lucene.search.Query;
 import org.apache.lucene.spatial.geopoint.document.GeoPointField.TermEncoding;
 import org.apache.lucene.spatial.util.GeoRect;
-import org.apache.lucene.spatial.util.GeoUtils;
+import org.apache.lucene.geo.GeoUtils;
 
 /** Implements a simple point distance query on a GeoPoint field. This is based on
  * {@link GeoPointInBBoxQuery} and is implemented using a two phase approach. First,
@@ -80,7 +80,7 @@ public class GeoPointDistanceQuery extends GeoPointInBBoxQuery {
    * {@link org.apache.lucene.spatial.geopoint.document.GeoPointField.TermEncoding} parameter
    **/
   public GeoPointDistanceQuery(final String field, final TermEncoding termEncoding, final double centerLat, final double centerLon, final double radiusMeters) {
-    this(field, termEncoding, GeoUtils.circleToBBox(checkLatitude(centerLat), checkLongitude(centerLon), checkRadius(radiusMeters)), centerLat, centerLon, radiusMeters);
+    this(field, termEncoding, GeoRect.fromPointDistance(centerLat, centerLon, checkRadius(radiusMeters)), centerLat, centerLon, radiusMeters);
   }
 
   private GeoPointDistanceQuery(final String field, final TermEncoding termEncoding, final GeoRect bbox,

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/3f217aba/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/search/GeoPointDistanceQueryImpl.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/search/GeoPointDistanceQueryImpl.java b/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/search/GeoPointDistanceQueryImpl.java
index dea2be8..46dcce9 100644
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/search/GeoPointDistanceQueryImpl.java
+++ b/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/search/GeoPointDistanceQueryImpl.java
@@ -19,7 +19,6 @@ package org.apache.lucene.spatial.geopoint.search;
 import org.apache.lucene.search.MultiTermQuery;
 import org.apache.lucene.spatial.geopoint.document.GeoPointField.TermEncoding;
 import org.apache.lucene.spatial.util.GeoRect;
-import org.apache.lucene.spatial.util.GeoUtils;
 import org.apache.lucene.util.SloppyMath;
 
 /** Package private implementation for the public facing GeoPointDistanceQuery delegate class.
@@ -50,7 +49,7 @@ final class GeoPointDistanceQueryImpl extends GeoPointInBBoxQueryImpl {
     } else {
       maxPartialDistance = Double.POSITIVE_INFINITY;
     }
-    axisLat = GeoUtils.axisLat(distanceQuery.centerLat, distanceQuery.radiusMeters);
+    axisLat = GeoRect.axisLat(distanceQuery.centerLat, distanceQuery.radiusMeters);
   }
 
   @Override
@@ -76,7 +75,7 @@ final class GeoPointDistanceQueryImpl extends GeoPointInBBoxQueryImpl {
           minLat > GeoPointDistanceQueryImpl.this.maxLat ||
           minLon > GeoPointDistanceQueryImpl.this.maxLon) {
         return false;
-      } else if ((centerLon < minLon || centerLon > maxLon) && (axisLat+GeoUtils.AXISLAT_ERROR < minLat || axisLat-GeoUtils.AXISLAT_ERROR > maxLat)) {
+      } else if ((centerLon < minLon || centerLon > maxLon) && (axisLat+GeoRect.AXISLAT_ERROR < minLat || axisLat-GeoRect.AXISLAT_ERROR > maxLat)) {
         if (SloppyMath.haversinMeters(distanceQuery.centerLat, centerLon, minLat, minLon) > distanceQuery.radiusMeters &&
             SloppyMath.haversinMeters(distanceQuery.centerLat, centerLon, minLat, maxLon) > distanceQuery.radiusMeters &&
             SloppyMath.haversinMeters(distanceQuery.centerLat, centerLon, maxLat, minLon) > distanceQuery.radiusMeters &&

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/3f217aba/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/search/GeoPointInBBoxQuery.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/search/GeoPointInBBoxQuery.java b/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/search/GeoPointInBBoxQuery.java
index 4229b28..f30950e 100644
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/search/GeoPointInBBoxQuery.java
+++ b/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/search/GeoPointInBBoxQuery.java
@@ -23,7 +23,7 @@ import org.apache.lucene.search.FieldValueQuery;
 import org.apache.lucene.search.LegacyNumericRangeQuery;
 import org.apache.lucene.search.Query;
 import org.apache.lucene.spatial.geopoint.document.GeoPointField.TermEncoding;
-import org.apache.lucene.spatial.util.GeoUtils;
+import org.apache.lucene.geo.GeoUtils;
 
 /** Implements a simple bounding box query on a GeoPoint field. This is inspired by
  * {@link LegacyNumericRangeQuery} and is implemented using a

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/3f217aba/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/search/GeoPointInPolygonQuery.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/search/GeoPointInPolygonQuery.java b/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/search/GeoPointInPolygonQuery.java
index 4e6bdce..0d29d25 100644
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/search/GeoPointInPolygonQuery.java
+++ b/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/search/GeoPointInPolygonQuery.java
@@ -82,7 +82,7 @@ public final class GeoPointInPolygonQuery extends GeoPointInBBoxQuery {
    * that fall within or on the boundary of the polygon defined by the input parameters. 
    */
   public GeoPointInPolygonQuery(String field, TermEncoding termEncoding, Polygon... polygons) {
-    this(field, termEncoding, Polygon.getBoundingBox(polygons), polygons);
+    this(field, termEncoding, GeoRect.fromPolygon(polygons), polygons);
   }
   
   // internal constructor

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/3f217aba/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/search/GeoPointMultiTermQuery.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/search/GeoPointMultiTermQuery.java b/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/search/GeoPointMultiTermQuery.java
index ec08475..f1f53e3 100644
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/search/GeoPointMultiTermQuery.java
+++ b/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/search/GeoPointMultiTermQuery.java
@@ -29,7 +29,7 @@ import org.apache.lucene.spatial.geopoint.document.GeoPointField;
 import org.apache.lucene.spatial.geopoint.document.GeoPointField.TermEncoding;
 import org.apache.lucene.spatial.util.GeoEncodingUtils;
 import org.apache.lucene.spatial.util.GeoRelationUtils;
-import org.apache.lucene.spatial.util.GeoUtils;
+import org.apache.lucene.geo.GeoUtils;
 import org.apache.lucene.util.SloppyMath;
 
 /**

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/3f217aba/lucene/spatial/src/java/org/apache/lucene/spatial/util/GeoEncodingUtils.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/util/GeoEncodingUtils.java b/lucene/spatial/src/java/org/apache/lucene/spatial/util/GeoEncodingUtils.java
index 7bed892..d2141d9 100644
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/util/GeoEncodingUtils.java
+++ b/lucene/spatial/src/java/org/apache/lucene/spatial/util/GeoEncodingUtils.java
@@ -21,8 +21,8 @@ import org.apache.lucene.util.BitUtil;
 import org.apache.lucene.util.BytesRef;
 import org.apache.lucene.util.BytesRefBuilder;
 
-import static org.apache.lucene.spatial.util.GeoUtils.MIN_LON_INCL;
-import static org.apache.lucene.spatial.util.GeoUtils.MIN_LAT_INCL;
+import static org.apache.lucene.geo.GeoUtils.MIN_LON_INCL;
+import static org.apache.lucene.geo.GeoUtils.MIN_LAT_INCL;
 
 /**
  * Basic reusable geopoint encoding methods

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/3f217aba/lucene/spatial/src/java/org/apache/lucene/spatial/util/GeoRect.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/util/GeoRect.java b/lucene/spatial/src/java/org/apache/lucene/spatial/util/GeoRect.java
index 2dbba6d..391f6d7 100644
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/util/GeoRect.java
+++ b/lucene/spatial/src/java/org/apache/lucene/spatial/util/GeoRect.java
@@ -16,6 +16,27 @@
  */
 package org.apache.lucene.spatial.util;
 
+import org.apache.lucene.geo.GeoUtils;
+
+import static java.lang.Math.PI;
+import static java.lang.Math.max;
+import static java.lang.Math.min;
+import static java.lang.Math.toDegrees;
+import static java.lang.Math.toRadians;
+import static org.apache.lucene.geo.GeoUtils.checkLatitude;
+import static org.apache.lucene.geo.GeoUtils.checkLongitude;
+import static org.apache.lucene.geo.GeoUtils.MAX_LAT_INCL;
+import static org.apache.lucene.geo.GeoUtils.MIN_LAT_INCL;
+import static org.apache.lucene.geo.GeoUtils.MAX_LAT_RADIANS;
+import static org.apache.lucene.geo.GeoUtils.MAX_LON_RADIANS;
+import static org.apache.lucene.geo.GeoUtils.MIN_LAT_RADIANS;
+import static org.apache.lucene.geo.GeoUtils.MIN_LON_RADIANS;
+import static org.apache.lucene.geo.GeoUtils.EARTH_MEAN_RADIUS_METERS;
+import static org.apache.lucene.geo.GeoUtils.sloppySin;
+import static org.apache.lucene.util.SloppyMath.TO_DEGREES;
+import static org.apache.lucene.util.SloppyMath.asin;
+import static org.apache.lucene.util.SloppyMath.cos;
+
 /** Represents a lat/lon rectangle. */
 public class GeoRect {
   /** maximum longitude value (in degrees) */
@@ -67,4 +88,104 @@ public class GeoRect {
   public boolean crossesDateline() {
     return maxLon < minLon;
   }
+
+  /** Compute Bounding Box for a circle using WGS-84 parameters */
+  public static GeoRect fromPointDistance(final double centerLat, final double centerLon, final double radiusMeters) {
+    checkLatitude(centerLat);
+    checkLongitude(centerLon);
+    final double radLat = toRadians(centerLat);
+    final double radLon = toRadians(centerLon);
+    // LUCENE-7143
+    double radDistance = (radiusMeters + 7E-2) / EARTH_MEAN_RADIUS_METERS;
+    double minLat = radLat - radDistance;
+    double maxLat = radLat + radDistance;
+    double minLon;
+    double maxLon;
+
+    if (minLat > MIN_LAT_RADIANS && maxLat < MAX_LAT_RADIANS) {
+      double deltaLon = asin(sloppySin(radDistance) / cos(radLat));
+      minLon = radLon - deltaLon;
+      if (minLon < MIN_LON_RADIANS) {
+        minLon += 2d * PI;
+      }
+      maxLon = radLon + deltaLon;
+      if (maxLon > MAX_LON_RADIANS) {
+        maxLon -= 2d * PI;
+      }
+    } else {
+      // a pole is within the distance
+      minLat = max(minLat, MIN_LAT_RADIANS);
+      maxLat = min(maxLat, MAX_LAT_RADIANS);
+      minLon = MIN_LON_RADIANS;
+      maxLon = MAX_LON_RADIANS;
+    }
+
+    return new GeoRect(toDegrees(minLat), toDegrees(maxLat), toDegrees(minLon), toDegrees(maxLon));
+  }
+
+  /** maximum error from {@link #axisLat(double, double)}. logic must be prepared to handle this */
+  public static final double AXISLAT_ERROR = 0.1D / EARTH_MEAN_RADIUS_METERS * TO_DEGREES;
+
+  /**
+   * Calculate the latitude of a circle's intersections with its bbox meridians.
+   * <p>
+   * <b>NOTE:</b> the returned value will be +/- {@link #AXISLAT_ERROR} of the actual value.
+   * @param centerLat The latitude of the circle center
+   * @param radiusMeters The radius of the circle in meters
+   * @return A latitude
+   */
+  public static double axisLat(double centerLat, double radiusMeters) {
+    // A spherical triangle with:
+    // r is the radius of the circle in radians
+    // l1 is the latitude of the circle center
+    // l2 is the latitude of the point at which the circle intersect's its bbox longitudes
+    // We know r is tangent to the bbox meridians at l2, therefore it is a right angle.
+    // So from the law of cosines, with the angle of l1 being 90, we have:
+    // cos(l1) = cos(r) * cos(l2) + sin(r) * sin(l2) * cos(90)
+    // The second part cancels out because cos(90) == 0, so we have:
+    // cos(l1) = cos(r) * cos(l2)
+    // Solving for l2, we get:
+    // l2 = acos( cos(l1) / cos(r) )
+    // We ensure r is in the range (0, PI/2) and l1 in the range (0, PI/2]. This means we
+    // cannot divide by 0, and we will always get a positive value in the range [0, 1) as
+    // the argument to arc cosine, resulting in a range (0, PI/2].
+    final double PIO2 = Math.PI / 2D;
+    double l1 = toRadians(centerLat);
+    double r = (radiusMeters + 7E-2) / EARTH_MEAN_RADIUS_METERS;
+
+    // if we are within radius range of a pole, the lat is the pole itself
+    if (Math.abs(l1) + r >= MAX_LAT_RADIANS) {
+      return centerLat >= 0 ? MAX_LAT_INCL : MIN_LAT_INCL;
+    }
+
+    // adjust l1 as distance from closest pole, to form a right triangle with bbox meridians
+    // and ensure it is in the range (0, PI/2]
+    l1 = centerLat >= 0 ? PIO2 - l1 : l1 + PIO2;
+
+    double l2 = Math.acos(Math.cos(l1) / Math.cos(r));
+    assert !Double.isNaN(l2);
+
+    // now adjust back to range [-pi/2, pi/2], ie latitude in radians
+    l2 = centerLat >= 0 ? PIO2 - l2 : l2 - PIO2;
+
+    return toDegrees(l2);
+  }
+
+  /** Returns the bounding box over an array of polygons */
+  public static GeoRect fromPolygon(Polygon[] polygons) {
+    // compute bounding box
+    double minLat = Double.POSITIVE_INFINITY;
+    double maxLat = Double.NEGATIVE_INFINITY;
+    double minLon = Double.POSITIVE_INFINITY;
+    double maxLon = Double.NEGATIVE_INFINITY;
+
+    for (int i = 0;i < polygons.length; i++) {
+      minLat = Math.min(polygons[i].minLat, minLat);
+      maxLat = Math.max(polygons[i].maxLat, maxLat);
+      minLon = Math.min(polygons[i].minLon, minLon);
+      maxLon = Math.max(polygons[i].maxLon, maxLon);
+    }
+
+    return new GeoRect(minLat, maxLat, minLon, maxLon);
+  }
 }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/3f217aba/lucene/spatial/src/java/org/apache/lucene/spatial/util/GeoUtils.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/util/GeoUtils.java b/lucene/spatial/src/java/org/apache/lucene/spatial/util/GeoUtils.java
deleted file mode 100644
index 0d510f3..0000000
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/util/GeoUtils.java
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * 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.
- */
-package org.apache.lucene.spatial.util;
-
-import static java.lang.Math.max;
-import static java.lang.Math.min;
-import static java.lang.Math.PI;
-
-import static org.apache.lucene.util.SloppyMath.asin;
-import static org.apache.lucene.util.SloppyMath.cos;
-import static org.apache.lucene.util.SloppyMath.TO_DEGREES;
-import static org.apache.lucene.util.SloppyMath.TO_RADIANS;
-
-/**
- * Basic reusable geo-spatial utility methods
- *
- * @lucene.experimental
- */
-public final class GeoUtils {
-  /** Minimum longitude value. */
-  public static final double MIN_LON_INCL = -180.0D;
-
-  /** Maximum longitude value. */
-  public static final double MAX_LON_INCL = 180.0D;
-
-  /** Minimum latitude value. */
-  public static final double MIN_LAT_INCL = -90.0D;
-
-  /** Maximum latitude value. */
-  public static final double MAX_LAT_INCL = 90.0D;
-  
-  /** min longitude value in radians */
-  public static final double MIN_LON_RADIANS = TO_RADIANS * MIN_LON_INCL;
-  /** min latitude value in radians */
-  public static final double MIN_LAT_RADIANS = TO_RADIANS * MIN_LAT_INCL;
-  /** max longitude value in radians */
-  public static final double MAX_LON_RADIANS = TO_RADIANS * MAX_LON_INCL;
-  /** max latitude value in radians */
-  public static final double MAX_LAT_RADIANS = TO_RADIANS * MAX_LAT_INCL;
-  
-  // WGS84 earth-ellipsoid parameters
-  /** mean earth axis in meters */
-  // see http://earth-info.nga.mil/GandG/publications/tr8350.2/wgs84fin.pdf
-  public static final double EARTH_MEAN_RADIUS_METERS = 6_371_008.7714;
-
-  // No instance:
-  private GeoUtils() {
-  }
-
-  /** validates latitude value is within standard +/-90 coordinate bounds */
-  public static void checkLatitude(double latitude) {
-    if (Double.isNaN(latitude) || latitude < MIN_LAT_INCL || latitude > MAX_LAT_INCL) {
-      throw new IllegalArgumentException("invalid latitude " +  latitude + "; must be between " + MIN_LAT_INCL + " and " + MAX_LAT_INCL);
-    }
-  }
-
-  /** validates longitude value is within standard +/-180 coordinate bounds */
-  public static void checkLongitude(double longitude) {
-    if (Double.isNaN(longitude) || longitude < MIN_LON_INCL || longitude > MAX_LON_INCL) {
-      throw new IllegalArgumentException("invalid longitude " +  longitude + "; must be between " + MIN_LON_INCL + " and " + MAX_LON_INCL);
-    }
-  }
-  
-  /** Compute Bounding Box for a circle using WGS-84 parameters */
-  public static GeoRect circleToBBox(final double centerLat, final double centerLon, final double radiusMeters) {
-    final double radLat = TO_RADIANS * centerLat;
-    final double radLon = TO_RADIANS * centerLon;
-    // LUCENE-7143
-    double radDistance = (radiusMeters + 7E-2) / EARTH_MEAN_RADIUS_METERS;
-    double minLat = radLat - radDistance;
-    double maxLat = radLat + radDistance;
-    double minLon;
-    double maxLon;
-
-    if (minLat > MIN_LAT_RADIANS && maxLat < MAX_LAT_RADIANS) {
-      double deltaLon = asin(sloppySin(radDistance) / cos(radLat));
-      minLon = radLon - deltaLon;
-      if (minLon < MIN_LON_RADIANS) {
-        minLon += 2d * PI;
-      }
-      maxLon = radLon + deltaLon;
-      if (maxLon > MAX_LON_RADIANS) {
-        maxLon -= 2d * PI;
-      }
-    } else {
-      // a pole is within the distance
-      minLat = max(minLat, MIN_LAT_RADIANS);
-      maxLat = min(maxLat, MAX_LAT_RADIANS);
-      minLon = MIN_LON_RADIANS;
-      maxLon = MAX_LON_RADIANS;
-    }
-
-    return new GeoRect(TO_DEGREES * minLat, TO_DEGREES * maxLat, TO_DEGREES * minLon, TO_DEGREES * maxLon);
-  }
-  
-  // some sloppyish stuff, do we really need this to be done in a sloppy way?
-  // unless it is performance sensitive, we should try to remove.
-  private static final double PIO2 = Math.PI / 2D;
-
-  /**
-   * Returns the trigonometric sine of an angle converted as a cos operation.
-   * <p>
-   * Note that this is not quite right... e.g. sin(0) != 0
-   * <p>
-   * Special cases:
-   * <ul>
-   *  <li>If the argument is {@code NaN} or an infinity, then the result is {@code NaN}.
-   * </ul>
-   * @param a an angle, in radians.
-   * @return the sine of the argument.
-   * @see Math#sin(double)
-   */
-  // TODO: deprecate/remove this? at least its no longer public.
-  private static double sloppySin(double a) {
-    return cos(a - PIO2);
-  }
-
-  /** maximum error from {@link #axisLat(double, double)}. logic must be prepared to handle this */
-  public static final double AXISLAT_ERROR = 0.1D / EARTH_MEAN_RADIUS_METERS * TO_DEGREES;
-
-  /**
-   * Calculate the latitude of a circle's intersections with its bbox meridians.
-   * <p>
-   * <b>NOTE:</b> the returned value will be +/- {@link #AXISLAT_ERROR} of the actual value.
-   * @param centerLat The latitude of the circle center
-   * @param radiusMeters The radius of the circle in meters
-   * @return A latitude
-   */
-  public static double axisLat(double centerLat, double radiusMeters) {
-    // A spherical triangle with:
-    // r is the radius of the circle in radians
-    // l1 is the latitude of the circle center
-    // l2 is the latitude of the point at which the circle intersect's its bbox longitudes
-    // We know r is tangent to the bbox meridians at l2, therefore it is a right angle.
-    // So from the law of cosines, with the angle of l1 being 90, we have:
-    // cos(l1) = cos(r) * cos(l2) + sin(r) * sin(l2) * cos(90)
-    // The second part cancels out because cos(90) == 0, so we have:
-    // cos(l1) = cos(r) * cos(l2)
-    // Solving for l2, we get:
-    // l2 = acos( cos(l1) / cos(r) )
-    // We ensure r is in the range (0, PI/2) and l1 in the range (0, PI/2]. This means we
-    // cannot divide by 0, and we will always get a positive value in the range [0, 1) as
-    // the argument to arc cosine, resulting in a range (0, PI/2].
-
-    double l1 = TO_RADIANS * centerLat;
-    double r = (radiusMeters + 7E-2) / EARTH_MEAN_RADIUS_METERS;
-
-    // if we are within radius range of a pole, the lat is the pole itself
-    if (Math.abs(l1) + r >= MAX_LAT_RADIANS) {
-      return centerLat >= 0 ? MAX_LAT_INCL : MIN_LAT_INCL;
-    }
-
-    // adjust l1 as distance from closest pole, to form a right triangle with bbox meridians
-    // and ensure it is in the range (0, PI/2]
-    l1 = centerLat >= 0 ? PIO2 - l1 : l1 + PIO2;
-
-    double l2 = Math.acos(Math.cos(l1) / Math.cos(r));
-    assert !Double.isNaN(l2);
-
-    // now adjust back to range [-pi/2, pi/2], ie latitude in radians
-    l2 = centerLat >= 0 ? PIO2 - l2 : l2 - PIO2;
-
-    return TO_DEGREES * l2;
-  }
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/3f217aba/lucene/spatial/src/java/org/apache/lucene/spatial/util/Polygon.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/util/Polygon.java b/lucene/spatial/src/java/org/apache/lucene/spatial/util/Polygon.java
index 5dca23d..c0e2323 100644
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/util/Polygon.java
+++ b/lucene/spatial/src/java/org/apache/lucene/spatial/util/Polygon.java
@@ -18,6 +18,8 @@ package org.apache.lucene.spatial.util;
 
 import java.util.Arrays;
 
+import org.apache.lucene.geo.GeoUtils;
+
 /** 
  * Represents a closed polygon on the earth's surface.
  * @lucene.experimental 
@@ -241,24 +243,6 @@ public final class Polygon {
     return holes.clone();
   }
   
-  /** Returns the bounding box over an array of polygons */
-  public static GeoRect getBoundingBox(Polygon[] polygons) {
-    // compute bounding box
-    double minLat = Double.POSITIVE_INFINITY;
-    double maxLat = Double.NEGATIVE_INFINITY;
-    double minLon = Double.POSITIVE_INFINITY;
-    double maxLon = Double.NEGATIVE_INFINITY;
-
-    for (int i = 0;i < polygons.length; i++) {
-      minLat = Math.min(polygons[i].minLat, minLat);
-      maxLat = Math.max(polygons[i].maxLat, maxLat);
-      minLon = Math.min(polygons[i].minLon, minLon);
-      maxLon = Math.max(polygons[i].maxLon, maxLon);
-    }
-    
-    return new GeoRect(minLat, maxLat, minLon, maxLon);
-  }
-  
   /** Helper for multipolygon logic: returns true if any of the supplied polygons contain the point */
   public static boolean contains(Polygon[] polygons, double latitude, double longitude) {
     for (Polygon polygon : polygons) {

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/3f217aba/lucene/spatial/src/test/org/apache/lucene/spatial/util/BaseGeoPointTestCase.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/test/org/apache/lucene/spatial/util/BaseGeoPointTestCase.java b/lucene/spatial/src/test/org/apache/lucene/spatial/util/BaseGeoPointTestCase.java
index 2b5f885..da69b24 100644
--- a/lucene/spatial/src/test/org/apache/lucene/spatial/util/BaseGeoPointTestCase.java
+++ b/lucene/spatial/src/test/org/apache/lucene/spatial/util/BaseGeoPointTestCase.java
@@ -37,6 +37,7 @@ import org.apache.lucene.document.Field;
 import org.apache.lucene.document.NumericDocValuesField;
 import org.apache.lucene.document.StoredField;
 import org.apache.lucene.document.StringField;
+import org.apache.lucene.geo.GeoUtils;
 import org.apache.lucene.index.DirectoryReader;
 import org.apache.lucene.index.IndexReader;
 import org.apache.lucene.index.IndexWriter;

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/3f217aba/lucene/spatial/src/test/org/apache/lucene/spatial/util/GeoTestUtil.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/test/org/apache/lucene/spatial/util/GeoTestUtil.java b/lucene/spatial/src/test/org/apache/lucene/spatial/util/GeoTestUtil.java
index 1785c12..1e4fcf3 100644
--- a/lucene/spatial/src/test/org/apache/lucene/spatial/util/GeoTestUtil.java
+++ b/lucene/spatial/src/test/org/apache/lucene/spatial/util/GeoTestUtil.java
@@ -20,6 +20,7 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.Random;
 
+import org.apache.lucene.geo.GeoUtils;
 import org.apache.lucene.util.SloppyMath;
 
 import com.carrotsearch.randomizedtesting.RandomizedContext;
@@ -398,7 +399,7 @@ public class GeoTestUtil {
                                    double rectMinLongitude, double rectMaxLongitude,
                                    double centerLatitude, double centerLongitude,
                                    double radiusMeters) {
-    GeoRect box = GeoUtils.circleToBBox(centerLatitude, centerLongitude, radiusMeters);
+    GeoRect box = GeoRect.fromPointDistance(centerLatitude, centerLongitude, radiusMeters);
     System.out.println("<!DOCTYPE HTML>");
     System.out.println("<html>");
     System.out.println("  <head>");
@@ -420,7 +421,7 @@ public class GeoTestUtil {
     System.out.println("        }).addTo(earth);");
     plotLatApproximatelyOnEarthSurface("lat0", "#ffffff", 4.68, 0.0, 360.0);
     plotLatApproximatelyOnEarthSurface("lat1", "#ffffff", 180-93.09, 0.0, 360.0);
-    plotLatApproximatelyOnEarthSurface("axisLat", "#00ff00", GeoUtils.axisLat(centerLatitude, radiusMeters), box.minLon, box.maxLon);
+    plotLatApproximatelyOnEarthSurface("axisLat", "#00ff00", GeoRect.axisLat(centerLatitude, radiusMeters), box.minLon, box.maxLon);
     plotLonApproximatelyOnEarthSurface("axisLon", "#00ff00", centerLongitude, box.minLat, box.maxLat);
     System.out.println("      }");
     System.out.println("    </script>");

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/3f217aba/lucene/spatial/src/test/org/apache/lucene/spatial/util/TestGeoUtils.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/test/org/apache/lucene/spatial/util/TestGeoUtils.java b/lucene/spatial/src/test/org/apache/lucene/spatial/util/TestGeoUtils.java
index 7bd3fed..06ef48c 100644
--- a/lucene/spatial/src/test/org/apache/lucene/spatial/util/TestGeoUtils.java
+++ b/lucene/spatial/src/test/org/apache/lucene/spatial/util/TestGeoUtils.java
@@ -18,6 +18,7 @@ package org.apache.lucene.spatial.util;
 
 import java.util.Locale;
 
+import org.apache.lucene.geo.GeoUtils;
 import org.apache.lucene.util.BytesRefBuilder;
 import org.apache.lucene.util.LuceneTestCase;
 import org.apache.lucene.util.SloppyMath;
@@ -155,7 +156,7 @@ public class TestGeoUtils extends LuceneTestCase {
 
       // TODO: randomly quantize radius too, to provoke exact math errors?
 
-      GeoRect bbox = GeoUtils.circleToBBox(centerLat, centerLon, radiusMeters);
+      GeoRect bbox = GeoRect.fromPointDistance(centerLat, centerLon, radiusMeters);
 
       int numPointsToTry = 1000;
       for(int i=0;i<numPointsToTry;i++) {
@@ -218,7 +219,7 @@ public class TestGeoUtils extends LuceneTestCase {
       double lat = GeoTestUtil.nextLatitude();
       double lon = GeoTestUtil.nextLongitude();
       double radius = 50000000 * random().nextDouble();
-      GeoRect box = GeoUtils.circleToBBox(lat, lon, radius);
+      GeoRect box = GeoRect.fromPointDistance(lat, lon, radius);
       final GeoRect box1;
       final GeoRect box2;
       if (box.crossesDateline()) {
@@ -247,7 +248,7 @@ public class TestGeoUtils extends LuceneTestCase {
       double lat = GeoTestUtil.nextLatitude();
       double lon = GeoTestUtil.nextLongitude();
       double radius = 50000000 * random().nextDouble();
-      GeoRect box = GeoUtils.circleToBBox(lat, lon, radius);
+      GeoRect box = GeoRect.fromPointDistance(lat, lon, radius);
 
       if (box.maxLon - lon < 90 && lon - box.minLon < 90) {
         double minPartialDistance = Math.max(SloppyMath.haversinSortKey(lat, lon, lat, box.maxLon),
@@ -270,7 +271,7 @@ public class TestGeoUtils extends LuceneTestCase {
     for (int i = 0; i < 1000; i++) {
       double centerLat = GeoTestUtil.nextLatitude();
       double centerLon = GeoTestUtil.nextLongitude();
-      GeoRect rect = GeoUtils.circleToBBox(centerLat, centerLon, Double.POSITIVE_INFINITY);
+      GeoRect rect = GeoRect.fromPointDistance(centerLat, centerLon, Double.POSITIVE_INFINITY);
       assertEquals(-180.0, rect.minLon, 0.0D);
       assertEquals(180.0, rect.maxLon, 0.0D);
       assertEquals(-90.0, rect.minLat, 0.0D);
@@ -281,16 +282,16 @@ public class TestGeoUtils extends LuceneTestCase {
   
   public void testAxisLat() {
     double earthCircumference = 2D * Math.PI * GeoUtils.EARTH_MEAN_RADIUS_METERS;
-    assertEquals(90, GeoUtils.axisLat(0, earthCircumference / 4), 0.0D);
+    assertEquals(90, GeoRect.axisLat(0, earthCircumference / 4), 0.0D);
 
     for (int i = 0; i < 100; ++i) {
       boolean reallyBig = random().nextInt(10) == 0;
       final double maxRadius = reallyBig ? 1.1 * earthCircumference : earthCircumference / 8;
       final double radius = maxRadius * random().nextDouble();
-      double prevAxisLat = GeoUtils.axisLat(0.0D, radius);
+      double prevAxisLat = GeoRect.axisLat(0.0D, radius);
       for (double lat = 0.1D; lat < 90D; lat += 0.1D) {
-        double nextAxisLat = GeoUtils.axisLat(lat, radius);
-        GeoRect bbox = GeoUtils.circleToBBox(lat, 180D, radius);
+        double nextAxisLat = GeoRect.axisLat(lat, radius);
+        GeoRect bbox = GeoRect.fromPointDistance(lat, 180D, radius);
         double dist = SloppyMath.haversinMeters(lat, 180D, nextAxisLat, bbox.maxLon);
         if (nextAxisLat < GeoUtils.MAX_LAT_INCL) {
           assertEquals("lat = " + lat, dist, radius, 0.1D);
@@ -299,10 +300,10 @@ public class TestGeoUtils extends LuceneTestCase {
         prevAxisLat = nextAxisLat;
       }
 
-      prevAxisLat = GeoUtils.axisLat(-0.0D, radius);
+      prevAxisLat = GeoRect.axisLat(-0.0D, radius);
       for (double lat = -0.1D; lat > -90D; lat -= 0.1D) {
-        double nextAxisLat = GeoUtils.axisLat(lat, radius);
-        GeoRect bbox = GeoUtils.circleToBBox(lat, 180D, radius);
+        double nextAxisLat = GeoRect.axisLat(lat, radius);
+        GeoRect bbox = GeoRect.fromPointDistance(lat, 180D, radius);
         double dist = SloppyMath.haversinMeters(lat, 180D, nextAxisLat, bbox.maxLon);
         if (nextAxisLat > GeoUtils.MIN_LAT_INCL) {
           assertEquals("lat = " + lat, dist, radius, 0.1D);
@@ -321,13 +322,13 @@ public class TestGeoUtils extends LuceneTestCase {
       final double centerLat = -90 + 180.0 * random().nextDouble();
       final double centerLon = -180 + 360.0 * random().nextDouble();
       final double radius = 50_000_000D * random().nextDouble();
-      final GeoRect box = GeoUtils.circleToBBox(centerLat, centerLon, radius);
+      final GeoRect box = GeoRect.fromPointDistance(centerLat, centerLon, radius);
       // TODO: remove this leniency!
       if (box.crossesDateline()) {
         --i; // try again...
         continue;
       }
-      final double axisLat = GeoUtils.axisLat(centerLat, radius);
+      final double axisLat = GeoRect.axisLat(centerLat, radius);
 
       for (int k = 0; k < 1000; ++k) {
 
@@ -380,7 +381,7 @@ public class TestGeoUtils extends LuceneTestCase {
                     "lonMax=%s) == false BUT\n" +
                     "haversin(%s, %s, %s, %s) = %s\nbbox=%s",
                 centerLat, centerLon, radius, latMin, latMax, lonMin, lonMax,
-                centerLat, centerLon, lat, lon, distance, GeoUtils.circleToBBox(centerLat, centerLon, radius)),
+                centerLat, centerLon, lat, lon, distance, GeoRect.fromPointDistance(centerLat, centerLon, radius)),
                 distance > radius);
             } catch (AssertionError e) {
               GeoTestUtil.toWebGLEarth(latMin, latMax, lonMin, lonMax, centerLat, centerLon, radius);
@@ -397,7 +398,7 @@ public class TestGeoUtils extends LuceneTestCase {
   }
   
   static boolean isDisjoint(double centerLat, double centerLon, double radius, double axisLat, double latMin, double latMax, double lonMin, double lonMax) {
-    if ((centerLon < lonMin || centerLon > lonMax) && (axisLat+GeoUtils.AXISLAT_ERROR < latMin || axisLat-GeoUtils.AXISLAT_ERROR > latMax)) {
+    if ((centerLon < lonMin || centerLon > lonMax) && (axisLat+GeoRect.AXISLAT_ERROR < latMin || axisLat-GeoRect.AXISLAT_ERROR > latMax)) {
       // circle not fully inside / crossing axis
       if (SloppyMath.haversinMeters(centerLat, centerLon, latMin, lonMin) > radius &&
           SloppyMath.haversinMeters(centerLat, centerLon, latMin, lonMax) > radius &&