Skip to content

Commit

Permalink
Geo: Fixes BoundingBox across complete longitudinal range
Browse files Browse the repository at this point in the history
Adds a special case to the GeoBoundingBoxFilterParser so that the left of the box is not normalised in the case where left and right are 360 apart.  Before this change the left would be normalised to 180 in this case and the filter would only match points with a longitude of 180 (or -180).

Closes #5128
  • Loading branch information
colings86 committed Sep 12, 2014
1 parent 3ceadd4 commit e6816e1
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 3 deletions.
Expand Up @@ -155,10 +155,17 @@ public Filter parse(QueryParseContext parseContext) throws IOException, QueryPar

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);
// Special case: if the difference bettween the left and right is 360 and the right is greater than the left, we are asking for
// the complete longitude range so need to set longitude to the complete longditude range
boolean completeLonRange = ((right - left) % 360 == 0 && right > left);
GeoUtils.normalizePoint(topLeft, true, !completeLonRange);
GeoUtils.normalizePoint(bottomRight, true, !completeLonRange);
if (completeLonRange) {
topLeft.resetLon(-180);
bottomRight.resetLon(180);
}
}

MapperService.SmartNameFieldMappers smartMappers = parseContext.smartFieldMappers(fieldName);
Expand Down
Expand Up @@ -261,5 +261,80 @@ public void limit2BoundingBoxTest() throws Exception {
).execute().actionGet();
assertThat(searchResponse.getHits().totalHits(), equalTo(1l));
}

@Test
public void completeLonRangeTest() throws Exception {
XContentBuilder xContentBuilder = XContentFactory.jsonBuilder().startObject().startObject("type1")
.startObject("properties").startObject("location").field("type", "geo_point").field("lat_lon", true).endObject().endObject()
.endObject().endObject();
assertAcked(prepareCreate("test").addMapping("type1", xContentBuilder));
ensureGreen();

client().prepareIndex("test", "type1", "1").setSource(jsonBuilder().startObject()
.field("userid", 880)
.field("title", "Place in Stockholm")
.startObject("location").field("lat", 59.328355000000002).field("lon", 18.036842).endObject()
.endObject())
.setRefresh(true)
.execute().actionGet();

client().prepareIndex("test", "type1", "2").setSource(jsonBuilder().startObject()
.field("userid", 534)
.field("title", "Place in Montreal")
.startObject("location").field("lat", 45.509526999999999).field("lon", -73.570986000000005).endObject()
.endObject())
.setRefresh(true)
.execute().actionGet();

SearchResponse searchResponse = client().prepareSearch()
.setQuery(
filteredQuery(matchAllQuery(),
geoBoundingBoxFilter("location").topLeft(50, -180).bottomRight(-50, 180))
).execute().actionGet();
assertThat(searchResponse.getHits().totalHits(), equalTo(1l));
searchResponse = client().prepareSearch()
.setQuery(
filteredQuery(matchAllQuery(),
geoBoundingBoxFilter("location").topLeft(50, -180).bottomRight(-50, 180).type("indexed"))
).execute().actionGet();
assertThat(searchResponse.getHits().totalHits(), equalTo(1l));
searchResponse = client().prepareSearch()
.setQuery(
filteredQuery(matchAllQuery(),
geoBoundingBoxFilter("location").topLeft(90, -180).bottomRight(-90, 180))
).execute().actionGet();
assertThat(searchResponse.getHits().totalHits(), equalTo(2l));
searchResponse = client().prepareSearch()
.setQuery(
filteredQuery(matchAllQuery(),
geoBoundingBoxFilter("location").topLeft(90, -180).bottomRight(-90, 180).type("indexed"))
).execute().actionGet();
assertThat(searchResponse.getHits().totalHits(), equalTo(2l));

searchResponse = client().prepareSearch()
.setQuery(
filteredQuery(matchAllQuery(),
geoBoundingBoxFilter("location").topLeft(50, 0).bottomRight(-50, 360))
).execute().actionGet();
assertThat(searchResponse.getHits().totalHits(), equalTo(1l));
searchResponse = client().prepareSearch()
.setQuery(
filteredQuery(matchAllQuery(),
geoBoundingBoxFilter("location").topLeft(50, 0).bottomRight(-50, 360).type("indexed"))
).execute().actionGet();
assertThat(searchResponse.getHits().totalHits(), equalTo(1l));
searchResponse = client().prepareSearch()
.setQuery(
filteredQuery(matchAllQuery(),
geoBoundingBoxFilter("location").topLeft(90, 0).bottomRight(-90, 360))
).execute().actionGet();
assertThat(searchResponse.getHits().totalHits(), equalTo(2l));
searchResponse = client().prepareSearch()
.setQuery(
filteredQuery(matchAllQuery(),
geoBoundingBoxFilter("location").topLeft(90, 0).bottomRight(-90, 360).type("indexed"))
).execute().actionGet();
assertThat(searchResponse.getHits().totalHits(), equalTo(2l));
}
}

0 comments on commit e6816e1

Please sign in to comment.