diff --git a/src/ol/vectorimagetile.js b/src/ol/vectorimagetile.js index 795281ff40..5938191d6a 100644 --- a/src/ol/vectorimagetile.js +++ b/src/ol/vectorimagetile.js @@ -105,10 +105,11 @@ ol.VectorImageTile = function(tileCoord, state, src, format, tileLoadFunction, var sourceTileKey = sourceTileCoord.toString(); var sourceTile = sourceTiles[sourceTileKey]; if (!sourceTile) { - var tileUrl = /** @type {string} */ - (tileUrlFunction(sourceTileCoord, pixelRatio, projection)); - sourceTile = sourceTiles[sourceTileKey] = new tileClass( - sourceTileCoord, ol.TileState.IDLE, tileUrl, format, tileLoadFunction); + var tileUrl = tileUrlFunction(sourceTileCoord, pixelRatio, projection); + sourceTile = sourceTiles[sourceTileKey] = new tileClass(sourceTileCoord, + tileUrl == undefined ? ol.TileState.EMPTY : ol.TileState.IDLE, + tileUrl == undefined ? '' : tileUrl, + format, tileLoadFunction); } sourceTile.consumers++; this.usedSourceTileKeys_.push(sourceTileKey); @@ -219,6 +220,7 @@ ol.VectorImageTile.prototype.getSourceTiles = function() { */ ol.VectorImageTile.prototype.load = function() { var leftToLoad = 0; + var errors = false; if (this.state == ol.TileState.IDLE) { this.setState(ol.TileState.LOADING); } @@ -228,18 +230,26 @@ ol.VectorImageTile.prototype.load = function() { if (sourceTile.state == ol.TileState.IDLE) { sourceTile.setLoader(this.loader_); sourceTile.load(); + } else if (sourceTile.state == ol.TileState.ERROR) { + errors = true; + } else if (sourceTile.state == ol.TileState.EMPTY) { + ol.array.remove(this.usedSourceTileKeys_, sourceTileKey); } if (sourceTile.state == ol.TileState.LOADING) { var key = ol.events.listen(sourceTile, ol.events.EventType.CHANGE, function(e) { var state = sourceTile.getState(); if (state == ol.TileState.LOADED || - state == ol.TileState.ERROR || - state == ol.TileState.EMPTY) { + state == ol.TileState.ERROR) { --leftToLoad; ol.events.unlistenByKey(key); ol.array.remove(this.loadListenerKeys_, key); + if (state == ol.TileState.ERROR) { + ol.array.remove(this.usedSourceTileKeys_, sourceTileKey); + errors = true; + } if (leftToLoad == 0) { - this.setState(ol.TileState.LOADED); + this.setState(this.usedSourceTileKeys_.length > 0 ? + ol.TileState.LOADED : ol.TileState.ERROR); } } }.bind(this)); @@ -250,7 +260,9 @@ ol.VectorImageTile.prototype.load = function() { } if (leftToLoad == 0) { setTimeout(function() { - this.setState(ol.TileState.LOADED); + this.setState(this.usedSourceTileKeys_.length > 0 ? + ol.TileState.LOADED : + (errors ? ol.TileState.ERROR : ol.TileState.EMPTY)); }.bind(this), 0); } }; diff --git a/test/spec/ol/vectorimagetile.test.js b/test/spec/ol/vectorimagetile.test.js index 8a3d6d25bb..03b7029683 100644 --- a/test/spec/ol/vectorimagetile.test.js +++ b/test/spec/ol/vectorimagetile.test.js @@ -9,20 +9,7 @@ goog.require('ol.proj'); describe('ol.VectorImageTile', function() { - it('sets the loader function on source tiles', function() { - var format = new ol.format.GeoJSON(); - var url = 'spec/ol/data/point.json'; - 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); - - tile.load(); - var loader = tile.getSourceTiles()[0].loader_; - expect(typeof loader).to.be('function'); - }); - - it('loader sets features on the source tile', function(done) { + it('configures loader that sets features on the source tile', function(done) { var format = new ol.format.GeoJSON(); var url = 'spec/ol/data/point.json'; var tile = new ol.VectorImageTile([0, 0, 0], 0, url, format, @@ -33,6 +20,8 @@ describe('ol.VectorImageTile', function() { tile.load(); var sourceTile = tile.getSourceTiles()[0]; + var loader = sourceTile.loader_; + expect(typeof loader).to.be('function'); ol.events.listen(sourceTile, 'change', function(e) { expect(sourceTile.getFeatures().length).to.be.greaterThan(0); @@ -40,4 +29,37 @@ describe('ol.VectorImageTile', function() { }); }); + it('sets ERROR state when source tiles fail to load', function(done) { + var format = new ol.format.GeoJSON(); + var url = 'spec/ol/data/unavailable.json'; + var tile = new ol.VectorImageTile([0, 0, 0], 0, url, format, + ol.VectorImageTile.defaultLoadFunction, [0, 0, 0], function() { + return url; + }, ol.tilegrid.createXYZ(), ol.tilegrid.createXYZ(), {}, + 1, ol.proj.get('EPSG:3857'), ol.VectorTile); + + tile.load(); + + ol.events.listen(tile, 'change', function(e) { + expect(tile.getState()).to.be(ol.TileState.ERROR); + done(); + }); + }); + + it('sets EMPTY state when tile has only empty source tiles', function(done) { + var format = new ol.format.GeoJSON(); + var url = ''; + 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); + + tile.load(); + + ol.events.listen(tile, 'change', function(e) { + expect(tile.getState()).to.be(ol.TileState.EMPTY); + done(); + }); + }); + });