Skip to content

Commit

Permalink
handle degenerated rectangles while indexing (#64122)
Browse files Browse the repository at this point in the history
We currently generate invalid polygons if a rectangle is degenerated. This commit handles those cases by generating lines or points when necessary.
  • Loading branch information
iverase authored Oct 27, 2020
1 parent 7bf32f4 commit 266f52d
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -262,13 +262,29 @@ public Void visit(Polygon polygon) {

@Override
public Void visit(Rectangle 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 {
if (r.getMinLon() > r.getMaxLon()) {
if (r.getMinLon() == GeoUtils.MAX_LON) {
Line line = new Line(new double[] {GeoUtils.MAX_LON, GeoUtils.MAX_LON}, new double[] {r.getMaxLat(), r.getMinLat()});
visit(line);
} else {
Rectangle left = new Rectangle(r.getMinLon(), GeoUtils.MAX_LON, r.getMaxLat(), r.getMinLat());
visit(left);
}
if (r.getMaxLon() == GeoUtils.MIN_LON) {
Line line = new Line(new double[] {GeoUtils.MIN_LON, GeoUtils.MIN_LON}, new double[] {r.getMaxLat(), r.getMinLat()});
visit(line);
} else {
Rectangle right = new Rectangle(GeoUtils.MIN_LON, r.getMaxLon(), r.getMaxLat(), r.getMinLat());
visit(right);
}
} else if (r.getMinLon() == r.getMaxLon() || r.getMinLat() == r.getMaxLat()) {
if (r.getMinLat() == r.getMaxLat()) {
addFields(LatLonShape.createIndexableFields(name, r.getMinLat(), r.getMinLon()));
} else {
Line line = new Line(new double[]{r.getMinLon(), r.getMaxLon()}, new double[]{r.getMaxLat(), r.getMinLat()});
visit(line);
}
} else {
addFields(LatLonShape.createIndexableFields(name, GeoShapeUtils.toLucenePolygon(r)));
}
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,66 @@ public void testRectangle() {
assertEquals(fields.size(), 4);
}

public void testDegeneratedRectangles() {
Rectangle indexed = new Rectangle(-179, -179, 10, -10);
Geometry processed = indexer.prepareForIndexing(indexed);
assertEquals(indexed, processed);

// Rectangle is a line
List<IndexableField> fields = indexer.indexShape(null, indexed);
assertEquals(fields.size(), 1);

indexed = new Rectangle(-179, -178, 10, 10);
processed = indexer.prepareForIndexing(indexed);
assertEquals(indexed, processed);

// Rectangle is a line
fields = indexer.indexShape(null, indexed);
assertEquals(fields.size(), 1);

indexed = new Rectangle(-179, -179, 10, 10);
processed = indexer.prepareForIndexing(indexed);
assertEquals(indexed, processed);

// Rectangle is a point
fields = indexer.indexShape(null, indexed);
assertEquals(fields.size(), 1);

indexed = new Rectangle(180, -179, 10, -10);
processed = indexer.prepareForIndexing(indexed);
assertEquals(indexed, processed);

// Rectangle crossing the dateline, one side is a line
fields = indexer.indexShape(null, indexed);
assertEquals(fields.size(), 3);

indexed = new Rectangle(180, -179, 10, 10);
processed = indexer.prepareForIndexing(indexed);
assertEquals(indexed, processed);

// Rectangle crossing the dateline, one side is a point,
// other side a line
fields = indexer.indexShape(null, indexed);
assertEquals(fields.size(), 2);

indexed = new Rectangle(-178, -180, 10, -10);
processed = indexer.prepareForIndexing(indexed);
assertEquals(indexed, processed);

// Rectangle crossing the dateline, one side is a line
fields = indexer.indexShape(null, indexed);
assertEquals(fields.size(), 3);

indexed = new Rectangle(-178, -180, 10, 10);
processed = indexer.prepareForIndexing(indexed);
assertEquals(indexed, processed);

// Rectangle crossing the dateline, one side is a point,
// other side a line
fields = indexer.indexShape(null, indexed);
assertEquals(fields.size(), 2);
}

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(
Expand Down

0 comments on commit 266f52d

Please sign in to comment.