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 java.util.Collection;
|
||||||
|
|
||||||
import org.apache.lucene.spatial.geopoint.document.GeoPointField;
|
import org.apache.lucene.spatial.geopoint.document.GeoPointField;
|
||||||
|
import org.apache.lucene.geo.Rectangle;
|
||||||
import org.apache.lucene.util.BitUtil;
|
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];
|
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.
|
* Calculate all neighbors of a given geohash cell.
|
||||||
*
|
*
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
package org.elasticsearch.index.query;
|
package org.elasticsearch.index.query;
|
||||||
|
|
||||||
|
import org.apache.lucene.geo.Rectangle;
|
||||||
import org.apache.lucene.search.MatchNoDocsQuery;
|
import org.apache.lucene.search.MatchNoDocsQuery;
|
||||||
import org.apache.lucene.search.Query;
|
import org.apache.lucene.search.Query;
|
||||||
import org.apache.lucene.spatial.geopoint.document.GeoPointField;
|
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.Numbers;
|
||||||
import org.elasticsearch.common.ParseField;
|
import org.elasticsearch.common.ParseField;
|
||||||
import org.elasticsearch.common.ParsingException;
|
import org.elasticsearch.common.ParsingException;
|
||||||
|
import org.elasticsearch.common.geo.GeoHashUtils;
|
||||||
import org.elasticsearch.common.geo.GeoPoint;
|
import org.elasticsearch.common.geo.GeoPoint;
|
||||||
import org.elasticsearch.common.geo.GeoUtils;
|
import org.elasticsearch.common.geo.GeoUtils;
|
||||||
import org.elasticsearch.common.io.stream.StreamInput;
|
import org.elasticsearch.common.io.stream.StreamInput;
|
||||||
|
@ -155,7 +157,13 @@ public class GeoBoundingBoxQueryBuilder extends AbstractQueryBuilder<GeoBounding
|
||||||
if (top < bottom) {
|
if (top < bottom) {
|
||||||
throw new IllegalArgumentException("top is below bottom corner: " +
|
throw new IllegalArgumentException("top is below bottom corner: " +
|
||||||
top + " vs. " + bottom);
|
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
|
// 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());
|
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.
|
* Adds points.
|
||||||
* @param topLeft topLeft point to add as geohash.
|
* @param topLeft topLeft point to add as geohash.
|
||||||
|
|
|
@ -349,7 +349,7 @@ public class GeoBoundingBoxQueryBuilderTests extends AbstractQueryTestCase<GeoBo
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void fillIn(double coordinate, GeoBoundingBoxQueryBuilder qb) {
|
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.ObjectIntHashMap;
|
||||||
import com.carrotsearch.hppc.ObjectIntMap;
|
import com.carrotsearch.hppc.ObjectIntMap;
|
||||||
import com.carrotsearch.hppc.cursors.ObjectIntCursor;
|
import com.carrotsearch.hppc.cursors.ObjectIntCursor;
|
||||||
|
|
||||||
import org.elasticsearch.Version;
|
import org.elasticsearch.Version;
|
||||||
import org.elasticsearch.action.index.IndexRequestBuilder;
|
import org.elasticsearch.action.index.IndexRequestBuilder;
|
||||||
import org.elasticsearch.action.search.SearchResponse;
|
import org.elasticsearch.action.search.SearchResponse;
|
||||||
|
@ -202,7 +201,7 @@ public class GeoHashGridIT extends ESIntegTestCase {
|
||||||
|
|
||||||
public void testFiltered() throws Exception {
|
public void testFiltered() throws Exception {
|
||||||
GeoBoundingBoxQueryBuilder bbox = new GeoBoundingBoxQueryBuilder("location");
|
GeoBoundingBoxQueryBuilder bbox = new GeoBoundingBoxQueryBuilder("location");
|
||||||
bbox.setCorners(smallestGeoHash, smallestGeoHash).queryName("bbox");
|
bbox.setCorners(smallestGeoHash).queryName("bbox");
|
||||||
for (int precision = 1; precision <= PRECISION; precision++) {
|
for (int precision = 1; precision <= PRECISION; precision++) {
|
||||||
SearchResponse response = client().prepareSearch("idx")
|
SearchResponse response = client().prepareSearch("idx")
|
||||||
.addAggregation(
|
.addAggregation(
|
||||||
|
|
Loading…
Reference in New Issue