diff --git a/core/src/main/java/org/elasticsearch/common/geo/GeoUtils.java b/core/src/main/java/org/elasticsearch/common/geo/GeoUtils.java index f29cdd6092d..a6de679991f 100644 --- a/core/src/main/java/org/elasticsearch/common/geo/GeoUtils.java +++ b/core/src/main/java/org/elasticsearch/common/geo/GeoUtils.java @@ -66,6 +66,19 @@ public class GeoUtils { /** Earth ellipsoid polar distance in meters */ public static final double EARTH_POLAR_DISTANCE = Math.PI * EARTH_SEMI_MINOR_AXIS; + /** Returns the maximum distance/radius from the point 'center' before overlapping */ + public static double maxRadialDistance(GeoPoint center) { + return SloppyMath.haversin(center.lat(), center.lon(), center.lat(), (180.0 + center.lon()) % 360)*1000.0; + } + + /** Returns the minimum between the provided distance 'initialRadius' and the + * maximum distance/radius from the point 'center' before overlapping + **/ + public static double maxRadialDistance(GeoPoint center, double initialRadius) { + final double maxRadius = maxRadialDistance(center); + return Math.min(initialRadius, maxRadius); + } + /** Returns true if latitude is actually a valid latitude value.*/ public static boolean isValidLatitude(double latitude) { if (Double.isNaN(latitude) || Double.isInfinite(latitude) || latitude < GeoUtils.MIN_LAT || latitude > GeoUtils.MAX_LAT) { diff --git a/core/src/main/java/org/elasticsearch/index/query/GeoBoundingBoxQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/GeoBoundingBoxQueryBuilder.java index 59d20cef611..cf0fa0c5b09 100644 --- a/core/src/main/java/org/elasticsearch/index/query/GeoBoundingBoxQueryBuilder.java +++ b/core/src/main/java/org/elasticsearch/index/query/GeoBoundingBoxQueryBuilder.java @@ -19,6 +19,7 @@ package org.elasticsearch.index.query; +import org.apache.lucene.search.GeoPointInBBoxQuery; import org.apache.lucene.search.Query; import org.elasticsearch.Version; import org.elasticsearch.common.Numbers; @@ -263,21 +264,26 @@ public class GeoBoundingBoxQueryBuilder extends AbstractQueryBuilder { public static final String NAME = "geo_distance_range"; @@ -235,7 +238,10 @@ public class GeoDistanceRangeQueryBuilder extends AbstractQueryBuilder 0); String query = "{\n" + @@ -185,7 +213,7 @@ public class GeoDistanceQueryBuilderTests extends AbstractQueryTestCase 0); Query parsedQuery = parseQuery(query).toQuery(createShardContext()); - GeoDistanceRangeQuery filter = (GeoDistanceRangeQuery) parsedQuery; - assertThat(filter.fieldName(), equalTo(GEO_POINT_FIELD_NAME)); - assertThat(filter.lat(), closeTo(40, 0.00001)); - assertThat(filter.lon(), closeTo(-70, 0.00001)); - assertThat(filter.minInclusiveDistance(), equalTo(Double.NEGATIVE_INFINITY)); - assertThat(filter.maxInclusiveDistance(), closeTo(DistanceUnit.DEFAULT.convert(12, DistanceUnit.MILES), 0.00001)); + Version version = queryShardContext().indexVersionCreated(); + // norelease update to .before(Version.V_2_2_0 once GeoPointFieldV2 is fully merged + if (version.onOrBefore(Version.CURRENT)) { + GeoDistanceRangeQuery q = (GeoDistanceRangeQuery) parsedQuery; + assertThat(q.fieldName(), equalTo(GEO_POINT_FIELD_NAME)); + assertThat(q.lat(), closeTo(lat, 1E-5D)); + assertThat(q.lon(), closeTo(lon, 1E-5D)); + assertThat(q.minInclusiveDistance(), equalTo(Double.NEGATIVE_INFINITY)); + assertThat(q.maxInclusiveDistance(), closeTo(distanceUnit.convert(distance, DistanceUnit.MILES), 1E-5D)); + } else { + GeoPointDistanceQuery q = (GeoPointDistanceQuery) parsedQuery; + assertThat(q.getField(), equalTo(GEO_POINT_FIELD_NAME)); + assertThat(q.getCenterLat(), closeTo(lat, 1E-5D)); + assertThat(q.getCenterLon(), closeTo(lon, 1E-5D)); + assertThat(q.getRadiusMeters(), closeTo(distanceUnit.convert(distance, DistanceUnit.MILES), 1E-5D)); + } } } diff --git a/core/src/test/java/org/elasticsearch/index/query/GeoDistanceRangeQueryTests.java b/core/src/test/java/org/elasticsearch/index/query/GeoDistanceRangeQueryTests.java index 2165507d821..99b14481670 100644 --- a/core/src/test/java/org/elasticsearch/index/query/GeoDistanceRangeQueryTests.java +++ b/core/src/test/java/org/elasticsearch/index/query/GeoDistanceRangeQueryTests.java @@ -19,7 +19,10 @@ package org.elasticsearch.index.query; +import org.apache.lucene.search.GeoPointDistanceRangeQuery; import org.apache.lucene.search.Query; +import org.apache.lucene.util.SloppyMath; +import org.elasticsearch.Version; import org.elasticsearch.common.geo.GeoDistance; import org.elasticsearch.common.geo.GeoPoint; import org.elasticsearch.common.geo.GeoUtils; @@ -37,6 +40,7 @@ public class GeoDistanceRangeQueryTests extends AbstractQueryTestCase queryBuilderPoints = queryBuilder.points(); + double[] lats = geoQuery.getLats(); + double[] lons = geoQuery.getLons(); + assertThat(lats.length, equalTo(queryBuilderPoints.size())); + assertThat(lons.length, equalTo(queryBuilderPoints.size())); + for (int i=0; i < queryBuilderPoints.size(); ++i) { + final GeoPoint queryBuilderPoint = queryBuilderPoints.get(i); + final GeoPoint pointCopy = new GeoPoint(queryBuilderPoint); + GeoUtils.normalizePoint(pointCopy); + assertThat(lats[i], closeTo(pointCopy.getLat(), 1E-5D)); + assertThat(lons[i], closeTo(pointCopy.getLon(), 1E-5D)); + } + } + /** * Overridden here to ensure the test is only run if at least one type is * present in the mappings. Geo queries do not execute if the field is not @@ -267,15 +297,35 @@ public class GeoPolygonQueryBuilderTests extends AbstractQueryTestCase