Create hit detection data per layer and without requestAnimationFrame

This commit is contained in:
Andreas Hocevar
2019-11-17 21:01:12 +01:00
parent 32932a7fd3
commit 9317ad850e
3 changed files with 48 additions and 53 deletions
+2 -2
View File
@@ -61,9 +61,9 @@ class VectorRenderTile extends Tile {
this.errorSourceTileKeys = {}; this.errorSourceTileKeys = {};
/** /**
* @type {ImageData} * @type {Object<number, ImageData>}
*/ */
this.hitDetectionImageData = null; this.hitDetectionImageData = {};
/** /**
* @private * @private
+36 -40
View File
@@ -232,49 +232,45 @@ class CanvasVectorLayerRenderer extends CanvasLayerRenderer {
getFeatures(pixel) { getFeatures(pixel) {
return new Promise(function(resolve, reject) { return new Promise(function(resolve, reject) {
if (!this.hitDetectionImageData_ && !this.animatingOrInteracting_) { if (!this.hitDetectionImageData_ && !this.animatingOrInteracting_) {
requestAnimationFrame(function() { const size = [this.context.canvas.width, this.context.canvas.height];
const size = [this.context.canvas.width, this.context.canvas.height]; apply(this.pixelTransform, size);
apply(this.pixelTransform, size); const center = this.renderedCenter_;
const center = this.renderedCenter_; const resolution = this.renderedResolution_;
const resolution = this.renderedResolution_; const rotation = this.renderedRotation_;
const rotation = this.renderedRotation_; const projection = this.renderedProjection_;
const projection = this.renderedProjection_; const extent = this.renderedExtent_;
const extent = this.renderedExtent_; const layer = this.getLayer();
const layer = this.getLayer(); const transforms = [];
const transforms = []; const width = size[0] / 2;
const width = size[0] / 2; const height = size[1] / 2;
const height = size[1] / 2; transforms.push(this.getRenderTransform(center, resolution, rotation, 0.5, width, height, 0).slice());
transforms.push(this.getRenderTransform(center, resolution, rotation, 0.5, width, height, 0).slice()); const source = layer.getSource();
const source = layer.getSource(); const projectionExtent = projection.getExtent();
const projectionExtent = projection.getExtent(); if (source.getWrapX() && projection.canWrapX() && !containsExtent(projectionExtent, extent)) {
if (source.getWrapX() && projection.canWrapX() && !containsExtent(projectionExtent, extent)) { let startX = extent[0];
let startX = extent[0]; const worldWidth = getWidth(projectionExtent);
const worldWidth = getWidth(projectionExtent); let world = 0;
let world = 0; let offsetX;
let offsetX; while (startX < projectionExtent[0]) {
while (startX < projectionExtent[0]) { --world;
--world; offsetX = worldWidth * world;
offsetX = worldWidth * world; transforms.push(this.getRenderTransform(center, resolution, rotation, 0.5, width, height, offsetX).slice());
transforms.push(this.getRenderTransform(center, resolution, rotation, 0.5, width, height, offsetX).slice()); startX += worldWidth;
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;
}
} }
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.hitDetectionImageData_ = createHitDetectionImageData(size, transforms,
this.renderedFeatures_, layer.getStyleFunction(), extent, resolution, rotation); this.renderedFeatures_, layer.getStyleFunction(), extent, resolution, rotation);
resolve(hitDetect(pixel, this.renderedFeatures_, this.hitDetectionImageData_));
}.bind(this));
} else {
resolve(hitDetect(pixel, this.renderedFeatures_, this.hitDetectionImageData_));
} }
resolve(hitDetect(pixel, this.renderedFeatures_, this.hitDetectionImageData_));
}.bind(this)); }.bind(this));
} }
+10 -11
View File
@@ -221,7 +221,7 @@ class CanvasVectorTileLayerRenderer extends CanvasTileLayerRenderer {
executorGroups[i].dispose(); executorGroups[i].dispose();
} }
} }
tile.hitDetectionImageData = null; delete tile.hitDetectionImageData[layerUid];
tile.executorGroups[layerUid] = []; tile.executorGroups[layerUid] = [];
for (let t = 0, tt = sourceTiles.length; t < tt; ++t) { for (let t = 0, tt = sourceTiles.length; t < tt; ++t) {
const sourceTile = sourceTiles[t]; const sourceTile = sourceTiles[t];
@@ -341,6 +341,7 @@ class CanvasVectorTileLayerRenderer extends CanvasTileLayerRenderer {
getFeatures(pixel) { getFeatures(pixel) {
return new Promise(function(resolve, reject) { return new Promise(function(resolve, reject) {
const layer = /** @type {import("../../layer/VectorTile.js").default} */ (this.getLayer()); const layer = /** @type {import("../../layer/VectorTile.js").default} */ (this.getLayer());
const layerUid = getUid(layer);
const source = layer.getSource(); const source = layer.getSource();
const projection = this.renderedProjection; const projection = this.renderedProjection;
const projectionExtent = projection.getExtent(); const projectionExtent = projection.getExtent();
@@ -377,7 +378,8 @@ class CanvasVectorTileLayerRenderer extends CanvasTileLayerRenderer {
const features = tile.getSourceTiles().reduce(function(accumulator, sourceTile) { const features = tile.getSourceTiles().reduce(function(accumulator, sourceTile) {
return accumulator.concat(sourceTile.getFeatures()); 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 tileSize = toSize(tileGrid.getTileSize(tileGrid.getZForResolution(resolution)));
const size = [tileSize[0] / 2, tileSize[1] / 2]; const size = [tileSize[0] / 2, tileSize[1] / 2];
const rotation = this.renderedRotation_; const rotation = this.renderedRotation_;
@@ -385,16 +387,13 @@ class CanvasVectorTileLayerRenderer extends CanvasTileLayerRenderer {
this.getRenderTransform(tileGrid.getTileCoordCenter(tile.wrappedTileCoord), this.getRenderTransform(tileGrid.getTileCoordCenter(tile.wrappedTileCoord),
resolution, 0, 0.5, size[0], size[1], 0) resolution, 0, 0.5, size[0], size[1], 0)
]; ];
requestAnimationFrame(function() { hitDetectionImageData = createHitDetectionImageData(tileSize, transforms,
tile.hitDetectionImageData = createHitDetectionImageData(tileSize, transforms, features, layer.getStyleFunction(),
features, layer.getStyleFunction(), tileGrid.getTileCoordExtent(tile.wrappedTileCoord),
tileGrid.getTileCoordExtent(tile.wrappedTileCoord), tile.getReplayState(layer).renderedResolution, rotation);
tile.getReplayState(layer).renderedResolution, rotation); tile.hitDetectionImageData[layerUid] = hitDetectionImageData;
resolve(hitDetect(tilePixel, features, tile.hitDetectionImageData));
});
} else {
resolve(hitDetect(tilePixel, features, tile.hitDetectionImageData));
} }
resolve(hitDetect(tilePixel, features, hitDetectionImageData));
}.bind(this)); }.bind(this));
} }