diff --git a/src/ol/source/VectorTile.js b/src/ol/source/VectorTile.js index 8ba2db678e..409af735bf 100644 --- a/src/ol/source/VectorTile.js +++ b/src/ol/source/VectorTile.js @@ -215,17 +215,17 @@ class VectorTile extends UrlTile { } } else if (loadedZ === sourceZ) { const tileUrl = this.tileUrlFunction(sourceTileCoord, pixelRatio, projection); - sourceTile = new this.tileClass(sourceTileCoord, - tileUrl == undefined ? TileState.EMPTY : TileState.IDLE, - tileUrl == undefined ? '' : tileUrl, - this.format_, this.tileLoadFunction); - sourceTile.extent = sourceTileGrid.getTileCoordExtent(sourceTileCoord); - sourceTile.projection = projection; - sourceTile.resolution = sourceTileGrid.getResolution(sourceTileCoord[0]); - this.sourceTiles_[tileKey] = sourceTile; - empty = empty && sourceTile.getState() === TileState.EMPTY; - listen(sourceTile, EventType.CHANGE, this.handleTileChange, this); - sourceTile.load(); + if (tileUrl !== undefined) { + sourceTile = new this.tileClass(sourceTileCoord, TileState.IDLE, tileUrl, + this.format_, this.tileLoadFunction); + sourceTile.extent = sourceTileGrid.getTileCoordExtent(sourceTileCoord); + sourceTile.projection = projection; + sourceTile.resolution = sourceTileGrid.getResolution(sourceTileCoord[0]); + this.sourceTiles_[tileKey] = sourceTile; + empty = false; + listen(sourceTile, EventType.CHANGE, this.handleTileChange, this); + sourceTile.load(); + } } else { empty = false; } @@ -312,26 +312,34 @@ class VectorTile extends UrlTile { */ getTile(z, x, y, pixelRatio, projection) { const tileCoordKey = getKeyZXY(z, x, y); + const key = this.getKey(); + let tile; if (this.tileCache.containsKey(tileCoordKey)) { - return ( - /** @type {!import("../Tile.js").default} */ (this.tileCache.get(tileCoordKey)) - ); - } else { - const tileCoord = [z, x, y]; - const urlTileCoord = this.getTileCoordForTileUrlFunction( - tileCoord, projection); - const tile = new VectorRenderTile( - tileCoord, - urlTileCoord !== null ? TileState.IDLE : TileState.EMPTY, - urlTileCoord, - this.tileGrid, - this.getSourceTiles.bind(this, pixelRatio, projection), - this.removeSourceTiles.bind(this)); - - tile.key = this.getRevision().toString(); - this.tileCache.set(tileCoordKey, tile); - return tile; + tile = /** @type {!import("../Tile.js").default} */ (this.tileCache.get(tileCoordKey)); + if (tile.key === key) { + return tile; + } } + const tileCoord = [z, x, y]; + const urlTileCoord = this.getTileCoordForTileUrlFunction( + tileCoord, projection); + const newTile = new VectorRenderTile( + tileCoord, + urlTileCoord !== null ? TileState.IDLE : TileState.EMPTY, + urlTileCoord, + this.tileGrid, + this.getSourceTiles.bind(this, pixelRatio, projection), + this.removeSourceTiles.bind(this)); + + newTile.key = key; + if (tile) { + newTile.interimTile = tile; + newTile.refreshInterimChain(); + this.tileCache.replace(tileCoordKey, newTile); + } else { + this.tileCache.set(tileCoordKey, newTile); + } + return newTile; } /** diff --git a/test/spec/ol/source/vectortile.test.js b/test/spec/ol/source/vectortile.test.js index 9a8c57a1c8..896396fdbf 100644 --- a/test/spec/ol/source/vectortile.test.js +++ b/test/spec/ol/source/vectortile.test.js @@ -38,17 +38,21 @@ describe('ol.source.VectorTile', function() { }); describe('#getTile()', function() { + it('creates a tile with the correct tile class', function() { tile = source.getTile(0, 0, 0, 1, getProjection('EPSG:3857')); expect(tile).to.be.a(VectorRenderTile); }); + it('sets the correct tileCoord on the created tile', function() { expect(tile.getTileCoord()).to.eql([0, 0, 0]); }); + it('fetches tile from cache when requested again', function() { expect(source.getTile(0, 0, 0, 1, getProjection('EPSG:3857'))) .to.equal(tile); }); + it('loads source tiles', function(done) { const source = new VectorTileSource({ format: new GeoJSON(), @@ -67,6 +71,32 @@ describe('ol.source.VectorTile', function() { }); }); + it('handles empty tiles tiles', function(done) { + const source = new VectorTileSource({ + format: new GeoJSON(), + url: '' + }); + const tile = source.getTile(0, 0, 0, 1, source.getProjection()); + + const key = listen(tile, 'change', function(e) { + unlistenByKey(key); + expect(tile.getState()).to.be(TileState.EMPTY); + done(); + }); + tile.load(); + }); + + it('creates new tile when source key changes', function() { + source.setKey('key1'); + const tile1 = source.getTile(0, 0, 0, 1, getProjection('EPSG:3857')); + const tile2 = source.getTile(0, 0, 0, 1, getProjection('EPSG:3857')); + source.setKey('key2'); + const tile3 = source.getTile(0, 0, 0, 1, getProjection('EPSG:3857')); + expect(tile1).to.equal(tile2); + expect(tile1.key).to.be('key1'); + expect(tile3.key).to.be('key2'); + }); + }); describe('#getTileGridForProjection', function() {