Geo-distance in scripts (like custom_score), closes #607.

This commit is contained in:
kimchy 2011-01-07 15:22:11 +02:00
parent 8b8bad7572
commit b9be6d9ea7
2 changed files with 46 additions and 0 deletions

View File

@ -19,6 +19,7 @@
package org.elasticsearch.index.mapper.xcontent.geo;
import org.elasticsearch.common.unit.DistanceUnit;
import org.elasticsearch.index.field.data.DocFieldData;
/**
@ -38,6 +39,22 @@ public class GeoPointDocFieldData extends DocFieldData<GeoPointFieldData> {
return fieldData.values(docId);
}
public double distance(double lat, double lon) {
return fieldData.distance(docId, DistanceUnit.MILES, lat, lon);
}
public double distanceInKm(double lat, double lon) {
return fieldData.distance(docId, DistanceUnit.KILOMETERS, lat, lon);
}
public double geohashDistance(String geohash) {
return fieldData.distanceGeohash(docId, DistanceUnit.MILES, geohash);
}
public double geohashDistanceInKm(String geohash) {
return fieldData.distanceGeohash(docId, DistanceUnit.KILOMETERS, geohash);
}
public double getLat() {
return fieldData.latValue(docId);
}

View File

@ -23,9 +23,11 @@ import org.apache.lucene.index.IndexReader;
import org.elasticsearch.common.RamUsage;
import org.elasticsearch.common.thread.ThreadLocals;
import org.elasticsearch.common.trove.TDoubleArrayList;
import org.elasticsearch.common.unit.DistanceUnit;
import org.elasticsearch.index.field.data.FieldData;
import org.elasticsearch.index.field.data.FieldDataType;
import org.elasticsearch.index.field.data.support.FieldDataLoader;
import org.elasticsearch.index.search.geo.GeoDistance;
import org.elasticsearch.index.search.geo.GeoHashUtils;
import java.io.IOException;
@ -41,6 +43,18 @@ public abstract class GeoPointFieldData extends FieldData<GeoPointDocFieldData>
}
};
static class GeoPointHash {
public double lat;
public double lon;
public String geoHash = "";
}
static ThreadLocal<ThreadLocals.CleanableValue<GeoPointHash>> geoHashCache = new ThreadLocal<ThreadLocals.CleanableValue<GeoPointHash>>() {
@Override protected ThreadLocals.CleanableValue<GeoPointHash> initialValue() {
return new ThreadLocals.CleanableValue<GeoPointHash>(new GeoPointHash());
}
};
public static final GeoPoint[] EMPTY_ARRAY = new GeoPoint[0];
protected final double[] lat;
@ -64,6 +78,21 @@ public abstract class GeoPointFieldData extends FieldData<GeoPointDocFieldData>
abstract public double[] lonValues(int docId);
public double distance(int docId, DistanceUnit unit, double lat, double lon) {
return GeoDistance.PLANE.calculate(latValue(docId), lonValue(docId), lat, lon, unit);
}
public double distanceGeohash(int docId, DistanceUnit unit, String geoHash) {
GeoPointHash geoPointHash = geoHashCache.get().get();
if (geoPointHash.geoHash != geoHash) {
geoPointHash.geoHash = geoHash;
double[] decode = GeoHashUtils.decode(geoHash);
geoPointHash.lat = decode[0];
geoPointHash.lon = decode[1];
}
return GeoDistance.PLANE.calculate(latValue(docId), lonValue(docId), geoPointHash.lat, geoPointHash.lon, unit);
}
@Override public GeoPointDocFieldData docFieldData(int docId) {
return super.docFieldData(docId);
}