Skip to content

[8.5] Fix handling indexed envelopes crossing the dateline in mvt API (#91105) #91254

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Nov 2, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions docs/changelog/91105.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
pr: 91105
summary: Fix handling indexed envelopes crossing the dateline in mvt API
area: Geo
type: bug
issues:
- 91060
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,61 @@ private Geometry normalize(Geometry geometry) {
}
}

public void testFetchSourceValueDateLine() throws IOException {
public void testFetchSourcePolygonDateLine() throws IOException {
assertFetchSourceGeometry(
"POLYGON((170 -10, -170 -10, -170 10, 170 10, 170 -10))",
"MULTIPOLYGON (((180.0 -10.0, 180.0 10.0, 170.0 10.0, 170.0 -10.0, 180.0 -10.0)),"
+ "((-180.0 10.0, -180.0 -10.0, -170.0 -10.0, -170.0 10.0, -180.0 10.0)))",
Map.of(
"type",
"MultiPolygon",
"coordinates",
List.of(
List.of(
List.of(
List.of(180.0, -10.0),
List.of(180.0, 10.0),
List.of(170.0, 10.0),
List.of(170.0, -10.0),
List.of(180.0, -10.0)
)
),
List.of(
List.of(
List.of(-180.0, 10.0),
List.of(-180.0, -10.0),
List.of(-170.0, -10.0),
List.of(-170.0, 10.0),
List.of(-180.0, 10.0)
)
)
)
),
"MULTIPOLYGON (((180.0 -10.0, 180.0 10.0, 170.0 10.0, 170.0 -10.0, 180.0 -10.0)),"
+ "((-180.0 10.0, -180.0 -10.0, -170.0 -10.0, -170.0 10.0, -180.0 10.0)))"
);
}

public void testFetchSourceEnvelope() throws IOException {
assertFetchSourceGeometry(
"BBOX(-10, 10, 10, -10)",
"BBOX (-10.0, 10.0, 10.0, -10.0)",
Map.of("type", "Envelope", "coordinates", List.of(List.of(-10.0, 10.0), List.of(10.0, -10.0))),
"POLYGON ((-10 -10, 10 -10, 10 10, -10 10, -10 -10)))"
);
}

public void testFetchSourceEnvelopeDateLine() throws IOException {
assertFetchSourceGeometry(
"BBOX(10, -10, 10, -10)",
"BBOX (10.0, -10.0, 10.0, -10.0)",
Map.of("type", "Envelope", "coordinates", List.of(List.of(10.0, 10.0), List.of(-10.0, -10.0))),
"MULTIPOLYGON (((-180 -10, -10 -10, -10 10, -180 10, -180 -10)), ((10 -10, 180 -10, 180 10, 10 10, 10 -10)))"
);
}

private void assertFetchSourceGeometry(Object sourceValue, String wktValue, Map<String, Object> jsonValue, String mvtEquivalentAsWKT)
throws IOException {
final GeoFormatterFactory<Geometry> geoFormatterFactory = new GeoFormatterFactory<>(
new SpatialGeometryFormatterExtension().getGeometryFormatterFactories()
);
Expand All @@ -161,38 +215,13 @@ public void testFetchSourceValueDateLine() throws IOException {
false,
geoFormatterFactory
).build(MapperBuilderContext.ROOT).fieldType();
// Test a polygon crossing the dateline
Object sourceValue = "POLYGON((170 -10, -170 -10, -170 10, 170 10, 170 -10))";
String polygonDateLine = "MULTIPOLYGON (((180.0 -10.0, 180.0 10.0, 170.0 10.0, 170.0 -10.0, 180.0 -10.0)),"
+ "((-180.0 10.0, -180.0 -10.0, -170.0 -10.0, -170.0 10.0, -180.0 10.0)))";
Map<String, Object> jsonPolygonDateLine = Map.of(
"type",
"MultiPolygon",
"coordinates",
List.of(
List.of(
List.of(List.of(180.0, -10.0), List.of(180.0, 10.0), List.of(170.0, 10.0), List.of(170.0, -10.0), List.of(180.0, -10.0))
),
List.of(
List.of(
List.of(-180.0, 10.0),
List.of(-180.0, -10.0),
List.of(-170.0, -10.0),
List.of(-170.0, 10.0),
List.of(-180.0, 10.0)
)
)
)
);

assertEquals(List.of(jsonPolygonDateLine), fetchSourceValue(mapper, sourceValue, null));
assertEquals(List.of(polygonDateLine), fetchSourceValue(mapper, sourceValue, "wkt"));

String mvtPolygonDateLine = "MULTIPOLYGON (((180.0 -10.0, 180.0 10.0, 170.0 10.0, 170.0 -10.0, 180.0 -10.0)),"
+ "((-180.0 10.0, -180.0 -10.0, -170.0 -10.0, -170.0 10.0, -180.0 10.0)))";
assertEquals(List.of(jsonValue), fetchSourceValue(mapper, sourceValue, null));
assertEquals(List.of(wktValue), fetchSourceValue(mapper, sourceValue, "wkt"));

List<?> mvtExpected = fetchSourceValue(mapper, mvtPolygonDateLine, "mvt(0/0/0@256)");
List<?> mvt = fetchSourceValue(mapper, sourceValue, "mvt(0/0/0@256)");
final int extent = randomIntBetween(256, 4096);
List<?> mvtExpected = fetchSourceValue(mapper, mvtEquivalentAsWKT, "mvt(0/0/0@" + extent + ")");
List<?> mvt = fetchSourceValue(mapper, sourceValue, "mvt(0/0/0@" + extent + ")");
assertThat(mvt.size(), Matchers.equalTo(1));
assertThat(mvt.size(), Matchers.equalTo(mvtExpected.size()));
assertThat(mvtExpected.get(0), Matchers.instanceOf(byte[].class));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -288,8 +288,15 @@ public org.locationtech.jts.geom.Geometry visit(Rectangle rectangle) throws Runt
final double yMin = SphericalMercatorUtils.latToSphericalMercator(rectangle.getMinY());
final double xMax = SphericalMercatorUtils.lonToSphericalMercator(rectangle.getMaxX());
final double yMax = SphericalMercatorUtils.latToSphericalMercator(rectangle.getMaxY());
final Envelope envelope = new Envelope(xMin, xMax, yMin, yMax);
return geomFactory.toGeometry(envelope);
if (rectangle.getMinX() > rectangle.getMaxX()) {
// crosses dateline
final Envelope westEnvelope = new Envelope(-SphericalMercatorUtils.MERCATOR_BOUNDS, xMax, yMin, yMax);
final Envelope eastEnvelope = new Envelope(xMin, SphericalMercatorUtils.MERCATOR_BOUNDS, yMin, yMax);
return geomFactory.buildGeometry(List.of(geomFactory.toGeometry(westEnvelope), geomFactory.toGeometry(eastEnvelope)));
} else {
final Envelope envelope = new Envelope(xMin, xMax, yMin, yMax);
return geomFactory.toGeometry(envelope);
}
}
}

Expand Down