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();