diff --git a/src/ol/VectorImageTile.js b/src/ol/VectorImageTile.js index 9a6c56cc19..2884f4d5e6 100644 --- a/src/ol/VectorImageTile.js +++ b/src/ol/VectorImageTile.js @@ -9,6 +9,7 @@ import {listen, unlistenByKey} from './events.js'; import {getHeight, getIntersection, getWidth} from './extent.js'; import EventType from './events/EventType.js'; import {loadFeaturesXhr} from './featureloader.js'; +import {UNDEFINED} from './functions.js'; /** @@ -40,11 +41,11 @@ import {loadFeaturesXhr} from './featureloader.js'; * instantiate for source tiles. * @param {function(this: module:ol/source/VectorTile, module:ol/events/Event)} handleTileChange * Function to call when a source tile's state changes. - * @param {module:ol/Tile~Options=} opt_options Tile options. + * @param {number} zoom Integer zoom to render the tile for. */ const VectorImageTile = function(tileCoord, state, sourceRevision, format, tileLoadFunction, urlTileCoord, tileUrlFunction, sourceTileGrid, tileGrid, - sourceTiles, pixelRatio, projection, tileClass, handleTileChange, opt_options) { + sourceTiles, pixelRatio, projection, tileClass, handleTileChange, zoom) { Tile.call(this, tileCoord, state, {transition: 0}); @@ -105,8 +106,10 @@ const VectorImageTile = function(tileCoord, state, sourceRevision, format, if (urlTileCoord) { const extent = this.extent = tileGrid.getTileCoordExtent(urlTileCoord); - const resolution = tileGrid.getResolution(tileCoord[0]); + const resolution = tileGrid.getResolution(zoom); const sourceZ = sourceTileGrid.getZForResolution(resolution); + const useLoadedOnly = zoom != tileCoord[0]; + let loadCount = 0; sourceTileGrid.forEachTileCoord(extent, sourceZ, function(sourceTileCoord) { let sharedExtent = getIntersection(extent, sourceTileGrid.getTileCoordExtent(sourceTileCoord)); @@ -117,9 +120,10 @@ const VectorImageTile = function(tileCoord, state, sourceRevision, format, if (getWidth(sharedExtent) / resolution >= 0.5 && getHeight(sharedExtent) / resolution >= 0.5) { // only include source tile if overlap is at least 1 pixel + ++loadCount; const sourceTileKey = sourceTileCoord.toString(); let sourceTile = sourceTiles[sourceTileKey]; - if (!sourceTile) { + if (!sourceTile && !useLoadedOnly) { const tileUrl = tileUrlFunction(sourceTileCoord, pixelRatio, projection); sourceTile = sourceTiles[sourceTileKey] = new tileClass(sourceTileCoord, tileUrl == undefined ? TileState.EMPTY : TileState.IDLE, @@ -128,10 +132,29 @@ const VectorImageTile = function(tileCoord, state, sourceRevision, format, this.sourceTileListenerKeys_.push( listen(sourceTile, EventType.CHANGE, handleTileChange)); } - sourceTile.consumers++; - this.tileKeys.push(sourceTileKey); + if (sourceTile && (!useLoadedOnly || sourceTile.getState() == TileState.LOADED)) { + sourceTile.consumers++; + this.tileKeys.push(sourceTileKey); + } } }.bind(this)); + + if (useLoadedOnly && loadCount == this.tileKeys.length) { + this.finishLoading_(); + } + + if (zoom <= tileCoord[0] && this.state != TileState.LOADED) { + while (zoom > tileGrid.getMinZoom()) { + const tile = new VectorImageTile(tileCoord, state, sourceRevision, + format, tileLoadFunction, urlTileCoord, tileUrlFunction, + sourceTileGrid, tileGrid, sourceTiles, pixelRatio, projection, + tileClass, UNDEFINED, --zoom); + if (tile.state == TileState.LOADED) { + this.interimTile = tile; + break; + } + } + } } }; diff --git a/src/ol/source/VectorTile.js b/src/ol/source/VectorTile.js index e4a0323f82..20d83a4a88 100644 --- a/src/ol/source/VectorTile.js +++ b/src/ol/source/VectorTile.js @@ -166,7 +166,7 @@ VectorTile.prototype.getTile = function(z, x, y, pixelRatio, projection) { this.format_, this.tileLoadFunction, urlTileCoord, this.tileUrlFunction, this.tileGrid, this.getTileGridForProjection(projection), this.sourceTiles_, pixelRatio, projection, this.tileClass, - this.handleTileChange.bind(this)); + this.handleTileChange.bind(this), tileCoord[0]); this.tileCache.set(tileCoordKey, tile); return tile;