diff --git a/src/source/source_cache.js b/src/source/source_cache.js index 0c97e2fcc79..3b5836c220e 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 e67efa40609..2c4c4fefebb 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, painter.style.getLayer(bucket.layerIds[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 + } + } + ] +} diff --git a/test/unit/source/source_cache.test.js b/test/unit/source/source_cache.test.js index 0986b0f7773..5e0cb00fa60 100644 --- a/test/unit/source/source_cache.test.js +++ b/test/unit/source/source_cache.test.js @@ -1152,6 +1152,7 @@ test('SourceCache#tilesIn', (t) => { const sourceCache = createSourceCache({ loadTile: function(tile, callback) { tile.state = 'loaded'; + tile.additionalRadius = 0; callback(); } }); @@ -1193,7 +1194,11 @@ test('SourceCache#tilesIn', (t) => { t.test('reparsed overscaled tiles', (t) => { const sourceCache = createSourceCache({ - loadTile: function(tile, callback) { tile.state = 'loaded'; callback(); }, + loadTile: function(tile, callback) { + tile.state = 'loaded'; + tile.additionalRadius = 0; + callback(); + }, reparseOverscaled: true, minzoom: 1, maxzoom: 1,