Geo clean Up

============
The default unit for measuring distances is *MILES* in most cases. This commit moves ES
over to the *International System of Units* and make it work on a default which relates
to *METERS* . Also the current structures of the `GeoBoundingBox Filter` changed in
order to define the *Bounding* by setting abitrary corners.

Distances
---------
Since the default unit for measuring distances has changed to a default unit
`DistanceUnit.DEFAULT` relating to *meters*, the **REST API** has changed at the
following places:

  * `ScriptDocValues.factorDistance()` returns *meters* instead of *miles*
  * `ScriptDocValues.factorDistanceWithDefault()` returns *meters* instead of *miles*
  * `ScriptDocValues.arcDistance()` returns *meters* instead of *miles*
        one might use `ScriptDocValues.arcDistanceInMiles()`
  * `ScriptDocValues.arcDistanceWithDefault()` returns *meters* instead of *miles*
  * `ScriptDocValues.distance()` returns *meters* instead of *miles*
        one might use `ScriptDocValues.distanceInMiles()`
  * `ScriptDocValues.distanceWithDefault()` returns *meters* instead of *miles*
        one might use `ScriptDocValues.distanceInMilesWithDefault()`
  * `GeoDistanceFilter` default unit changes from *kilometers* to *meters*
  * `GeoDistanceRangeFilter` default unit changes from *miles* to *meters*
  * `GeoDistanceFacet` default unit changes from *miles* to *meters*

Geo Bounding Box Filter
-----------------------
The naming of the GeoBoundingBoxFilter properties allows to set arbitrary corners
(see #4084) namely `top_right`, `top_left`, `bottom_right` and `bottom_left`. This
change also includes the fields `topRight` and `bottomLeft` Also it is be possible to
set the single values by using just `top`, `bottom`, `left` and `right` parameters.

Closes #4515, #4084
This commit is contained in:
Florian Schilling 2013-12-19 13:52:33 +09:00
parent a500ba752e
commit 464037e0c1
37 changed files with 515 additions and 282 deletions

View File

@ -152,6 +152,7 @@ The full list of units is listed below:
[horizontal]
Mile:: `mi` or `miles`
Yard:: `yd` or `yards`
Feet:: `ft` or `feet`
Inch:: `in` or `inch`
Kilometer:: `km` or `kilometers`
Meter:: `m` or `meters`

View File

@ -149,6 +149,38 @@ Format in `lat,lon`.
}
--------------------------------------------------
[float]
==== Vertices
The vertices of the bounding box can either be set by `top_left` and
`bottom_right` or by `top_right` and `bottom_left` parameters. More
over the names `topLeft`, `bottomRight`, `topRight` and `bottomLeft`
are supported. Instead of setting the values pairwise, one can use
the simple names `top`, `left`, `bottom` and `right` to set the
values separately.
[source,js]
--------------------------------------------------
{
"filtered" : {
"query" : {
"match_all" : {}
},
"filter" : {
"geo_bounding_box" : {
"pin.location" : {
"top" : -74.1,
"left" : 40.73,
"bottom" : -71.12,
"right" : 40.01
}
}
}
}
}
--------------------------------------------------
[float]
==== geo_point Type

View File

@ -169,7 +169,7 @@ itself.
|=======================================================================
|Option |Description
|`unit` |The unit the ranges are provided in. Defaults to `km`. Can also
be `mi`, `miles`, `in`, `inch`, `yd`, `yards`, `kilometers`, `mm`, `millimeters`, `cm`, `centimeters`, `m` or `meters`.
be `mi`, `miles`, `in`, `inch`, `yd`, `yards`, `ft`, `feet`, `kilometers`, `mm`, `millimeters`, `cm`, `centimeters`, `m` or `meters`.
|`distance_type` |How to compute the distance. Can either be `arc`
(better precision), `sloppy_arc` (faster) or `plane` (fastest). Defaults to `sloppy_arc`.

View File

