From 72de3da2f117f8614c317d2c19c020a56f585e55 Mon Sep 17 00:00:00 2001 From: Ansis Brammanis Date: Mon, 22 Jan 2018 17:31:49 -0500 Subject: [PATCH] fix querying features that extend across tile boundaries fix #5756 Some rendered features (circles, symbols, lines) can extend outside of the boundaries of the tile they are stored in. When querying we have to check all tiles within `additionalRadius` of the query. --- src/source/source_cache.js | 8 ++-- src/source/tile.js | 7 +++ .../circle-radius/tile-boundary/expected.json | 13 ++++++ .../circle-radius/tile-boundary/style.json | 43 +++++++++++++++++++ 4 files changed, 68 insertions(+), 3 deletions(-) create mode 100644 test/integration/query-tests/circle-radius/tile-boundary/expected.json create mode 100644 test/integration/query-tests/circle-radius/tile-boundary/style.json diff --git a/src/source/source_cache.js b/src/source/source_cache.js index 75921baf74d..8f82f9a4789 100644 --- a/src/source/source_cache.js +++ b/src/source/source_cache.js @@ -704,14 +704,16 @@ class SourceCache extends Evented { for (let i = 0; i < ids.length; i++) { const tile = this._tiles[ids[i]]; const tileID = tile.tileID; + const scale = Math.pow(2, this.transform.zoom - tile.tileID.overscaledZ) + const additionalRadius = tile.additionalRadius * EXTENT / tile.tileSize / scale; const tileSpaceBounds = [ coordinateToTilePoint(tileID, new Coordinate(minX, minY, z)), coordinateToTilePoint(tileID, new Coordinate(maxX, maxY, z)) ]; - if (tileSpaceBounds[0].x < EXTENT && tileSpaceBounds[0].y < EXTENT && - tileSpaceBounds[1].x >= 0 && tileSpaceBounds[1].y >= 0) { + if (tileSpaceBounds[0].x - additionalRadius < EXTENT && tileSpaceBounds[0].y - additionalRadius < EXTENT && + tileSpaceBounds[1].x + additionalRadius >= 0 && tileSpaceBounds[1].y + additionalRadius >= 0) { const tileSpaceQueryGeometry = []; for (let j = 0; j < queryGeometry.length; j++) { @@ -722,7 +724,7 @@ class SourceCache extends Evented { tile: tile, tileID: tileID, queryGeometry: [tileSpaceQueryGeometry], - scale: Math.pow(2, this.transform.zoom - tile.tileID.overscaledZ) + scale: scale }); } } diff --git a/src/source/tile.js b/src/source/tile.js index 048aac96af1..2c2f1be21b2 100644 --- a/src/source/tile.js +++ b/src/source/tile.js @@ -91,6 +91,7 @@ class Tile { refreshedUponExpiration: boolean; reloadCallback: any; resourceTiming: ?Array; + additionalRadius: number; /** * @param {OverscaledTileID} tileID @@ -166,6 +167,12 @@ class Tile { } } + this.additionalRadius = 0; + for (const id in this.buckets) { + const bucket = this.buckets[id]; + this.additionalRadius = Math.max(this.additionalRadius, bucket.layers[0].queryRadius(bucket)); + } + if (data.iconAtlasImage) { this.iconAtlasImage = data.iconAtlasImage; } diff --git a/test/integration/query-tests/circle-radius/tile-boundary/expected.json b/test/integration/query-tests/circle-radius/tile-boundary/expected.json new file mode 100644 index 00000000000..51c0a144bad --- /dev/null +++ b/test/integration/query-tests/circle-radius/tile-boundary/expected.json @@ -0,0 +1,13 @@ +[ + { + "geometry": { + "type": "Point", + "coordinates": [ + -84.3310546875, + 33.92512970007199 + ] + }, + "type": "Feature", + "properties": {} + } +] \ No newline at end of file diff --git a/test/integration/query-tests/circle-radius/tile-boundary/style.json b/test/integration/query-tests/circle-radius/tile-boundary/style.json new file mode 100644 index 00000000000..d0d8bafb0b1 --- /dev/null +++ b/test/integration/query-tests/circle-radius/tile-boundary/style.json @@ -0,0 +1,43 @@ +{ + "version": 8, + "metadata": { + "test": { + "debug": true, + "height": 256, + "queryGeometry": [ + 240, + 125 + ] + } + }, + "center": [ + -92.3780691249957, + 35.94102132783915 + ], + "zoom": 2, + "sources": { + "geojson": { + "type": "geojson", + "data": { + "type": "FeatureCollection", + "features": [{ + "type": "Feature", + "geometry": { + "type": "Point", + "coordinates": [-84.333565, 33.925575] + } + }] + } + } + }, + "layers": [ + { + "id": "road", + "type": "circle", + "source": "geojson", + "paint": { + "circle-radius": 100 + } + } + ] +}