下面列出了org.apache.lucene.search.ConstantScoreWeight#org.elasticsearch.common.geo.GeoDistance 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@Override
public double getDistance() {
String geohash = (String) ((ElasticsearchDocument) getDocument()).getSource().get(geoPointField);
GeoPoint dstPoint = GeoPoint.fromGeohash(geohash);
double unitDist = GeoDistance.ARC.calculate(srcPoint.getLat(), srcPoint.getLon(), dstPoint.getLat(),
dstPoint.getLon(), unit);
double distance;
if (GEOF.UOM_METRE.equals(units)) {
distance = unit.toMeters(unitDist);
} else if (GEOF.UOM_DEGREE.equals(units)) {
distance = unitDist / unit.getDistancePerDegree();
} else if (GEOF.UOM_RADIAN.equals(units)) {
distance = DistanceUtils.dist2Radians(unit.convert(unitDist, DistanceUnit.KILOMETERS),
DistanceUtils.EARTH_MEAN_RADIUS_KM);
} else if (GEOF.UOM_UNITY.equals(units)) {
distance = unit.convert(unitDist, DistanceUnit.KILOMETERS) / (Math.PI * DistanceUtils.EARTH_MEAN_RADIUS_KM);
} else {
throw new UnsupportedOperationException("Unsupported units: " + units);
}
return distance;
}
public Double evaluate(Input arg1, Input arg2) {
Object value1 = arg1.value();
if (value1 == null) {
return null;
}
Object value2 = arg2.value();
if (value2 == null) {
return null;
}
double sourceLongitude;
double sourceLatitude;
double targetLongitude;
double targetLatitude;
// need to handle list also - because e.g. ESSearchTask returns geo_points as list
if (value1 instanceof List) {
sourceLongitude = (Double)((List) value1).get(0);
sourceLatitude = (Double)((List) value1).get(1);
} else {
sourceLongitude = ((Double[]) value1)[0];
sourceLatitude = ((Double[]) value1)[1];
}
if (value2 instanceof List) {
targetLongitude = (Double)((List) value2).get(0);
targetLatitude = (Double)((List) value2).get(1);
} else {
targetLongitude = ((Double[]) value2)[0];
targetLatitude = ((Double[]) value2)[1];
}
return GeoDistance.SLOPPY_ARC.calculate(
sourceLatitude, sourceLongitude, targetLatitude, targetLongitude, DistanceUnit.METERS);
}
public GeoDistanceFactory(String name, ValuesSourceConfig<ValuesSource.GeoPoint> valueSourceConfig,
InternalRange.Factory rangeFactory, GeoPoint origin, DistanceUnit unit, GeoDistance distanceType,
List<RangeAggregator.Range> ranges, boolean keyed) {
super(name, rangeFactory.type(), valueSourceConfig);
this.origin = origin;
this.unit = unit;
this.distanceType = distanceType;
this.rangeFactory = rangeFactory;
this.ranges = ranges;
this.keyed = keyed;
}
public DistanceSource(ValuesSource.GeoPoint source, GeoDistance distanceType, org.elasticsearch.common.geo.GeoPoint origin, DistanceUnit unit) {
this.source = source;
// even if the geo points are unique, there's no guarantee the distances are
this.distanceType = distanceType;
this.unit = unit;
this.origin = origin;
}
public double factorDistanceWithDefault(double lat, double lon, double defaultValue) {
if (isEmpty()) {
return defaultValue;
}
GeoPoint point = getValue();
return GeoDistance.FACTOR.calculate(point.lat(), point.lon(), lat, lon, DistanceUnit.DEFAULT);
}
public double arcDistanceWithDefault(double lat, double lon, double defaultValue) {
if (isEmpty()) {
return defaultValue;
}
GeoPoint point = getValue();
return GeoDistance.ARC.calculate(point.lat(), point.lon(), lat, lon, DistanceUnit.DEFAULT);
}
public double arcDistanceInKmWithDefault(double lat, double lon, double defaultValue) {
if (isEmpty()) {
return defaultValue;
}
GeoPoint point = getValue();
return GeoDistance.ARC.calculate(point.lat(), point.lon(), lat, lon, DistanceUnit.KILOMETERS);
}
public double arcDistanceInMilesWithDefault(double lat, double lon, double defaultValue) {
if (isEmpty()) {
return defaultValue;
}
GeoPoint point = getValue();
return GeoDistance.ARC.calculate(point.lat(), point.lon(), lat, lon, DistanceUnit.MILES);
}
public double distanceWithDefault(double lat, double lon, double defaultValue) {
if (isEmpty()) {
return defaultValue;
}
GeoPoint point = getValue();
return GeoDistance.PLANE.calculate(point.lat(), point.lon(), lat, lon, DistanceUnit.DEFAULT);
}
public double distanceInKmWithDefault(double lat, double lon, double defaultValue) {
if (isEmpty()) {
return defaultValue;
}
GeoPoint point = getValue();
return GeoDistance.PLANE.calculate(point.lat(), point.lon(), lat, lon, DistanceUnit.KILOMETERS);
}
public double distanceInMilesWithDefault(double lat, double lon, double defaultValue) {
if (isEmpty()) {
return defaultValue;
}
GeoPoint point = getValue();
return GeoDistance.PLANE.calculate(point.lat(), point.lon(), lat, lon, DistanceUnit.MILES);
}
@Override
public AggregatorFactory parse(String aggregationName, XContentParser parser, SearchContext context) throws IOException {
ValuesSourceParser<ValuesSource.GeoPoint> vsParser = ValuesSourceParser.geoPoint(aggregationName, InternalGeoDistance.TYPE, context).build();
GeoPointParser geoPointParser = new GeoPointParser(aggregationName, InternalGeoDistance.TYPE, context, ORIGIN_FIELD);
List<RangeAggregator.Range> ranges = null;
DistanceUnit unit = DistanceUnit.DEFAULT;
GeoDistance distanceType = GeoDistance.DEFAULT;
boolean keyed = false;
XContentParser.Token token;
String currentFieldName = null;
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
if (token == XContentParser.Token.FIELD_NAME) {
currentFieldName = parser.currentName();
} else if (vsParser.token(currentFieldName, token, parser)) {
continue;
} else if (geoPointParser.token(currentFieldName, token, parser)) {
continue;
} else if (token == XContentParser.Token.VALUE_STRING) {
if ("unit".equals(currentFieldName)) {
unit = DistanceUnit.fromString(parser.text());
} else if ("distance_type".equals(currentFieldName) || "distanceType".equals(currentFieldName)) {
distanceType = GeoDistance.fromString(parser.text());
} else {
throw new SearchParseException(context, "Unknown key for a " + token + " in [" + aggregationName + "]: ["
+ currentFieldName + "].", parser.getTokenLocation());
}
} else if (token == XContentParser.Token.VALUE_BOOLEAN) {
if ("keyed".equals(currentFieldName)) {
keyed = parser.booleanValue();
} else {
throw new SearchParseException(context, "Unknown key for a " + token + " in [" + aggregationName + "]: ["
+ currentFieldName + "].", parser.getTokenLocation());
}
} else if (token == XContentParser.Token.START_ARRAY) {
if ("ranges".equals(currentFieldName)) {
ranges = new ArrayList<>();
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
String fromAsStr = null;
String toAsStr = null;
double from = 0.0;
double to = Double.POSITIVE_INFINITY;
String key = null;
String toOrFromOrKey = null;
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
if (token == XContentParser.Token.FIELD_NAME) {
toOrFromOrKey = parser.currentName();
} else if (token == XContentParser.Token.VALUE_NUMBER) {
if ("from".equals(toOrFromOrKey)) {
from = parser.doubleValue();
} else if ("to".equals(toOrFromOrKey)) {
to = parser.doubleValue();
}
} else if (token == XContentParser.Token.VALUE_STRING) {
if ("key".equals(toOrFromOrKey)) {
key = parser.text();
} else if ("from".equals(toOrFromOrKey)) {
fromAsStr = parser.text();
} else if ("to".equals(toOrFromOrKey)) {
toAsStr = parser.text();
}
}
}
ranges.add(new RangeAggregator.Range(key(key, from, to), from, fromAsStr, to, toAsStr));
}
} else {
throw new SearchParseException(context, "Unknown key for a " + token + " in [" + aggregationName + "]: ["
+ currentFieldName + "].", parser.getTokenLocation());
}
} else {
throw new SearchParseException(context, "Unexpected token " + token + " in [" + aggregationName + "]: ["
+ currentFieldName + "].", parser.getTokenLocation());
}
}
if (ranges == null) {
throw new SearchParseException(context, "Missing [ranges] in geo_distance aggregator [" + aggregationName + "]",
parser.getTokenLocation());
}
GeoPoint origin = geoPointParser.geoPoint();
if (origin == null) {
throw new SearchParseException(context, "Missing [origin] in geo_distance aggregator [" + aggregationName + "]",
parser.getTokenLocation());
}
return new GeoDistanceFactory(aggregationName, vsParser.config(), InternalGeoDistance.FACTORY, origin, unit, distanceType, ranges, keyed);
}
@Override
public SortedNumericDoubleValues doubleValues(LeafReaderContext ctx) {
final MultiGeoPointValues geoValues = source.geoPointValues(ctx);
final FixedSourceDistance distance = distanceType.fixedSourceDistance(origin.getLat(), origin.getLon(), unit);
return GeoDistance.distanceValues(geoValues, distance);
}
public double factorDistance(double lat, double lon) {
GeoPoint point = getValue();
return GeoDistance.FACTOR.calculate(point.lat(), point.lon(), lat, lon, DistanceUnit.DEFAULT);
}
public double factorDistance02(double lat, double lon) {
GeoPoint point = getValue();
return GeoDistance.FACTOR.calculate(point.lat(), point.lon(), lat, lon, DistanceUnit.DEFAULT) + 1;
}
public double factorDistance13(double lat, double lon) {
GeoPoint point = getValue();
return GeoDistance.FACTOR.calculate(point.lat(), point.lon(), lat, lon, DistanceUnit.DEFAULT) + 2;
}
public double arcDistance(double lat, double lon) {
GeoPoint point = getValue();
return GeoDistance.ARC.calculate(point.lat(), point.lon(), lat, lon, DistanceUnit.DEFAULT);
}
public double arcDistanceInKm(double lat, double lon) {
GeoPoint point = getValue();
return GeoDistance.ARC.calculate(point.lat(), point.lon(), lat, lon, DistanceUnit.KILOMETERS);
}
public double arcDistanceInMiles(double lat, double lon) {
GeoPoint point = getValue();
return GeoDistance.ARC.calculate(point.lat(), point.lon(), lat, lon, DistanceUnit.MILES);
}
public double distance(double lat, double lon) {
GeoPoint point = getValue();
return GeoDistance.PLANE.calculate(point.lat(), point.lon(), lat, lon, DistanceUnit.DEFAULT);
}
public double distanceInKm(double lat, double lon) {
GeoPoint point = getValue();
return GeoDistance.PLANE.calculate(point.lat(), point.lon(), lat, lon, DistanceUnit.KILOMETERS);
}
public double distanceInMiles(double lat, double lon) {
GeoPoint point = getValue();
return GeoDistance.PLANE.calculate(point.lat(), point.lon(), lat, lon, DistanceUnit.MILES);
}
public double geohashDistance(String geohash) {
GeoPoint point = getValue();
GeoPoint p = new GeoPoint().resetFromGeoHash(geohash);
return GeoDistance.ARC.calculate(point.lat(), point.lon(), p.lat(), p.lon(), DistanceUnit.DEFAULT);
}
public double geohashDistanceInKm(String geohash) {
GeoPoint point = getValue();
GeoPoint p = new GeoPoint().resetFromGeoHash(geohash);
return GeoDistance.ARC.calculate(point.lat(), point.lon(), p.lat(), p.lon(), DistanceUnit.KILOMETERS);
}
public double geohashDistanceInMiles(String geohash) {
GeoPoint point = getValue();
GeoPoint p = new GeoPoint().resetFromGeoHash(geohash);
return GeoDistance.ARC.calculate(point.lat(), point.lon(), p.lat(), p.lon(), DistanceUnit.MILES);
}
public GeoDistance geoDistance() {
return geoDistance;
}
@Override
public Weight createWeight(IndexSearcher searcher, boolean needsScores) throws IOException {
final Weight boundingBoxWeight;
if (boundingBoxFilter != null) {
boundingBoxWeight = searcher.createNormalizedWeight(boundingBoxFilter, false);
} else {
boundingBoxWeight = null;
}
return new ConstantScoreWeight(this) {
@Override
public Scorer scorer(LeafReaderContext context) throws IOException {
final DocIdSetIterator approximation;
if (boundingBoxWeight != null) {
Scorer s = boundingBoxWeight.scorer(context);
if (s == null) {
// if the approximation does not match anything, we're done
return null;
}
approximation = s.iterator();
} else {
approximation = DocIdSetIterator.all(context.reader().maxDoc());
}
final MultiGeoPointValues values = indexFieldData.load(context).getGeoPointValues();
final TwoPhaseIterator twoPhaseIterator = new TwoPhaseIterator(approximation) {
@Override
public boolean matches() throws IOException {
final int doc = approximation.docID();
values.setDocument(doc);
final int length = values.count();
for (int i = 0; i < length; i++) {
GeoPoint point = values.valueAt(i);
if (distanceBoundingCheck.isWithin(point.lat(), point.lon())) {
double d = fixedSourceDistance.calculate(point.lat(), point.lon());
if (d >= inclusiveLowerPoint && d <= inclusiveUpperPoint) {
return true;
}
}
}
return false;
}
@Override
public float matchCost() {
if (distanceBoundingCheck == GeoDistance.ALWAYS_INSTANCE) {
return 0.0f;
} else {
// TODO: is this right (up to 4 comparisons from GeoDistance.SimpleDistanceBoundingCheck)?
return 4.0f;
}
}
};
return new ConstantScoreScorer(this, score(), twoPhaseIterator);
}
};
}
@Override
public void visit( WithinOperand op ) {
final String name = op.getProperty().getValue().toLowerCase();
float lat = op.getLatitude().getFloatValue();
float lon = op.getLongitude().getFloatValue();
float distance = op.getDistance().getFloatValue();
final FilterBuilder fb =
FilterBuilders.geoDistanceFilter( IndexingUtils.FIELD_LOCATION_NESTED ).lat( lat ).lon( lon )
.distance( distance, DistanceUnit.METERS );
filterBuilders.push( fieldNameTerm( name, fb ) );
//create our geo-sort based off of this point specified
//this geoSort won't has a sort on it
final GeoDistanceSortBuilder geoSort =
SortBuilders.geoDistanceSort( IndexingUtils.FIELD_LOCATION_NESTED ).unit( DistanceUnit.METERS )
.geoDistance(GeoDistance.SLOPPY_ARC).point(lat, lon);
final TermFilterBuilder sortPropertyName = sortPropertyTermFilter(name);
geoSort.setNestedFilter( sortPropertyName );
geoSortFields.addField(name, geoSort);
//no op for query, push
queryBuilders.push( NoOpQueryBuilder.INSTANCE );
}