@ -281,22 +281,26 @@ public class GeoHashUtils {
}
}
/**
* Decodes the given geohash
*
* @param geohash Geohash to decocde
* @return {@link GeoPoint} at the center of cell, given by the geohash
*/
public static GeoPoint decode(String geohash) {
GeoPoint point = new GeoPoint();
decode(geohash, point);
return point;
return decode(geohash, new GeoPoint());
}
/**
* Decodes the given geohash into a latitude and longitude
*
* @param geohash Geohash to deocde
* @return Array with the latitude at index 0, and longitude at index 1
* @param geohash Geohash to decocde
* @return the given {@link GeoPoint} reseted to the center of
* cell, given by the geohash
*/
public static void decode(String geohash, GeoPoint ret) {
public static GeoPoint decode(String geohash, GeoPoint ret) {
double[] interval = decodeCell(geohash);
ret.reset((interval[0] + interval[1]) / 2D, (interval[2] + interval[3]) / 2D);
return ret.reset((interval[0] + interval[1]) / 2D, (interval[2] + interval[3]) / 2D);
}
/**

View File

@ -19,13 +19,13 @@
package org.elasticsearch.common.geo;
import java.io.IOException;
import org.elasticsearch.ElasticsearchParseException;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.common.xcontent.XContentParser.Token;
import org.elasticsearch.index.mapper.geo.GeoPointFieldMapper;
import java.io.IOException;
/**
*
*/

View File

@ -137,7 +137,7 @@ public class GeoUtils {
* @return levels need to achieve precision
*/
public static int quadTreeLevelsForPrecision(String distance) {
return quadTreeLevelsForPrecision(DistanceUnit.parse(distance, DistanceUnit.METERS, DistanceUnit.METERS));
return quadTreeLevelsForPrecision(DistanceUnit.METERS.parse(distance, DistanceUnit.DEFAULT));
}
/**
@ -173,7 +173,7 @@ public class GeoUtils {
* @return levels need to achieve precision
*/
public static int geoHashLevelsForPrecision(String distance) {
return geoHashLevelsForPrecision(DistanceUnit.parse(distance, DistanceUnit.METERS, DistanceUnit.METERS));
return geoHashLevelsForPrecision(DistanceUnit.METERS.parse(distance, DistanceUnit.DEFAULT));
}
/**

View File

@ -19,14 +19,13 @@
package org.elasticsearch.common.geo.builders;
import java.io.IOException;
import org.elasticsearch.common.unit.DistanceUnit;
import org.elasticsearch.common.unit.DistanceUnit.Distance;
import org.elasticsearch.common.xcontent.XContentBuilder;
import com.spatial4j.core.shape.Circle;
import com.vividsolutions.jts.geom.Coordinate;
import java.io.IOException;
public class CircleBuilder extends ShapeBuilder {
@ -64,7 +63,7 @@ public class CircleBuilder extends ShapeBuilder {
* @return this
*/
public CircleBuilder radius(String radius) {
return radius(DistanceUnit.Distance.parseDistance(radius, DistanceUnit.METERS));
return radius(DistanceUnit.Distance.parseDistance(radius));
}
/**

View File

@ -19,22 +19,21 @@
package org.elasticsearch.common.geo.builders;
import java.io.IOException;
import org.elasticsearch.common.xcontent.XContentBuilder;
import com.spatial4j.core.shape.Rectangle;
import com.vividsolutions.jts.geom.Coordinate;
import org.elasticsearch.common.xcontent.XContentBuilder;
import java.io.IOException;
public class EnvelopeBuilder extends ShapeBuilder {
public static final GeoShapeType TYPE = GeoShapeType.ENVELOPE;
protected Coordinate northEast;
protected Coordinate southWest;
public EnvelopeBuilder topLeft(Coordinate northEast) {
this.northEast = northEast;
protected Coordinate topLeft;
protected Coordinate bottomRight;
public EnvelopeBuilder topLeft(Coordinate topLeft) {
this.topLeft = topLeft;
return this;
}
@ -42,8 +41,8 @@ public class EnvelopeBuilder extends ShapeBuilder {
return topLeft(coordinate(longitude, latitude));
}
public EnvelopeBuilder bottomRight(Coordinate southWest) {
this.southWest = southWest;
public EnvelopeBuilder bottomRight(Coordinate bottomRight) {
this.bottomRight = bottomRight;
return this;
}
@ -56,17 +55,15 @@ public class EnvelopeBuilder extends ShapeBuilder {
builder.startObject();
builder.field(FIELD_TYPE, TYPE.shapename);
builder.startArray(FIELD_COORDINATES);
toXContent(builder, northEast);
toXContent(builder, southWest);
toXContent(builder, topLeft);
toXContent(builder, bottomRight);
builder.endArray();
return builder.endObject();
}
@Override
public Rectangle build() {
return SPATIAL_CONTEXT.makeRectangle(
northEast.x, southWest.x,
southWest.y, northEast.y);
return SPATIAL_CONTEXT.makeRectangle(topLeft.x, bottomRight.x, bottomRight.y, topLeft.y);
}
@Override

View File

@ -19,14 +19,10 @@
package org.elasticsearch.common.geo.builders;
import java.io.IOException;
import java.util.*;
import org.elasticsearch.ElasticsearchIllegalArgumentException;
import org.elasticsearch.ElasticsearchParseException;
import org.elasticsearch.common.logging.ESLogger;
import org.elasticsearch.common.logging.ESLoggerFactory;
import org.elasticsearch.common.unit.DistanceUnit;
import org.elasticsearch.common.unit.DistanceUnit.Distance;
import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContent;
@ -38,7 +34,12 @@ import com.spatial4j.core.context.jts.JtsSpatialContext;
import com.spatial4j.core.shape.Shape;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.GeometryFactory;
import java.io.IOException;
import java.util.*;
/**
* Basic class for building GeoJSON shapes like Polygons, Linestrings, etc
*/
public abstract class ShapeBuilder implements ToXContent {
protected static final ESLogger LOGGER = ESLoggerFactory.getLogger(ShapeBuilder.class.getName());
@ -541,7 +542,7 @@ public abstract class ShapeBuilder implements ToXContent {
node = parseCoordinates(parser);
} else if (CircleBuilder.FIELD_RADIUS.equals(fieldName)) {
parser.nextToken();
radius = Distance.parseDistance(parser.text(), DistanceUnit.METERS);
radius = Distance.parseDistance(parser.text());
} else {
parser.nextToken();
parser.skipChildren();

View File

@ -30,25 +30,29 @@ import java.io.IOException;
* The DistanceUnit enumerates several units for measuring distances. These units
* provide methods for converting strings and methods to convert units among each
* others. Some methods like {@link DistanceUnit#getEarthCircumference} refer to
* the earth ellipsoid defined in {@link GeoUtils}.
* the earth ellipsoid defined in {@link GeoUtils}. The default unit used within
* this project is <code>METERS</code> which is defined by <code>DEFAULT</code>
*/
public enum DistanceUnit {
INCH(0.0254, "in", "inch"),
YARD(0.9144, "yd", "yards"),
FEET(0.3048, "ft", "feet"),
MILES(1609.344, "mi", "miles"),
KILOMETERS(1000.0, "km", "kilometers"),
MILLIMETERS(0.001, "mm", "millimeters"),
CENTIMETERS(0.01, "cm", "centimeters"),
// since 'm' is suffix of other unit
// it must be the last entry of unit
// names ending with 'm'. otherwise
// parsing would fail
METERS(1, "m", "meters");
METERS(1, "m", "meters");
public static DistanceUnit DEFAULT = METERS;
private double meters;
private final String[] names;
DistanceUnit(double meters, String...names) {
this.meters = meters;
this.names = names;
@ -81,26 +85,6 @@ public enum DistanceUnit {
return GeoUtils.EARTH_EQUATOR / (360.0 * meters);
}
/**
* Convert a value into miles
*
* @param distance distance in this unit
* @return value in miles
*/
public double toMiles(double distance) {
return convert(distance, this, DistanceUnit.MILES);
}
/**
* Convert a value into kilometers
*
* @param distance distance in this unit
* @return value in kilometers
*/
public double toKilometers(double distance) {
return convert(distance, this, DistanceUnit.KILOMETERS);
}
/**
* Convert a value into meters
*
@ -125,11 +109,11 @@ public enum DistanceUnit {
* Convert a given value into another unit
*
* @param distance value in this unit
* @param unit target unit
* @return value of the target unit
* @param unit source unit
* @return value in this unit
*/
public double convert(double distance, DistanceUnit unit) {
return convert(distance, this, unit);
return convert(distance, unit, this);
}
/**
@ -141,7 +125,7 @@ public enum DistanceUnit {
public String toString(double distance) {
return distance + toString();
}
@Override
public String toString() {
return names[0];
@ -176,6 +160,17 @@ public enum DistanceUnit {
return convert(dist.value, dist.unit, to);
}
/**
* Parses a given distance and converts it to this unit.
*
* @param distance String defining a distance (value and unit)
* @param defaultUnit unit to expect if none if provided
* @return parsed distance
*/
public double parse(String distance, DistanceUnit defaultUnit) {
return parse(distance, defaultUnit, this);
}
/**
* Convert a String to a {@link DistanceUnit}
*
@ -296,6 +291,17 @@ public enum DistanceUnit {
return unit.toString(value);
}
/**
* Parse a {@link Distance} from a given String. If no unit is given
* <code>DistanceUnit.DEFAULT</code> will be used
*
* @param distance String defining a {@link Distance}
* @return parsed {@link Distance}
*/
public static Distance parseDistance(String distance) {
return parseDistance(distance, DEFAULT);
}
/**
* Parse a {@link Distance} from a given String
*
@ -304,7 +310,7 @@ public enum DistanceUnit {
* if not unit is provided in the first argument
* @return parsed {@link Distance}
*/
public static Distance parseDistance(String distance, DistanceUnit defaultUnit) {
private static Distance parseDistance(String distance, DistanceUnit defaultUnit) {
for (DistanceUnit unit : values()) {
for (String name : unit.names) {
if(distance.endsWith(name)) {

View File

@ -136,7 +136,6 @@ public abstract class ScriptDocValues {
}
public static class Longs extends ScriptDocValues {
private final LongValues values;
@ -252,7 +251,6 @@ public abstract class ScriptDocValues {
};
}
@Override
public boolean isEmpty() {
return values.setDocument(docId) == 0;
@ -292,7 +290,6 @@ public abstract class ScriptDocValues {
return getValue().lon();
}
public List<GeoPoint> getValues() {
if (!listLoaded) {
int numValues = values.setDocument(docId);
@ -316,7 +313,7 @@ public abstract class ScriptDocValues {
public double factorDistance(double lat, double lon) {
GeoPoint point = getValue();
return GeoDistance.FACTOR.calculate(point.lat(), point.lon(), lat, lon, DistanceUnit.MILES);
return GeoDistance.FACTOR.calculate(point.lat(), point.lon(), lat, lon, DistanceUnit.DEFAULT);
}
public double factorDistanceWithDefault(double lat, double lon, double defaultValue) {
@ -324,22 +321,22 @@ public abstract class ScriptDocValues {
return defaultValue;
}
GeoPoint point = getValue();
return GeoDistance.FACTOR.calculate(point.lat(), point.lon(), lat, lon, DistanceUnit.MILES);
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.MILES) + 1;
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.MILES) + 2;
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.MILES);
return GeoDistance.ARC.calculate(point.lat(), point.lon(), lat, lon, DistanceUnit.DEFAULT);
}
public double arcDistanceWithDefault(double lat, double lon, double defaultValue) {
@ -347,7 +344,7 @@ public abstract class ScriptDocValues {
return defaultValue;
}
GeoPoint point = getValue();
return GeoDistance.ARC.calculate(point.lat(), point.lon(), lat, lon, DistanceUnit.MILES);
return GeoDistance.ARC.calculate(point.lat(), point.lon(), lat, lon, DistanceUnit.DEFAULT);
}
public double arcDistanceInKm(double lat, double lon) {
@ -363,9 +360,22 @@ public abstract class ScriptDocValues {
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 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 distance(double lat, double lon) {
GeoPoint point = getValue();
return GeoDistance.PLANE.calculate(point.lat(), point.lon(), lat, lon, DistanceUnit.MILES);
return GeoDistance.PLANE.calculate(point.lat(), point.lon(), lat, lon, DistanceUnit.DEFAULT);
}
public double distanceWithDefault(double lat, double lon, double defaultValue) {
@ -373,7 +383,7 @@ public abstract class ScriptDocValues {
return defaultValue;
}
GeoPoint point = getValue();
return GeoDistance.PLANE.calculate(point.lat(), point.lon(), lat, lon, DistanceUnit.MILES);
return GeoDistance.PLANE.calculate(point.lat(), point.lon(), lat, lon, DistanceUnit.DEFAULT);
}
public double distanceInKm(double lat, double lon) {
@ -388,5 +398,18 @@ public abstract class ScriptDocValues {
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 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);
}
}
}

View File

@ -56,7 +56,7 @@ public class GeoPointCompressedIndexFieldData extends AbstractGeoPointIndexField
final String precisionAsString = type.getSettings().get(PRECISION_KEY);
final Distance precision;
if (precisionAsString != null) {
precision = Distance.parseDistance(precisionAsString, DistanceUnit.METERS);
precision = Distance.parseDistance(precisionAsString);
} else {
precision = DEFAULT_PRECISION_VALUE;
}

View File

@ -298,11 +298,11 @@ public class GeoPointFieldMapper extends AbstractFieldMapper<GeoPoint> implement
assert (1L << (numBytesPerCoordinate * 8 - 1)) * factor > 180 && (1L << (numBytesPerCoordinate * 8 - 2)) * factor < 180 : numBytesPerCoordinate + " " + factor;
if (numBytes == MAX_NUM_BYTES) {
// no precision loss compared to a double
precision = new DistanceUnit.Distance(0, DistanceUnit.METERS);
precision = new DistanceUnit.Distance(0, DistanceUnit.DEFAULT);
} else {
precision = new DistanceUnit.Distance(
GeoDistance.PLANE.calculate(0, 0, factor / 2, factor / 2, DistanceUnit.METERS), // factor/2 because we use Math.round instead of a cast to convert the double to a long
DistanceUnit.METERS);
GeoDistance.PLANE.calculate(0, 0, factor / 2, factor / 2, DistanceUnit.DEFAULT), // factor/2 because we use Math.round instead of a cast to convert the double to a long
DistanceUnit.DEFAULT);
}
}

View File

@ -179,7 +179,7 @@ public class GeoShapeFieldMapper extends AbstractFieldMapper<String> {
} else if (Names.TREE_LEVELS.equals(fieldName)) {
builder.treeLevels(Integer.parseInt(fieldNode.toString()));
} else if (Names.TREE_PRESISION.equals(fieldName)) {
builder.treeLevelsByDistance(DistanceUnit.parse(fieldNode.toString(), DistanceUnit.METERS, DistanceUnit.METERS));
builder.treeLevelsByDistance(DistanceUnit.parse(fieldNode.toString(), DistanceUnit.DEFAULT, DistanceUnit.DEFAULT));
} else if (Names.DISTANCE_ERROR_PCT.equals(fieldName)) {
builder.distanceErrorPct(Double.parseDouble(fieldNode.toString()));
} else if (Names.STRATEGY.equals(fieldName)) {

View File

@ -31,21 +31,22 @@ import java.io.IOException;
*/
public class GeoBoundingBoxFilterBuilder extends BaseFilterBuilder {
public static final String TOP_LEFT = GeoBoundingBoxFilterParser.TOP_LEFT;
public static final String BOTTOM_RIGHT = GeoBoundingBoxFilterParser.BOTTOM_RIGHT;
private static final int TOP = 0;
private static final int LEFT = 1;
private static final int BOTTOM = 2;
private static final int RIGHT = 3;
private final String name;
private GeoPoint topLeft;
private String topLeftGeohash;
private GeoPoint bottomRight;
private String bottomRightGeohash;
private double[] box = {Double.NaN, Double.NaN, Double.NaN, Double.NaN};
private Boolean cache;
private String cacheKey;
private String filterName;
private String type;
public GeoBoundingBoxFilterBuilder(String name) {
@ -59,43 +60,78 @@ public class GeoBoundingBoxFilterBuilder extends BaseFilterBuilder {
* @param lon The longitude
*/
public GeoBoundingBoxFilterBuilder topLeft(double lat, double lon) {
topLeft = new GeoPoint(lat, lon);
box[TOP] = lat;
box[LEFT] = lon;
return this;
}
public GeoBoundingBoxFilterBuilder topLeft(GeoPoint point) {
return topLeft(point.lat(), point.lon());
}
public GeoBoundingBoxFilterBuilder topLeft(String geohash) {
return topLeft(GeoHashUtils.decode(geohash));
}
/**
* Adds bottom right point.
* Adds bottom right corner.
*
* @param lat The latitude
* @param lon The longitude
*/
public GeoBoundingBoxFilterBuilder bottomRight(double lat, double lon) {
bottomRight = new GeoPoint(lat, lon);
box[BOTTOM] = lat;
box[RIGHT] = lon;
return this;
}
public GeoBoundingBoxFilterBuilder topLeft(String geohash) {
this.topLeftGeohash = geohash;
return this;
public GeoBoundingBoxFilterBuilder bottomRight(GeoPoint point) {
return bottomRight(point.lat(), point.lon());
}
public GeoBoundingBoxFilterBuilder bottomRight(String geohash) {
this.bottomRightGeohash = geohash;
return this;
return bottomRight(GeoHashUtils.decode(geohash));
}
/**
* Adds top left and bottom right by geohash cell.
* Adds bottom left corner.
*
* @param geohash the geohash of the cell definign the boundingbox
* @param lat The latitude
* @param lon The longitude
*/
public GeoBoundingBoxFilterBuilder geohash(String geohash) {
topLeft = new GeoPoint();
bottomRight = new GeoPoint();
GeoHashUtils.decodeCell(geohash, topLeft, bottomRight);
public GeoBoundingBoxFilterBuilder bottomLeft(double lat, double lon) {
box[BOTTOM] = lat;
box[LEFT] = lon;
return this;
}
public GeoBoundingBoxFilterBuilder bottomLeft(GeoPoint point) {
return bottomLeft(point.lat(), point.lon());
}
public GeoBoundingBoxFilterBuilder bottomLeft(String geohash) {
return bottomLeft(GeoHashUtils.decode(geohash));
}
/**
* Adds top right point.
*
* @param lat The latitude
* @param lon The longitude
*/
public GeoBoundingBoxFilterBuilder topRight(double lat, double lon) {
box[TOP] = lat;
box[RIGHT] = lon;
return this;
}
public GeoBoundingBoxFilterBuilder topRight(GeoPoint point) {
return topRight(point.lat(), point.lon());
}
public GeoBoundingBoxFilterBuilder topRight(String geohash) {
return topRight(GeoHashUtils.decode(geohash));
}
/**
* Sets the filter name for the filter that can be used when searching for matched_filters per hit.
@ -129,24 +165,22 @@ public class GeoBoundingBoxFilterBuilder extends BaseFilterBuilder {
@Override
protected void doXContent(XContentBuilder builder, Params params) throws IOException {
// check values
if(Double.isNaN(box[TOP])) {
throw new ElasticsearchIllegalArgumentException("geo_bounding_box requires top latitude to be set");
} else if(Double.isNaN(box[BOTTOM])) {
throw new ElasticsearchIllegalArgumentException("geo_bounding_box requires bottom latitude to be set");
} else if(Double.isNaN(box[RIGHT])) {
throw new ElasticsearchIllegalArgumentException("geo_bounding_box requires right longitude to be set");
} else if(Double.isNaN(box[LEFT])) {
throw new ElasticsearchIllegalArgumentException("geo_bounding_box requires left longitude to be set");
}
builder.startObject(GeoBoundingBoxFilterParser.NAME);
builder.startObject(name);
if (topLeftGeohash != null) {
builder.field("top_left", topLeftGeohash);
} else if (topLeft != null) {
builder.startArray("top_left").value(topLeft.lon()).value(topLeft.lat()).endArray();
} else {
throw new ElasticsearchIllegalArgumentException("geo_bounding_box requires 'top_left' to be set");
}
if (bottomRightGeohash != null) {
builder.field("bottom_right", bottomRightGeohash);
} else if (bottomRight != null) {
builder.startArray("bottom_right").value(bottomRight.lon()).value(bottomRight.lat()).endArray();
} else {
throw new ElasticsearchIllegalArgumentException("geo_bounding_box requires 'bottom_right' to be set");
}
builder.array(TOP_LEFT, box[LEFT], box[TOP]);
builder.array(BOTTOM_RIGHT, box[RIGHT], box[BOTTOM]);
builder.endObject();
if (filterName != null) {

View File

@ -42,11 +42,22 @@ import static org.elasticsearch.index.query.support.QueryParsers.wrapSmartNameFi
*/
public class GeoBoundingBoxFilterParser implements FilterParser {
public static final String NAME = "geo_bbox";
public static final String TOP_LEFT = "top_left";
public static final String TOP = "top";
public static final String LEFT = "left";
public static final String RIGHT = "right";
public static final String BOTTOM = "bottom";
public static final String TOP_LEFT = TOP + "_" + LEFT;
public static final String TOP_RIGHT = TOP + "_" + RIGHT;
public static final String BOTTOM_LEFT = BOTTOM + "_" + LEFT;
public static final String BOTTOM_RIGHT = BOTTOM + "_" + RIGHT;
public static final String TOPLEFT = "topLeft";
public static final String BOTTOM_RIGHT = "bottom_right";
public static final String TOPRIGHT = "topRight";
public static final String BOTTOMLEFT = "bottomLeft";
public static final String BOTTOMRIGHT = "bottomRight";
public static final String NAME = "geo_bbox";
public static final String FIELD = "field";
@Inject
@ -65,14 +76,19 @@ public class GeoBoundingBoxFilterParser implements FilterParser {
boolean cache = false;
CacheKeyFilter.Key cacheKey = null;
String fieldName = null;
GeoPoint topLeft = new GeoPoint();
GeoPoint bottomRight = new GeoPoint();
double top = Double.NaN;
double bottom = Double.NaN;
double left = Double.NaN;
double right = Double.NaN;
String filterName = null;
String currentFieldName = null;
XContentParser.Token token;
boolean normalize = true;
GeoPoint sparse = new GeoPoint();
String type = "memory";
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
@ -87,12 +103,34 @@ public class GeoBoundingBoxFilterParser implements FilterParser {
token = parser.nextToken();
if (FIELD.equals(currentFieldName)) {
fieldName = parser.text();
} else if (TOP_LEFT.equals(currentFieldName) || TOPLEFT.equals(currentFieldName)) {
GeoPoint.parse(parser, topLeft);
} else if ( BOTTOM_RIGHT.equals(currentFieldName) || BOTTOMRIGHT.equals(currentFieldName)) {
GeoPoint.parse(parser, bottomRight);
} else if (TOP.equals(currentFieldName)) {
top = parser.doubleValue();
} else if (BOTTOM.equals(currentFieldName)) {
bottom = parser.doubleValue();
} else if (LEFT.equals(currentFieldName)) {
left = parser.doubleValue();
} else if (RIGHT.equals(currentFieldName)) {
right = parser.doubleValue();
} else {
throw new ElasticsearchParseException("Unexpected field [" + currentFieldName + "]");
if (TOP_LEFT.equals(currentFieldName) || TOPLEFT.equals(currentFieldName)) {
GeoPoint.parse(parser, sparse);
top = sparse.getLat();
left = sparse.getLon();
} else if (BOTTOM_RIGHT.equals(currentFieldName) || BOTTOMRIGHT.equals(currentFieldName)) {
GeoPoint.parse(parser, sparse);
bottom = sparse.getLat();
right = sparse.getLon();
} else if (TOP_RIGHT.equals(currentFieldName) || TOPRIGHT.equals(currentFieldName)) {
GeoPoint.parse(parser, sparse);
top = sparse.getLat();
right = sparse.getLon();
} else if (BOTTOM_LEFT.equals(currentFieldName) || BOTTOMLEFT.equals(currentFieldName)) {
GeoPoint.parse(parser, sparse);
bottom = sparse.getLat();
left = sparse.getLon();
} else {
throw new ElasticsearchParseException("Unexpected field [" + currentFieldName + "]");
}
}
} else {
throw new ElasticsearchParseException("fieldname expected but [" + token + "] found");
@ -115,6 +153,9 @@ public class GeoBoundingBoxFilterParser implements FilterParser {
}
}
final GeoPoint topLeft = sparse.reset(top, left); //just keep the object
final GeoPoint bottomRight = new GeoPoint(bottom, right);
if (normalize) {
GeoUtils.normalizePoint(topLeft);
GeoUtils.normalizePoint(bottomRight);
@ -148,5 +189,5 @@ public class GeoBoundingBoxFilterParser implements FilterParser {
parseContext.addNamedFilter(filterName, filter);
}
return filter;
}
}
}

View File

@ -73,7 +73,7 @@ public class GeoDistanceFilterParser implements FilterParser {
String fieldName = null;
double distance = 0;
Object vDistance = null;
DistanceUnit unit = DistanceUnit.KILOMETERS; // default unit
DistanceUnit unit = DistanceUnit.DEFAULT;
GeoDistance geoDistance = GeoDistance.DEFAULT;
String optimizeBbox = "memory";
boolean normalizeLon = true;
@ -142,11 +142,11 @@ public class GeoDistanceFilterParser implements FilterParser {
}
if (vDistance instanceof Number) {
distance = unit.toMiles(((Number) vDistance).doubleValue());
distance = DistanceUnit.DEFAULT.convert(((Number) vDistance).doubleValue(), unit);
} else {
distance = DistanceUnit.parse((String) vDistance, unit, DistanceUnit.MILES);
distance = DistanceUnit.parse((String) vDistance, unit, DistanceUnit.DEFAULT);
}
distance = geoDistance.normalize(distance, DistanceUnit.MILES);
distance = geoDistance.normalize(distance, DistanceUnit.DEFAULT);
if (normalizeLat || normalizeLon) {
GeoUtils.normalizePoint(point, normalizeLat, normalizeLon);

View File

@ -75,7 +75,7 @@ public class GeoDistanceRangeFilterParser implements FilterParser {
Object vTo = null;
boolean includeLower = true;
boolean includeUpper = true;
DistanceUnit unit = DistanceUnit.KILOMETERS; // default unit
DistanceUnit unit = DistanceUnit.DEFAULT;
GeoDistance geoDistance = GeoDistance.DEFAULT;
String optimizeBbox = "memory";
boolean normalizeLon = true;
@ -176,19 +176,19 @@ public class GeoDistanceRangeFilterParser implements FilterParser {
Double to = null;
if (vFrom != null) {
if (vFrom instanceof Number) {
from = unit.toMiles(((Number) vFrom).doubleValue());
from = unit.toMeters(((Number) vFrom).doubleValue());
} else {
from = DistanceUnit.parse((String) vFrom, unit, DistanceUnit.MILES);
from = DistanceUnit.parse((String) vFrom, unit, DistanceUnit.DEFAULT);
}
from = geoDistance.normalize(from, DistanceUnit.MILES);
from = geoDistance.normalize(from, DistanceUnit.DEFAULT);
}
if (vTo != null) {
if (vTo instanceof Number) {
to = unit.toMiles(((Number) vTo).doubleValue());
to = unit.toMeters(((Number) vTo).doubleValue());
} else {
to = DistanceUnit.parse((String) vTo, unit, DistanceUnit.MILES);
to = DistanceUnit.parse((String) vTo, unit, DistanceUnit.DEFAULT);
}
to = geoDistance.normalize(to, DistanceUnit.MILES);
to = geoDistance.normalize(to, DistanceUnit.DEFAULT);
}
if (normalizeLat || normalizeLon) {

View File

@ -32,9 +32,11 @@ import java.util.List;
*/
public class GeoPolygonFilterBuilder extends BaseFilterBuilder {
public static final String POINTS = GeoPolygonFilterParser.POINTS;
private final String name;
private final List<GeoPoint> points = Lists.newArrayList();
private final List<GeoPoint> shell = Lists.newArrayList();
private Boolean cache;
private String cacheKey;
@ -53,15 +55,18 @@ public class GeoPolygonFilterBuilder extends BaseFilterBuilder {
* @return
*/
public GeoPolygonFilterBuilder addPoint(double lat, double lon) {
points.add(new GeoPoint(lat, lon));
return this;
return addPoint(new GeoPoint(lat, lon));
}
public GeoPolygonFilterBuilder addPoint(String geohash) {
points.add(GeoHashUtils.decode(geohash));
return this;
return addPoint(GeoHashUtils.decode(geohash));
}
public GeoPolygonFilterBuilder addPoint(GeoPoint point) {
shell.add(point);
return this;
}
/**
* Sets the filter name for the filter that can be used when searching for matched_filters per hit.
*/
@ -88,8 +93,8 @@ public class GeoPolygonFilterBuilder extends BaseFilterBuilder {
builder.startObject(GeoPolygonFilterParser.NAME);
builder.startObject(name);
builder.startArray("points");
for (GeoPoint point : points) {
builder.startArray(POINTS);
for (GeoPoint point : shell) {
builder.startArray().value(point.lon()).value(point.lat()).endArray();
}
builder.endArray();

View File

@ -25,6 +25,7 @@ import org.elasticsearch.common.geo.GeoPoint;
import org.elasticsearch.common.geo.GeoUtils;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.common.xcontent.XContentParser.Token;
import org.elasticsearch.index.cache.filter.support.CacheKeyFilter;
import org.elasticsearch.index.fielddata.IndexGeoPointFieldData;
import org.elasticsearch.index.mapper.FieldMapper;
@ -52,6 +53,7 @@ import static org.elasticsearch.index.query.support.QueryParsers.wrapSmartNameFi
public class GeoPolygonFilterParser implements FilterParser {
public static final String NAME = "geo_polygon";
public static final String POINTS = "points";
@Inject
public GeoPolygonFilterParser() {
@ -69,7 +71,8 @@ public class GeoPolygonFilterParser implements FilterParser {
boolean cache = false;
CacheKeyFilter.Key cacheKey = null;
String fieldName = null;
List<GeoPoint> points = Lists.newArrayList();
List<GeoPoint> shell = Lists.newArrayList();
boolean normalizeLon = true;
boolean normalizeLat = true;
@ -88,9 +91,9 @@ public class GeoPolygonFilterParser implements FilterParser {
if (token == XContentParser.Token.FIELD_NAME) {
currentFieldName = parser.currentName();
} else if (token == XContentParser.Token.START_ARRAY) {
if ("points".equals(currentFieldName)) {
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
points.add(GeoPoint.parse(parser));
if(POINTS.equals(currentFieldName)) {
while((token = parser.nextToken()) != Token.END_ARRAY) {
shell.add(GeoPoint.parse(parser));
}
} else {
throw new QueryParsingException(parseContext.index(), "[geo_polygon] filter does not support [" + currentFieldName + "]");
@ -113,12 +116,23 @@ public class GeoPolygonFilterParser implements FilterParser {
}
}
if (points.isEmpty()) {
if (shell.isEmpty()) {
throw new QueryParsingException(parseContext.index(), "no points defined for geo_polygon filter");
} else {
if(shell.size() < 3) {
throw new QueryParsingException(parseContext.index(), "to few points defined for geo_polygon filter");
}
GeoPoint start = shell.get(0);
if(!start.equals(shell.get(shell.size()-1))) {
shell.add(start);
}
if(shell.size() < 4) {
throw new QueryParsingException(parseContext.index(), "to few points defined for geo_polygon filter");
}
}
if (normalizeLat || normalizeLon) {
for (GeoPoint point : points) {
for (GeoPoint point : shell) {
GeoUtils.normalizePoint(point, normalizeLat, normalizeLon);
}
}
@ -133,7 +147,7 @@ public class GeoPolygonFilterParser implements FilterParser {
}
IndexGeoPointFieldData<?> indexFieldData = parseContext.fieldData().getForField(mapper);
Filter filter = new GeoPolygonFilter(points.toArray(new GeoPoint[points.size()]), indexFieldData);
Filter filter = new GeoPolygonFilter(indexFieldData, shell.toArray(new GeoPoint[shell.size()]));
if (cache) {
filter = parseContext.cacheFilter(filter, cacheKey);
}

View File

@ -170,7 +170,6 @@ public class GeoShapeFilterParser implements FilterParser {
throw new QueryParsingException(parseContext.index(), "Field [" + fieldName + "] is not a geo_shape");
}
GeoShapeFieldMapper shapeFieldMapper = (GeoShapeFieldMapper) fieldMapper;
PrefixTreeStrategy strategy = shapeFieldMapper.defaultStrategy();
if (strategyName != null) {

View File

@ -140,7 +140,7 @@ public class GeohashCellFilter {
}
public Builder precision(String precision) {
double meters = DistanceUnit.parse(precision, DistanceUnit.METERS, DistanceUnit.METERS);
double meters = DistanceUnit.parse(precision, DistanceUnit.DEFAULT, DistanceUnit.METERS);
return precision(GeoUtils.geoHashLevelsForPrecision(meters));
}
@ -203,7 +203,7 @@ public class GeohashCellFilter {
if(token == Token.VALUE_NUMBER) {
levels = parser.intValue();
} else if(token == Token.VALUE_STRING) {
double meters = DistanceUnit.parse(parser.text(), DistanceUnit.METERS, DistanceUnit.METERS);
double meters = DistanceUnit.parse(parser.text(), DistanceUnit.DEFAULT, DistanceUnit.METERS);
levels = GeoUtils.geoHashLevelsForPrecision(meters);
}
} else if (NEIGHBORS.equals(field)) {

View File

@ -218,8 +218,8 @@ public abstract class DecayFunctionParser implements ScoreFunctionParser {
if (origin == null || scaleString == null) {
throw new ElasticsearchParseException(DecayFunctionBuilder.ORIGIN + " and " + DecayFunctionBuilder.SCALE + " must be set for geo fields.");
}
double scale = DistanceUnit.parse(scaleString, DistanceUnit.METERS, DistanceUnit.METERS);
double offset = DistanceUnit.parse(offsetString, DistanceUnit.METERS, DistanceUnit.METERS);
double scale = DistanceUnit.DEFAULT.parse(scaleString, DistanceUnit.DEFAULT);
double offset = DistanceUnit.DEFAULT.parse(offsetString, DistanceUnit.DEFAULT);
IndexGeoPointFieldData<?> indexFieldData = parseContext.fieldData().getForField(mapper);
return new GeoFieldDataScoreFunction(origin, scale, decay, offset, getDecayFunction(), indexFieldData);

View File

@ -63,9 +63,9 @@ public class GeoDistanceFilter extends Filter {
this.geoDistance = geoDistance;
this.indexFieldData = indexFieldData;
this.fixedSourceDistance = geoDistance.fixedSourceDistance(lat, lon, DistanceUnit.MILES);
this.fixedSourceDistance = geoDistance.fixedSourceDistance(lat, lon, DistanceUnit.DEFAULT);
if (optimizeBbox != null && !"none".equals(optimizeBbox)) {
distanceBoundingCheck = GeoDistance.distanceBoundingCheck(lat, lon, distance, DistanceUnit.MILES);
distanceBoundingCheck = GeoDistance.distanceBoundingCheck(lat, lon, distance, DistanceUnit.DEFAULT);
if ("memory".equals(optimizeBbox)) {
boundingBoxFilter = null;
} else if ("indexed".equals(optimizeBbox)) {

View File

@ -46,8 +46,8 @@ public class GeoDistanceRangeFilter extends Filter {
private final double lat;
private final double lon;
private final double inclusiveLowerPoint; // in miles
private final double inclusiveUpperPoint; // in miles
private final double inclusiveLowerPoint; // in meters
private final double inclusiveUpperPoint; // in meters
private final GeoDistance geoDistance;
private final GeoDistance.FixedSourceDistance fixedSourceDistance;
@ -63,7 +63,7 @@ public class GeoDistanceRangeFilter extends Filter {
this.geoDistance = geoDistance;
this.indexFieldData = indexFieldData;
this.fixedSourceDistance = geoDistance.fixedSourceDistance(lat, lon, DistanceUnit.MILES);
this.fixedSourceDistance = geoDistance.fixedSourceDistance(lat, lon, DistanceUnit.DEFAULT);
if (lowerVal != null) {
double f = lowerVal.doubleValue();
@ -85,7 +85,7 @@ public class GeoDistanceRangeFilter extends Filter {
}
if (optimizeBbox != null && !"none".equals(optimizeBbox)) {
distanceBoundingCheck = GeoDistance.distanceBoundingCheck(lat, lon, inclusiveUpperPoint, DistanceUnit.MILES);
distanceBoundingCheck = GeoDistance.distanceBoundingCheck(lat, lon, inclusiveUpperPoint, DistanceUnit.DEFAULT);
if ("memory".equals(optimizeBbox)) {
boundingBoxFilter = null;
} else if ("indexed".equals(optimizeBbox)) {

View File

@ -41,7 +41,7 @@ public class GeoPolygonFilter extends Filter {
private final IndexGeoPointFieldData indexFieldData;
public GeoPolygonFilter(GeoPoint[] points, IndexGeoPointFieldData indexFieldData) {
public GeoPolygonFilter(IndexGeoPointFieldData indexFieldData, GeoPoint...points) {
this.points = points;
this.indexFieldData = indexFieldData;
}
@ -62,7 +62,10 @@ public class GeoPolygonFilter extends Filter {
@Override
public String toString() {
return "GeoPolygonFilter(" + indexFieldData.getFieldNames().indexName() + ", " + Arrays.toString(points) + ")";
StringBuilder sb = new StringBuilder("GeoPolygonFilter(");
sb.append(indexFieldData.getFieldNames().indexName());
sb.append(", ").append(Arrays.toString(points)).append(')');
return sb.toString();
}
public static class GeoPolygonDocIdSet extends MatchDocIdSet {
@ -93,19 +96,16 @@ public class GeoPolygonFilter extends Filter {
}
private static boolean pointInPolygon(GeoPoint[] points, double lat, double lon) {
int i;
int j = points.length - 1;
boolean inPoly = false;
for (i = 0; i < points.length; i++) {
if (points[i].lon() < lon && points[j].lon() >= lon
|| points[j].lon() < lon && points[i].lon() >= lon) {
for (int i = 1; i < points.length; i++) {
if (points[i].lon() < lon && points[i-1].lon() >= lon
|| points[i-1].lon() < lon && points[i].lon() >= lon) {
if (points[i].lat() + (lon - points[i].lon()) /
(points[j].lon() - points[i].lon()) * (points[j].lat() - points[i].lat()) < lat) {
(points[i-1].lon() - points[i].lon()) * (points[i-1].lat() - points[i].lat()) < lat) {
inPoly = !inPoly;
}
}
j = i;
}
return inPoly;
}

View File

@ -41,19 +41,19 @@ public class IndexedGeoBoundingBoxFilter {
}
//checks to see if bounding box crosses 180 degrees
if (topLeft.lon() > bottomRight.lon()) {
return new LeftGeoBoundingBoxFilter(topLeft, bottomRight, fieldMapper);
return new WestGeoBoundingBoxFilter(topLeft, bottomRight, fieldMapper);
} else {
return new RightGeoBoundingBoxFilter(topLeft, bottomRight, fieldMapper);
return new EastGeoBoundingBoxFilter(topLeft, bottomRight, fieldMapper);
}
}
static class LeftGeoBoundingBoxFilter extends Filter {
static class WestGeoBoundingBoxFilter extends Filter {
final Filter lonFilter1;
final Filter lonFilter2;
final Filter latFilter;
public LeftGeoBoundingBoxFilter(GeoPoint topLeft, GeoPoint bottomRight, GeoPointFieldMapper fieldMapper) {
public WestGeoBoundingBoxFilter(GeoPoint topLeft, GeoPoint bottomRight, GeoPointFieldMapper fieldMapper) {
lonFilter1 = fieldMapper.lonMapper().rangeFilter(null, bottomRight.lon(), true, true);
lonFilter2 = fieldMapper.lonMapper().rangeFilter(topLeft.lon(), null, true, true);
latFilter = fieldMapper.latMapper().rangeFilter(bottomRight.lat(), topLeft.lat(), true, true);
@ -97,7 +97,7 @@ public class IndexedGeoBoundingBoxFilter {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
LeftGeoBoundingBoxFilter that = (LeftGeoBoundingBoxFilter) o;
WestGeoBoundingBoxFilter that = (WestGeoBoundingBoxFilter) o;
if (latFilter != null ? !latFilter.equals(that.latFilter) : that.latFilter != null) return false;
if (lonFilter1 != null ? !lonFilter1.equals(that.lonFilter1) : that.lonFilter1 != null) return false;
@ -115,12 +115,12 @@ public class IndexedGeoBoundingBoxFilter {
}
}
static class RightGeoBoundingBoxFilter extends Filter {
static class EastGeoBoundingBoxFilter extends Filter {
final Filter lonFilter;
final Filter latFilter;
public RightGeoBoundingBoxFilter(GeoPoint topLeft, GeoPoint bottomRight, GeoPointFieldMapper fieldMapper) {
public EastGeoBoundingBoxFilter(GeoPoint topLeft, GeoPoint bottomRight, GeoPointFieldMapper fieldMapper) {
lonFilter = fieldMapper.lonMapper().rangeFilter(topLeft.lon(), bottomRight.lon(), true, true);
latFilter = fieldMapper.latMapper().rangeFilter(bottomRight.lat(), topLeft.lat(), true, true);
}
@ -146,7 +146,7 @@ public class IndexedGeoBoundingBoxFilter {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
RightGeoBoundingBoxFilter that = (RightGeoBoundingBoxFilter) o;
EastGeoBoundingBoxFilter that = (EastGeoBoundingBoxFilter) o;
if (latFilter != null ? !latFilter.equals(that.latFilter) : that.latFilter != null) return false;
if (lonFilter != null ? !lonFilter.equals(that.lonFilter) : that.lonFilter != null) return false;

View File

@ -66,7 +66,7 @@ public class GeoDistanceParser implements Aggregator.Parser {
String field = null;
List<RangeAggregator.Range> ranges = null;
GeoPoint origin = null;
DistanceUnit unit = DistanceUnit.KILOMETERS;
DistanceUnit unit = DistanceUnit.DEFAULT;
GeoDistance distanceType = GeoDistance.DEFAULT;
boolean keyed = false;

View File

@ -73,7 +73,7 @@ public class GeoDistanceFacetParser extends AbstractComponent implements FacetPa
String scriptLang = null;
Map<String, Object> params = null;
GeoPoint point = new GeoPoint();
DistanceUnit unit = DistanceUnit.KILOMETERS;
DistanceUnit unit = DistanceUnit.DEFAULT;
GeoDistance geoDistance = GeoDistance.DEFAULT;
List<GeoDistanceFacet.Entry> entries = Lists.newArrayList();

View File

@ -53,7 +53,7 @@ public class GeoDistanceSortParser implements SortParser {
public SortField parse(XContentParser parser, SearchContext context) throws Exception {
String fieldName = null;
GeoPoint point = new GeoPoint();
DistanceUnit unit = DistanceUnit.KILOMETERS;
DistanceUnit unit = DistanceUnit.DEFAULT;
GeoDistance geoDistance = GeoDistance.DEFAULT;
boolean reverse = false;
SortMode sortMode = null;

View File

@ -22,7 +22,6 @@ package org.elasticsearch.common.unit;
import org.elasticsearch.test.ElasticsearchTestCase;
import org.junit.Test;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.closeTo;
import static org.hamcrest.Matchers.equalTo;
@ -33,30 +32,30 @@ public class DistanceUnitTests extends ElasticsearchTestCase {
@Test
public void testSimpleDistanceUnit() {
assertThat(DistanceUnit.MILES.toKilometers(10), closeTo(16.09344, 0.001));
assertThat(DistanceUnit.MILES.toMiles(10), closeTo(10, 0.001));
assertThat(DistanceUnit.KILOMETERS.toMiles(10), closeTo(6.21371192, 0.001));
assertThat(DistanceUnit.KILOMETERS.toKilometers(10), closeTo(10, 0.001));
assertThat(DistanceUnit.METERS.toKilometers(10), closeTo(0.01, 0.00001));
assertThat(DistanceUnit.METERS.toKilometers(1000), closeTo(1, 0.001));
assertThat(DistanceUnit.KILOMETERS.toMeters(1), closeTo(1000, 0.001));
assertThat(DistanceUnit.KILOMETERS.convert(10, DistanceUnit.MILES), closeTo(16.09344, 0.001));
assertThat(DistanceUnit.MILES.convert(10, DistanceUnit.MILES), closeTo(10, 0.001));
assertThat(DistanceUnit.MILES.convert(10, DistanceUnit.KILOMETERS), closeTo(6.21371192, 0.001));
assertThat(DistanceUnit.KILOMETERS.convert(10, DistanceUnit.KILOMETERS), closeTo(10, 0.001));
assertThat(DistanceUnit.KILOMETERS.convert(10, DistanceUnit.METERS), closeTo(0.01, 0.00001));
assertThat(DistanceUnit.KILOMETERS.convert(1000,DistanceUnit.METERS), closeTo(1, 0.001));
assertThat(DistanceUnit.METERS.convert(1, DistanceUnit.KILOMETERS), closeTo(1000, 0.001));
}
@Test
public void testDistanceUnitParsing() {
assertThat(DistanceUnit.Distance.parseDistance("50km", null).unit, equalTo(DistanceUnit.KILOMETERS));
assertThat(DistanceUnit.Distance.parseDistance("500m", null).unit, equalTo(DistanceUnit.METERS));
assertThat(DistanceUnit.Distance.parseDistance("51mi", null).unit, equalTo(DistanceUnit.MILES));
assertThat(DistanceUnit.Distance.parseDistance("52yd", null).unit, equalTo(DistanceUnit.YARD));
assertThat(DistanceUnit.Distance.parseDistance("12in", null).unit, equalTo(DistanceUnit.INCH));
assertThat(DistanceUnit.Distance.parseDistance("23mm", null).unit, equalTo(DistanceUnit.MILLIMETERS));
assertThat(DistanceUnit.Distance.parseDistance("23cm", null).unit, equalTo(DistanceUnit.CENTIMETERS));
assertThat(DistanceUnit.Distance.parseDistance("50km").unit, equalTo(DistanceUnit.KILOMETERS));
assertThat(DistanceUnit.Distance.parseDistance("500m").unit, equalTo(DistanceUnit.METERS));
assertThat(DistanceUnit.Distance.parseDistance("51mi").unit, equalTo(DistanceUnit.MILES));
assertThat(DistanceUnit.Distance.parseDistance("52yd").unit, equalTo(DistanceUnit.YARD));
assertThat(DistanceUnit.Distance.parseDistance("12in").unit, equalTo(DistanceUnit.INCH));
assertThat(DistanceUnit.Distance.parseDistance("23mm").unit, equalTo(DistanceUnit.MILLIMETERS));
assertThat(DistanceUnit.Distance.parseDistance("23cm").unit, equalTo(DistanceUnit.CENTIMETERS));
double testValue = 12345.678;
for (DistanceUnit unit : DistanceUnit.values()) {
assertThat("Unit can be parsed from '" + unit.toString() + "'", DistanceUnit.fromString(unit.toString()), equalTo(unit));
assertThat("Unit can be parsed from '" + testValue + unit.toString() + "'", DistanceUnit.fromString(unit.toString()), equalTo(unit));
assertThat("Value can be parsed from '" + testValue + unit.toString() + "'", DistanceUnit.Distance.parseDistance(unit.toString(testValue), null).value, equalTo(testValue));
assertThat("Value can be parsed from '" + testValue + unit.toString() + "'", DistanceUnit.Distance.parseDistance(unit.toString(testValue)).value, equalTo(testValue));
}
}

View File

@ -71,7 +71,7 @@ public class GeoMappingTests extends ElasticsearchIntegrationTest {
Map<String, ?> properties = (Map<String, ?>) mappings.get("test").get("type1").getSourceAsMap().get("properties");
Map<String, ?> pinProperties = (Map<String, ?>) properties.get("pin");
Map<String, ?> pinFieldData = (Map<String, ?>) pinProperties.get("fielddata");
Distance precision = Distance.parseDistance(pinFieldData.get("precision").toString(), DistanceUnit.METERS);
Distance precision = Distance.parseDistance(pinFieldData.get("precision").toString());
assertEquals(expected, precision);
}

View File

@ -43,6 +43,7 @@ import org.elasticsearch.common.lucene.search.function.FunctionScoreQuery;
import org.elasticsearch.common.settings.ImmutableSettings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.settings.SettingsModule;
import org.elasticsearch.common.unit.DistanceUnit;
import org.elasticsearch.common.unit.Fuzziness;
import org.elasticsearch.index.Index;
import org.elasticsearch.index.IndexNameModule;
@ -60,10 +61,10 @@ import org.elasticsearch.index.search.geo.GeoPolygonFilter;
import org.elasticsearch.index.search.geo.InMemoryGeoBoundingBoxFilter;
import org.elasticsearch.index.settings.IndexSettingsModule;
import org.elasticsearch.index.similarity.SimilarityModule;
import org.elasticsearch.indices.query.IndicesQueriesModule;
import org.elasticsearch.script.ScriptModule;
import org.elasticsearch.indices.fielddata.breaker.CircuitBreakerService;
import org.elasticsearch.indices.fielddata.breaker.DummyCircuitBreakerService;
import org.elasticsearch.indices.query.IndicesQueriesModule;
import org.elasticsearch.script.ScriptModule;
import org.elasticsearch.test.ElasticsearchTestCase;
import org.elasticsearch.threadpool.ThreadPool;
import org.elasticsearch.threadpool.ThreadPoolModule;
@ -1768,7 +1769,7 @@ public class SimpleIndexQueryParserTests extends ElasticsearchTestCase {
assertThat(filter.fieldName(), equalTo("location"));
assertThat(filter.lat(), closeTo(40, 0.00001));
assertThat(filter.lon(), closeTo(-70, 0.00001));
assertThat(filter.distance(), closeTo(12, 0.00001));
assertThat(filter.distance(), closeTo(DistanceUnit.DEFAULT.convert(12, DistanceUnit.MILES), 0.00001));
}
@Test
@ -1782,7 +1783,7 @@ public class SimpleIndexQueryParserTests extends ElasticsearchTestCase {
assertThat(filter.fieldName(), equalTo("location"));
assertThat(filter.lat(), closeTo(40, 0.00001));
assertThat(filter.lon(), closeTo(-70, 0.00001));
assertThat(filter.distance(), closeTo(12, 0.00001));
assertThat(filter.distance(), closeTo(DistanceUnit.DEFAULT.convert(12, DistanceUnit.MILES), 0.00001));
}
@Test
@ -1796,7 +1797,7 @@ public class SimpleIndexQueryParserTests extends ElasticsearchTestCase {
assertThat(filter.fieldName(), equalTo("location"));
assertThat(filter.lat(), closeTo(40, 0.00001));
assertThat(filter.lon(), closeTo(-70, 0.00001));
assertThat(filter.distance(), closeTo(12, 0.00001));
assertThat(filter.distance(), closeTo(DistanceUnit.DEFAULT.convert(12, DistanceUnit.MILES), 0.00001));
}
@Test
@ -1810,7 +1811,7 @@ public class SimpleIndexQueryParserTests extends ElasticsearchTestCase {
assertThat(filter.fieldName(), equalTo("location"));
assertThat(filter.lat(), closeTo(40, 0.00001));
assertThat(filter.lon(), closeTo(-70, 0.00001));
assertThat(filter.distance(), closeTo(12, 0.00001));
assertThat(filter.distance(), closeTo(DistanceUnit.DEFAULT.convert(12, DistanceUnit.MILES), 0.00001));
}
@Test
@ -1824,7 +1825,7 @@ public class SimpleIndexQueryParserTests extends ElasticsearchTestCase {
assertThat(filter.fieldName(), equalTo("location"));
assertThat(filter.lat(), closeTo(40, 0.00001));
assertThat(filter.lon(), closeTo(-70, 0.00001));
assertThat(filter.distance(), closeTo(12, 0.00001));
assertThat(filter.distance(), closeTo(DistanceUnit.DEFAULT.convert(12, DistanceUnit.MILES), 0.00001));
}
@Test
@ -1838,7 +1839,7 @@ public class SimpleIndexQueryParserTests extends ElasticsearchTestCase {
assertThat(filter.fieldName(), equalTo("location"));
assertThat(filter.lat(), closeTo(40, 0.00001));
assertThat(filter.lon(), closeTo(-70, 0.00001));
assertThat(filter.distance(), closeTo(12, 0.00001));
assertThat(filter.distance(), closeTo(DistanceUnit.DEFAULT.convert(12, DistanceUnit.MILES), 0.00001));
}
@Test
@ -1852,7 +1853,7 @@ public class SimpleIndexQueryParserTests extends ElasticsearchTestCase {
assertThat(filter.fieldName(), equalTo("location"));
assertThat(filter.lat(), closeTo(40, 0.00001));
assertThat(filter.lon(), closeTo(-70, 0.00001));
assertThat(filter.distance(), closeTo(12, 0.00001));
assertThat(filter.distance(), closeTo(DistanceUnit.DEFAULT.convert(12, DistanceUnit.MILES), 0.00001));
}
@Test
@ -1866,7 +1867,7 @@ public class SimpleIndexQueryParserTests extends ElasticsearchTestCase {
assertThat(filter.fieldName(), equalTo("location"));
assertThat(filter.lat(), closeTo(40, 0.00001));
assertThat(filter.lon(), closeTo(-70, 0.00001));
assertThat(filter.distance(), closeTo(12, 0.00001));
assertThat(filter.distance(), closeTo(DistanceUnit.DEFAULT.convert(0.012, DistanceUnit.MILES), 0.00001));
}
@Test
@ -1880,7 +1881,7 @@ public class SimpleIndexQueryParserTests extends ElasticsearchTestCase {
assertThat(filter.fieldName(), equalTo("location"));
assertThat(filter.lat(), closeTo(40, 0.00001));
assertThat(filter.lon(), closeTo(-70, 0.00001));
assertThat(filter.distance(), closeTo(12, 0.00001));
assertThat(filter.distance(), closeTo(DistanceUnit.KILOMETERS.convert(12, DistanceUnit.MILES), 0.00001));
}
@Test
@ -1894,7 +1895,7 @@ public class SimpleIndexQueryParserTests extends ElasticsearchTestCase {
assertThat(filter.fieldName(), equalTo("location"));
assertThat(filter.lat(), closeTo(40, 0.00001));
assertThat(filter.lon(), closeTo(-70, 0.00001));
assertThat(filter.distance(), closeTo(12, 0.00001));
assertThat(filter.distance(), closeTo(DistanceUnit.DEFAULT.convert(12, DistanceUnit.MILES), 0.00001));
}
@Test
@ -1908,7 +1909,7 @@ public class SimpleIndexQueryParserTests extends ElasticsearchTestCase {
assertThat(filter.fieldName(), equalTo("location"));
assertThat(filter.lat(), closeTo(40, 0.00001));
assertThat(filter.lon(), closeTo(-70, 0.00001));
assertThat(filter.distance(), closeTo(12, 0.00001));
assertThat(filter.distance(), closeTo(DistanceUnit.DEFAULT.convert(12, DistanceUnit.MILES), 0.00001));
}
@Test
@ -1922,7 +1923,7 @@ public class SimpleIndexQueryParserTests extends ElasticsearchTestCase {
assertThat(filter.fieldName(), equalTo("location"));
assertThat(filter.lat(), closeTo(40, 0.00001));
assertThat(filter.lon(), closeTo(-70, 0.00001));
assertThat(filter.distance(), closeTo(12, 0.00001));
assertThat(filter.distance(), closeTo(DistanceUnit.DEFAULT.convert(12, DistanceUnit.MILES), 0.00001));
}
@Test
@ -1936,7 +1937,7 @@ public class SimpleIndexQueryParserTests extends ElasticsearchTestCase {
assertThat(filter.fieldName(), equalTo("location"));
assertThat(filter.lat(), closeTo(40, 0.00001));
assertThat(filter.lon(), closeTo(-70, 0.00001));
assertThat(filter.distance(), closeTo(12, 0.00001));
assertThat(filter.distance(), closeTo(DistanceUnit.DEFAULT.convert(12, DistanceUnit.MILES), 0.00001));
}
@Test
@ -2016,6 +2017,37 @@ public class SimpleIndexQueryParserTests extends ElasticsearchTestCase {
assertThat(filter.bottomRight().lon(), closeTo(-80, 0.00001));
}
@Test
public void testGeoBoundingBoxFilter5() throws IOException {
IndexQueryParserService queryParser = queryParser();
String query = copyToStringFromClasspath("/org/elasticsearch/index/query/geo_boundingbox5.json");
Query parsedQuery = queryParser.parse(query).query();
assertThat(parsedQuery, instanceOf(XConstantScoreQuery.class));
XConstantScoreQuery constantScoreQuery = (XConstantScoreQuery) parsedQuery;
InMemoryGeoBoundingBoxFilter filter = (InMemoryGeoBoundingBoxFilter) constantScoreQuery.getFilter();
assertThat(filter.fieldName(), equalTo("location"));
assertThat(filter.topLeft().lat(), closeTo(40, 0.00001));
assertThat(filter.topLeft().lon(), closeTo(-70, 0.00001));
assertThat(filter.bottomRight().lat(), closeTo(30, 0.00001));
assertThat(filter.bottomRight().lon(), closeTo(-80, 0.00001));
}
@Test
public void testGeoBoundingBoxFilter6() throws IOException {
IndexQueryParserService queryParser = queryParser();
String query = copyToStringFromClasspath("/org/elasticsearch/index/query/geo_boundingbox6.json");
Query parsedQuery = queryParser.parse(query).query();
assertThat(parsedQuery, instanceOf(XConstantScoreQuery.class));
XConstantScoreQuery constantScoreQuery = (XConstantScoreQuery) parsedQuery;
InMemoryGeoBoundingBoxFilter filter = (InMemoryGeoBoundingBoxFilter) constantScoreQuery.getFilter();
assertThat(filter.fieldName(), equalTo("location"));
assertThat(filter.topLeft().lat(), closeTo(40, 0.00001));
assertThat(filter.topLeft().lon(), closeTo(-70, 0.00001));
assertThat(filter.bottomRight().lat(), closeTo(30, 0.00001));
assertThat(filter.bottomRight().lon(), closeTo(-80, 0.00001));
}
@Test
public void testGeoPolygonNamedFilter() throws IOException {
IndexQueryParserService queryParser = queryParser();
@ -2026,7 +2058,7 @@ public class SimpleIndexQueryParserTests extends ElasticsearchTestCase {
XConstantScoreQuery constantScoreQuery = (XConstantScoreQuery) parsedQuery.query();
GeoPolygonFilter filter = (GeoPolygonFilter) constantScoreQuery.getFilter();
assertThat(filter.fieldName(), equalTo("location"));
assertThat(filter.points().length, equalTo(3));
assertThat(filter.points().length, equalTo(4));
assertThat(filter.points()[0].lat(), closeTo(40, 0.00001));
assertThat(filter.points()[0].lon(), closeTo(-70, 0.00001));
assertThat(filter.points()[1].lat(), closeTo(30, 0.00001));
@ -2044,7 +2076,7 @@ public class SimpleIndexQueryParserTests extends ElasticsearchTestCase {
XConstantScoreQuery constantScoreQuery = (XConstantScoreQuery) parsedQuery;
GeoPolygonFilter filter = (GeoPolygonFilter) constantScoreQuery.getFilter();
assertThat(filter.fieldName(), equalTo("location"));
assertThat(filter.points().length, equalTo(3));
assertThat(filter.points().length, equalTo(4));
assertThat(filter.points()[0].lat(), closeTo(40, 0.00001));
assertThat(filter.points()[0].lon(), closeTo(-70, 0.00001));
assertThat(filter.points()[1].lat(), closeTo(30, 0.00001));
@ -2062,7 +2094,7 @@ public class SimpleIndexQueryParserTests extends ElasticsearchTestCase {
XConstantScoreQuery constantScoreQuery = (XConstantScoreQuery) parsedQuery;
GeoPolygonFilter filter = (GeoPolygonFilter) constantScoreQuery.getFilter();
assertThat(filter.fieldName(), equalTo("location"));
assertThat(filter.points().length, equalTo(3));
assertThat(filter.points().length, equalTo(4));
assertThat(filter.points()[0].lat(), closeTo(40, 0.00001));
assertThat(filter.points()[0].lon(), closeTo(-70, 0.00001));
assertThat(filter.points()[1].lat(), closeTo(30, 0.00001));
@ -2080,7 +2112,7 @@ public class SimpleIndexQueryParserTests extends ElasticsearchTestCase {
XConstantScoreQuery constantScoreQuery = (XConstantScoreQuery) parsedQuery;
GeoPolygonFilter filter = (GeoPolygonFilter) constantScoreQuery.getFilter();
assertThat(filter.fieldName(), equalTo("location"));
assertThat(filter.points().length, equalTo(3));
assertThat(filter.points().length, equalTo(4));
assertThat(filter.points()[0].lat(), closeTo(40, 0.00001));
assertThat(filter.points()[0].lon(), closeTo(-70, 0.00001));
assertThat(filter.points()[1].lat(), closeTo(30, 0.00001));
@ -2098,7 +2130,7 @@ public class SimpleIndexQueryParserTests extends ElasticsearchTestCase {
XConstantScoreQuery constantScoreQuery = (XConstantScoreQuery) parsedQuery;
GeoPolygonFilter filter = (GeoPolygonFilter) constantScoreQuery.getFilter();
assertThat(filter.fieldName(), equalTo("location"));
assertThat(filter.points().length, equalTo(3));
assertThat(filter.points().length, equalTo(4));
assertThat(filter.points()[0].lat(), closeTo(40, 0.00001));
assertThat(filter.points()[0].lon(), closeTo(-70, 0.00001));
assertThat(filter.points()[1].lat(), closeTo(30, 0.00001));

View File

@ -0,0 +1,15 @@
{
"filtered":{
"query":{
"match_all":{}
},
"filter":{
"geo_bounding_box":{
"location":{
"top_right":"40, -80",
"bottom_left":"30, -70"
}
}
}
}
}

View File

@ -0,0 +1,17 @@
{
"filtered":{
"query":{
"match_all":{}
},
"filter":{
"geo_bounding_box":{
"location":{
"right": -80,
"top": 40,
"left": -70,
"bottom": 30
}
}
}
}
}

View File

@ -262,10 +262,10 @@ public class GeoDistanceTests extends ElasticsearchIntegrationTest {
assertHitCount(searchResponse, 4);
assertOrderedSearchHits(searchResponse, "1", "2", "3", "4");
assertThat(((Number) searchResponse.getHits().getAt(0).sortValues()[0]).doubleValue(), closeTo(0d, 0.01d));
assertThat(((Number) searchResponse.getHits().getAt(1).sortValues()[0]).doubleValue(), closeTo(0.4621d, 0.01d));
assertThat(((Number) searchResponse.getHits().getAt(2).sortValues()[0]).doubleValue(), closeTo(1.055d, 0.01d));
assertThat(((Number) searchResponse.getHits().getAt(3).sortValues()[0]).doubleValue(), closeTo(2.029d, 0.01d));
assertThat(((Number) searchResponse.getHits().getAt(0).sortValues()[0]).doubleValue(), closeTo(0d, 10d));
assertThat(((Number) searchResponse.getHits().getAt(1).sortValues()[0]).doubleValue(), closeTo(462.1d, 10d));
assertThat(((Number) searchResponse.getHits().getAt(2).sortValues()[0]).doubleValue(), closeTo(1055.0d, 10d));
assertThat(((Number) searchResponse.getHits().getAt(3).sortValues()[0]).doubleValue(), closeTo(2029.0d, 10d));
// Order: Asc, Mode: max
searchResponse = client().prepareSearch("test").setQuery(matchAllQuery())
@ -274,10 +274,10 @@ public class GeoDistanceTests extends ElasticsearchIntegrationTest {
assertHitCount(searchResponse, 4);
assertOrderedSearchHits(searchResponse, "1", "3", "2", "4");
assertThat(((Number) searchResponse.getHits().getAt(0).sortValues()[0]).doubleValue(), closeTo(0d, 0.01d));
assertThat(((Number) searchResponse.getHits().getAt(1).sortValues()[0]).doubleValue(), closeTo(1.258d, 0.01d));
assertThat(((Number) searchResponse.getHits().getAt(2).sortValues()[0]).doubleValue(), closeTo(5.286d, 0.01d));
assertThat(((Number) searchResponse.getHits().getAt(3).sortValues()[0]).doubleValue(), closeTo(8.572d, 0.01d));
assertThat(((Number) searchResponse.getHits().getAt(0).sortValues()[0]).doubleValue(), closeTo(0d, 10d));
assertThat(((Number) searchResponse.getHits().getAt(1).sortValues()[0]).doubleValue(), closeTo(1258.0d, 10d));
assertThat(((Number) searchResponse.getHits().getAt(2).sortValues()[0]).doubleValue(), closeTo(5286.0d, 10d));
assertThat(((Number) searchResponse.getHits().getAt(3).sortValues()[0]).doubleValue(), closeTo(8572.0d, 10d));
// Order: Desc
searchResponse = client().prepareSearch("test").setQuery(matchAllQuery())
@ -286,10 +286,10 @@ public class GeoDistanceTests extends ElasticsearchIntegrationTest {
assertHitCount(searchResponse, 4);
assertOrderedSearchHits(searchResponse, "4", "2", "3", "1");
assertThat(((Number) searchResponse.getHits().getAt(0).sortValues()[0]).doubleValue(), closeTo(8.572d, 0.01d));
assertThat(((Number) searchResponse.getHits().getAt(1).sortValues()[0]).doubleValue(), closeTo(5.286d, 0.01d));
assertThat(((Number) searchResponse.getHits().getAt(2).sortValues()[0]).doubleValue(), closeTo(1.258d, 0.01d));
assertThat(((Number) searchResponse.getHits().getAt(3).sortValues()[0]).doubleValue(), closeTo(0d, 0.01d));
assertThat(((Number) searchResponse.getHits().getAt(0).sortValues()[0]).doubleValue(), closeTo(8572.0d, 10d));
assertThat(((Number) searchResponse.getHits().getAt(1).sortValues()[0]).doubleValue(), closeTo(5286.0d, 10d));
assertThat(((Number) searchResponse.getHits().getAt(2).sortValues()[0]).doubleValue(), closeTo(1258.0d, 10d));
assertThat(((Number) searchResponse.getHits().getAt(3).sortValues()[0]).doubleValue(), closeTo(0d, 10d));
// Order: Desc, Mode: min
searchResponse = client().prepareSearch("test").setQuery(matchAllQuery())
@ -298,10 +298,10 @@ public class GeoDistanceTests extends ElasticsearchIntegrationTest {
assertHitCount(searchResponse, 4);
assertOrderedSearchHits(searchResponse, "4", "3", "2", "1");
assertThat(((Number) searchResponse.getHits().getAt(0).sortValues()[0]).doubleValue(), closeTo(2.029d, 0.01d));
assertThat(((Number) searchResponse.getHits().getAt(1).sortValues()[0]).doubleValue(), closeTo(1.055d, 0.01d));
assertThat(((Number) searchResponse.getHits().getAt(2).sortValues()[0]).doubleValue(), closeTo(0.4621d, 0.01d));
assertThat(((Number) searchResponse.getHits().getAt(3).sortValues()[0]).doubleValue(), closeTo(0d, 0.01d));
assertThat(((Number) searchResponse.getHits().getAt(0).sortValues()[0]).doubleValue(), closeTo(2029.0d, 10d));
assertThat(((Number) searchResponse.getHits().getAt(1).sortValues()[0]).doubleValue(), closeTo(1055.0d, 10d));
assertThat(((Number) searchResponse.getHits().getAt(2).sortValues()[0]).doubleValue(), closeTo(462.1d, 10d));
assertThat(((Number) searchResponse.getHits().getAt(3).sortValues()[0]).doubleValue(), closeTo(0d, 10d));
searchResponse = client().prepareSearch("test").setQuery(matchAllQuery())
.addSort(SortBuilders.geoDistanceSort("locations").point(40.7143528, -74.0059731).sortMode("avg").order(SortOrder.ASC))
@ -309,21 +309,21 @@ public class GeoDistanceTests extends ElasticsearchIntegrationTest {
assertHitCount(searchResponse, 4);
assertOrderedSearchHits(searchResponse, "1", "3", "2", "4");
assertThat(((Number) searchResponse.getHits().getAt(0).sortValues()[0]).doubleValue(), closeTo(0d, 0.01d));
assertThat(((Number) searchResponse.getHits().getAt(1).sortValues()[0]).doubleValue(), closeTo(1.157d, 0.01d));
assertThat(((Number) searchResponse.getHits().getAt(2).sortValues()[0]).doubleValue(), closeTo(2.874d, 0.01d));
assertThat(((Number) searchResponse.getHits().getAt(3).sortValues()[0]).doubleValue(), closeTo(5.301d, 0.01d));
assertThat(((Number) searchResponse.getHits().getAt(0).sortValues()[0]).doubleValue(), closeTo(0d, 10d));
assertThat(((Number) searchResponse.getHits().getAt(1).sortValues()[0]).doubleValue(), closeTo(1157d, 10d));
assertThat(((Number) searchResponse.getHits().getAt(2).sortValues()[0]).doubleValue(), closeTo(2874d, 10d));
assertThat(((Number) searchResponse.getHits().getAt(3).sortValues()[0]).doubleValue(), closeTo(5301d, 10d));
searchResponse = client().prepareSearch("test").setQuery(matchAllQuery())
.addSort(SortBuilders.geoDistanceSort("locations").point(40.7143528, -74.0059731).sortMode("avg").order(SortOrder.DESC))
.execute().actionGet();
assertHitCount(searchResponse, 4);
assertOrderedSearchHits(searchResponse, "4", "2", "3", "1");
assertThat(((Number) searchResponse.getHits().getAt(0).sortValues()[0]).doubleValue(), closeTo(5.301d, 0.01d));
assertThat(((Number) searchResponse.getHits().getAt(1).sortValues()[0]).doubleValue(), closeTo(2.874d, 0.01d));
assertThat(((Number) searchResponse.getHits().getAt(2).sortValues()[0]).doubleValue(), closeTo(1.157d, 0.01d));
assertThat(((Number) searchResponse.getHits().getAt(3).sortValues()[0]).doubleValue(), closeTo(0d, 0.01d));
assertOrderedSearchHits(searchResponse, "4", "2", "3", "1");
assertThat(((Number) searchResponse.getHits().getAt(0).sortValues()[0]).doubleValue(), closeTo(5301.0d, 10d));
assertThat(((Number) searchResponse.getHits().getAt(1).sortValues()[0]).doubleValue(), closeTo(2874.0d, 10d));
assertThat(((Number) searchResponse.getHits().getAt(2).sortValues()[0]).doubleValue(), closeTo(1157.0d, 10d));
assertThat(((Number) searchResponse.getHits().getAt(3).sortValues()[0]).doubleValue(), closeTo(0d, 10d));
try {
client().prepareSearch("test").setQuery(matchAllQuery())
@ -372,7 +372,7 @@ public class GeoDistanceTests extends ElasticsearchIntegrationTest {
assertHitCount(searchResponse, 2);
assertOrderedSearchHits(searchResponse, "1", "2");
assertThat(((Number) searchResponse.getHits().getAt(0).sortValues()[0]).doubleValue(), closeTo(0.4621d, 0.01d));
assertThat(((Number) searchResponse.getHits().getAt(0).sortValues()[0]).doubleValue(), closeTo(462.1d, 10d));
assertThat(((Number) searchResponse.getHits().getAt(1).sortValues()[0]).doubleValue(), equalTo(Double.MAX_VALUE));
// Order: Desc
@ -384,7 +384,7 @@ public class GeoDistanceTests extends ElasticsearchIntegrationTest {
assertHitCount(searchResponse, 2);
assertOrderedSearchHits(searchResponse, "2", "1");
assertThat(((Number) searchResponse.getHits().getAt(0).sortValues()[0]).doubleValue(), equalTo(Double.MAX_VALUE));
assertThat(((Number) searchResponse.getHits().getAt(1).sortValues()[0]).doubleValue(), closeTo(5.286d, 0.01d));
assertThat(((Number) searchResponse.getHits().getAt(1).sortValues()[0]).doubleValue(), closeTo(5286d, 10d));
}
@Test
@ -409,11 +409,11 @@ public class GeoDistanceTests extends ElasticsearchIntegrationTest {
SearchResponse searchResponse1 = client().prepareSearch().addField("_source").addScriptField("distance", "doc['location'].arcDistance(" + target_lat + "," + target_long + ")").execute().actionGet();
Double resultDistance1 = searchResponse1.getHits().getHits()[0].getFields().get("distance").getValue();
assertThat(resultDistance1, closeTo(GeoDistance.ARC.calculate(source_lat, source_long, target_lat, target_long, DistanceUnit.MILES), 0.0001d));
assertThat(resultDistance1, closeTo(GeoDistance.ARC.calculate(source_lat, source_long, target_lat, target_long, DistanceUnit.DEFAULT), 0.0001d));
SearchResponse searchResponse2 = client().prepareSearch().addField("_source").addScriptField("distance", "doc['location'].distance(" + target_lat + "," + target_long + ")").execute().actionGet();
Double resultDistance2 = searchResponse2.getHits().getHits()[0].getFields().get("distance").getValue();
assertThat(resultDistance2, closeTo(GeoDistance.PLANE.calculate(source_lat, source_long, target_lat, target_long, DistanceUnit.MILES), 0.0001d));
assertThat(resultDistance2, closeTo(GeoDistance.PLANE.calculate(source_lat, source_long, target_lat, target_long, DistanceUnit.DEFAULT), 0.0001d));
SearchResponse searchResponse3 = client().prepareSearch().addField("_source").addScriptField("distance", "doc['location'].arcDistanceInKm(" + target_lat + "," + target_long + ")").execute().actionGet();
Double resultArcDistance3 = searchResponse3.getHits().getHits()[0].getFields().get("distance").getValue();
@ -430,6 +430,15 @@ public class GeoDistanceTests extends ElasticsearchIntegrationTest {
SearchResponse searchResponse6 = client().prepareSearch().addField("_source").addScriptField("distance", "doc['location'].arcDistanceInKm(" + (target_lat + 360) + "," + (target_long) + ")").execute().actionGet();
Double resultArcDistance6 = searchResponse6.getHits().getHits()[0].getFields().get("distance").getValue();
assertThat(resultArcDistance6, closeTo(GeoDistance.ARC.calculate(source_lat, source_long, target_lat, target_long, DistanceUnit.KILOMETERS), 0.0001d));
SearchResponse searchResponse7 = client().prepareSearch().addField("_source").addScriptField("distance", "doc['location'].arcDistanceInMiles(" + target_lat + "," + target_long + ")").execute().actionGet();
Double resultDistance7 = searchResponse7.getHits().getHits()[0].getFields().get("distance").getValue();
assertThat(resultDistance7, closeTo(GeoDistance.ARC.calculate(source_lat, source_long, target_lat, target_long, DistanceUnit.MILES), 0.0001d));
SearchResponse searchResponse8 = client().prepareSearch().addField("_source").addScriptField("distance", "doc['location'].distanceInMiles(" + target_lat + "," + target_long + ")").execute().actionGet();
Double resultDistance8 = searchResponse8.getHits().getHits()[0].getFields().get("distance").getValue();
assertThat(resultDistance8, closeTo(GeoDistance.PLANE.calculate(source_lat, source_long, target_lat, target_long, DistanceUnit.MILES), 0.0001d));
}
@Test
@ -509,10 +518,10 @@ public class GeoDistanceTests extends ElasticsearchIntegrationTest {
assertHitCount(searchResponse, 4);
assertOrderedSearchHits(searchResponse, "1", "2", "3", "4");
assertThat(((Number) searchResponse.getHits().getAt(0).sortValues()[0]).doubleValue(), closeTo(0d, 0.01d));
assertThat(((Number) searchResponse.getHits().getAt(1).sortValues()[0]).doubleValue(), closeTo(0.4621d, 0.01d));
assertThat(((Number) searchResponse.getHits().getAt(2).sortValues()[0]).doubleValue(), closeTo(1.055d, 0.01d));
assertThat(((Number) searchResponse.getHits().getAt(3).sortValues()[0]).doubleValue(), closeTo(2.029d, 0.01d));
assertThat(((Number) searchResponse.getHits().getAt(0).sortValues()[0]).doubleValue(), closeTo(0d, 10d));
assertThat(((Number) searchResponse.getHits().getAt(1).sortValues()[0]).doubleValue(), closeTo(462.1d, 10d));
assertThat(((Number) searchResponse.getHits().getAt(2).sortValues()[0]).doubleValue(), closeTo(1055.0d, 10d));
assertThat(((Number) searchResponse.getHits().getAt(3).sortValues()[0]).doubleValue(), closeTo(2029.0d, 10d));
// Order: Asc, Mode: max
searchResponse = client().prepareSearch("companies").setQuery(matchAllQuery())
@ -521,10 +530,10 @@ public class GeoDistanceTests extends ElasticsearchIntegrationTest {
assertHitCount(searchResponse, 4);
assertOrderedSearchHits(searchResponse, "1", "3", "2", "4");
assertThat(((Number) searchResponse.getHits().getAt(0).sortValues()[0]).doubleValue(), closeTo(0d, 0.01d));
assertThat(((Number) searchResponse.getHits().getAt(1).sortValues()[0]).doubleValue(), closeTo(1.258d, 0.01d));
assertThat(((Number) searchResponse.getHits().getAt(2).sortValues()[0]).doubleValue(), closeTo(5.286d, 0.01d));
assertThat(((Number) searchResponse.getHits().getAt(3).sortValues()[0]).doubleValue(), closeTo(8.572d, 0.01d));
assertThat(((Number) searchResponse.getHits().getAt(0).sortValues()[0]).doubleValue(), closeTo(0d, 10d));
assertThat(((Number) searchResponse.getHits().getAt(1).sortValues()[0]).doubleValue(), closeTo(1258.0d, 10d));
assertThat(((Number) searchResponse.getHits().getAt(2).sortValues()[0]).doubleValue(), closeTo(5286.0d, 10d));
assertThat(((Number) searchResponse.getHits().getAt(3).sortValues()[0]).doubleValue(), closeTo(8572.0d, 10d));
// Order: Desc
searchResponse = client().prepareSearch("companies").setQuery(matchAllQuery())
@ -533,10 +542,10 @@ public class GeoDistanceTests extends ElasticsearchIntegrationTest {
assertHitCount(searchResponse, 4);
assertOrderedSearchHits(searchResponse, "4", "2", "3", "1");
assertThat(((Number) searchResponse.getHits().getAt(0).sortValues()[0]).doubleValue(), closeTo(8.572d, 0.01d));
assertThat(((Number) searchResponse.getHits().getAt(1).sortValues()[0]).doubleValue(), closeTo(5.286d, 0.01d));
assertThat(((Number) searchResponse.getHits().getAt(2).sortValues()[0]).doubleValue(), closeTo(1.258d, 0.01d));
assertThat(((Number) searchResponse.getHits().getAt(3).sortValues()[0]).doubleValue(), closeTo(0d, 0.01d));
assertThat(((Number) searchResponse.getHits().getAt(0).sortValues()[0]).doubleValue(), closeTo(8572.0d, 10d));
assertThat(((Number) searchResponse.getHits().getAt(1).sortValues()[0]).doubleValue(), closeTo(5286.0d, 10d));
assertThat(((Number) searchResponse.getHits().getAt(2).sortValues()[0]).doubleValue(), closeTo(1258.0d, 10d));
assertThat(((Number) searchResponse.getHits().getAt(3).sortValues()[0]).doubleValue(), closeTo(0d, 10d));
// Order: Desc, Mode: min
searchResponse = client().prepareSearch("companies").setQuery(matchAllQuery())
@ -545,10 +554,10 @@ public class GeoDistanceTests extends ElasticsearchIntegrationTest {
assertHitCount(searchResponse, 4);
assertOrderedSearchHits(searchResponse, "4", "3", "2", "1");
assertThat(((Number) searchResponse.getHits().getAt(0).sortValues()[0]).doubleValue(), closeTo(2.029d, 0.01d));
assertThat(((Number) searchResponse.getHits().getAt(1).sortValues()[0]).doubleValue(), closeTo(1.055d, 0.01d));
assertThat(((Number) searchResponse.getHits().getAt(2).sortValues()[0]).doubleValue(), closeTo(0.4621d, 0.01d));
assertThat(((Number) searchResponse.getHits().getAt(3).sortValues()[0]).doubleValue(), closeTo(0d, 0.01d));
assertThat(((Number) searchResponse.getHits().getAt(0).sortValues()[0]).doubleValue(), closeTo(2029.0d, 10d));
assertThat(((Number) searchResponse.getHits().getAt(1).sortValues()[0]).doubleValue(), closeTo(1055.0d, 10d));
assertThat(((Number) searchResponse.getHits().getAt(2).sortValues()[0]).doubleValue(), closeTo(462.1d, 10d));
assertThat(((Number) searchResponse.getHits().getAt(3).sortValues()[0]).doubleValue(), closeTo(0d, 10d));
searchResponse = client().prepareSearch("companies").setQuery(matchAllQuery())
.addSort(SortBuilders.geoDistanceSort("branches.location").point(40.7143528, -74.0059731).sortMode("avg").order(SortOrder.ASC))
@ -556,10 +565,10 @@ public class GeoDistanceTests extends ElasticsearchIntegrationTest {
assertHitCount(searchResponse, 4);
assertOrderedSearchHits(searchResponse, "1", "3", "2", "4");
assertThat(((Number) searchResponse.getHits().getAt(0).sortValues()[0]).doubleValue(), closeTo(0d, 0.01d));
assertThat(((Number) searchResponse.getHits().getAt(1).sortValues()[0]).doubleValue(), closeTo(1.157d, 0.01d));
assertThat(((Number) searchResponse.getHits().getAt(2).sortValues()[0]).doubleValue(), closeTo(2.874d, 0.01d));
assertThat(((Number) searchResponse.getHits().getAt(3).sortValues()[0]).doubleValue(), closeTo(5.301d, 0.01d));
assertThat(((Number) searchResponse.getHits().getAt(0).sortValues()[0]).doubleValue(), closeTo(0d, 10d));
assertThat(((Number) searchResponse.getHits().getAt(1).sortValues()[0]).doubleValue(), closeTo(1157.0d, 10d));
assertThat(((Number) searchResponse.getHits().getAt(2).sortValues()[0]).doubleValue(), closeTo(2874.0d, 10d));
assertThat(((Number) searchResponse.getHits().getAt(3).sortValues()[0]).doubleValue(), closeTo(5301.0d, 10d));
searchResponse = client().prepareSearch("companies").setQuery(matchAllQuery())
.addSort(
@ -570,10 +579,10 @@ public class GeoDistanceTests extends ElasticsearchIntegrationTest {
assertHitCount(searchResponse, 4);
assertOrderedSearchHits(searchResponse, "4", "2", "3", "1");
assertThat(((Number) searchResponse.getHits().getAt(0).sortValues()[0]).doubleValue(), closeTo(5.301d, 0.01d));
assertThat(((Number) searchResponse.getHits().getAt(1).sortValues()[0]).doubleValue(), closeTo(2.874d, 0.01d));
assertThat(((Number) searchResponse.getHits().getAt(2).sortValues()[0]).doubleValue(), closeTo(1.157d, 0.01d));
assertThat(((Number) searchResponse.getHits().getAt(3).sortValues()[0]).doubleValue(), closeTo(0d, 0.01d));
assertThat(((Number) searchResponse.getHits().getAt(0).sortValues()[0]).doubleValue(), closeTo(5301.0d, 10d));
assertThat(((Number) searchResponse.getHits().getAt(1).sortValues()[0]).doubleValue(), closeTo(2874.0d, 10d));
assertThat(((Number) searchResponse.getHits().getAt(2).sortValues()[0]).doubleValue(), closeTo(1157.0d, 10d));
assertThat(((Number) searchResponse.getHits().getAt(3).sortValues()[0]).doubleValue(), closeTo(0d, 10d));
searchResponse = client().prepareSearch("companies").setQuery(matchAllQuery())
.addSort(
@ -584,7 +593,7 @@ public class GeoDistanceTests extends ElasticsearchIntegrationTest {
assertHitCount(searchResponse, 4);
assertFirstHit(searchResponse, hasId("4"));
assertSearchHits(searchResponse, "1", "2", "3", "4");
assertThat(((Number) searchResponse.getHits().getAt(0).sortValues()[0]).doubleValue(), closeTo(8.572d, 0.01d));
assertThat(((Number) searchResponse.getHits().getAt(0).sortValues()[0]).doubleValue(), closeTo(8572.0d, 10d));
assertThat(((Number) searchResponse.getHits().getAt(1).sortValues()[0]).doubleValue(), equalTo(Double.MAX_VALUE));
assertThat(((Number) searchResponse.getHits().getAt(2).sortValues()[0]).doubleValue(), equalTo(Double.MAX_VALUE));
assertThat(((Number) searchResponse.getHits().getAt(3).sortValues()[0]).doubleValue(), equalTo(Double.MAX_VALUE));

View File

@ -39,7 +39,7 @@ import org.junit.Test;
import java.io.IOException;
import static org.elasticsearch.index.query.QueryBuilders.queryString;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.*;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertNoFailures;
import static org.hamcrest.Matchers.*;
/**
@ -136,7 +136,8 @@ public class SimpleValidateQueryTests extends ElasticsearchIntegrationTest {
.addPoint(40, -70)
.addPoint(30, -80)
.addPoint(20, -90)
), equalTo("ConstantScore(GeoPolygonFilter(pin.location, [[40.0, -70.0], [30.0, -80.0], [20.0, -90.0]]))"));
.addPoint(40, -70) // closing polygon
), equalTo("ConstantScore(GeoPolygonFilter(pin.location, [[40.0, -70.0], [30.0, -80.0], [20.0, -90.0], [40.0, -70.0]]))"));
assertExplanation(QueryBuilders.constantScoreQuery(FilterBuilders.geoBoundingBoxFilter("pin.location")
.topLeft(40, -80)
@ -144,17 +145,21 @@ public class SimpleValidateQueryTests extends ElasticsearchIntegrationTest {
), equalTo("ConstantScore(GeoBoundingBoxFilter(pin.location, [40.0, -80.0], [20.0, -70.0]))"));
assertExplanation(QueryBuilders.constantScoreQuery(FilterBuilders.geoDistanceFilter("pin.location")
.lat(10).lon(20).distance(15, DistanceUnit.MILES).geoDistance(GeoDistance.PLANE)
.lat(10).lon(20).distance(15, DistanceUnit.DEFAULT).geoDistance(GeoDistance.PLANE)
), equalTo("ConstantScore(GeoDistanceFilter(pin.location, PLANE, 15.0, 10.0, 20.0))"));
assertExplanation(QueryBuilders.constantScoreQuery(FilterBuilders.geoDistanceFilter("pin.location")
.lat(10).lon(20).distance(15, DistanceUnit.MILES).geoDistance(GeoDistance.PLANE)
.lat(10).lon(20).distance(15, DistanceUnit.DEFAULT).geoDistance(GeoDistance.PLANE)
), equalTo("ConstantScore(GeoDistanceFilter(pin.location, PLANE, 15.0, 10.0, 20.0))"));
assertExplanation(QueryBuilders.constantScoreQuery(FilterBuilders.geoDistanceRangeFilter("pin.location")
.lat(10).lon(20).from("15miles").to("25miles").geoDistance(GeoDistance.PLANE)
.lat(10).lon(20).from("15m").to("25m").geoDistance(GeoDistance.PLANE)
), equalTo("ConstantScore(GeoDistanceRangeFilter(pin.location, PLANE, [15.0 - 25.0], 10.0, 20.0))"));
assertExplanation(QueryBuilders.constantScoreQuery(FilterBuilders.geoDistanceRangeFilter("pin.location")
.lat(10).lon(20).from("15miles").to("25miles").geoDistance(GeoDistance.PLANE)
), equalTo("ConstantScore(GeoDistanceRangeFilter(pin.location, PLANE, [" + DistanceUnit.DEFAULT.convert(15.0, DistanceUnit.MILES) + " - " + DistanceUnit.DEFAULT.convert(25.0, DistanceUnit.MILES) + "], 10.0, 20.0))"));
assertExplanation(QueryBuilders.filteredQuery(
QueryBuilders.termQuery("foo", "1"),
FilterBuilders.andFilter(