Merge pull request #8227 from ahocevar/better-vectortile-experience

Better vectortile experience
This commit is contained in:
Andreas Hocevar
2018-05-28 09:49:26 +02:00
committed by GitHub
7 changed files with 128 additions and 76 deletions

View File

@@ -51,6 +51,12 @@ const CanvasTileLayerRenderer = function(tileLayer) {
*/
this.renderedTiles = [];
/**
* @private
* @type {boolean}
*/
this.newTiles_ = false;
/**
* @protected
* @type {module:ol/extent~Extent}
@@ -114,6 +120,34 @@ CanvasTileLayerRenderer.prototype.isDrawableTile_ = function(tile) {
tileState == TileState.ERROR && !useInterimTilesOnError;
};
/**
* @param {number} z Tile coordinate z.
* @param {number} x Tile coordinate x.
* @param {number} y Tile coordinate y.
* @param {number} pixelRatio Pixel ratio.
* @param {module:ol/proj/Projection} projection Projection.
* @return {!module:ol/Tile} Tile.
*/
CanvasTileLayerRenderer.prototype.getTile = function(z, x, y, pixelRatio, projection) {
const layer = this.getLayer();
const source = /** @type {module:ol/source/Tile} */ (layer.getSource());
let tile = source.getTile(z, x, y, pixelRatio, projection);
if (tile.getState() == TileState.ERROR) {
if (!layer.getUseInterimTilesOnError()) {
// When useInterimTilesOnError is false, we consider the error tile as loaded.
tile.setState(TileState.LOADED);
} else if (layer.getPreload() > 0) {
// Preloaded tiles for lower resolutions might have finished loading.
this.newTiles_ = true;
}
}
if (!this.isDrawableTile_(tile)) {
tile = tile.getInterimTile();
}
return tile;
};
/**
* @inheritDoc
*/
@@ -157,32 +191,26 @@ CanvasTileLayerRenderer.prototype.prepareFrame = function(frameState, layerState
const findLoadedTiles = this.createLoadedTileFinder(
tileSource, projection, tilesToDrawByZ);
const hints = frameState.viewHints;
const animatingOrInteracting = hints[ViewHint.ANIMATING] || hints[ViewHint.INTERACTING];
const tmpExtent = this.tmpExtent;
const tmpTileRange = this.tmpTileRange_;
let newTiles = false;
this.newTiles_ = false;
let tile, x, y;
for (x = tileRange.minX; x <= tileRange.maxX; ++x) {
for (y = tileRange.minY; y <= tileRange.maxY; ++y) {
tile = tileSource.getTile(z, x, y, pixelRatio, projection);
if (tile.getState() == TileState.ERROR) {
if (!tileLayer.getUseInterimTilesOnError()) {
// When useInterimTilesOnError is false, we consider the error tile as loaded.
tile.setState(TileState.LOADED);
} else if (tileLayer.getPreload() > 0) {
// Preloaded tiles for lower resolutions might have finished loading.
newTiles = true;
}
}
if (!this.isDrawableTile_(tile)) {
tile = tile.getInterimTile();
if (Date.now() - frameState.time > 16 && animatingOrInteracting) {
continue;
}
tile = this.getTile(z, x, y, pixelRatio, projection);
if (this.isDrawableTile_(tile)) {
const uid = getUid(this);
if (tile.getState() == TileState.LOADED) {
tilesToDrawByZ[z][tile.tileCoord.toString()] = tile;
const inTransition = tile.inTransition(uid);
if (!newTiles && (inTransition || this.renderedTiles.indexOf(tile) === -1)) {
newTiles = true;
if (!this.newTiles_ && (inTransition || this.renderedTiles.indexOf(tile) === -1)) {
this.newTiles_ = true;
}
}
if (tile.getAlpha(uid, frameState.time) === 1) {
@@ -206,10 +234,8 @@ CanvasTileLayerRenderer.prototype.prepareFrame = function(frameState, layerState
}
const renderedResolution = tileResolution * pixelRatio / tilePixelRatio * oversampling;
const hints = frameState.viewHints;
const animatingOrInteracting = hints[ViewHint.ANIMATING] || hints[ViewHint.INTERACTING];
if (!(this.renderedResolution && Date.now() - frameState.time > 16 && animatingOrInteracting) && (
newTiles ||
this.newTiles_ ||
!(this.renderedExtent_ && containsExtent(this.renderedExtent_, extent)) ||
this.renderedRevision != sourceRevision ||
oversampling != this.oversampling_ ||

View File

@@ -126,6 +126,21 @@ CanvasVectorTileLayerRenderer.prototype.disposeInternal = function() {
};
/**
* @inheritDoc
*/
CanvasVectorTileLayerRenderer.prototype.getTile = function(z, x, y, pixelRatio, projection) {
const tile = CanvasTileLayerRenderer.prototype.getTile.call(this, z, x, y, pixelRatio, projection);
if (tile.getState() === TileState.LOADED) {
this.createReplayGroup_(tile, pixelRatio, projection);
if (this.context) {
this.renderTileImage_(tile, pixelRatio, projection);
}
}
return tile;
};
/**
* @inheritDoc
*/
@@ -149,13 +164,12 @@ CanvasVectorTileLayerRenderer.prototype.prepareFrame = function(frameState, laye
/**
* @param {module:ol/VectorImageTile} tile Tile.
* @param {module:ol/PluggableMap~FrameState} frameState Frame state.
* @param {number} pixelRatio Pixel ratio.
* @param {module:ol/proj/Projection} projection Projection.
* @private
*/
CanvasVectorTileLayerRenderer.prototype.createReplayGroup_ = function(tile, frameState) {
CanvasVectorTileLayerRenderer.prototype.createReplayGroup_ = function(tile, pixelRatio, projection) {
const layer = this.getLayer();
const pixelRatio = frameState.pixelRatio;
const projection = frameState.viewState.projection;
const revision = layer.getRevision();
const renderOrder = /** @type {module:ol/render~OrderFunction} */ (layer.getRenderOrder()) || null;
@@ -169,7 +183,7 @@ CanvasVectorTileLayerRenderer.prototype.createReplayGroup_ = function(tile, fram
const sourceTileGrid = source.getTileGrid();
const tileGrid = source.getTileGridForProjection(projection);
const resolution = tileGrid.getResolution(tile.tileCoord[0]);
const tileExtent = tileGrid.getTileCoordExtent(tile.wrappedTileCoord);
const tileExtent = tile.extent;
const zIndexKeys = {};
for (let t = 0, tt = tile.tileKeys.length; t < tt; ++t) {
@@ -241,20 +255,6 @@ CanvasVectorTileLayerRenderer.prototype.createReplayGroup_ = function(tile, fram
};
/**
* @inheritDoc
*/
CanvasVectorTileLayerRenderer.prototype.drawTileImage = function(
tile, frameState, layerState, x, y, w, h, gutter, transition) {
const vectorImageTile = /** @type {module:ol/VectorImageTile} */ (tile);
this.createReplayGroup_(vectorImageTile, frameState);
if (this.context) {
this.renderTileImage_(vectorImageTile, frameState, layerState);
CanvasTileLayerRenderer.prototype.drawTileImage.apply(this, arguments);
}
};
/**
* @inheritDoc
*/
@@ -269,16 +269,11 @@ CanvasVectorTileLayerRenderer.prototype.forEachFeatureAtCoordinate = function(co
/** @type {Array.<module:ol/VectorImageTile>} */
const renderedTiles = this.renderedTiles;
const source = /** @type {module:ol/source/VectorTile} */ (layer.getSource());
const tileGrid = source.getTileGridForProjection(frameState.viewState.projection);
let bufferedExtent, found;
let i, ii, replayGroup;
let tile, tileCoord, tileExtent;
for (i = 0, ii = renderedTiles.length; i < ii; ++i) {
tile = renderedTiles[i];
tileCoord = tile.wrappedTileCoord;
tileExtent = tileGrid.getTileCoordExtent(tileCoord, this.tmpExtent);
bufferedExtent = buffer(tileExtent, hitTolerance * resolution, bufferedExtent);
const tile = renderedTiles[i];
bufferedExtent = buffer(tile.extent, hitTolerance * resolution, bufferedExtent);
if (!containsCoordinate(bufferedExtent, coordinate)) {
continue;
}
@@ -388,8 +383,7 @@ CanvasVectorTileLayerRenderer.prototype.postCompose = function(context, frameSta
continue;
}
const tileCoord = tile.tileCoord;
const worldOffset = tileGrid.getTileCoordExtent(tileCoord, this.tmpExtent)[0] -
tileGrid.getTileCoordExtent(tile.wrappedTileCoord, this.tmpExtent)[0];
const worldOffset = tileGrid.getTileCoordExtent(tileCoord, this.tmpExtent)[0] - tile.extent[0];
let transform = undefined;
for (let t = 0, tt = tile.tileKeys.length; t < tt; ++t) {
const sourceTile = tile.getTile(tile.tileKeys[t]);
@@ -472,12 +466,12 @@ CanvasVectorTileLayerRenderer.prototype.renderFeature = function(feature, square
/**
* @param {module:ol/VectorImageTile} tile Tile.
* @param {module:ol/PluggableMap~FrameState} frameState Frame state.
* @param {module:ol/layer/Layer~State} layerState Layer state.
* @param {number} pixelRatio Pixel ratio.
* @param {module:ol/proj/Projection} projection Projection.
* @private
*/
CanvasVectorTileLayerRenderer.prototype.renderTileImage_ = function(
tile, frameState, layerState) {
tile, pixelRatio, projection) {
const layer = this.getLayer();
const replayState = tile.getReplayState(layer);
const revision = layer.getRevision();
@@ -486,12 +480,11 @@ CanvasVectorTileLayerRenderer.prototype.renderTileImage_ = function(
replayState.renderedTileRevision = revision;
const tileCoord = tile.wrappedTileCoord;
const z = tileCoord[0];
const pixelRatio = frameState.pixelRatio;
const source = /** @type {module:ol/source/VectorTile} */ (layer.getSource());
const tileGrid = source.getTileGridForProjection(frameState.viewState.projection);
const tileGrid = source.getTileGridForProjection(projection);
const resolution = tileGrid.getResolution(z);
const context = tile.getContext(layer);
const size = source.getTilePixelSize(z, pixelRatio, frameState.viewState.projection);
const size = source.getTilePixelSize(z, pixelRatio, projection);
context.canvas.width = size[0];
context.canvas.height = size[1];
const tileExtent = tileGrid.getTileCoordExtent(tileCoord, this.tmpExtent);
@@ -509,4 +502,5 @@ CanvasVectorTileLayerRenderer.prototype.renderTileImage_ = function(
}
}
};
export default CanvasVectorTileLayerRenderer;