/* * 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. */ using System; using System.Collections.Generic; namespace Lucene.Net.Spatial.Tier { public enum Precision { EXACT, TWOFEET, TWENTYFEET, TWOHUNDREDFEET, } /// /// Provide a high level access point to distances /// Used by DistanceSortSource and DistanceQuery /// public class DistanceHandler { private readonly Dictionary _distances; private readonly Dictionary _distanceLookupCache; private readonly Precision? _precision; public DistanceHandler(Dictionary distances, Dictionary distanceLookupCache, Precision precision) { _distances = distances; _distanceLookupCache = distanceLookupCache; _precision = precision; } public static double GetPrecision(double x, Precision? thisPrecision) { if(thisPrecision.HasValue) { double dif = 0; switch (thisPrecision) { case Precision.EXACT: return x; case Precision.TWOFEET: dif = x%0.0001; break; case Precision.TWENTYFEET: dif = x%0.001; break; case Precision.TWOHUNDREDFEET: dif = x%0.01; break; } return x - dif; } return x; } public Precision GetPrecision() { return _precision.Value; } 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.GetInstance().GetDistanceMi(centerLat, centerLng, lat, lng); } // check to see if the doc id has a cached distance double docd; _distances.TryGetValue(docid, out docd); if (docd > 0) return docd; //check to see if we have a precision code // and if another lat/long has been calculated at // that rounded location if (_precision.HasValue) { double xLat = GetPrecision(lat, _precision); double xLng = GetPrecision(lng, _precision); String k = xLat + "," + xLng; Double d; _distanceLookupCache.TryGetValue(k, out d); if (d > 0) return d; } //all else fails calculate the distances return DistanceUtils.GetInstance().GetDistanceMi(centerLat, centerLng, lat, lng); } } }