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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 package org.apache.lucene.spatial.geohash;
20 import java.io.IOException;
22 import org.apache.lucene.index.IndexReader;
23 import org.apache.lucene.search.FieldCache;
24 import org.apache.lucene.search.Filter;
25 import org.apache.lucene.search.DocIdSet;
26 import org.apache.lucene.search.FilteredDocIdSet;
27 import org.apache.lucene.spatial.DistanceUtils;
28 import org.apache.lucene.spatial.tier.DistanceFilter;
31 /** <p><font color="red"><b>NOTE:</b> This API is still in
32 * flux and might change in incompatible ways in the next
36 public class GeoHashDistanceFilter extends DistanceFilter {
41 private static final long serialVersionUID = 1L;
45 private String geoHashField;
48 * Provide a distance filter based from a center point with a radius
50 * @param startingFilter
55 public GeoHashDistanceFilter(Filter startingFilter, double lat, double lng, double miles, String geoHashField) {
56 super(startingFilter, miles);
59 this.geoHashField = geoHashField;
63 public DocIdSet getDocIdSet(IndexReader reader) throws IOException {
65 final String[] geoHashValues = FieldCache.DEFAULT.getStrings(reader, geoHashField);
67 final int docBase = nextDocBase;
68 nextDocBase += reader.maxDoc();
70 return new FilteredDocIdSet(startingFilter.getDocIdSet(reader)) {
72 public boolean match(int doc) {
74 String geoHash = geoHashValues[doc];
75 double[] coords = GeoHashUtils.decode(geoHash);
79 // round off lat / longs if necessary
80 // x = DistanceHandler.getPrecision(x, precise);
81 // y = DistanceHandler.getPrecision(y, precise);
82 Double cachedDistance = distanceLookupCache.get(geoHash);
85 if (cachedDistance != null) {
86 d = cachedDistance.doubleValue();
88 d = DistanceUtils.getDistanceMi(lat, lng, x, y);
89 distanceLookupCache.put(geoHash, d);
93 distances.put(doc+docBase, d);
102 /** Returns true if <code>o</code> is equal to this. */
104 public boolean equals(Object o) {
105 if (this == o) return true;
106 if (!(o instanceof GeoHashDistanceFilter)) return false;
107 GeoHashDistanceFilter other = (GeoHashDistanceFilter) o;
109 if (!this.startingFilter.equals(other.startingFilter) ||
110 this.distance != other.distance ||
111 this.lat != other.lat ||
112 this.lng != other.lng ||
113 !this.geoHashField.equals(other.geoHashField) ) {
119 /** Returns a hash code value for this object.*/
121 public int hashCode() {
122 int h = Double.valueOf(distance).hashCode();
123 h ^= startingFilter.hashCode();
124 h ^= Double.valueOf(lat).hashCode();
125 h ^= Double.valueOf(lng).hashCode();
126 h ^= geoHashField.hashCode();