Skip to content

Commit

Permalink
fix querying features that extend across tile boundaries
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
ansis committed Jan 22, 2018
1 parent 19d233e commit 6383b0d
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 4 deletions.
8 changes: 5 additions & 3 deletions src/source/source_cache.js
Original file line number Diff line number Diff line change
Expand Up @@ -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++) {
Expand All @@ -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
});
}
}
Expand Down
7 changes: 7 additions & 0 deletions src/source/tile.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ class Tile {
refreshedUponExpiration: boolean;
reloadCallback: any;
resourceTiming: ?Array<PerformanceResourceTiming>;
additionalRadius: number;

/**
* @param {OverscaledTileID} tileID
Expand Down Expand Up @@ -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;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[
{
"geometry": {
"type": "Point",
"coordinates": [
-84.3310546875,
33.92512970007199
]
},
"type": "Feature",
"properties": {}
}
]
Original file line number Diff line number Diff line change
@@ -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
}
}
]
}
7 changes: 6 additions & 1 deletion test/unit/source/source_cache.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1152,6 +1152,7 @@ test('SourceCache#tilesIn', (t) => {
const sourceCache = createSourceCache({
loadTile: function(tile, callback) {
tile.state = 'loaded';
tile.additionalRadius = 0;
callback();
}
});
Expand Down Expand Up @@ -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,
Expand Down

0 comments on commit 6383b0d

Please sign in to comment.