GeoBoundingBoxQueryBuilder should fail when topLeft and bottomRight are the same coordinate
This commit is contained in:
parent
ee193f7697
commit
f77f79c24a
|
@ -20,6 +20,7 @@ import java.util.ArrayList;
|
|||
import java.util.Collection;
|
||||
|
||||
import org.apache.lucene.spatial.geopoint.document.GeoPointField;
|
||||
import org.apache.lucene.geo.Rectangle;
|
||||
import org.apache.lucene.util.BitUtil;
|
||||
|
||||
/**
|
||||
|
@ -176,6 +177,26 @@ public class GeoHashUtils {
|
|||
return BASE_32[((x & 1) + ((y & 1) * 2) + ((x & 2) * 2) + ((y & 2) * 4) + ((x & 4) * 4)) % 32];
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the bounding box coordinates from a given geohash
|
||||
*
|
||||
* @param geohash Geohash of the defined cell
|
||||
* @return GeoRect rectangle defining the bounding box
|
||||
*/
|
||||
public static Rectangle bbox(final String geohash) {
|
||||
// bottom left is the coordinate
|
||||
GeoPoint bottomLeft = GeoPoint.fromGeohash(geohash);
|
||||
long ghLong = longEncode(geohash);
|
||||
// shift away the level
|
||||
ghLong >>>= 4;
|
||||
// deinterleave and add 1 to lat and lon to get topRight
|
||||
long lat = BitUtil.deinterleave(ghLong >>> 1) + 1;
|
||||
long lon = BitUtil.deinterleave(ghLong) + 1;
|
||||
GeoPoint topRight = GeoPoint.fromGeohash(BitUtil.interleave((int)lon, (int)lat) << 4 | geohash.length());
|
||||
|
||||
return new Rectangle(bottomLeft.lat(), topRight.lat(), bottomLeft.lon(), topRight.lon());
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate all neighbors of a given geohash cell.
|
||||
*
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
package org.elasticsearch.index.query;
|
||||
|
||||
import org.apache.lucene.geo.Rectangle;
|
||||
import org.apache.lucene.search.MatchNoDocsQuery;
|
||||
import org.apache.lucene.search.Query;
|
||||
import org.apache.lucene.spatial.geopoint.document.GeoPointField;
|
||||
|
@ -28,6 +29,7 @@ import org.elasticsearch.Version;
|
|||
import org.elasticsearch.common.Numbers;
|
||||
import org.elasticsearch.common.ParseField;
|
||||
import org.elasticsearch.common.ParsingException;
|
||||
import org.elasticsearch.common.geo.GeoHashUtils;
|
||||
import org.elasticsearch.common.geo.GeoPoint;
|
||||
import org.elasticsearch.common.geo.GeoUtils;
|
||||
import org.elasticsearch.common.io.stream.StreamInput;
|
||||
|
@ -155,6 +157,12 @@ public class GeoBoundingBoxQueryBuilder extends AbstractQueryBuilder<GeoBounding
|
|||
if (top < bottom) {
|
||||
throw new IllegalArgumentException("top is below bottom corner: " +
|
||||
top + " vs. " + bottom);
|
||||
} else if (top == bottom) {
|
||||
throw new IllegalArgumentException("top cannot be the same as bottom: " +
|
||||
top + " == " + bottom);
|
||||
} else if (left == right) {
|
||||
throw new IllegalArgumentException("left cannot be the same as right: " +
|
||||
left + " == " + right);
|
||||
}
|
||||
|
||||
// we do not check longitudes as the query generation code can deal with flipped left/right values
|
||||
|
@ -174,6 +182,16 @@ public class GeoBoundingBoxQueryBuilder extends AbstractQueryBuilder<GeoBounding
|
|||
return setCorners(topLeft.getLat(), topLeft.getLon(), bottomRight.getLat(), bottomRight.getLon());
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds points from a single geohash.
|
||||
* @param geohash The geohash for computing the bounding box.
|
||||
*/
|
||||
public GeoBoundingBoxQueryBuilder setCorners(final String geohash) {
|
||||
// get the bounding box of the geohash and set topLeft and bottomRight
|
||||
Rectangle ghBBox = GeoHashUtils.bbox(geohash);
|
||||
return setCorners(new GeoPoint(ghBBox.maxLat, ghBBox.minLon), new GeoPoint(ghBBox.minLat, ghBBox.maxLon));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds points.
|
||||
* @param topLeft topLeft point to add as geohash.
|
||||
|
|
|
@ -349,7 +349,7 @@ public class GeoBoundingBoxQueryBuilderTests extends AbstractQueryTestCase<GeoBo
|
|||
|
||||
@Override
|
||||
public void fillIn(double coordinate, GeoBoundingBoxQueryBuilder qb) {
|
||||
qb.setCorners(qb.topLeft().getLat(), qb.topLeft().getLon(), qb.topLeft().getLat(), coordinate);
|
||||
qb.setCorners(qb.topLeft().getLat(), qb.topLeft().getLon(), qb.bottomRight().getLat(), coordinate);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,6 @@ package org.elasticsearch.search.aggregations.bucket;
|
|||
import com.carrotsearch.hppc.ObjectIntHashMap;
|
||||
import com.carrotsearch.hppc.ObjectIntMap;
|
||||
import com.carrotsearch.hppc.cursors.ObjectIntCursor;
|
||||
|
||||
import org.elasticsearch.Version;
|
||||
import org.elasticsearch.action.index.IndexRequestBuilder;
|
||||
import org.elasticsearch.action.search.SearchResponse;
|
||||
|
@ -202,7 +201,7 @@ public class GeoHashGridIT extends ESIntegTestCase {
|
|||
|
||||
public void testFiltered() throws Exception {
|
||||
GeoBoundingBoxQueryBuilder bbox = new GeoBoundingBoxQueryBuilder("location");
|
||||
bbox.setCorners(smallestGeoHash, smallestGeoHash).queryName("bbox");
|
||||
bbox.setCorners(smallestGeoHash).queryName("bbox");
|
||||
for (int precision = 1; precision <= PRECISION; precision++) {
|
||||
SearchResponse response = client().prepareSearch("idx")
|
||||
.addAggregation(
|
||||
|
|
Loading…
Reference in New Issue