diff --git a/src/ol/renderer/canvas/vectortilelayer.js b/src/ol/renderer/canvas/vectortilelayer.js index 2f4a026b09..65afef3403 100644 --- a/src/ol/renderer/canvas/vectortilelayer.js +++ b/src/ol/renderer/canvas/vectortilelayer.js @@ -108,7 +108,8 @@ ol.renderer.canvas.VectorTileLayer.prototype.createReplayGroup_ = function( var pixelRatio = frameState.pixelRatio; var projection = frameState.viewState.projection; var revision = layer.getRevision(); - var renderOrder = layer.getRenderOrder() || null; + var renderOrder = /** @type {ol.RenderOrderFunction} */ + (layer.getRenderOrder()) || null; var replayState = tile.getReplayState(); if (!replayState.dirty && replayState.renderedRevision == revision && diff --git a/src/ol/source/vectortile.js b/src/ol/source/vectortile.js index af3a529873..9b448c8771 100644 --- a/src/ol/source/vectortile.js +++ b/src/ol/source/vectortile.js @@ -4,8 +4,6 @@ goog.require('ol'); goog.require('ol.TileState'); goog.require('ol.VectorImageTile'); goog.require('ol.VectorTile'); -goog.require('ol.events'); -goog.require('ol.events.EventType'); goog.require('ol.proj'); goog.require('ol.size'); goog.require('ol.tilegrid'); @@ -114,9 +112,8 @@ ol.source.VectorTile.prototype.getTile = function(z, x, y, pixelRatio, projectio tileUrl !== undefined ? tileUrl : '', this.format_, this.tileLoadFunction, urlTileCoord, this.tileUrlFunction, this.tileGrid, this.getTileGridForProjection(projection), - this.sourceTiles_, pixelRatio, projection, this.tileClass); - ol.events.listen(tile, ol.events.EventType.CHANGE, - this.handleTileChange, this); + this.sourceTiles_, pixelRatio, projection, this.tileClass, + this.handleTileChange.bind(this)); this.tileCache.set(tileCoordKey, tile); return tile; diff --git a/src/ol/typedefs.js b/src/ol/typedefs.js index 9d2be5fe1e..c6bb11c223 100644 --- a/src/ol/typedefs.js +++ b/src/ol/typedefs.js @@ -453,9 +453,11 @@ ol.RegularShapeRenderOptions; /** * A function to be used when sorting features before rendering. - * It takes two instances of {@link ol.Feature} and returns a `{number}`. + * It takes two instances of {@link ol.Feature} or {@link ol.render.Feature} and + * returns a `{number}`. * - * @typedef {function(ol.Feature, ol.Feature):number} + * @typedef {function((ol.Feature|ol.render.Feature), (ol.Feature|ol.render.Feature)): + * number} */ ol.RenderOrderFunction; diff --git a/src/ol/vectorimagetile.js b/src/ol/vectorimagetile.js index 7ac49ab936..c3ff9cb6ae 100644 --- a/src/ol/vectorimagetile.js +++ b/src/ol/vectorimagetile.js @@ -29,10 +29,12 @@ goog.require('ol.featureloader'); * @param {function(new: ol.VectorTile, ol.TileCoord, ol.TileState, string, * ol.format.Feature, ol.TileLoadFunctionType)} tileClass Class to * instantiate for source tiles. + * @param {function(this: ol.source.VectorTile, ol.events.Event)} handleTileChange + * Function to call when a source tile's state changes. */ ol.VectorImageTile = function(tileCoord, state, src, format, tileLoadFunction, urlTileCoord, tileUrlFunction, sourceTileGrid, tileGrid, sourceTiles, - pixelRatio, projection, tileClass) { + pixelRatio, projection, tileClass, handleTileChange) { ol.Tile.call(this, tileCoord, state); @@ -86,6 +88,11 @@ ol.VectorImageTile = function(tileCoord, state, src, format, tileLoadFunction, */ this.loadListenerKeys_ = []; + /** + * @type {Array.} + */ + this.sourceTileListenerKeys_ = []; + if (urlTileCoord) { var extent = tileGrid.getTileCoordExtent(urlTileCoord); var resolution = tileGrid.getResolution(tileCoord[0]); @@ -104,6 +111,8 @@ ol.VectorImageTile = function(tileCoord, state, src, format, tileLoadFunction, tileUrl == undefined ? ol.TileState.EMPTY : ol.TileState.IDLE, tileUrl == undefined ? '' : tileUrl, format, tileLoadFunction); + this.sourceTileListenerKeys_.push( + ol.events.listen(sourceTile, ol.events.EventType.CHANGE, handleTileChange)); } sourceTile.consumers++; this.tileKeys.push(sourceTileKey); @@ -139,6 +148,8 @@ ol.VectorImageTile.prototype.disposeInternal = function() { } this.state = ol.TileState.ABORT; this.changed(); + this.sourceTileListenerKeys_.forEach(ol.events.unlistenByKey); + this.sourceTileListenerKeys_.length = 0; ol.Tile.prototype.disposeInternal.call(this); }; @@ -157,7 +168,6 @@ ol.VectorImageTile.prototype.getContext = function() { /** * Get the Canvas for this tile. * @return {HTMLCanvasElement} Canvas. - * @api */ ol.VectorImageTile.prototype.getImage = function() { return this.replayState_.renderedTileRevision == -1 ? diff --git a/src/ol/vectortile.js b/src/ol/vectortile.js index 11fa1f8f05..6a82372fc6 100644 --- a/src/ol/vectortile.js +++ b/src/ol/vectortile.js @@ -66,6 +66,18 @@ ol.VectorTile = function(tileCoord, state, src, format, tileLoadFunction) { ol.inherits(ol.VectorTile, ol.Tile); +/** + * @inheritDoc + */ +ol.VectorTile.prototype.disposeInternal = function() { + this.features_ = null; + this.replayGroups_ = {}; + this.state = ol.TileState.ABORT; + this.changed(); + ol.Tile.prototype.disposeInternal.call(this); +}; + + /** * Get the feature format assigned for reading this tile's features. * @return {ol.format.Feature} Feature format. @@ -77,7 +89,10 @@ ol.VectorTile.prototype.getFormat = function() { /** - * @return {Array.} Features. + * Get the features for this tile. Geometries will be in the projection returned + * by {@link #getProjection}. + * @return {Array.} Features. + * @api */ ol.VectorTile.prototype.getFeatures = function() { return this.features_; @@ -93,7 +108,9 @@ ol.VectorTile.prototype.getKey = function() { /** + * Get the feature projection of features returned by {@link #getFeatures}. * @return {ol.proj.Projection} Feature projection. + * @api */ ol.VectorTile.prototype.getProjection = function() { return this.projection_; diff --git a/test/spec/ol/source/vectortile.test.js b/test/spec/ol/source/vectortile.test.js index 7a90d3225a..273a66f137 100644 --- a/test/spec/ol/source/vectortile.test.js +++ b/test/spec/ol/source/vectortile.test.js @@ -13,7 +13,8 @@ describe('ol.source.VectorTile', function() { var source = new ol.source.VectorTile({ format: format, tileGrid: ol.tilegrid.createXYZ({tileSize: 512}), - url: '{z}/{x}/{y}.pbf' + tilePixelRatio: 8, + url: 'spec/ol/data/{z}-{x}-{y}.vector.pbf' }); var tile; @@ -47,4 +48,21 @@ describe('ol.source.VectorTile', function() { }); }); + describe('Tile load events', function() { + it('triggers tileloadstart and tileloadend with ol.VectorTile', function(done) { + tile = source.getTile(14, 8938, -5681, 1, ol.proj.get('EPSG:3857')); + var started = false; + source.on('tileloadstart', function() { + started = true; + }); + source.on('tileloadend', function(e) { + expect(started).to.be(true); + expect(e.tile).to.be.a(ol.VectorTile); + expect(e.tile.getFeatures().length).to.be(1327); + done(); + }); + tile.load(); + }); + }); + }); diff --git a/test/spec/ol/vectorimagetile.test.js b/test/spec/ol/vectorimagetile.test.js index 8abe2ef5a9..8cd14276e8 100644 --- a/test/spec/ol/vectorimagetile.test.js +++ b/test/spec/ol/vectorimagetile.test.js @@ -16,7 +16,7 @@ describe('ol.VectorImageTile', function() { ol.VectorImageTile.defaultLoadFunction, [0, 0, 0], function() { return url; }, ol.tilegrid.createXYZ(), ol.tilegrid.createXYZ(), {}, - 1, ol.proj.get('EPSG:3857'), ol.VectorTile); + 1, ol.proj.get('EPSG:3857'), ol.VectorTile, function() {}); tile.load(); var sourceTile = tile.getTile(tile.tileKeys[0]); @@ -36,7 +36,7 @@ describe('ol.VectorImageTile', function() { ol.VectorImageTile.defaultLoadFunction, [0, 0, 0], function() { return url; }, ol.tilegrid.createXYZ(), ol.tilegrid.createXYZ(), {}, - 1, ol.proj.get('EPSG:3857'), ol.VectorTile); + 1, ol.proj.get('EPSG:3857'), ol.VectorTile, function() {}); tile.load(); @@ -52,7 +52,7 @@ describe('ol.VectorImageTile', function() { var tile = new ol.VectorImageTile([0, 0, 0], 0, url, format, ol.VectorImageTile.defaultLoadFunction, [0, 0, 0], function() {}, ol.tilegrid.createXYZ(), ol.tilegrid.createXYZ(), {}, - 1, ol.proj.get('EPSG:3857'), ol.VectorTile); + 1, ol.proj.get('EPSG:3857'), ol.VectorTile, function() {}); tile.load(); @@ -69,7 +69,7 @@ describe('ol.VectorImageTile', function() { ol.VectorImageTile.defaultLoadFunction, [0, 0, 0], function() { return url; }, ol.tilegrid.createXYZ(), ol.tilegrid.createXYZ({tileSize: 512}), {}, - 1, ol.proj.get('EPSG:3857'), ol.VectorTile); + 1, ol.proj.get('EPSG:3857'), ol.VectorTile, function() {}); tile.load(); expect(tile.loadListenerKeys_.length).to.be(4); @@ -89,7 +89,7 @@ describe('ol.VectorImageTile', function() { ol.VectorImageTile.defaultLoadFunction, [0, 0, 0], function() { return url; }, ol.tilegrid.createXYZ(), ol.tilegrid.createXYZ({tileSize: 512}), {}, - 1, ol.proj.get('EPSG:3857'), ol.VectorTile); + 1, ol.proj.get('EPSG:3857'), ol.VectorTile, function() {}); tile.load(); ol.events.listenOnce(tile, 'change', function() {