Skip to content

Commit ebedd6a

Browse files
Praveen2112wendigo
authored andcommitted
Perform disjoint/contains operation on Polygon instead of Envelope
This would fix issue related to inaccuracies when converting from Geometry to BingTile. Benchmark also shows an improvement in average time per operation Before: Benchmark Mode Cnt Score Error Units BenchmarkGeometryToBingTiles.envelopeToBingTiles avgt 10 0.007 ± 0.001 ms/op BenchmarkGeometryToBingTiles.geometryToBingTiles avgt 10 172.830 ± 5.088 ms/op After: Benchmark Mode Cnt Score Error Units BenchmarkGeometryToBingTiles.envelopeToBingTiles avgt 10 0.007 ± 0.001 ms/op BenchmarkGeometryToBingTiles.geometryToBingTiles avgt 10 104.172 ± 0.749 ms/op
1 parent 3ee4e6c commit ebedd6a

File tree

4 files changed

+23
-9
lines changed

4 files changed

+23
-9
lines changed

lib/trino-geospatial-toolkit/src/main/java/io/trino/geospatial/GeometryUtils.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ public static Envelope getEnvelope(OGCGeometry ogcGeometry)
102102
}
103103
}
104104

105-
public static boolean disjoint(Envelope envelope, OGCGeometry ogcGeometry)
105+
public static boolean disjoint(Geometry polygon, OGCGeometry ogcGeometry)
106106
{
107107
GeometryCursor cursor = ogcGeometry.getEsriGeometryCursor();
108108
while (true) {
@@ -111,13 +111,13 @@ public static boolean disjoint(Envelope envelope, OGCGeometry ogcGeometry)
111111
return true;
112112
}
113113

114-
if (!GeometryEngine.disjoint(geometry, envelope, null)) {
114+
if (!GeometryEngine.disjoint(geometry, polygon, null)) {
115115
return false;
116116
}
117117
}
118118
}
119119

120-
public static boolean contains(OGCGeometry ogcGeometry, Envelope envelope)
120+
public static boolean contains(OGCGeometry ogcGeometry, Geometry polygon)
121121
{
122122
GeometryCursor cursor = ogcGeometry.getEsriGeometryCursor();
123123
while (true) {
@@ -126,7 +126,7 @@ public static boolean contains(OGCGeometry ogcGeometry, Envelope envelope)
126126
return false;
127127
}
128128

129-
if (GeometryEngine.contains(geometry, envelope, null)) {
129+
if (GeometryEngine.contains(geometry, polygon, null)) {
130130
return true;
131131
}
132132
}

plugin/trino-geospatial/src/main/java/io/trino/plugin/geospatial/BingTileFunctions.java

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
package io.trino.plugin.geospatial;
1515

1616
import com.esri.core.geometry.Envelope;
17+
import com.esri.core.geometry.Geometry;
1718
import com.esri.core.geometry.Point;
1819
import com.esri.core.geometry.ogc.OGCGeometry;
1920
import com.google.common.collect.ImmutableList;
@@ -377,7 +378,7 @@ public static Block geometryToBingTiles(@SqlType(StandardTypes.GEOMETRY) Slice i
377378
for (int x = leftUpperTile.getX(); x <= rightLowerTile.getX(); x++) {
378379
for (int y = leftUpperTile.getY(); y <= rightLowerTile.getY(); y++) {
379380
BingTile tile = BingTile.fromCoordinates(x, y, zoomLevel);
380-
if (pointOrRectangle || !disjoint(tileToEnvelope(tile), ogcGeometry)) {
381+
if (pointOrRectangle || !disjoint(tileToGeometry(tile), ogcGeometry)) {
381382
BIGINT.writeLong(blockBuilder, tile.encode());
382383
}
383384
}
@@ -533,15 +534,15 @@ private static void appendIntersectingSubtiles(
533534
int tileZoomLevel = tile.getZoomLevel();
534535
checkArgument(tileZoomLevel <= zoomLevel);
535536

536-
Envelope tileEnvelope = tileToEnvelope(tile);
537+
Geometry tileGeometry = tileToGeometry(tile);
537538
if (tileZoomLevel == zoomLevel) {
538-
if (!disjoint(tileEnvelope, ogcGeometry)) {
539+
if (!disjoint(tileGeometry, ogcGeometry)) {
539540
BIGINT.writeLong(blockBuilder, tile.encode());
540541
}
541542
return;
542543
}
543544

544-
if (contains(ogcGeometry, tileEnvelope)) {
545+
if (contains(ogcGeometry, tileGeometry)) {
545546
int subTileCount = 1 << (zoomLevel - tileZoomLevel);
546547
int minX = subTileCount * tile.getX();
547548
int minY = subTileCount * tile.getY();
@@ -553,7 +554,7 @@ private static void appendIntersectingSubtiles(
553554
return;
554555
}
555556

556-
if (disjoint(tileEnvelope, ogcGeometry)) {
557+
if (disjoint(tileGeometry, ogcGeometry)) {
557558
return;
558559
}
559560

@@ -637,6 +638,13 @@ private static Envelope tileToEnvelope(BingTile tile)
637638
return new Envelope(upperLeftCorner.getX(), lowerRightCorner.getY(), lowerRightCorner.getX(), upperLeftCorner.getY());
638639
}
639640

641+
private static Geometry tileToGeometry(BingTile tile)
642+
{
643+
Point upperLeftCorner = tileXYToLatitudeLongitude(tile.getX(), tile.getY(), tile.getZoomLevel());
644+
Point lowerRightCorner = tileXYToLatitudeLongitude(tile.getX() + 1, tile.getY() + 1, tile.getZoomLevel());
645+
return OGCGeometry.createFromEsriGeometry(new Envelope(upperLeftCorner.getX(), lowerRightCorner.getY(), lowerRightCorner.getX(), upperLeftCorner.getY()), null).getEsriGeometry();
646+
}
647+
640648
private static void checkZoomLevel(long zoomLevel)
641649
{
642650
checkCondition(zoomLevel > 0, ZOOM_LEVEL_TOO_SMALL);

plugin/trino-geospatial/src/test/java/io/trino/plugin/geospatial/TestBingTileFunctions.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -554,6 +554,10 @@ public void testLargeGeometryToBingTiles()
554554
.binding("geometry", "ST_GeometryFromText('%s')".formatted(wkt))
555555
.binding("zoom", Integer.toString(zoomLevel)))
556556
.isEqualTo(tileCount);
557+
assertThat(assertions.expression("ST_Within(geometry, geometry_union(transform(geometry_to_bing_tiles(geometry, zoom), bing_tile -> bing_tile_polygon(bing_tile))))")
558+
.binding("geometry", "ST_GeometryFromText('%s')".formatted(wkt))
559+
.binding("zoom", Integer.toString(zoomLevel)))
560+
.isEqualTo(true);
557561
}
558562
}
559563

plugin/trino-geospatial/src/test/resources/large_polygon.txt

Lines changed: 2 additions & 0 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)