/** * 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())); } }