Skip to content

Commit 266f52d

Browse files
authored
handle degenerated rectangles while indexing (#64122)
We currently generate invalid polygons if a rectangle is degenerated. This commit handles those cases by generating lines or points when necessary.
1 parent 7bf32f4 commit 266f52d

File tree

2 files changed

+83
-7
lines changed

2 files changed

+83
-7
lines changed

server/src/main/java/org/elasticsearch/index/mapper/GeoShapeIndexer.java

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -262,13 +262,29 @@ public Void visit(Polygon polygon) {
262262

263263
@Override
264264
public Void visit(Rectangle r) {
265-
if (r.getMinLon() > r.getMaxLon()) {
266-
Rectangle left = new Rectangle(r.getMinLon(), GeoUtils.MAX_LON, r.getMaxLat(), r.getMinLat());
267-
addFields(LatLonShape.createIndexableFields(name, GeoShapeUtils.toLucenePolygon(left)));
268-
Rectangle right = new Rectangle(GeoUtils.MIN_LON, r.getMaxLon(), r.getMaxLat(), r.getMinLat());
269-
addFields(LatLonShape.createIndexableFields(name, GeoShapeUtils.toLucenePolygon(right)));
270-
271-
} else {
265+
if (r.getMinLon() > r.getMaxLon()) {
266+
if (r.getMinLon() == GeoUtils.MAX_LON) {
267+
Line line = new Line(new double[] {GeoUtils.MAX_LON, GeoUtils.MAX_LON}, new double[] {r.getMaxLat(), r.getMinLat()});
268+
visit(line);
269+
} else {
270+
Rectangle left = new Rectangle(r.getMinLon(), GeoUtils.MAX_LON, r.getMaxLat(), r.getMinLat());
271+
visit(left);
272+
}
273+
if (r.getMaxLon() == GeoUtils.MIN_LON) {
274+
Line line = new Line(new double[] {GeoUtils.MIN_LON, GeoUtils.MIN_LON}, new double[] {r.getMaxLat(), r.getMinLat()});
275+
visit(line);
276+
} else {
277+
Rectangle right = new Rectangle(GeoUtils.MIN_LON, r.getMaxLon(), r.getMaxLat(), r.getMinLat());
278+
visit(right);
279+
}
280+
} else if (r.getMinLon() == r.getMaxLon() || r.getMinLat() == r.getMaxLat()) {
281+
if (r.getMinLat() == r.getMaxLat()) {
282+
addFields(LatLonShape.createIndexableFields(name, r.getMinLat(), r.getMinLon()));
283+
} else {
284+
Line line = new Line(new double[]{r.getMinLon(), r.getMaxLon()}, new double[]{r.getMaxLat(), r.getMinLat()});
285+
visit(line);
286+
}
287+
} else {
272288
addFields(LatLonShape.createIndexableFields(name, GeoShapeUtils.toLucenePolygon(r)));
273289
}
274290
return null;

server/src/test/java/org/elasticsearch/common/geo/GeometryIndexerTests.java

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,66 @@ public void testRectangle() {
316316
assertEquals(fields.size(), 4);
317317
}
318318

319+
public void testDegeneratedRectangles() {
320+
Rectangle indexed = new Rectangle(-179, -179, 10, -10);
321+
Geometry processed = indexer.prepareForIndexing(indexed);
322+
assertEquals(indexed, processed);
323+
324+
// Rectangle is a line
325+
List<IndexableField> fields = indexer.indexShape(null, indexed);
326+
assertEquals(fields.size(), 1);
327+
328+
indexed = new Rectangle(-179, -178, 10, 10);
329+
processed = indexer.prepareForIndexing(indexed);
330+
assertEquals(indexed, processed);
331+
332+
// Rectangle is a line
333+
fields = indexer.indexShape(null, indexed);
334+
assertEquals(fields.size(), 1);
335+
336+
indexed = new Rectangle(-179, -179, 10, 10);
337+
processed = indexer.prepareForIndexing(indexed);
338+
assertEquals(indexed, processed);
339+
340+
// Rectangle is a point
341+
fields = indexer.indexShape(null, indexed);
342+
assertEquals(fields.size(), 1);
343+
344+
indexed = new Rectangle(180, -179, 10, -10);
345+
processed = indexer.prepareForIndexing(indexed);
346+
assertEquals(indexed, processed);
347+
348+
// Rectangle crossing the dateline, one side is a line
349+
fields = indexer.indexShape(null, indexed);
350+
assertEquals(fields.size(), 3);
351+
352+
indexed = new Rectangle(180, -179, 10, 10);
353+
processed = indexer.prepareForIndexing(indexed);
354+
assertEquals(indexed, processed);
355+
356+
// Rectangle crossing the dateline, one side is a point,
357+
// other side a line
358+
fields = indexer.indexShape(null, indexed);
359+
assertEquals(fields.size(), 2);
360+
361+
indexed = new Rectangle(-178, -180, 10, -10);
362+
processed = indexer.prepareForIndexing(indexed);
363+
assertEquals(indexed, processed);
364+
365+
// Rectangle crossing the dateline, one side is a line
366+
fields = indexer.indexShape(null, indexed);
367+
assertEquals(fields.size(), 3);
368+
369+
indexed = new Rectangle(-178, -180, 10, 10);
370+
processed = indexer.prepareForIndexing(indexed);
371+
assertEquals(indexed, processed);
372+
373+
// Rectangle crossing the dateline, one side is a point,
374+
// other side a line
375+
fields = indexer.indexShape(null, indexed);
376+
assertEquals(fields.size(), 2);
377+
}
378+
319379
public void testPolygon() {
320380
Polygon polygon = new Polygon(new LinearRing(new double[]{160, 200, 200, 160, 160}, new double[]{10, 10, 20, 20, 10}));
321381
Geometry indexed = new MultiPolygon(Arrays.asList(

0 commit comments

Comments
 (0)