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/02/05 21:41:27 UTC

[5/7] lucene-solr git commit: LUCENE-6997: refactor sandboxed GeoPointField and query classes to lucene-spatial module

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/187fe876/lucene/sandbox/src/java/org/apache/lucene/util/GeoHashUtils.java
----------------------------------------------------------------------
diff --git a/lucene/sandbox/src/java/org/apache/lucene/util/GeoHashUtils.java b/lucene/sandbox/src/java/org/apache/lucene/util/GeoHashUtils.java
deleted file mode 100644
index d421cc9..0000000
--- a/lucene/sandbox/src/java/org/apache/lucene/util/GeoHashUtils.java
+++ /dev/null
@@ -1,273 +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.util;
-
-import java.util.ArrayList;
-import java.util.Collection;
-
-/**
- * Utilities for converting to/from the GeoHash standard
- *
- * The geohash long format is represented as lon/lat (x/y) interleaved with the 4 least significant bits
- * representing the level (1-12) [xyxy...xyxyllll]
- *
- * This differs from a morton encoded value which interleaves lat/lon (y/x).
- *
- * @lucene.experimental
- */
-public class GeoHashUtils {
-  public static final char[] BASE_32 = {'0', '1', '2', '3', '4', '5', '6',
-      '7', '8', '9', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'j', 'k', 'm', 'n',
-      'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'};
-
-  public static final String BASE_32_STRING = new String(BASE_32);
-
-  public static final int PRECISION = 12;
-  private static final short MORTON_OFFSET = (GeoUtils.BITS<<1) - (PRECISION*5);
-
-  /**
-   * Encode lon/lat to the geohash based long format (lon/lat interleaved, 4 least significant bits = level)
-   */
-  public static final long longEncode(final double lon, final double lat, final int level) {
-    // shift to appropriate level
-    final short msf = (short)(((12 - level) * 5) + MORTON_OFFSET);
-    return ((BitUtil.flipFlop(GeoUtils.mortonHash(lon, lat)) >>> msf) << 4) | level;
-  }
-
-  /**
-   * Encode from geohash string to the geohash based long format (lon/lat interleaved, 4 least significant bits = level)
-   */
-  public static final long longEncode(final String hash) {
-    int level = hash.length()-1;
-    long b;
-    long l = 0L;
-    for(char c : hash.toCharArray()) {
-      b = (long)(BASE_32_STRING.indexOf(c));
-      l |= (b<<(level--*5));
-    }
-    return (l<<4)|hash.length();
-  }
-
-  /**
-   * Encode an existing geohash long to the provided precision
-   */
-  public static long longEncode(long geohash, int level) {
-    final short precision = (short)(geohash & 15);
-    if (precision == level) {
-      return geohash;
-    } else if (precision > level) {
-      return ((geohash >>> (((precision - level) * 5) + 4)) << 4) | level;
-    }
-    return ((geohash >>> 4) << (((level - precision) * 5) + 4) | level);
-  }
-
-  public static long fromMorton(long morton, int level) {
-    long mFlipped = BitUtil.flipFlop(morton);
-    mFlipped >>>= (((GeoHashUtils.PRECISION - level) * 5) + MORTON_OFFSET);
-    return (mFlipped << 4) | level;
-  }
-
-  /**
-   * Encode to a geohash string from the geohash based long format
-   */
-  public static final String stringEncode(long geoHashLong) {
-    int level = (int)geoHashLong&15;
-    geoHashLong >>>= 4;
-    char[] chars = new char[level];
-    do {
-      chars[--level] = BASE_32[(int) (geoHashLong&31L)];
-      geoHashLong>>>=5;
-    } while(level > 0);
-
-    return new String(chars);
-  }
-
-  /**
-   * Encode to a geohash string from full resolution longitude, latitude)
-   */
-  public static final String stringEncode(final double lon, final double lat) {
-    return stringEncode(lon, lat, 12);
-  }
-
-  /**
-   * Encode to a level specific geohash string from full resolution longitude, latitude
-   */
-  public static final String stringEncode(final double lon, final double lat, final int level) {
-    // convert to geohashlong
-    final long ghLong = fromMorton(GeoUtils.mortonHash(lon, lat), level);
-    return stringEncode(ghLong);
-
-  }
-
-  /**
-   * Encode to a full precision geohash string from a given morton encoded long value
-   */
-  public static final String stringEncodeFromMortonLong(final long hashedVal) throws Exception {
-    return stringEncode(hashedVal, PRECISION);
-  }
-
-  /**
-   * Encode to a geohash string at a given level from a morton long
-   */
-  public static final String stringEncodeFromMortonLong(long hashedVal, final int level) {
-    // bit twiddle to geohash (since geohash is a swapped (lon/lat) encoding)
-    hashedVal = BitUtil.flipFlop(hashedVal);
-
-    StringBuilder geoHash = new StringBuilder();
-    short precision = 0;
-    final short msf = (GeoUtils.BITS<<1)-5;
-    long mask = 31L<<msf;
-    do {
-      geoHash.append(BASE_32[(int)((mask & hashedVal)>>>(msf-(precision*5)))]);
-      // next 5 bits
-      mask >>>= 5;
-    } while (++precision < level);
-    return geoHash.toString();
-  }
-
-  /**
-   * Encode to a morton long value from a given geohash string
-   */
-  public static final long mortonEncode(final String hash) {
-    int level = 11;
-    long b;
-    long l = 0L;
-    for(char c : hash.toCharArray()) {
-      b = (long)(BASE_32_STRING.indexOf(c));
-      l |= (b<<((level--*5) + MORTON_OFFSET));
-    }
-    return BitUtil.flipFlop(l);
-  }
-
-  /**
-   * Encode to a morton long value from a given geohash long value
-   */
-  public static final long mortonEncode(final long geoHashLong) {
-    final int level = (int)(geoHashLong&15);
-    final short odd = (short)(level & 1);
-
-    return BitUtil.flipFlop(((geoHashLong >>> 4) << odd) << (((12 - level) * 5) + (MORTON_OFFSET - odd)));
-  }
-
-  private static final char encode(int x, int y) {
-    return BASE_32[((x & 1) + ((y & 1) * 2) + ((x & 2) * 2) + ((y & 2) * 4) + ((x & 4) * 4)) % 32];
-  }
-
-  /**
-   * Calculate all neighbors of a given geohash cell.
-   *
-   * @param geohash Geohash of the defined cell
-   * @return geohashes of all neighbor cells
-   */
-  public static Collection<? extends CharSequence> neighbors(String geohash) {
-    return addNeighbors(geohash, geohash.length(), new ArrayList<CharSequence>(8));
-  }
-
-  /**
-   * Calculate the geohash of a neighbor of a geohash
-   *
-   * @param geohash the geohash of a cell
-   * @param level   level of the geohash
-   * @param dx      delta of the first grid coordinate (must be -1, 0 or +1)
-   * @param dy      delta of the second grid coordinate (must be -1, 0 or +1)
-   * @return geohash of the defined cell
-   */
-  public final static String neighbor(String geohash, int level, int dx, int dy) {
-    int cell = BASE_32_STRING.indexOf(geohash.charAt(level -1));
-
-    // Decoding the Geohash bit pattern to determine grid coordinates
-    int x0 = cell & 1;  // first bit of x
-    int y0 = cell & 2;  // first bit of y
-    int x1 = cell & 4;  // second bit of x
-    int y1 = cell & 8;  // second bit of y
-    int x2 = cell & 16; // third bit of x
-
-    // combine the bitpattern to grid coordinates.
-    // note that the semantics of x and y are swapping
-    // on each level
-    int x = x0 + (x1 / 2) + (x2 / 4);
-    int y = (y0 / 2) + (y1 / 4);
-
-    if (level == 1) {
-      // Root cells at north (namely "bcfguvyz") or at
-      // south (namely "0145hjnp") do not have neighbors
-      // in north/south direction
-      if ((dy < 0 && y == 0) || (dy > 0 && y == 3)) {
-        return null;
-      } else {
-        return Character.toString(encode(x + dx, y + dy));
-      }
-    } else {
-      // define grid coordinates for next level
-      final int nx = ((level % 2) == 1) ? (x + dx) : (x + dy);
-      final int ny = ((level % 2) == 1) ? (y + dy) : (y + dx);
-
-      // if the defined neighbor has the same parent a the current cell
-      // encode the cell directly. Otherwise find the cell next to this
-      // cell recursively. Since encoding wraps around within a cell
-      // it can be encoded here.
-      // xLimit and YLimit must always be respectively 7 and 3
-      // since x and y semantics are swapping on each level.
-      if (nx >= 0 && nx <= 7 && ny >= 0 && ny <= 3) {
-        return geohash.substring(0, level - 1) + encode(nx, ny);
-      } else {
-        String neighbor = neighbor(geohash, level - 1, dx, dy);
-        return (neighbor != null) ? neighbor + encode(nx, ny) : neighbor;
-      }
-    }
-  }
-
-  /**
-   * Add all geohashes of the cells next to a given geohash to a list.
-   *
-   * @param geohash   Geohash of a specified cell
-   * @param neighbors list to add the neighbors to
-   * @return the given list
-   */
-  public static final <E extends Collection<? super String>> E addNeighbors(String geohash, E neighbors) {
-    return addNeighbors(geohash, geohash.length(), neighbors);
-  }
-
-  /**
-   * Add all geohashes of the cells next to a given geohash to a list.
-   *
-   * @param geohash   Geohash of a specified cell
-   * @param length    level of the given geohash
-   * @param neighbors list to add the neighbors to
-   * @return the given list
-   */
-  public static final <E extends Collection<? super String>> E addNeighbors(String geohash, int length, E neighbors) {
-    String south = neighbor(geohash, length, 0, -1);
-    String north = neighbor(geohash, length, 0, +1);
-    if (north != null) {
-      neighbors.add(neighbor(north, length, -1, 0));
-      neighbors.add(north);
-      neighbors.add(neighbor(north, length, +1, 0));
-    }
-
-    neighbors.add(neighbor(geohash, length, -1, 0));
-    neighbors.add(neighbor(geohash, length, +1, 0));
-
-    if (south != null) {
-      neighbors.add(neighbor(south, length, -1, 0));
-      neighbors.add(south);
-      neighbors.add(neighbor(south, length, +1, 0));
-    }
-
-    return neighbors;
-  }
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/187fe876/lucene/sandbox/src/java/org/apache/lucene/util/GeoProjectionUtils.java
----------------------------------------------------------------------
diff --git a/lucene/sandbox/src/java/org/apache/lucene/util/GeoProjectionUtils.java b/lucene/sandbox/src/java/org/apache/lucene/util/GeoProjectionUtils.java
deleted file mode 100644
index 7e285da..0000000
--- a/lucene/sandbox/src/java/org/apache/lucene/util/GeoProjectionUtils.java
+++ /dev/null
@@ -1,437 +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.util;
-
-import static org.apache.lucene.util.SloppyMath.PIO2;
-import static org.apache.lucene.util.SloppyMath.TO_DEGREES;
-import static org.apache.lucene.util.SloppyMath.TO_RADIANS;
-
-/**
- * Reusable geo-spatial projection utility methods.
- *
- * @lucene.experimental
- */
-public class GeoProjectionUtils {
-  // WGS84 earth-ellipsoid major (a) minor (b) radius, (f) flattening and eccentricity (e)
-  public static final double SEMIMAJOR_AXIS = 6_378_137; // [m]
-  public static final double FLATTENING = 1.0/298.257223563;
-  public static final double SEMIMINOR_AXIS = SEMIMAJOR_AXIS * (1.0 - FLATTENING); //6_356_752.31420; // [m]
-  public static final double ECCENTRICITY = StrictMath.sqrt((2.0 - FLATTENING) * FLATTENING);
-  static final double SEMIMAJOR_AXIS2 = SEMIMAJOR_AXIS * SEMIMAJOR_AXIS;
-  static final double SEMIMINOR_AXIS2 = SEMIMINOR_AXIS * SEMIMINOR_AXIS;
-  public static final double MIN_LON_RADIANS = TO_RADIANS * GeoUtils.MIN_LON_INCL;
-  public static final double MIN_LAT_RADIANS = TO_RADIANS * GeoUtils.MIN_LAT_INCL;
-  public static final double MAX_LON_RADIANS = TO_RADIANS * GeoUtils.MAX_LON_INCL;
-  public static final double MAX_LAT_RADIANS = TO_RADIANS * GeoUtils.MAX_LAT_INCL;
-  private static final double E2 = (SEMIMAJOR_AXIS2 - SEMIMINOR_AXIS2)/(SEMIMAJOR_AXIS2);
-  private static final double EP2 = (SEMIMAJOR_AXIS2 - SEMIMINOR_AXIS2)/(SEMIMINOR_AXIS2);
-
-  /**
-   * Converts from geocentric earth-centered earth-fixed to geodesic lat/lon/alt
-   * @param x Cartesian x coordinate
-   * @param y Cartesian y coordinate
-   * @param z Cartesian z coordinate
-   * @param lla 0: longitude 1: latitude: 2: altitude
-   * @return double array as 0: longitude 1: latitude 2: altitude
-   */
-  public static final double[] ecfToLLA(final double x, final double y, final double z, double[] lla) {
-    boolean atPole = false;
-    final double ad_c = 1.0026000D;
-    final double cos67P5 = 0.38268343236508977D;
-
-    if (lla == null) {
-      lla = new double[3];
-    }
-
-    if (x != 0.0) {
-      lla[0] = StrictMath.atan2(y,x);
-    } else {
-      if (y > 0) {
-        lla[0] = PIO2;
-      } else if (y < 0) {
-        lla[0] = -PIO2;
-      } else {
-        atPole = true;
-        lla[0] = 0.0D;
-        if (z > 0.0) {
-          lla[1] = PIO2;
-        } else if (z < 0.0) {
-          lla[1] = -PIO2;
-        } else {
-          lla[1] = PIO2;
-          lla[2] = -SEMIMINOR_AXIS;
-          return lla;
-        }
-      }
-    }
-
-    final double w2 = x*x + y*y;
-    final double w = StrictMath.sqrt(w2);
-    final double t0 = z * ad_c;
-    final double s0 = StrictMath.sqrt(t0 * t0 + w2);
-    final double sinB0 = t0 / s0;
-    final double cosB0 = w / s0;
-    final double sin3B0 = sinB0 * sinB0 * sinB0;
-    final double t1 = z + SEMIMINOR_AXIS * EP2 * sin3B0;
-    final double sum = w - SEMIMAJOR_AXIS * E2 * cosB0 * cosB0 * cosB0;
-    final double s1 = StrictMath.sqrt(t1 * t1 + sum * sum);
-    final double sinP1 = t1 / s1;
-    final double cosP1 = sum / s1;
-    final double rn = SEMIMAJOR_AXIS / StrictMath.sqrt(1.0D - E2 * sinP1 * sinP1);
-
-    if (cosP1 >= cos67P5) {
-      lla[2] = w / cosP1 - rn;
-    } else if (cosP1 <= -cos67P5) {
-      lla[2] = w / -cosP1 - rn;
-    } else {
-      lla[2] = z / sinP1 + rn * (E2 - 1.0);
-    }
-    if (!atPole) {
-      lla[1] = StrictMath.atan(sinP1/cosP1);
-    }
-    lla[0] = TO_DEGREES * lla[0];
-    lla[1] = TO_DEGREES * lla[1];
-
-    return lla;
-  }
-
-  /**
-   * Converts from geodesic lon lat alt to geocentric earth-centered earth-fixed
-   * @param lon geodesic longitude
-   * @param lat geodesic latitude
-   * @param alt geodesic altitude
-   * @param ecf reusable earth-centered earth-fixed result
-   * @return either a new ecef array or the reusable ecf parameter
-   */
-  public static final double[] llaToECF(double lon, double lat, double alt, double[] ecf) {
-    lon = TO_RADIANS * lon;
-    lat = TO_RADIANS * lat;
-
-    final double sl = SloppyMath.sin(lat);
-    final double s2 = sl*sl;
-    final double cl = SloppyMath.cos(lat);
-
-    if (ecf == null) {
-      ecf = new double[3];
-    }
-
-    if (lat < -PIO2 && lat > -1.001D * PIO2) {
-      lat = -PIO2;
-    } else if (lat > PIO2 && lat < 1.001D * PIO2) {
-      lat = PIO2;
-    }
-    assert (lat >= -PIO2) || (lat <= PIO2);
-
-    if (lon > StrictMath.PI) {
-      lon -= (2*StrictMath.PI);
-    }
-
-    final double rn = SEMIMAJOR_AXIS / StrictMath.sqrt(1.0D - E2 * s2);
-    ecf[0] = (rn+alt) * cl * SloppyMath.cos(lon);
-    ecf[1] = (rn+alt) * cl * SloppyMath.sin(lon);
-    ecf[2] = ((rn*(1.0-E2))+alt)*sl;
-
-    return ecf;
-  }
-
-  /**
-   * Converts from lat lon alt (in degrees) to East North Up right-hand coordinate system
-   * @param lon longitude in degrees
-   * @param lat latitude in degrees
-   * @param alt altitude in meters
-   * @param centerLon reference point longitude in degrees
-   * @param centerLat reference point latitude in degrees
-   * @param centerAlt reference point altitude in meters
-   * @param enu result east, north, up coordinate
-   * @return east, north, up coordinate
-   */
-  public static double[] llaToENU(final double lon, final double lat, final double alt, double centerLon,
-                                  double centerLat, final double centerAlt, double[] enu) {
-    if (enu == null) {
-      enu = new double[3];
-    }
-
-    // convert point to ecf coordinates
-    final double[] ecf = llaToECF(lon, lat, alt, null);
-
-    // convert from ecf to enu
-    return ecfToENU(ecf[0], ecf[1], ecf[2], centerLon, centerLat, centerAlt, enu);
-  }
-
-  /**
-   * Converts from East North Up right-hand rule to lat lon alt in degrees
-   * @param x easting (in meters)
-   * @param y northing (in meters)
-   * @param z up (in meters)
-   * @param centerLon reference point longitude (in degrees)
-   * @param centerLat reference point latitude (in degrees)
-   * @param centerAlt reference point altitude (in meters)
-   * @param lla resulting lat, lon, alt point (in degrees)
-   * @return lat, lon, alt point (in degrees)
-   */
-  public static double[] enuToLLA(final double x, final double y, final double z, final double centerLon,
-                                  final double centerLat, final double centerAlt, double[] lla) {
-    // convert enuToECF
-    if (lla == null) {
-      lla = new double[3];
-    }
-
-    // convert enuToECF, storing intermediate result in lla
-    lla = enuToECF(x, y, z, centerLon, centerLat, centerAlt, lla);
-
-    // convert ecf to LLA
-    return ecfToLLA(lla[0], lla[1], lla[2], lla);
-  }
-
-  /**
-   * Convert from Earth-Centered-Fixed to Easting, Northing, Up Right Hand System
-   * @param x ECF X coordinate (in meters)
-   * @param y ECF Y coordinate (in meters)
-   * @param z ECF Z coordinate (in meters)
-   * @param centerLon ENU origin longitude (in degrees)
-   * @param centerLat ENU origin latitude (in degrees)
-   * @param centerAlt ENU altitude (in meters)
-   * @param enu reusable enu result
-   * @return Easting, Northing, Up coordinate
-   */
-  public static double[] ecfToENU(double x, double y, double z, final double centerLon,
-                                  final double centerLat, final double centerAlt, double[] enu) {
-    if (enu == null) {
-      enu = new double[3];
-    }
-
-    // create rotation matrix and rotate to enu orientation
-    final double[][] phi = createPhiTransform(centerLon, centerLat, null);
-
-    // convert origin to ENU
-    final double[] originECF = llaToECF(centerLon, centerLat, centerAlt, null);
-    final double[] originENU = new double[3];
-    originENU[0] = ((phi[0][0] * originECF[0]) + (phi[0][1] * originECF[1]) + (phi[0][2] * originECF[2]));
-    originENU[1] = ((phi[1][0] * originECF[0]) + (phi[1][1] * originECF[1]) + (phi[1][2] * originECF[2]));
-    originENU[2] = ((phi[2][0] * originECF[0]) + (phi[2][1] * originECF[1]) + (phi[2][2] * originECF[2]));
-
-    // rotate then translate
-    enu[0] = ((phi[0][0] * x) + (phi[0][1] * y) + (phi[0][2] * z)) - originENU[0];
-    enu[1] = ((phi[1][0] * x) + (phi[1][1] * y) + (phi[1][2] * z)) - originENU[1];
-    enu[2] = ((phi[2][0] * x) + (phi[2][1] * y) + (phi[2][2] * z)) - originENU[2];
-
-    return enu;
-  }
-
-  /**
-   * Convert from Easting, Northing, Up Right-Handed system to Earth Centered Fixed system
-   * @param x ENU x coordinate (in meters)
-   * @param y ENU y coordinate (in meters)
-   * @param z ENU z coordinate (in meters)
-   * @param centerLon ENU origin longitude (in degrees)
-   * @param centerLat ENU origin latitude (in degrees)
-   * @param centerAlt ENU origin altitude (in meters)
-   * @param ecf reusable ecf result
-   * @return ecf result coordinate
-   */
-  public static double[] enuToECF(final double x, final double y, final double z, double centerLon,
-                                  double centerLat, final double centerAlt, double[] ecf) {
-    if (ecf == null) {
-      ecf = new double[3];
-    }
-
-    double[][] phi = createTransposedPhiTransform(centerLon, centerLat, null);
-    double[] ecfOrigin = llaToECF(centerLon, centerLat, centerAlt, null);
-
-    // rotate and translate
-    ecf[0] = (phi[0][0]*x + phi[0][1]*y + phi[0][2]*z) + ecfOrigin[0];
-    ecf[1] = (phi[1][0]*x + phi[1][1]*y + phi[1][2]*z) + ecfOrigin[1];
-    ecf[2] = (phi[2][0]*x + phi[2][1]*y + phi[2][2]*z) + ecfOrigin[2];
-
-    return ecf;
-  }
-
-  /**
-   * Create the rotation matrix for converting Earth Centered Fixed to Easting Northing Up
-   * @param originLon ENU origin longitude (in degrees)
-   * @param originLat ENU origin latitude (in degrees)
-   * @param phiMatrix reusable phi matrix result
-   * @return phi rotation matrix
-   */
-  private static double[][] createPhiTransform(double originLon, double originLat, double[][] phiMatrix) {
-
-    if (phiMatrix == null) {
-      phiMatrix = new double[3][3];
-    }
-
-    originLon = TO_RADIANS * originLon;
-    originLat = TO_RADIANS * originLat;
-
-    final double sLon = SloppyMath.sin(originLon);
-    final double cLon = SloppyMath.cos(originLon);
-    final double sLat = SloppyMath.sin(originLat);
-    final double cLat = SloppyMath.cos(originLat);
-
-    phiMatrix[0][0] = -sLon;
-    phiMatrix[0][1] = cLon;
-    phiMatrix[0][2] = 0.0D;
-    phiMatrix[1][0] = -sLat * cLon;
-    phiMatrix[1][1] = -sLat * sLon;
-    phiMatrix[1][2] = cLat;
-    phiMatrix[2][0] = cLat * cLon;
-    phiMatrix[2][1] = cLat * sLon;
-    phiMatrix[2][2] = sLat;
-
-    return phiMatrix;
-  }
-
-  /**
-   * Create the transposed rotation matrix for converting Easting Northing Up coordinates to Earth Centered Fixed
-   * @param originLon ENU origin longitude (in degrees)
-   * @param originLat ENU origin latitude (in degrees)
-   * @param phiMatrix reusable phi rotation matrix result
-   * @return transposed phi rotation matrix
-   */
-  private static double[][] createTransposedPhiTransform(double originLon, double originLat, double[][] phiMatrix) {
-
-    if (phiMatrix == null) {
-      phiMatrix = new double[3][3];
-    }
-
-    originLon = TO_RADIANS * originLon;
-    originLat = TO_RADIANS * originLat;
-
-    final double sLat = SloppyMath.sin(originLat);
-    final double cLat = SloppyMath.cos(originLat);
-    final double sLon = SloppyMath.sin(originLon);
-    final double cLon = SloppyMath.cos(originLon);
-
-    phiMatrix[0][0] = -sLon;
-    phiMatrix[1][0] = cLon;
-    phiMatrix[2][0] = 0.0D;
-    phiMatrix[0][1] = -sLat * cLon;
-    phiMatrix[1][1] = -sLat * sLon;
-    phiMatrix[2][1] = cLat;
-    phiMatrix[0][2] = cLat * cLon;
-    phiMatrix[1][2] = cLat * sLon;
-    phiMatrix[2][2] = sLat;
-
-    return phiMatrix;
-  }
-
-  /**
-   * Finds a point along a bearing from a given lon,lat geolocation using vincenty's distance formula
-   *
-   * @param lon origin longitude in degrees
-   * @param lat origin latitude in degrees
-   * @param bearing azimuthal bearing in degrees
-   * @param dist distance in meters
-   * @param pt resulting point
-   * @return the point along a bearing at a given distance in meters
-   */
-  public static final double[] pointFromLonLatBearingVincenty(double lon, double lat, double bearing, double dist, double[] pt) {
-
-    if (pt == null) {
-      pt = new double[2];
-    }
-
-    final double alpha1 = TO_RADIANS * bearing;
-    final double cosA1 = SloppyMath.cos(alpha1);
-    final double sinA1 = SloppyMath.sin(alpha1);
-    final double tanU1 = (1-FLATTENING) * SloppyMath.tan(TO_RADIANS * lat);
-    final double cosU1 = 1 / StrictMath.sqrt((1+tanU1*tanU1));
-    final double sinU1 = tanU1*cosU1;
-    final double sig1 = StrictMath.atan2(tanU1, cosA1);
-    final double sinAlpha = cosU1 * sinA1;
-    final double cosSqAlpha = 1 - sinAlpha*sinAlpha;
-    final double uSq = cosSqAlpha * EP2;
-    final double A = 1 + uSq/16384D*(4096D + uSq * (-768D + uSq * (320D - 175D*uSq)));
-    final double B = uSq/1024D * (256D + uSq * (-128D + uSq * (74D - 47D * uSq)));
-
-    double sigma = dist / (SEMIMINOR_AXIS*A);
-    double sigmaP;
-    double sinSigma, cosSigma, cos2SigmaM, deltaSigma;
-
-    do {
-      cos2SigmaM = SloppyMath.cos(2*sig1 + sigma);
-      sinSigma = SloppyMath.sin(sigma);
-      cosSigma = SloppyMath.cos(sigma);
-
-      deltaSigma = B * sinSigma * (cos2SigmaM + (B/4D) * (cosSigma*(-1+2*cos2SigmaM*cos2SigmaM)-
-          (B/6) * cos2SigmaM*(-3+4*sinSigma*sinSigma)*(-3+4*cos2SigmaM*cos2SigmaM)));
-      sigmaP = sigma;
-      sigma = dist / (SEMIMINOR_AXIS*A) + deltaSigma;
-    } while (StrictMath.abs(sigma-sigmaP) > 1E-12);
-
-    final double tmp = sinU1*sinSigma - cosU1*cosSigma*cosA1;
-    final double lat2 = StrictMath.atan2(sinU1*cosSigma + cosU1*sinSigma*cosA1,
-        (1-FLATTENING) * StrictMath.sqrt(sinAlpha*sinAlpha + tmp*tmp));
-    final double lambda = StrictMath.atan2(sinSigma*sinA1, cosU1*cosSigma - sinU1*sinSigma*cosA1);
-    final double c = FLATTENING/16 * cosSqAlpha * (4 + FLATTENING * (4 - 3 * cosSqAlpha));
-
-    final double lam = lambda - (1-c) * FLATTENING * sinAlpha *
-        (sigma + c * sinSigma * (cos2SigmaM + c * cosSigma * (-1 + 2* cos2SigmaM*cos2SigmaM)));
-    pt[0] = GeoUtils.normalizeLon(lon + TO_DEGREES * lam);
-    pt[1] = GeoUtils.normalizeLat(TO_DEGREES * lat2);
-
-    return pt;
-  }
-
-  /**
-   * Finds a point along a bearing from a given lon,lat geolocation using great circle arc
-   *
-   * @param lon origin longitude in degrees
-   * @param lat origin latitude in degrees
-   * @param bearing azimuthal bearing in degrees
-   * @param dist distance in meters
-   * @param pt resulting point
-   * @return the point along a bearing at a given distance in meters
-   */
-  public static final double[] pointFromLonLatBearingGreatCircle(double lon, double lat, double bearing, double dist, double[] pt) {
-
-    if (pt == null) {
-      pt = new double[2];
-    }
-
-    lon *= TO_RADIANS;
-    lat *= TO_RADIANS;
-    bearing *= TO_RADIANS;
-
-    final double cLat = SloppyMath.cos(lat);
-    final double sLat = SloppyMath.sin(lat);
-    final double sinDoR = SloppyMath.sin(dist / GeoProjectionUtils.SEMIMAJOR_AXIS);
-    final double cosDoR = SloppyMath.cos(dist / GeoProjectionUtils.SEMIMAJOR_AXIS);
-
-    pt[1] = SloppyMath.asin(sLat*cosDoR + cLat * sinDoR * SloppyMath.cos(bearing));
-    pt[0] = TO_DEGREES * (lon + Math.atan2(SloppyMath.sin(bearing) * sinDoR * cLat, cosDoR - sLat * SloppyMath.sin(pt[1])));
-    pt[1] *= TO_DEGREES;
-
-    return pt;
-  }
-
-  /**
-   * Finds the bearing (in degrees) between 2 geo points (lon, lat) using great circle arc
-   * @param lon1 first point longitude in degrees
-   * @param lat1 first point latitude in degrees
-   * @param lon2 second point longitude in degrees
-   * @param lat2 second point latitude in degrees
-   * @return the bearing (in degrees) between the two provided points
-   */
-  public static double bearingGreatCircle(double lon1, double lat1, double lon2, double lat2) {
-    double dLon = (lon2 - lon1) * TO_RADIANS;
-    lat2 *= TO_RADIANS;
-    lat1 *= TO_RADIANS;
-    double y = SloppyMath.sin(dLon) * SloppyMath.cos(lat2);
-    double x = SloppyMath.cos(lat1) * SloppyMath.sin(lat2) - SloppyMath.sin(lat1) * SloppyMath.cos(lat2) * SloppyMath.cos(dLon);
-    return Math.atan2(y, x) * TO_DEGREES;
-  }
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/187fe876/lucene/sandbox/src/java/org/apache/lucene/util/GeoRect.java
----------------------------------------------------------------------
diff --git a/lucene/sandbox/src/java/org/apache/lucene/util/GeoRect.java b/lucene/sandbox/src/java/org/apache/lucene/util/GeoRect.java
deleted file mode 100644
index f8cf1da..0000000
--- a/lucene/sandbox/src/java/org/apache/lucene/util/GeoRect.java
+++ /dev/null
@@ -1,66 +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.util;
-
-/** Represents a lat/lon rectangle. */
-public class GeoRect {
-  public final double minLon;
-  public final double maxLon;
-  public final double minLat;
-  public final double maxLat;
-
-  public GeoRect(double minLon, double maxLon, double minLat, double maxLat) {
-    if (GeoUtils.isValidLon(minLon) == false) {
-      throw new IllegalArgumentException("invalid minLon " + minLon);
-    }
-    if (GeoUtils.isValidLon(maxLon) == false) {
-      throw new IllegalArgumentException("invalid maxLon " + maxLon);
-    }
-    if (GeoUtils.isValidLat(minLat) == false) {
-      throw new IllegalArgumentException("invalid minLat " + minLat);
-    }
-    if (GeoUtils.isValidLat(maxLat) == false) {
-      throw new IllegalArgumentException("invalid maxLat " + maxLat);
-    }
-    this.minLon = minLon;
-    this.maxLon = maxLon;
-    this.minLat = minLat;
-    this.maxLat = maxLat;
-    assert maxLat >= minLat;
-
-    // NOTE: cannot assert maxLon >= minLon since this rect could cross the dateline
-  }
-
-  @Override
-  public String toString() {
-    StringBuilder b = new StringBuilder();
-    b.append("GeoRect(lon=");
-    b.append(minLon);
-    b.append(" TO ");
-    b.append(maxLon);
-    if (maxLon < minLon) {
-      b.append(" (crosses dateline!)");
-    }
-    b.append(" lat=");
-    b.append(minLat);
-    b.append(" TO ");
-    b.append(maxLat);
-    b.append(")");
-
-    return b.toString();
-  }
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/187fe876/lucene/sandbox/src/java/org/apache/lucene/util/GeoRelationUtils.java
----------------------------------------------------------------------
diff --git a/lucene/sandbox/src/java/org/apache/lucene/util/GeoRelationUtils.java b/lucene/sandbox/src/java/org/apache/lucene/util/GeoRelationUtils.java
deleted file mode 100644
index 092b949..0000000
--- a/lucene/sandbox/src/java/org/apache/lucene/util/GeoRelationUtils.java
+++ /dev/null
@@ -1,497 +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.util;
-
-/**
- * Reusable geo-relation utility methods
- */
-public class GeoRelationUtils {
-
-  /**
-   * Determine if a bbox (defined by minLon, minLat, maxLon, maxLat) contains the provided point (defined by lon, lat)
-   * NOTE: this is a basic method that does not handle dateline or pole crossing. Unwrapping must be done before
-   * calling this method.
-   */
-  public static boolean pointInRectPrecise(final double lon, final double lat, final double minLon,
-                                           final double minLat, final double maxLon, final double maxLat) {
-    return lon >= minLon && lon <= maxLon && lat >= minLat && lat <= maxLat;
-  }
-
-  /**
-   * simple even-odd point in polygon computation
-   *    1.  Determine if point is contained in the longitudinal range
-   *    2.  Determine whether point crosses the edge by computing the latitudinal delta
-   *        between the end-point of a parallel vector (originating at the point) and the
-   *        y-component of the edge sink
-   *
-   * NOTE: Requires polygon point (x,y) order either clockwise or counter-clockwise
-   */
-  public static boolean pointInPolygon(double[] x, double[] y, double lat, double lon) {
-    assert x.length == y.length;
-    boolean inPoly = false;
-    /**
-     * Note: This is using a euclidean coordinate system which could result in
-     * upwards of 110KM error at the equator.
-     * TODO convert coordinates to cylindrical projection (e.g. mercator)
-     */
-    for (int i = 1; i < x.length; i++) {
-      if (x[i] <= lon && x[i-1] >= lon || x[i-1] <= lon && x[i] >= lon) {
-        if (y[i] + (lon - x[i]) / (x[i-1] - x[i]) * (y[i-1] - y[i]) <= lat) {
-          inPoly = !inPoly;
-        }
-      }
-    }
-    return inPoly;
-  }
-
-  /////////////////////////
-  // Rectangle relations
-  /////////////////////////
-
-  public static boolean rectDisjoint(final double aMinX, final double aMinY, final double aMaxX, final double aMaxY,
-                                     final double bMinX, final double bMinY, final double bMaxX, final double bMaxY) {
-    return (aMaxX < bMinX || aMinX > bMaxX || aMaxY < bMinY || aMinY > bMaxY);
-  }
-
-  /**
-   * Computes whether the first (a) rectangle is wholly within another (b) rectangle (shared boundaries allowed)
-   */
-  public static boolean rectWithin(final double aMinX, final double aMinY, final double aMaxX, final double aMaxY,
-                                   final double bMinX, final double bMinY, final double bMaxX, final double bMaxY) {
-    return !(aMinX < bMinX || aMinY < bMinY || aMaxX > bMaxX || aMaxY > bMaxY);
-  }
-
-  public static boolean rectCrosses(final double aMinX, final double aMinY, final double aMaxX, final double aMaxY,
-                                    final double bMinX, final double bMinY, final double bMaxX, final double bMaxY) {
-    return !(rectDisjoint(aMinX, aMinY, aMaxX, aMaxY, bMinX, bMinY, bMaxX, bMaxY) ||
-        rectWithin(aMinX, aMinY, aMaxX, aMaxY, bMinX, bMinY, bMaxX, bMaxY));
-  }
-
-  /**
-   * Computes whether rectangle a contains rectangle b (touching allowed)
-   */
-  public static boolean rectContains(final double aMinX, final double aMinY, final double aMaxX, final double aMaxY,
-                                     final double bMinX, final double bMinY, final double bMaxX, final double bMaxY) {
-    return !(bMinX < aMinX || bMinY < aMinY || bMaxX > aMaxX || bMaxY > aMaxY);
-  }
-
-  /**
-   * Computes whether a rectangle intersects another rectangle (crosses, within, touching, etc)
-   */
-  public static boolean rectIntersects(final double aMinX, final double aMinY, final double aMaxX, final double aMaxY,
-                                       final double bMinX, final double bMinY, final double bMaxX, final double bMaxY) {
-    return !((aMaxX < bMinX || aMinX > bMaxX || aMaxY < bMinY || aMinY > bMaxY) );
-  }
-
-  /////////////////////////
-  // Polygon relations
-  /////////////////////////
-
-  /**
-   * Convenience method for accurately computing whether a rectangle crosses a poly
-   */
-  public static boolean rectCrossesPolyPrecise(final double rMinX, final double rMinY, final double rMaxX,
-                                        final double rMaxY, final double[] shapeX, final double[] shapeY,
-                                        final double sMinX, final double sMinY, final double sMaxX,
-                                        final double sMaxY) {
-    // short-circuit: if the bounding boxes are disjoint then the shape does not cross
-    if (rectDisjoint(rMinX, rMinY, rMaxX, rMaxY, sMinX, sMinY, sMaxX, sMaxY)) {
-      return false;
-    }
-    return rectCrossesPoly(rMinX, rMinY, rMaxX, rMaxY, shapeX, shapeY);
-  }
-
-  /**
-   * Compute whether a rectangle crosses a shape. (touching not allowed) Includes a flag for approximating the
-   * relation.
-   */
-  public static boolean rectCrossesPolyApprox(final double rMinX, final double rMinY, final double rMaxX,
-                                              final double rMaxY, final double[] shapeX, final double[] shapeY,
-                                              final double sMinX, final double sMinY, final double sMaxX,
-                                              final double sMaxY) {
-    // short-circuit: if the bounding boxes are disjoint then the shape does not cross
-    if (rectDisjoint(rMinX, rMinY, rMaxX, rMaxY, sMinX, sMinY, sMaxX, sMaxY)) {
-      return false;
-    }
-
-    final int polyLength = shapeX.length-1;
-    for (short p=0; p<polyLength; ++p) {
-      if (lineCrossesRect(shapeX[p], shapeY[p], shapeX[p+1], shapeY[p+1], rMinX, rMinY, rMaxX, rMaxY) == true) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  /**
-   * Accurately compute (within restrictions of cartesian decimal degrees) whether a rectangle crosses a polygon
-   */
-  private static boolean rectCrossesPoly(final double rMinX, final double rMinY, final double rMaxX,
-                                         final double rMaxY, final double[] shapeX, final double[] shapeY) {
-    final double[][] bbox = new double[][] { {rMinX, rMinY}, {rMaxX, rMinY}, {rMaxX, rMaxY}, {rMinX, rMaxY}, {rMinX, rMinY} };
-    final int polyLength = shapeX.length-1;
-    double d, s, t, a1, b1, c1, a2, b2, c2;
-    double x00, y00, x01, y01, x10, y10, x11, y11;
-
-    // computes the intersection point between each bbox edge and the polygon edge
-    for (short b=0; b<4; ++b) {
-      a1 = bbox[b+1][1]-bbox[b][1];
-      b1 = bbox[b][0]-bbox[b+1][0];
-      c1 = a1*bbox[b+1][0] + b1*bbox[b+1][1];
-      for (int p=0; p<polyLength; ++p) {
-        a2 = shapeY[p+1]-shapeY[p];
-        b2 = shapeX[p]-shapeX[p+1];
-        // compute determinant
-        d = a1*b2 - a2*b1;
-        if (d != 0) {
-          // lines are not parallel, check intersecting points
-          c2 = a2*shapeX[p+1] + b2*shapeY[p+1];
-          s = (1/d)*(b2*c1 - b1*c2);
-          t = (1/d)*(a1*c2 - a2*c1);
-          x00 = StrictMath.min(bbox[b][0], bbox[b+1][0]) - GeoUtils.TOLERANCE;
-          x01 = StrictMath.max(bbox[b][0], bbox[b+1][0]) + GeoUtils.TOLERANCE;
-          y00 = StrictMath.min(bbox[b][1], bbox[b+1][1]) - GeoUtils.TOLERANCE;
-          y01 = StrictMath.max(bbox[b][1], bbox[b+1][1]) + GeoUtils.TOLERANCE;
-          x10 = StrictMath.min(shapeX[p], shapeX[p+1]) - GeoUtils.TOLERANCE;
-          x11 = StrictMath.max(shapeX[p], shapeX[p+1]) + GeoUtils.TOLERANCE;
-          y10 = StrictMath.min(shapeY[p], shapeY[p+1]) - GeoUtils.TOLERANCE;
-          y11 = StrictMath.max(shapeY[p], shapeY[p+1]) + GeoUtils.TOLERANCE;
-          // check whether the intersection point is touching one of the line segments
-          boolean touching = ((x00 == s && y00 == t) || (x01 == s && y01 == t))
-              || ((x10 == s && y10 == t) || (x11 == s && y11 == t));
-          // if line segments are not touching and the intersection point is within the range of either segment
-          if (!(touching || x00 > s || x01 < s || y00 > t || y01 < t || x10 > s || x11 < s || y10 > t || y11 < t)) {
-            return true;
-          }
-        }
-      } // for each poly edge
-    } // for each bbox edge
-    return false;
-  }
-
-  private static boolean lineCrossesRect(double aX1, double aY1, double aX2, double aY2,
-                                         final double rMinX, final double rMinY, final double rMaxX, final double rMaxY) {
-    // short-circuit: if one point inside rect, other outside
-    if (pointInRectPrecise(aX1, aY1, rMinX, rMinY, rMaxX, rMaxY) ?
-        !pointInRectPrecise(aX2, aY2, rMinX, rMinY, rMaxX, rMaxY) : pointInRectPrecise(aX2, aY2, rMinX, rMinY, rMaxX, rMaxY)) {
-      return true;
-    }
-
-    return lineCrossesLine(aX1, aY1, aX2, aY2, rMinX, rMinY, rMaxX, rMaxY)
-        || lineCrossesLine(aX1, aY1, aX2, aY2, rMaxX, rMinY, rMinX, rMaxY);
-  }
-
-  private static boolean lineCrossesLine(final double aX1, final double aY1, final double aX2, final double aY2,
-                                         final double bX1, final double bY1, final double bX2, final double bY2) {
-    // determine if three points are ccw (right-hand rule) by computing the determinate
-    final double aX2X1d = aX2 - aX1;
-    final double aY2Y1d = aY2 - aY1;
-    final double bX2X1d = bX2 - bX1;
-    final double bY2Y1d = bY2 - bY1;
-
-    final double t1B = aX2X1d * (bY2 - aY1) - aY2Y1d * (bX2 - aX1);
-    final double test1 = (aX2X1d * (bY1 - aY1) - aY2Y1d * (bX1 - aX1)) * t1B;
-    final double t2B = bX2X1d * (aY2 - bY1) - bY2Y1d * (aX2 - bX1);
-    final double test2 = (bX2X1d * (aY1 - bY1) - bY2Y1d * (aX1 - bX1)) * t2B;
-
-    if (test1 < 0 && test2 < 0) {
-      return true;
-    }
-
-    if (test1 == 0 || test2 == 0) {
-      // vertically collinear
-      if (aX1 == aX2 || bX1 == bX2) {
-        final double minAy = Math.min(aY1, aY2);
-        final double maxAy = Math.max(aY1, aY2);
-        final double minBy = Math.min(bY1, bY2);
-        final double maxBy = Math.max(bY1, bY2);
-
-        return !(minBy >= maxAy || maxBy <= minAy);
-      }
-      // horizontally collinear
-      final double minAx = Math.min(aX1, aX2);
-      final double maxAx = Math.max(aX1, aX2);
-      final double minBx = Math.min(bX1, bX2);
-      final double maxBx = Math.max(bX1, bX2);
-
-      return !(minBx >= maxAx || maxBx <= minAx);
-    }
-    return false;
-  }
-
-  public static boolean rectWithinPolyPrecise(final double rMinX, final double rMinY, final double rMaxX, final double rMaxY,
-                                       final double[] shapeX, final double[] shapeY, final double sMinX,
-                                       final double sMinY, final double sMaxX, final double sMaxY) {
-    // check if rectangle crosses poly (to handle concave/pacman polys), then check that all 4 corners
-    // are contained
-    return !(rectCrossesPolyPrecise(rMinX, rMinY, rMaxX, rMaxY, shapeX, shapeY, sMinX, sMinY, sMaxX, sMaxY) ||
-        !pointInPolygon(shapeX, shapeY, rMinY, rMinX) || !pointInPolygon(shapeX, shapeY, rMinY, rMaxX) ||
-        !pointInPolygon(shapeX, shapeY, rMaxY, rMaxX) || !pointInPolygon(shapeX, shapeY, rMaxY, rMinX));
-  }
-
-  /**
-   * Computes whether a rectangle is within a given polygon (shared boundaries allowed)
-   */
-  public static boolean rectWithinPolyApprox(final double rMinX, final double rMinY, final double rMaxX, final double rMaxY,
-                                       final double[] shapeX, final double[] shapeY, final double sMinX,
-                                       final double sMinY, final double sMaxX, final double sMaxY) {
-    // approximation: check if rectangle crosses poly (to handle concave/pacman polys), then check one of the corners
-    // are contained
-
-    // short-cut: if bounding boxes cross, rect is not within
-     if (rectCrosses(rMinX, rMinY, rMaxX, rMaxY, sMinX, sMinY, sMaxX, sMaxY) == true) {
-       return false;
-     }
-
-     return !(rectCrossesPolyApprox(rMinX, rMinY, rMaxX, rMaxY, shapeX, shapeY, sMinX, sMinY, sMaxX, sMaxY)
-         || !pointInPolygon(shapeX, shapeY, rMinY, rMinX));
-  }
-
-  /////////////////////////
-  // Circle relations
-  /////////////////////////
-
-  private static boolean rectAnyCornersInCircle(final double rMinX, final double rMinY, final double rMaxX,
-                                                final double rMaxY, final double centerLon, final double centerLat,
-                                                final double radiusMeters, final boolean approx) {
-    if (approx == true) {
-      return rectAnyCornersInCircleSloppy(rMinX, rMinY, rMaxX, rMaxY, centerLon, centerLat, radiusMeters);
-    }
-    double w = Math.abs(rMaxX - rMinX);
-    if (w <= 90.0) {
-      return GeoDistanceUtils.haversin(centerLat, centerLon, rMinY, rMinX) <= radiusMeters
-          || GeoDistanceUtils.haversin(centerLat, centerLon, rMaxY, rMinX) <= radiusMeters
-          || GeoDistanceUtils.haversin(centerLat, centerLon, rMaxY, rMaxX) <= radiusMeters
-          || GeoDistanceUtils.haversin(centerLat, centerLon, rMinY, rMaxX) <= radiusMeters;
-    }
-    // partition
-    w /= 4;
-    final double p1 = rMinX + w;
-    final double p2 = p1 + w;
-    final double p3 = p2 + w;
-
-    return GeoDistanceUtils.haversin(centerLat, centerLon, rMinY, rMinX) <= radiusMeters
-        || GeoDistanceUtils.haversin(centerLat, centerLon, rMaxY, rMinX) <= radiusMeters
-        || GeoDistanceUtils.haversin(centerLat, centerLon, rMaxY, p1) <= radiusMeters
-        || GeoDistanceUtils.haversin(centerLat, centerLon, rMinY, p1) <= radiusMeters
-        || GeoDistanceUtils.haversin(centerLat, centerLon, rMinY, p2) <= radiusMeters
-        || GeoDistanceUtils.haversin(centerLat, centerLon, rMaxY, p2) <= radiusMeters
-        || GeoDistanceUtils.haversin(centerLat, centerLon, rMaxY, p3) <= radiusMeters
-        || GeoDistanceUtils.haversin(centerLat, centerLon, rMinY, p3) <= radiusMeters
-        || GeoDistanceUtils.haversin(centerLat, centerLon, rMaxY, rMaxX) <= radiusMeters
-        || GeoDistanceUtils.haversin(centerLat, centerLon, rMinY, rMaxX) <= radiusMeters;
-  }
-
-  private static boolean rectAnyCornersInCircleSloppy(final double rMinX, final double rMinY, final double rMaxX, final double rMaxY,
-                                                      final double centerLon, final double centerLat, final double radiusMeters) {
-    return SloppyMath.haversin(centerLat, centerLon, rMinY, rMinX)*1000.0 <= radiusMeters
-        || SloppyMath.haversin(centerLat, centerLon, rMaxY, rMinX)*1000.0 <= radiusMeters
-        || SloppyMath.haversin(centerLat, centerLon, rMaxY, rMaxX)*1000.0 <= radiusMeters
-        || SloppyMath.haversin(centerLat, centerLon, rMinY, rMaxX)*1000.0 <= radiusMeters;
-  }
-
-  /**
-   * Compute whether any of the 4 corners of the rectangle (defined by min/max X/Y) are outside the circle (defined
-   * by centerLon, centerLat, radiusMeters)
-   *
-   * Note: exotic rectangles at the poles (e.g., those whose lon/lat distance ratios greatly deviate from 1) can not
-   * be determined by using distance alone. For this reason the approx flag may be set to false, in which case the
-   * space will be further divided to more accurately compute whether the rectangle crosses the circle
-   */
-  private static boolean rectAnyCornersOutsideCircle(final double rMinX, final double rMinY, final double rMaxX,
-                                                     final double rMaxY, final double centerLon, final double centerLat,
-                                                     final double radiusMeters, final boolean approx) {
-    if (approx == true) {
-      return rectAnyCornersOutsideCircleSloppy(rMinX, rMinY, rMaxX, rMaxY, centerLon, centerLat, radiusMeters);
-    }
-    // if span is less than 70 degrees we can approximate using distance alone
-    if (Math.abs(rMaxX - rMinX) <= 70.0) {
-      return GeoDistanceUtils.haversin(centerLat, centerLon, rMinY, rMinX) > radiusMeters
-          || GeoDistanceUtils.haversin(centerLat, centerLon, rMaxY, rMinX) > radiusMeters
-          || GeoDistanceUtils.haversin(centerLat, centerLon, rMaxY, rMaxX) > radiusMeters
-          || GeoDistanceUtils.haversin(centerLat, centerLon, rMinY, rMaxX) > radiusMeters;
-    }
-    return rectCrossesOblateCircle(centerLon, centerLat, radiusMeters, rMinX, rMinY, rMaxX, rMaxY);
-  }
-
-  /**
-   * Compute whether the rectangle (defined by min/max Lon/Lat) crosses a potentially oblate circle
-   *
-   * TODO benchmark for replacing existing rectCrossesCircle.
-   */
-  public static boolean rectCrossesOblateCircle(double centerLon, double centerLat, double radiusMeters, double rMinLon, double rMinLat, double  rMaxLon, double rMaxLat) {
-    double w = Math.abs(rMaxLon - rMinLon);
-    final int segs = (int)Math.ceil(w / 45.0);
-    w /= segs;
-    short i = 1;
-    double p1 = rMinLon;
-    double maxLon, midLon;
-    double[] pt = new double[2];
-
-    do {
-      maxLon = (i == segs) ? rMaxLon : p1 + w;
-
-      final double d1, d2;
-      // short-circuit if we find a corner outside the circle
-      if ( (d1 = GeoDistanceUtils.haversin(centerLat, centerLon, rMinLat, p1)) > radiusMeters
-          || (d2 = GeoDistanceUtils.haversin(centerLat, centerLon, rMinLat, maxLon)) > radiusMeters
-          || GeoDistanceUtils.haversin(centerLat, centerLon, rMaxLat, p1) > radiusMeters
-          || GeoDistanceUtils.haversin(centerLat, centerLon, rMaxLat, maxLon) > radiusMeters) {
-        return true;
-      }
-
-      // else we treat as an oblate circle by slicing the longitude space and checking the azimuthal range
-      // OPTIMIZATION: this is only executed for latitude values "closeTo" the poles (e.g., 88.0 > lat < -88.0)
-      if ( (rMaxLat > 88.0 || rMinLat < -88.0)
-          && (pt = GeoProjectionUtils.pointFromLonLatBearingGreatCircle(p1, rMinLat,
-          GeoProjectionUtils.bearingGreatCircle(p1, rMinLat, p1, rMaxLat), radiusMeters - d1, pt))[1] < rMinLat || pt[1] < rMaxLat
-          || (pt = GeoProjectionUtils.pointFromLonLatBearingGreatCircle(maxLon, rMinLat,
-          GeoProjectionUtils.bearingGreatCircle(maxLon, rMinLat, maxLon, rMaxLat), radiusMeters - d2, pt))[1] < rMinLat || pt[1] < rMaxLat
-          || (pt = GeoProjectionUtils.pointFromLonLatBearingGreatCircle(maxLon, rMinLat,
-          GeoProjectionUtils.bearingGreatCircle(maxLon, rMinLat, (midLon = p1 + 0.5*(maxLon - p1)), rMaxLat),
-          radiusMeters - GeoDistanceUtils.haversin(centerLat, centerLon, rMinLat, midLon), pt))[1] < rMinLat
-          || pt[1] < rMaxLat == false ) {
-        return true;
-      }
-      p1 += w;
-    } while (++i <= segs);
-    return false;
-  }
-
-  private static boolean rectAnyCornersOutsideCircleSloppy(final double rMinX, final double rMinY, final double rMaxX, final double rMaxY,
-                                                           final double centerLon, final double centerLat, final double radiusMeters) {
-    return SloppyMath.haversin(centerLat, centerLon, rMinY, rMinX)*1000.0 > radiusMeters
-        || SloppyMath.haversin(centerLat, centerLon, rMaxY, rMinX)*1000.0 > radiusMeters
-        || SloppyMath.haversin(centerLat, centerLon, rMaxY, rMaxX)*1000.0 > radiusMeters
-        || SloppyMath.haversin(centerLat, centerLon, rMinY, rMaxX)*1000.0 > radiusMeters;
-  }
-
-  public static boolean rectWithinCircle(final double rMinX, final double rMinY, final double rMaxX, final double rMaxY,
-                                         final double centerLon, final double centerLat, final double radiusMeters) {
-    return rectWithinCircle(rMinX, rMinY, rMaxX, rMaxY, centerLon, centerLat, radiusMeters, false);
-  }
-
-  public static boolean rectWithinCircle(final double rMinX, final double rMinY, final double rMaxX, final double rMaxY,
-                                         final double centerLon, final double centerLat, final double radiusMeters,
-                                         final boolean approx) {
-    return rectAnyCornersOutsideCircle(rMinX, rMinY, rMaxX, rMaxY, centerLon, centerLat, radiusMeters, approx) == false;
-  }
-
-  /**
-   * Determine if a bbox (defined by minLon, minLat, maxLon, maxLat) contains the provided point (defined by lon, lat)
-   * NOTE: this is basic method that does not handle dateline or pole crossing. Unwrapping must be done before
-   * calling this method.
-   */
-  public static boolean rectCrossesCircle(final double rMinX, final double rMinY, final double rMaxX, final double rMaxY,
-                                          final double centerLon, final double centerLat, final double radiusMeters) {
-    return rectCrossesCircle(rMinX, rMinY, rMaxX, rMaxY, centerLon, centerLat, radiusMeters, false);
-  }
-
-  public static boolean rectCrossesCircle(final double rMinX, final double rMinY, final double rMaxX, final double rMaxY,
-                                          final double centerLon, final double centerLat, final double radiusMeters,
-                                          final boolean approx) {
-    if (approx == true) {
-      return rectAnyCornersInCircle(rMinX, rMinY, rMaxX, rMaxY, centerLon, centerLat, radiusMeters, approx)
-          || isClosestPointOnRectWithinRange(rMinX, rMinY, rMaxX, rMaxY, centerLon, centerLat, radiusMeters, approx);
-    }
-
-    return (rectAnyCornersInCircle(rMinX, rMinY, rMaxX, rMaxY, centerLon, centerLat, radiusMeters, approx) &&
-        rectAnyCornersOutsideCircle(rMinX, rMinY, rMaxX, rMaxY, centerLon, centerLat, radiusMeters, approx))
-        || isClosestPointOnRectWithinRange(rMinX, rMinY, rMaxX, rMaxY, centerLon, centerLat, radiusMeters, approx);
-  }
-
-  private static boolean isClosestPointOnRectWithinRange(final double rMinX, final double rMinY, final double rMaxX, final double rMaxY,
-                                                         final double centerLon, final double centerLat, final double radiusMeters,
-                                                         final boolean approx) {
-    double[] closestPt = {0, 0};
-    GeoDistanceUtils.closestPointOnBBox(rMinX, rMinY, rMaxX, rMaxY, centerLon, centerLat, closestPt);
-    boolean haverShortCut = GeoDistanceUtils.haversin(centerLat, centerLon, closestPt[1], closestPt[0]) <= radiusMeters;
-    if (approx == true || haverShortCut == true) {
-      return haverShortCut;
-    }
-    double lon1 = rMinX;
-    double lon2 = rMaxX;
-    double lat1 = rMinY;
-    double lat2 = rMaxY;
-    if (closestPt[0] == rMinX || closestPt[0] == rMaxX) {
-      lon1 = closestPt[0];
-      lon2 = lon1;
-    } else if (closestPt[1] == rMinY || closestPt[1] == rMaxY) {
-      lat1 = closestPt[1];
-      lat2 = lat1;
-    }
-
-    return lineCrossesSphere(lon1, lat1, 0, lon2, lat2, 0, centerLon, centerLat, 0, radiusMeters);
-  }
-
-  /**
-   * Computes whether or a 3dimensional line segment intersects or crosses a sphere
-   *
-   * @param lon1 longitudinal location of the line segment start point (in degrees)
-   * @param lat1 latitudinal location of the line segment start point (in degrees)
-   * @param alt1 altitude of the line segment start point (in degrees)
-   * @param lon2 longitudinal location of the line segment end point (in degrees)
-   * @param lat2 latitudinal location of the line segment end point (in degrees)
-   * @param alt2 altitude of the line segment end point (in degrees)
-   * @param centerLon longitudinal location of center search point (in degrees)
-   * @param centerLat latitudinal location of center search point (in degrees)
-   * @param centerAlt altitude of the center point (in meters)
-   * @param radiusMeters search sphere radius (in meters)
-   * @return whether the provided line segment is a secant of the
-   */
-  private static boolean lineCrossesSphere(double lon1, double lat1, double alt1, double lon2,
-                                           double lat2, double alt2, double centerLon, double centerLat,
-                                           double centerAlt, double radiusMeters) {
-    // convert to cartesian 3d (in meters)
-    double[] ecf1 = GeoProjectionUtils.llaToECF(lon1, lat1, alt1, null);
-    double[] ecf2 = GeoProjectionUtils.llaToECF(lon2, lat2, alt2, null);
-    double[] cntr = GeoProjectionUtils.llaToECF(centerLon, centerLat, centerAlt, null);
-
-    // convert radius from arc radius to cartesian radius
-    double[] oneEighty = GeoProjectionUtils.pointFromLonLatBearingGreatCircle(centerLon, centerLat, 180.0d, radiusMeters, new double[3]);
-    GeoProjectionUtils.llaToECF(oneEighty[0], oneEighty[1], 0, oneEighty);
-
-    radiusMeters = GeoDistanceUtils.linearDistance(oneEighty, cntr);//   Math.sqrt(oneEighty[0]*cntr[0] + oneEighty[1]*cntr[1] + oneEighty[2]*cntr[2]);
-
-    final double dX = ecf2[0] - ecf1[0];
-    final double dY = ecf2[1] - ecf1[1];
-    final double dZ = ecf2[2] - ecf1[2];
-    final double fX = ecf1[0] - cntr[0];
-    final double fY = ecf1[1] - cntr[1];
-    final double fZ = ecf1[2] - cntr[2];
-
-    final double a = dX*dX + dY*dY + dZ*dZ;
-    final double b = 2 * (fX*dX + fY*dY + fZ*dZ);
-    final double c = (fX*fX + fY*fY + fZ*fZ) - (radiusMeters*radiusMeters);
-
-    double discrim = (b*b)-(4*a*c);
-    if (discrim < 0) {
-      return false;
-    }
-
-    discrim = StrictMath.sqrt(discrim);
-    final double a2 = 2*a;
-    final double t1 = (-b - discrim)/a2;
-    final double t2 = (-b + discrim)/a2;
-
-    if ( (t1 < 0 || t1 > 1) ) {
-      return !(t2 < 0 || t2 > 1);
-    }
-
-    return true;
-  }
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/187fe876/lucene/sandbox/src/java/org/apache/lucene/util/GeoUtils.java
----------------------------------------------------------------------
diff --git a/lucene/sandbox/src/java/org/apache/lucene/util/GeoUtils.java b/lucene/sandbox/src/java/org/apache/lucene/util/GeoUtils.java
deleted file mode 100644
index a2d0fd1..0000000
--- a/lucene/sandbox/src/java/org/apache/lucene/util/GeoUtils.java
+++ /dev/null
@@ -1,237 +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.util;
-
-import java.util.ArrayList;
-
-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 {
-  public static final short BITS = 31;
-  private static final double LON_SCALE = (0x1L<<BITS)/360.0D;
-  private static final double LAT_SCALE = (0x1L<<BITS)/180.0D;
-  public static final double TOLERANCE = 1E-6;
-
-  /** 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;
-
-  // No instance:
-  private GeoUtils() {
-  }
-
-  public static final Long mortonHash(final double lon, final double lat) {
-    return BitUtil.interleave(scaleLon(lon), scaleLat(lat));
-  }
-
-  public static final double mortonUnhashLon(final long hash) {
-    return unscaleLon(BitUtil.deinterleave(hash));
-  }
-
-  public static final double mortonUnhashLat(final long hash) {
-    return unscaleLat(BitUtil.deinterleave(hash >>> 1));
-  }
-
-  private static final long scaleLon(final double val) {
-    return (long) ((val-MIN_LON_INCL) * LON_SCALE);
-  }
-
-  private static final long scaleLat(final double val) {
-    return (long) ((val-MIN_LAT_INCL) * LAT_SCALE);
-  }
-
-  private static final double unscaleLon(final long val) {
-    return (val / LON_SCALE) + MIN_LON_INCL;
-  }
-
-  private static final double unscaleLat(final long val) {
-    return (val / LAT_SCALE) + MIN_LAT_INCL;
-  }
-
-  /**
-   * Compare two position values within a {@link org.apache.lucene.util.GeoUtils#TOLERANCE} factor
-   */
-  public static double compare(final double v1, final double v2) {
-    final double delta = v1-v2;
-    return Math.abs(delta) <= TOLERANCE ? 0 : delta;
-  }
-
-  /**
-   * Puts longitude in range of -180 to +180.
-   */
-  public static double normalizeLon(double lon_deg) {
-    if (lon_deg >= -180 && lon_deg <= 180) {
-      return lon_deg; //common case, and avoids slight double precision shifting
-    }
-    double off = (lon_deg + 180) % 360;
-    if (off < 0) {
-      return 180 + off;
-    } else if (off == 0 && lon_deg > 0) {
-      return 180;
-    } else {
-      return -180 + off;
-    }
-  }
-
-  /**
-   * Puts latitude in range of -90 to 90.
-   */
-  public static double normalizeLat(double lat_deg) {
-    if (lat_deg >= -90 && lat_deg <= 90) {
-      return lat_deg; //common case, and avoids slight double precision shifting
-    }
-    double off = Math.abs((lat_deg + 90) % 360);
-    return (off <= 180 ? off : 360-off) - 90;
-  }
-
-  public static String geoTermToString(long term) {
-    StringBuilder s = new StringBuilder(64);
-    final int numberOfLeadingZeros = Long.numberOfLeadingZeros(term);
-    for (int i = 0; i < numberOfLeadingZeros; i++) {
-      s.append('0');
-    }
-    if (term != 0) {
-      s.append(Long.toBinaryString(term));
-    }
-    return s.toString();
-  }
-
-  /**
-   * Converts a given circle (defined as a point/radius) to an approximated line-segment polygon
-   *
-   * @param lon longitudinal center of circle (in degrees)
-   * @param lat latitudinal center of circle (in degrees)
-   * @param radiusMeters distance radius of circle (in meters)
-   * @return a list of lon/lat points representing the circle
-   */
-  @SuppressWarnings({"unchecked","rawtypes"})
-  public static ArrayList<double[]> circleToPoly(final double lon, final double lat, final double radiusMeters) {
-    double angle;
-    // a little under-sampling (to limit the number of polygonal points): using archimedes estimation of pi
-    final int sides = 25;
-    ArrayList<double[]> geometry = new ArrayList();
-    double[] lons = new double[sides];
-    double[] lats = new double[sides];
-
-    double[] pt = new double[2];
-    final int sidesLen = sides-1;
-    for (int i=0; i<sidesLen; ++i) {
-      angle = (i*360/sides);
-      pt = GeoProjectionUtils.pointFromLonLatBearingGreatCircle(lon, lat, angle, radiusMeters, pt);
-      lons[i] = pt[0];
-      lats[i] = pt[1];
-    }
-    // close the poly
-    lons[sidesLen] = lons[0];
-    lats[sidesLen] = lats[0];
-    geometry.add(lons);
-    geometry.add(lats);
-
-    return geometry;
-  }
-
-  /**
-   * Compute Bounding Box for a circle using WGS-84 parameters
-   */
-  public static GeoRect circleToBBox(final double centerLon, final double centerLat, final double radiusMeters) {
-    final double radLat = TO_RADIANS * centerLat;
-    final double radLon = TO_RADIANS * centerLon;
-    double radDistance = radiusMeters / GeoProjectionUtils.SEMIMAJOR_AXIS;
-    double minLat = radLat - radDistance;
-    double maxLat = radLat + radDistance;
-    double minLon;
-    double maxLon;
-
-    if (minLat > GeoProjectionUtils.MIN_LAT_RADIANS && maxLat < GeoProjectionUtils.MAX_LAT_RADIANS) {
-      double deltaLon = SloppyMath.asin(SloppyMath.sin(radDistance) / SloppyMath.cos(radLat));
-      minLon = radLon - deltaLon;
-      if (minLon < GeoProjectionUtils.MIN_LON_RADIANS) {
-        minLon += 2d * StrictMath.PI;
-      }
-      maxLon = radLon + deltaLon;
-      if (maxLon > GeoProjectionUtils.MAX_LON_RADIANS) {
-        maxLon -= 2d * StrictMath.PI;
-      }
-    } else {
-      // a pole is within the distance
-      minLat = StrictMath.max(minLat, GeoProjectionUtils.MIN_LAT_RADIANS);
-      maxLat = StrictMath.min(maxLat, GeoProjectionUtils.MAX_LAT_RADIANS);
-      minLon = GeoProjectionUtils.MIN_LON_RADIANS;
-      maxLon = GeoProjectionUtils.MAX_LON_RADIANS;
-    }
-
-    return new GeoRect(TO_DEGREES * minLon, TO_DEGREES * maxLon, TO_DEGREES * minLat, TO_DEGREES * maxLat);
-  }
-
-  /**
-   * Compute Bounding Box for a polygon using WGS-84 parameters
-   */
-  public static GeoRect polyToBBox(double[] polyLons, double[] polyLats) {
-    if (polyLons.length != polyLats.length) {
-      throw new IllegalArgumentException("polyLons and polyLats must be equal length");
-    }
-
-    double minLon = Double.POSITIVE_INFINITY;
-    double maxLon = Double.NEGATIVE_INFINITY;
-    double minLat = Double.POSITIVE_INFINITY;
-    double maxLat = Double.NEGATIVE_INFINITY;
-
-    for (int i=0;i<polyLats.length;i++) {
-      if (GeoUtils.isValidLon(polyLons[i]) == false) {
-        throw new IllegalArgumentException("invalid polyLons[" + i + "]=" + polyLons[i]);
-      }
-      if (GeoUtils.isValidLat(polyLats[i]) == false) {
-        throw new IllegalArgumentException("invalid polyLats[" + i + "]=" + polyLats[i]);
-      }
-      minLon = Math.min(polyLons[i], minLon);
-      maxLon = Math.max(polyLons[i], maxLon);
-      minLat = Math.min(polyLats[i], minLat);
-      maxLat = Math.max(polyLats[i], maxLat);
-    }
-    // expand bounding box by TOLERANCE factor to handle round-off error
-    return new GeoRect(Math.max(minLon - TOLERANCE, MIN_LON_INCL), Math.min(maxLon + TOLERANCE, MAX_LON_INCL),
-        Math.max(minLat - TOLERANCE, MIN_LAT_INCL), Math.min(maxLat + TOLERANCE, MAX_LAT_INCL));
-  }
-
-  /**
-   * validates latitude value is within standard +/-90 coordinate bounds
-   */
-  public static boolean isValidLat(double lat) {
-    return Double.isNaN(lat) == false && lat >= MIN_LAT_INCL && lat <= MAX_LAT_INCL;
-  }
-
-  /**
-   * validates longitude value is within standard +/-180 coordinate bounds
-   */
-  public static boolean isValidLon(double lon) {
-    return Double.isNaN(lon) == false && lon >= MIN_LON_INCL && lon <= MAX_LON_INCL;
-  }
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/187fe876/lucene/sandbox/src/java/org/apache/lucene/util/package.html
----------------------------------------------------------------------
diff --git a/lucene/sandbox/src/java/org/apache/lucene/util/package.html b/lucene/sandbox/src/java/org/apache/lucene/util/package.html
deleted file mode 100644
index 9a8856c..0000000
--- a/lucene/sandbox/src/java/org/apache/lucene/util/package.html
+++ /dev/null
@@ -1,28 +0,0 @@
-<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
-<!--
- 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.
--->
-
-<!-- not a package-info.java, because we already defined this package in core/ -->
-
-<html>
-<head>
-   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-</head>
-<body>
-This package contains utility APIs, currently for geospatial searching.
-</body>
-</html>

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/187fe876/lucene/sandbox/src/test/org/apache/lucene/bkdtree/TestBKDTree.java
----------------------------------------------------------------------
diff --git a/lucene/sandbox/src/test/org/apache/lucene/bkdtree/TestBKDTree.java b/lucene/sandbox/src/test/org/apache/lucene/bkdtree/TestBKDTree.java
index 238ec36..a0ceef2 100644
--- a/lucene/sandbox/src/test/org/apache/lucene/bkdtree/TestBKDTree.java
+++ b/lucene/sandbox/src/test/org/apache/lucene/bkdtree/TestBKDTree.java
@@ -30,11 +30,11 @@ import org.apache.lucene.store.Directory;
 import org.apache.lucene.store.MockDirectoryWrapper;
 import org.apache.lucene.util.Accountable;
 import org.apache.lucene.util.Accountables;
-import org.apache.lucene.util.BaseGeoPointTestCase;
-import org.apache.lucene.util.GeoRect;
 import org.apache.lucene.util.IOUtils;
 import org.apache.lucene.util.SloppyMath;
 import org.apache.lucene.util.TestUtil;
+import org.apache.lucene.spatial.util.BaseGeoPointTestCase;
+import org.apache.lucene.spatial.util.GeoRect;
 
 // TODO: can test framework assert we don't leak temp files?
 

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/187fe876/lucene/sandbox/src/test/org/apache/lucene/search/TestGeoPointQuery.java
----------------------------------------------------------------------
diff --git a/lucene/sandbox/src/test/org/apache/lucene/search/TestGeoPointQuery.java b/lucene/sandbox/src/test/org/apache/lucene/search/TestGeoPointQuery.java
deleted file mode 100644
index c5c1fb5..0000000
--- a/lucene/sandbox/src/test/org/apache/lucene/search/TestGeoPointQuery.java
+++ /dev/null
@@ -1,381 +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.search;
-
-import org.apache.lucene.analysis.MockAnalyzer;
-import org.apache.lucene.document.Document;
-import org.apache.lucene.document.Field;
-import org.apache.lucene.document.FieldType;
-import org.apache.lucene.document.GeoPointField;
-import org.apache.lucene.document.StringField;
-import org.apache.lucene.index.IndexReader;
-import org.apache.lucene.index.RandomIndexWriter;
-import org.apache.lucene.store.Directory;
-import org.apache.lucene.util.BaseGeoPointTestCase;
-import org.apache.lucene.util.GeoRect;
-import org.apache.lucene.util.GeoRelationUtils;
-import org.apache.lucene.util.GeoUtils;
-import org.apache.lucene.util.SloppyMath;
-import org.apache.lucene.util.TestUtil;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-
-import static org.apache.lucene.util.GeoDistanceUtils.DISTANCE_PCT_ERR;
-
-/**
- * Unit testing for basic GeoPoint query logic
- *
- * @lucene.experimental
- */
-
-public class TestGeoPointQuery extends BaseGeoPointTestCase {
-
-  private static Directory directory = null;
-  private static IndexReader reader = null;
-  private static IndexSearcher searcher = null;
-
-  @Override
-  protected void addPointToDoc(String field, Document doc, double lat, double lon) {
-    doc.add(new GeoPointField(field, lon, lat, Field.Store.NO));
-  }
-
-  @Override
-  protected Query newBBoxQuery(String field, GeoRect rect) {
-    return new GeoPointInBBoxQuery(field, rect.minLon, rect.minLat, rect.maxLon, rect.maxLat);
-  }
-
-  @Override
-  protected Query newDistanceQuery(String field, double centerLat, double centerLon, double radiusMeters) {
-    return new GeoPointDistanceQuery(field, centerLon, centerLat, radiusMeters);
-  }
-
-  @Override
-  protected Query newDistanceRangeQuery(String field, double centerLat, double centerLon, double minRadiusMeters, double radiusMeters) {
-    return new GeoPointDistanceRangeQuery(field, centerLon, centerLat, minRadiusMeters, radiusMeters);
-  }
-
-  @Override
-  protected Query newPolygonQuery(String field, double[] lats, double[] lons) {
-    return new GeoPointInPolygonQuery(field, lons, lats);
-  }
-
-  @BeforeClass
-  public static void beforeClass() throws Exception {
-    directory = newDirectory();
-
-    RandomIndexWriter writer = new RandomIndexWriter(random(), directory,
-        newIndexWriterConfig(new MockAnalyzer(random()))
-            .setMaxBufferedDocs(TestUtil.nextInt(random(), 100, 1000))
-            .setMergePolicy(newLogMergePolicy()));
-
-    // create some simple geo points
-    final FieldType storedPoint = new FieldType(GeoPointField.TYPE_STORED);
-    // this is a simple systematic test
-    GeoPointField[] pts = new GeoPointField[] {
-        new GeoPointField(FIELD_NAME, -96.774, 32.763420, storedPoint),
-        new GeoPointField(FIELD_NAME, -96.7759895324707, 32.7559529921407, storedPoint),
-        new GeoPointField(FIELD_NAME, -96.77701950073242, 32.77866942010977, storedPoint),
-        new GeoPointField(FIELD_NAME, -96.7706036567688, 32.7756745755423, storedPoint),
-        new GeoPointField(FIELD_NAME, -139.73458170890808, 27.703618681345585, storedPoint),
-        new GeoPointField(FIELD_NAME, -96.4538113027811, 32.94823588839368, storedPoint),
-        new GeoPointField(FIELD_NAME, -96.65084838867188, 33.06047141970814, storedPoint),
-        new GeoPointField(FIELD_NAME, -96.7772, 32.778650, storedPoint),
-        new GeoPointField(FIELD_NAME, -177.23537676036358, -88.56029371730983, storedPoint),
-        new GeoPointField(FIELD_NAME, -26.779373834241003, 33.541429799076354, storedPoint),
-        new GeoPointField(FIELD_NAME, -77.35379276106497, 26.774024500421728, storedPoint),
-        new GeoPointField(FIELD_NAME, -14.796283808944777, -90.0, storedPoint),
-        new GeoPointField(FIELD_NAME, -178.8538113027811, 32.94823588839368, storedPoint),
-        new GeoPointField(FIELD_NAME, 178.8538113027811, 32.94823588839368, storedPoint),
-        new GeoPointField(FIELD_NAME, -73.998776, 40.720611, storedPoint),
-        new GeoPointField(FIELD_NAME, -179.5, -44.5, storedPoint)};
-
-    for (GeoPointField p : pts) {
-      Document doc = new Document();
-      doc.add(p);
-      writer.addDocument(doc);
-    }
-
-    // add explicit multi-valued docs
-    for (int i=0; i<pts.length; i+=2) {
-      Document doc = new Document();
-      doc.add(pts[i]);
-      doc.add(pts[i+1]);
-      writer.addDocument(doc);
-    }
-
-    // index random string documents
-    for (int i=0; i<random().nextInt(10); ++i) {
-      Document doc = new Document();
-      doc.add(new StringField("string", Integer.toString(i), Field.Store.NO));
-      writer.addDocument(doc);
-    }
-
-    reader = writer.getReader();
-    searcher = newSearcher(reader);
-    writer.close();
-  }
-
-  @AfterClass
-  public static void afterClass() throws Exception {
-    searcher = null;
-    reader.close();
-    reader = null;
-    directory.close();
-    directory = null;
-  }
-
-  private TopDocs bboxQuery(double minLon, double minLat, double maxLon, double maxLat, int limit) throws Exception {
-    GeoPointInBBoxQuery q = new GeoPointInBBoxQuery(FIELD_NAME, minLon, minLat, maxLon, maxLat);
-    return searcher.search(q, limit);
-  }
-
-  private TopDocs polygonQuery(double[] lon, double[] lat, int limit) throws Exception {
-    GeoPointInPolygonQuery q = new GeoPointInPolygonQuery(FIELD_NAME, lon, lat);
-    return searcher.search(q, limit);
-  }
-
-  private TopDocs geoDistanceQuery(double lon, double lat, double radius, int limit) throws Exception {
-    GeoPointDistanceQuery q = new GeoPointDistanceQuery(FIELD_NAME, lon, lat, radius);
-    return searcher.search(q, limit);
-  }
-
-  @Override
-  protected Boolean rectContainsPoint(GeoRect rect, double pointLat, double pointLon) {
-    if (GeoUtils.compare(pointLon, rect.minLon) == 0.0 ||
-        GeoUtils.compare(pointLon, rect.maxLon) == 0.0 ||
-        GeoUtils.compare(pointLat, rect.minLat) == 0.0 ||
-        GeoUtils.compare(pointLat, rect.maxLat) == 0.0) {
-      // Point is very close to rect boundary
-      return null;
-    }
-
-    if (rect.minLon < rect.maxLon) {
-      return GeoRelationUtils.pointInRectPrecise(pointLon, pointLat, rect.minLon, rect.minLat, rect.maxLon, rect.maxLat);
-    } else {
-      // Rect crosses dateline:
-      return GeoRelationUtils.pointInRectPrecise(pointLon, pointLat, -180.0, rect.minLat, rect.maxLon, rect.maxLat)
-          || GeoRelationUtils.pointInRectPrecise(pointLon, pointLat, rect.minLon, rect.minLat, 180.0, rect.maxLat);
-    }
-  }
-
-  @Override
-  protected Boolean polyRectContainsPoint(GeoRect rect, double pointLat, double pointLon) {
-    return rectContainsPoint(rect, pointLat, pointLon);
-  }
-
-  @Override
-  protected Boolean circleContainsPoint(double centerLat, double centerLon, double radiusMeters, double pointLat, double pointLon) {
-    if (radiusQueryCanBeWrong(centerLat, centerLon, pointLon, pointLat, radiusMeters)) {
-      return null;
-    } else {
-      return SloppyMath.haversin(centerLat, centerLon, pointLat, pointLon)*1000.0 <= radiusMeters;
-    }
-  }
-
-  @Override
-  protected Boolean distanceRangeContainsPoint(double centerLat, double centerLon, double minRadiusMeters, double radiusMeters, double pointLat, double pointLon) {
-    if (radiusQueryCanBeWrong(centerLat, centerLon, pointLon, pointLat, minRadiusMeters)
-        || radiusQueryCanBeWrong(centerLat, centerLon, pointLon, pointLat, radiusMeters)) {
-      return null;
-    } else {
-      final double d = SloppyMath.haversin(centerLat, centerLon, pointLat, pointLon)*1000.0;
-      return d >= minRadiusMeters && d <= radiusMeters;
-    }
-  }
-
-  private static boolean radiusQueryCanBeWrong(double centerLat, double centerLon, double ptLon, double ptLat,
-                                               final double radius) {
-    final long hashedCntr = GeoUtils.mortonHash(centerLon, centerLat);
-    centerLon = GeoUtils.mortonUnhashLon(hashedCntr);
-    centerLat = GeoUtils.mortonUnhashLat(hashedCntr);
-    final long hashedPt = GeoUtils.mortonHash(ptLon, ptLat);
-    ptLon = GeoUtils.mortonUnhashLon(hashedPt);
-    ptLat = GeoUtils.mortonUnhashLat(hashedPt);
-
-    double ptDistance = SloppyMath.haversin(centerLat, centerLon, ptLat, ptLon)*1000.0;
-    double delta = StrictMath.abs(ptDistance - radius);
-
-    // if its within the distance error then it can be wrong
-    return delta < (ptDistance*DISTANCE_PCT_ERR);
-  }
-
-  public void testRectCrossesCircle() throws Exception {
-    assertTrue(GeoRelationUtils.rectCrossesCircle(-180, -90, 180, 0.0, 0.667, 0.0, 88000.0));
-  }
-
-  private TopDocs geoDistanceRangeQuery(double lon, double lat, double minRadius, double maxRadius, int limit)
-      throws Exception {
-    GeoPointDistanceRangeQuery q = new GeoPointDistanceRangeQuery(FIELD_NAME, lon, lat, minRadius, maxRadius);
-    return searcher.search(q, limit);
-  }
-
-  public void testBBoxQuery() throws Exception {
-    TopDocs td = bboxQuery(-96.7772, 32.778650, -96.77690000, 32.778950, 5);
-    assertEquals("GeoBoundingBoxQuery failed", 4, td.totalHits);
-  }
-
-  public void testPolyQuery() throws Exception {
-    TopDocs td = polygonQuery(new double[]{-96.7682647, -96.8280029, -96.6288757, -96.4929199,
-            -96.6041564, -96.7449188, -96.76826477, -96.7682647},
-        new double[]{33.073130, 32.9942669, 32.938386, 33.0374494,
-            33.1369762, 33.1162747, 33.073130, 33.073130}, 5);
-    assertEquals("GeoPolygonQuery failed", 2, td.totalHits);
-  }
-
-  public void testPacManPolyQuery() throws Exception {
-    // pacman
-    double[] px = {0, 10, 10, 0, -8, -10, -8, 0, 10, 10, 0};
-    double[] py = {0, 5, 9, 10, 9, 0, -9, -10, -9, -5, 0};
-
-    // shape bbox
-    double xMinA = -10;
-    double xMaxA = 10;
-    double yMinA = -10;
-    double yMaxA = 10;
-
-    // candidate crosses cell
-    double xMin = 2;//-5;
-    double xMax = 11;//0.000001;
-    double yMin = -1;//0;
-    double yMax = 1;//5;
-
-    // test cell crossing poly
-    assertTrue(GeoRelationUtils.rectCrossesPolyApprox(xMin, yMin, xMax, yMax, px, py, xMinA, yMinA, xMaxA, yMaxA));
-    assertFalse(GeoRelationUtils.rectCrossesPolyApprox(-5, 0,  0.000001, 5, px, py, xMin, yMin, xMax, yMax));
-    assertTrue(GeoRelationUtils.rectWithinPolyApprox(-5, 0, -2, 5, px, py, xMin, yMin, xMax, yMax));
-  }
-
-  public void testBBoxCrossDateline() throws Exception {
-    TopDocs td = bboxQuery(179.0, -45.0, -179.0, -44.0, 20);
-    assertEquals("BBoxCrossDateline query failed", 2, td.totalHits);
-  }
-
-  public void testWholeMap() throws Exception {
-    TopDocs td = bboxQuery(GeoUtils.MIN_LON_INCL, GeoUtils.MIN_LAT_INCL, GeoUtils.MAX_LON_INCL, GeoUtils.MAX_LAT_INCL, 20);
-    assertEquals("testWholeMap failed", 24, td.totalHits);
-    td = polygonQuery(new double[] {GeoUtils.MIN_LON_INCL, GeoUtils.MIN_LON_INCL, GeoUtils.MAX_LON_INCL, GeoUtils.MAX_LON_INCL, GeoUtils.MIN_LON_INCL},
-        new double[] {GeoUtils.MIN_LAT_INCL, GeoUtils.MAX_LAT_INCL, GeoUtils.MAX_LAT_INCL, GeoUtils.MIN_LAT_INCL, GeoUtils.MIN_LAT_INCL}, 20);
-    assertEquals("testWholeMap failed", 24, td.totalHits);
-  }
-
-  public void smallTest() throws Exception {
-    TopDocs td = geoDistanceQuery(-73.998776, 40.720611, 1, 20);
-    assertEquals("smallTest failed", 2, td.totalHits);
-  }
-
-  public void testInvalidBBox() throws Exception {
-    try {
-      bboxQuery(179.0, -92.0, 181.0, -91.0, 20);
-    } catch(Exception e) {
-      return;
-    }
-    throw new Exception("GeoBoundingBox should not accept invalid lat/lon");
-  }
-
-  public void testGeoDistanceQuery() throws Exception {
-    TopDocs td = geoDistanceQuery(-96.4538113027811, 32.94823588839368, 6000, 20);
-    assertEquals("GeoDistanceQuery failed", 2, td.totalHits);
-  }
-
-  /** see https://issues.apache.org/jira/browse/LUCENE-6905 */
-  public void testNonEmptyTermsEnum() throws Exception {
-    TopDocs td = geoDistanceQuery(-177.23537676036358, -88.56029371730983, 7757.999232959935, 20);
-    assertEquals("GeoDistanceQuery failed", 2, td.totalHits);
-  }
-
-  public void testMultiValuedQuery() throws Exception {
-    TopDocs td = bboxQuery(-96.4538113027811, 32.7559529921407, -96.7706036567688, 32.7756745755423, 20);
-    // 3 single valued docs + 2 multi-valued docs
-    assertEquals("testMultiValuedQuery failed", 5, td.totalHits);
-  }
-
-  public void testTooBigRadius() throws Exception {
-    try {
-      geoDistanceQuery(0.0, 85.0, 4000000, 20);
-    } catch (IllegalArgumentException e) {
-      e.getMessage().contains("exceeds maxRadius");
-    }
-  }
-
-  /**
-   * Explicitly large
-   */
-  public void testGeoDistanceQueryHuge() throws Exception {
-    TopDocs td = geoDistanceQuery(-96.4538113027811, 32.94823588839368, 6000000, 20);
-    assertEquals("GeoDistanceQuery failed", 16, td.totalHits);
-  }
-
-  public void testGeoDistanceQueryCrossDateline() throws Exception {
-    TopDocs td = geoDistanceQuery(-179.9538113027811, 32.94823588839368, 120000, 20);
-    assertEquals("GeoDistanceQuery failed", 3, td.totalHits);
-  }
-
-  public void testInvalidGeoDistanceQuery() throws Exception {
-    try {
-      geoDistanceQuery(181.0, 92.0, 120000, 20);
-    } catch (Exception e) {
-      return;
-    }
-    throw new Exception("GeoDistanceQuery should not accept invalid lat/lon as origin");
-  }
-
-  public void testMaxDistanceRangeQuery() throws Exception {
-    TopDocs td = geoDistanceRangeQuery(0.0, 0.0, 10, 20000000, 20);
-    assertEquals("GeoDistanceRangeQuery failed", 24, td.totalHits);
-  }
-
-  public void testMortonEncoding() throws Exception {
-    long hash = GeoUtils.mortonHash(180, 90);
-    assertEquals(180.0, GeoUtils.mortonUnhashLon(hash), 0);
-    assertEquals(90.0, GeoUtils.mortonUnhashLat(hash), 0);
-  }
-
-  public void testEncodeDecode() throws Exception {
-    int iters = atLeast(10000);
-    boolean small = random().nextBoolean();
-    for(int iter=0;iter<iters;iter++) {
-      double lat = randomLat(small);
-      double lon = randomLon(small);
-
-      long enc = GeoUtils.mortonHash(lon, lat);
-      double latEnc = GeoUtils.mortonUnhashLat(enc);
-      double lonEnc = GeoUtils.mortonUnhashLon(enc);
-
-      assertEquals("lat=" + lat + " latEnc=" + latEnc + " diff=" + (lat - latEnc), lat, latEnc, GeoUtils.TOLERANCE);
-      assertEquals("lon=" + lon + " lonEnc=" + lonEnc + " diff=" + (lon - lonEnc), lon, lonEnc, GeoUtils.TOLERANCE);
-    }
-  }
-
-  public void testScaleUnscaleIsStable() throws Exception {
-    int iters = atLeast(1000);
-    boolean small = random().nextBoolean();
-    for(int iter=0;iter<iters;iter++) {
-      double lat = randomLat(small);
-      double lon = randomLon(small);
-
-      long enc = GeoUtils.mortonHash(lon, lat);
-      double latEnc = GeoUtils.mortonUnhashLat(enc);
-      double lonEnc = GeoUtils.mortonUnhashLon(enc);
-
-      long enc2 = GeoUtils.mortonHash(lon, lat);
-      double latEnc2 = GeoUtils.mortonUnhashLat(enc2);
-      double lonEnc2 = GeoUtils.mortonUnhashLon(enc2);
-      assertEquals(latEnc, latEnc2, 0.0);
-      assertEquals(lonEnc, lonEnc2, 0.0);
-    }
-  }
-}