add --shared
[pylucene.git] / lucene-java-3.4.0 / lucene / contrib / spatial / src / java / org / apache / lucene / spatial / tier / DistanceHandler.java
1 /**
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements.  See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License.  You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 package org.apache.lucene.spatial.tier;
19
20 import org.apache.lucene.spatial.DistanceUtils;
21
22 import java.util.HashMap;
23 import java.util.Map;
24
25 /**
26  * Provide a high level access point to distances
27  * Used by DistanceSortSource and DistanceQuery
28  *  
29  * <p><font color="red"><b>NOTE:</b> This API is still in
30  * flux and might change in incompatible ways in the next
31  * release.</font>
32  *
33  */
34 public class DistanceHandler {
35
36   public enum Precision {EXACT, TWOFEET, TWENTYFEET, TWOHUNDREDFEET}
37   
38   private Map<Integer,Double> distances;
39   private Map<String, Double> distanceLookupCache;
40   private Precision precise;
41   
42   public DistanceHandler (Map<Integer,Double> distances, Map<String, Double> distanceLookupCache, Precision precise){
43     this.distances = distances;
44     this.distanceLookupCache = distanceLookupCache;
45     this.precise = precise; 
46   }
47   
48   
49   public static double getPrecision(double x, Precision thisPrecise){
50     
51     if(thisPrecise != null){
52       double dif = 0;
53       switch(thisPrecise) {
54         case EXACT: return x;
55         case TWOFEET:        dif = x % 0.0001; break;
56         case TWENTYFEET:     dif = x % 0.001;  break;
57         case TWOHUNDREDFEET: dif = x % 0.01; break;
58       }
59       return x - dif;
60     }
61     return x;
62   }
63   
64   public Precision getPrecision() {
65     return precise;
66   }
67   
68   public double getDistance(int docid, double centerLat, double centerLng, double lat, double lng){
69   
70     // check to see if we have distances
71     // if not calculate the distance
72     if(distances == null){
73       return DistanceUtils.getDistanceMi(centerLat, centerLng, lat, lng);
74     }
75     
76     // check to see if the doc id has a cached distance
77     Double docd = distances.get( docid );
78     if (docd != null){
79       return docd.doubleValue();
80     }
81     
82     //check to see if we have a precision code
83     // and if another lat/long has been calculated at
84     // that rounded location
85     if (precise != null) {
86       double xLat = getPrecision(lat, precise);
87       double xLng = getPrecision(lng, precise);
88       
89       String k = Double.valueOf(xLat).toString() +","+ Double.valueOf(xLng).toString();
90     
91       Double d = (distanceLookupCache.get(k));
92       if (d != null){
93         return d.doubleValue();
94       }
95     }
96     
97     //all else fails calculate the distances    
98     return DistanceUtils.getDistanceMi(centerLat, centerLng, lat, lng);
99   }
100   
101   
102   public static void main(String args[]){ 
103     DistanceHandler db = new DistanceHandler(new HashMap<Integer,Double>(), new HashMap<String,Double>(), Precision.TWOHUNDREDFEET);
104     System.out.println(DistanceHandler.getPrecision(-1234.123456789, db.getPrecision()));
105   }
106 }