diff --git a/src/ol/VectorRenderTile.js b/src/ol/VectorRenderTile.js index 79d539859e..a22a38991a 100644 --- a/src/ol/VectorRenderTile.js +++ b/src/ol/VectorRenderTile.js @@ -61,9 +61,9 @@ class VectorRenderTile extends Tile { this.errorSourceTileKeys = {}; /** - * @type {ImageData} + * @type {Object} */ - this.hitDetectionImageData = null; + this.hitDetectionImageData = {}; /** * @private diff --git a/src/ol/renderer/canvas/VectorLayer.js b/src/ol/renderer/canvas/VectorLayer.js index f543ad659a..b451a01b88 100644 --- a/src/ol/renderer/canvas/VectorLayer.js +++ b/src/ol/renderer/canvas/VectorLayer.js @@ -232,49 +232,45 @@ class CanvasVectorLayerRenderer extends CanvasLayerRenderer { getFeatures(pixel) { return new Promise(function(resolve, reject) { if (!this.hitDetectionImageData_ && !this.animatingOrInteracting_) { - requestAnimationFrame(function() { - const size = [this.context.canvas.width, this.context.canvas.height]; - apply(this.pixelTransform, size); - const center = this.renderedCenter_; - const resolution = this.renderedResolution_; - const rotation = this.renderedRotation_; - const projection = this.renderedProjection_; - const extent = this.renderedExtent_; - const layer = this.getLayer(); - const transforms = []; - const width = size[0] / 2; - const height = size[1] / 2; - transforms.push(this.getRenderTransform(center, resolution, rotation, 0.5, width, height, 0).slice()); - const source = layer.getSource(); - const projectionExtent = projection.getExtent(); - if (source.getWrapX() && projection.canWrapX() && !containsExtent(projectionExtent, extent)) { - let startX = extent[0]; - const worldWidth = getWidth(projectionExtent); - let world = 0; - let offsetX; - while (startX < projectionExtent[0]) { - --world; - offsetX = worldWidth * world; - transforms.push(this.getRenderTransform(center, resolution, rotation, 0.5, width, height, offsetX).slice()); - startX += worldWidth; - } - world = 0; - startX = extent[2]; - while (startX > projectionExtent[2]) { - ++world; - offsetX = worldWidth * world; - transforms.push(this.getRenderTransform(center, resolution, rotation, 0.5, width, height, offsetX).slice()); - startX -= worldWidth; - } + const size = [this.context.canvas.width, this.context.canvas.height]; + apply(this.pixelTransform, size); + const center = this.renderedCenter_; + const resolution = this.renderedResolution_; + const rotation = this.renderedRotation_; + const projection = this.renderedProjection_; + const extent = this.renderedExtent_; + const layer = this.getLayer(); + const transforms = []; + const width = size[0] / 2; + const height = size[1] / 2; + transforms.push(this.getRenderTransform(center, resolution, rotation, 0.5, width, height, 0).slice()); + const source = layer.getSource(); + const projectionExtent = projection.getExtent(); + if (source.getWrapX() && projection.canWrapX() && !containsExtent(projectionExtent, extent)) { + let startX = extent[0]; + const worldWidth = getWidth(projectionExtent); + let world = 0; + let offsetX; + while (startX < projectionExtent[0]) { + --world; + offsetX = worldWidth * world; + transforms.push(this.getRenderTransform(center, resolution, rotation, 0.5, width, height, offsetX).slice()); + startX += worldWidth; } + world = 0; + startX = extent[2]; + while (startX > projectionExtent[2]) { + ++world; + offsetX = worldWidth * world; + transforms.push(this.getRenderTransform(center, resolution, rotation, 0.5, width, height, offsetX).slice()); + startX -= worldWidth; + } + } - this.hitDetectionImageData_ = createHitDetectionImageData(size, transforms, - this.renderedFeatures_, layer.getStyleFunction(), extent, resolution, rotation); - resolve(hitDetect(pixel, this.renderedFeatures_, this.hitDetectionImageData_)); - }.bind(this)); - } else { - resolve(hitDetect(pixel, this.renderedFeatures_, this.hitDetectionImageData_)); + this.hitDetectionImageData_ = createHitDetectionImageData(size, transforms, + this.renderedFeatures_, layer.getStyleFunction(), extent, resolution, rotation); } + resolve(hitDetect(pixel, this.renderedFeatures_, this.hitDetectionImageData_)); }.bind(this)); } diff --git a/src/ol/renderer/canvas/VectorTileLayer.js b/src/ol/renderer/canvas/VectorTileLayer.js index 0b6c80d335..df3e1b8011 100644 --- a/src/ol/renderer/canvas/VectorTileLayer.js +++ b/src/ol/renderer/canvas/VectorTileLayer.js @@ -221,7 +221,7 @@ class CanvasVectorTileLayerRenderer extends CanvasTileLayerRenderer { executorGroups[i].dispose(); } } - tile.hitDetectionImageData = null; + delete tile.hitDetectionImageData[layerUid]; tile.executorGroups[layerUid] = []; for (let t = 0, tt = sourceTiles.length; t < tt; ++t) { const sourceTile = sourceTiles[t]; @@ -341,6 +341,7 @@ class CanvasVectorTileLayerRenderer extends CanvasTileLayerRenderer { getFeatures(pixel) { return new Promise(function(resolve, reject) { const layer = /** @type {import("../../layer/VectorTile.js").default} */ (this.getLayer()); + const layerUid = getUid(layer); const source = layer.getSource(); const projection = this.renderedProjection; const projectionExtent = projection.getExtent(); @@ -377,7 +378,8 @@ class CanvasVectorTileLayerRenderer extends CanvasTileLayerRenderer { const features = tile.getSourceTiles().reduce(function(accumulator, sourceTile) { return accumulator.concat(sourceTile.getFeatures()); }, []); - if (!tile.hitDetectionImageData) { + let hitDetectionImageData = tile.hitDetectionImageData[layerUid]; + if (!hitDetectionImageData && !this.animatingOrInteracting_) { const tileSize = toSize(tileGrid.getTileSize(tileGrid.getZForResolution(resolution))); const size = [tileSize[0] / 2, tileSize[1] / 2]; const rotation = this.renderedRotation_; @@ -385,16 +387,13 @@ class CanvasVectorTileLayerRenderer extends CanvasTileLayerRenderer { this.getRenderTransform(tileGrid.getTileCoordCenter(tile.wrappedTileCoord), resolution, 0, 0.5, size[0], size[1], 0) ]; - requestAnimationFrame(function() { - tile.hitDetectionImageData = createHitDetectionImageData(tileSize, transforms, - features, layer.getStyleFunction(), - tileGrid.getTileCoordExtent(tile.wrappedTileCoord), - tile.getReplayState(layer).renderedResolution, rotation); - resolve(hitDetect(tilePixel, features, tile.hitDetectionImageData)); - }); - } else { - resolve(hitDetect(tilePixel, features, tile.hitDetectionImageData)); + hitDetectionImageData = createHitDetectionImageData(tileSize, transforms, + features, layer.getStyleFunction(), + tileGrid.getTileCoordExtent(tile.wrappedTileCoord), + tile.getReplayState(layer).renderedResolution, rotation); + tile.hitDetectionImageData[layerUid] = hitDetectionImageData; } + resolve(hitDetect(tilePixel, features, hitDetectionImageData)); }.bind(this)); }