When indexing a rectangle that crosses the dateline, we are currently not handling it properly and we index a polygon that do not cross the dateline. This changes generates two polygons wrapping the dateline.
This commit is contained in:
parent
cde8725e3c
commit
efd1838206
|
@ -26,6 +26,7 @@ import org.elasticsearch.common.geo.GeoLineDecomposer;
|
|||
import org.elasticsearch.common.geo.GeoPolygonDecomposer;
|
||||
import org.elasticsearch.common.geo.GeoShapeUtils;
|
||||
import org.elasticsearch.common.geo.GeoShapeType;
|
||||
import org.elasticsearch.common.geo.GeoUtils;
|
||||
import org.elasticsearch.geometry.Circle;
|
||||
import org.elasticsearch.geometry.Geometry;
|
||||
import org.elasticsearch.geometry.GeometryCollection;
|
||||
|
@ -261,7 +262,15 @@ public final class GeoShapeIndexer implements AbstractGeometryFieldMapper.Indexe
|
|||
|
||||
@Override
|
||||
public Void visit(Rectangle r) {
|
||||
addFields(LatLonShape.createIndexableFields(name, GeoShapeUtils.toLucenePolygon(r)));
|
||||
if (r.getMinLon() > r.getMaxLon()) {
|
||||
Rectangle left = new Rectangle(r.getMinLon(), GeoUtils.MAX_LON, r.getMaxLat(), r.getMinLat());
|
||||
addFields(LatLonShape.createIndexableFields(name, GeoShapeUtils.toLucenePolygon(left)));
|
||||
Rectangle right = new Rectangle(GeoUtils.MIN_LON, r.getMaxLon(), r.getMaxLat(), r.getMinLat());
|
||||
addFields(LatLonShape.createIndexableFields(name, GeoShapeUtils.toLucenePolygon(right)));
|
||||
|
||||
} else {
|
||||
addFields(LatLonShape.createIndexableFields(name, GeoShapeUtils.toLucenePolygon(r)));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
package org.elasticsearch.common.geo;
|
||||
|
||||
import org.apache.lucene.index.IndexableField;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.common.xcontent.XContentFactory;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
|
@ -33,6 +34,7 @@ import org.elasticsearch.geometry.MultiPoint;
|
|||
import org.elasticsearch.geometry.MultiPolygon;
|
||||
import org.elasticsearch.geometry.Point;
|
||||
import org.elasticsearch.geometry.Polygon;
|
||||
import org.elasticsearch.geometry.Rectangle;
|
||||
import org.elasticsearch.index.mapper.GeoShapeIndexer;
|
||||
import org.elasticsearch.test.ESTestCase;
|
||||
import java.io.IOException;
|
||||
|
@ -292,6 +294,24 @@ public class GeometryIndexerTests extends ESTestCase {
|
|||
assertEquals(indexed, indexer.prepareForIndexing(multiPoint));
|
||||
}
|
||||
|
||||
public void testRectangle() {
|
||||
Rectangle indexed = new Rectangle(-179, -178, 10, -10);
|
||||
Geometry processed = indexer.prepareForIndexing(indexed);
|
||||
assertEquals(indexed, processed);
|
||||
|
||||
// a rectangle is broken into two triangles
|
||||
List<IndexableField> fields = indexer.indexShape(null, indexed);
|
||||
assertEquals(fields.size(), 2);
|
||||
|
||||
indexed = new Rectangle(179, -179, 10, -10);
|
||||
processed = indexer.prepareForIndexing(indexed);
|
||||
assertEquals(indexed, processed);
|
||||
|
||||
// a rectangle crossing the dateline is broken into 4 triangles
|
||||
fields = indexer.indexShape(null, indexed);
|
||||
assertEquals(fields.size(), 4);
|
||||
}
|
||||
|
||||
public void testPolygon() {
|
||||
Polygon polygon = new Polygon(new LinearRing(new double[]{160, 200, 200, 160, 160}, new double[]{10, 10, 20, 20, 10}));
|
||||
Geometry indexed = new MultiPolygon(Arrays.asList(
|
||||
|
|
|
@ -799,4 +799,23 @@ public class GeoShapeQueryTests extends GeoQueryTests {
|
|||
assertEquals(0, response.getHits().getTotalHits().value);
|
||||
}
|
||||
|
||||
public void testIndexRectangleSpanningDateLine() throws Exception {
|
||||
String mapping = Strings.toString(createRandomMapping());
|
||||
|
||||
client().admin().indices().prepareCreate("test").addMapping("type1", mapping, XContentType.JSON).get();
|
||||
ensureGreen();
|
||||
|
||||
EnvelopeBuilder envelopeBuilder = new EnvelopeBuilder(new Coordinate(178, 10), new Coordinate(-178, -10));
|
||||
|
||||
XContentBuilder docSource = envelopeBuilder.toXContent(jsonBuilder().startObject().field("geo"), null).endObject();
|
||||
client().prepareIndex("test", "type1", "1").setSource(docSource).setRefreshPolicy(IMMEDIATE).get();
|
||||
|
||||
ShapeBuilder filterShape = new PointBuilder(179, 0);
|
||||
|
||||
GeoShapeQueryBuilder geoShapeQueryBuilder = QueryBuilders.geoShapeQuery("geo", filterShape);
|
||||
geoShapeQueryBuilder.relation(ShapeRelation.INTERSECTS);
|
||||
SearchResponse result = client().prepareSearch("test").setQuery(geoShapeQueryBuilder).get();
|
||||
assertSearchResponse(result);
|
||||
assertHitCount(result, 1);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue