--- /dev/null
+/**
+ * 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.tier;
+
+import org.apache.lucene.spatial.DistanceUtils;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Provide a high level access point to distances
+ * Used by DistanceSortSource and DistanceQuery
+ *
+ * <p><font color="red"><b>NOTE:</b> This API is still in
+ * flux and might change in incompatible ways in the next
+ * release.</font>
+ *
+ */
+public class DistanceHandler {
+
+ public enum Precision {EXACT, TWOFEET, TWENTYFEET, TWOHUNDREDFEET}
+
+ private Map<Integer,Double> distances;
+ private Map<String, Double> distanceLookupCache;
+ private Precision precise;
+
+ public DistanceHandler (Map<Integer,Double> distances, Map<String, Double> distanceLookupCache, Precision precise){
+ this.distances = distances;
+ this.distanceLookupCache = distanceLookupCache;
+ this.precise = precise;
+ }
+
+
+ public static double getPrecision(double x, Precision thisPrecise){
+
+ if(thisPrecise != null){
+ double dif = 0;
+ switch(thisPrecise) {
+ case EXACT: return x;
+ case TWOFEET: dif = x % 0.0001; break;
+ case TWENTYFEET: dif = x % 0.001; break;
+ case TWOHUNDREDFEET: dif = x % 0.01; break;
+ }
+ return x - dif;
+ }
+ return x;
+ }
+
+ public Precision getPrecision() {
+ return precise;
+ }
+
+ public double getDistance(int docid, double centerLat, double centerLng, double lat, double lng){
+
+ // check to see if we have distances
+ // if not calculate the distance
+ if(distances == null){
+ return DistanceUtils.getDistanceMi(centerLat, centerLng, lat, lng);
+ }
+
+ // check to see if the doc id has a cached distance
+ Double docd = distances.get( docid );
+ if (docd != null){
+ return docd.doubleValue();
+ }
+
+ //check to see if we have a precision code
+ // and if another lat/long has been calculated at
+ // that rounded location
+ if (precise != null) {
+ double xLat = getPrecision(lat, precise);
+ double xLng = getPrecision(lng, precise);
+
+ String k = Double.valueOf(xLat).toString() +","+ Double.valueOf(xLng).toString();
+
+ Double d = (distanceLookupCache.get(k));
+ if (d != null){
+ return d.doubleValue();
+ }
+ }
+
+ //all else fails calculate the distances
+ return DistanceUtils.getDistanceMi(centerLat, centerLng, lat, lng);
+ }
+
+
+ public static void main(String args[]){
+ DistanceHandler db = new DistanceHandler(new HashMap<Integer,Double>(), new HashMap<String,Double>(), Precision.TWOHUNDREDFEET);
+ System.out.println(DistanceHandler.getPrecision(-1234.123456789, db.getPrecision()));
+ }
+}