Simpler and faster VectorTile loading
This commit is contained in:
@@ -102,14 +102,6 @@ class Tile extends EventTarget {
|
|||||||
*/
|
*/
|
||||||
this.interimTile = null;
|
this.interimTile = null;
|
||||||
|
|
||||||
/**
|
|
||||||
* The tile is available at the highest possible resolution. Subclasses can
|
|
||||||
* set this to `false` initially. Tile load listeners will not be
|
|
||||||
* unregistered before this is set to `true` and a `#changed()` is called.
|
|
||||||
* @type {boolean}
|
|
||||||
*/
|
|
||||||
this.hifi = true;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A key assigned to the tile. This is used by the tile source to determine
|
* A key assigned to the tile. This is used by the tile source to determine
|
||||||
* if this tile can effectively be used, or if a new tile should be created
|
* if this tile can effectively be used, or if a new tile should be created
|
||||||
|
|||||||
+1
-1
@@ -82,7 +82,7 @@ class TileQueue extends PriorityQueue {
|
|||||||
const tile = /** @type {import("./Tile.js").default} */ (event.target);
|
const tile = /** @type {import("./Tile.js").default} */ (event.target);
|
||||||
const state = tile.getState();
|
const state = tile.getState();
|
||||||
if (
|
if (
|
||||||
(tile.hifi && state === TileState.LOADED) ||
|
state === TileState.LOADED ||
|
||||||
state === TileState.ERROR ||
|
state === TileState.ERROR ||
|
||||||
state === TileState.EMPTY
|
state === TileState.EMPTY
|
||||||
) {
|
) {
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ import {getUid} from './util.js';
|
|||||||
* @property {number} renderedTileRevision RenderedTileRevision.
|
* @property {number} renderedTileRevision RenderedTileRevision.
|
||||||
* @property {number} renderedResolution RenderedResolution.
|
* @property {number} renderedResolution RenderedResolution.
|
||||||
* @property {number} renderedRevision RenderedRevision.
|
* @property {number} renderedRevision RenderedRevision.
|
||||||
* @property {number} renderedZ RenderedZ.
|
|
||||||
* @property {number} renderedTileResolution RenderedTileResolution.
|
* @property {number} renderedTileResolution RenderedTileResolution.
|
||||||
* @property {number} renderedTileZ RenderedTileZ.
|
* @property {number} renderedTileZ RenderedTileZ.
|
||||||
*/
|
*/
|
||||||
@@ -57,12 +56,6 @@ class VectorRenderTile extends Tile {
|
|||||||
*/
|
*/
|
||||||
this.loadingSourceTiles = 0;
|
this.loadingSourceTiles = 0;
|
||||||
|
|
||||||
/**
|
|
||||||
* Tile keys of error source tiles. Read/written by the source.
|
|
||||||
* @type {Object<string, boolean>}
|
|
||||||
*/
|
|
||||||
this.errorSourceTileKeys = {};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {Object<number, ImageData>}
|
* @type {Object<number, ImageData>}
|
||||||
*/
|
*/
|
||||||
@@ -77,7 +70,12 @@ class VectorRenderTile extends Tile {
|
|||||||
/**
|
/**
|
||||||
* @type {Array<import("./VectorTile.js").default>}
|
* @type {Array<import("./VectorTile.js").default>}
|
||||||
*/
|
*/
|
||||||
this.sourceTiles = null;
|
this.sourceTiles = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {Object<string, boolean>}
|
||||||
|
*/
|
||||||
|
this.errorTileKeys = {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {number}
|
* @type {number}
|
||||||
@@ -89,18 +87,6 @@ class VectorRenderTile extends Tile {
|
|||||||
*/
|
*/
|
||||||
this.getSourceTiles = getSourceTiles.bind(undefined, this);
|
this.getSourceTiles = getSourceTiles.bind(undefined, this);
|
||||||
|
|
||||||
/**
|
|
||||||
* z of the source tiles of the last getSourceTiles call.
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
this.sourceZ = -1;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* True when all tiles for this tile's nominal resolution are available.
|
|
||||||
* @type {boolean}
|
|
||||||
*/
|
|
||||||
this.hifi = false;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {import("./tilecoord.js").TileCoord}
|
* @type {import("./tilecoord.js").TileCoord}
|
||||||
*/
|
*/
|
||||||
@@ -150,7 +136,6 @@ class VectorRenderTile extends Tile {
|
|||||||
renderedRevision: -1,
|
renderedRevision: -1,
|
||||||
renderedTileResolution: NaN,
|
renderedTileResolution: NaN,
|
||||||
renderedTileRevision: -1,
|
renderedTileRevision: -1,
|
||||||
renderedZ: -1,
|
|
||||||
renderedTileZ: -1,
|
renderedTileZ: -1,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -141,8 +141,7 @@ class CanvasVectorTileLayerRenderer extends CanvasTileLayerRenderer {
|
|||||||
const tileUid = getUid(tile);
|
const tileUid = getUid(tile);
|
||||||
const state = tile.getState();
|
const state = tile.getState();
|
||||||
if (
|
if (
|
||||||
((state === TileState.LOADED && tile.hifi) ||
|
(state === TileState.LOADED || state === TileState.ERROR) &&
|
||||||
state === TileState.ERROR) &&
|
|
||||||
tileUid in this.tileListenerKeys_
|
tileUid in this.tileListenerKeys_
|
||||||
) {
|
) {
|
||||||
unlistenByKey(this.tileListenerKeys_[tileUid]);
|
unlistenByKey(this.tileListenerKeys_[tileUid]);
|
||||||
@@ -253,8 +252,7 @@ class CanvasVectorTileLayerRenderer extends CanvasTileLayerRenderer {
|
|||||||
!builderState.dirty &&
|
!builderState.dirty &&
|
||||||
builderState.renderedResolution === resolution &&
|
builderState.renderedResolution === resolution &&
|
||||||
builderState.renderedRevision == revision &&
|
builderState.renderedRevision == revision &&
|
||||||
builderState.renderedRenderOrder == renderOrder &&
|
builderState.renderedRenderOrder == renderOrder
|
||||||
builderState.renderedZ === tile.sourceZ
|
|
||||||
) {
|
) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -372,7 +370,6 @@ class CanvasVectorTileLayerRenderer extends CanvasTileLayerRenderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
builderState.renderedRevision = revision;
|
builderState.renderedRevision = revision;
|
||||||
builderState.renderedZ = tile.sourceZ;
|
|
||||||
builderState.renderedRenderOrder = renderOrder;
|
builderState.renderedRenderOrder = renderOrder;
|
||||||
builderState.renderedResolution = resolution;
|
builderState.renderedResolution = resolution;
|
||||||
}
|
}
|
||||||
@@ -516,7 +513,7 @@ class CanvasVectorTileLayerRenderer extends CanvasTileLayerRenderer {
|
|||||||
tileCoord.toString() === this.renderedTiles[i].tileCoord.toString()
|
tileCoord.toString() === this.renderedTiles[i].tileCoord.toString()
|
||||||
) {
|
) {
|
||||||
tile = this.renderedTiles[i];
|
tile = this.renderedTiles[i];
|
||||||
if (tile.getState() === TileState.LOADED && tile.hifi) {
|
if (tile.getState() === TileState.LOADED) {
|
||||||
const extent = tileGrid.getTileCoordExtent(tile.tileCoord);
|
const extent = tileGrid.getTileCoordExtent(tile.tileCoord);
|
||||||
if (
|
if (
|
||||||
source.getWrapX() &&
|
source.getWrapX() &&
|
||||||
@@ -843,12 +840,10 @@ class CanvasVectorTileLayerRenderer extends CanvasTileLayerRenderer {
|
|||||||
}
|
}
|
||||||
const replayState = tile.getReplayState(layer);
|
const replayState = tile.getReplayState(layer);
|
||||||
const revision = layer.getRevision();
|
const revision = layer.getRevision();
|
||||||
const sourceZ = tile.sourceZ;
|
|
||||||
const resolution = tile.wantedResolution;
|
const resolution = tile.wantedResolution;
|
||||||
return (
|
return (
|
||||||
replayState.renderedTileResolution !== resolution ||
|
replayState.renderedTileResolution !== resolution ||
|
||||||
replayState.renderedTileRevision !== revision ||
|
replayState.renderedTileRevision !== revision
|
||||||
replayState.renderedTileZ !== sourceZ
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -863,7 +858,6 @@ class CanvasVectorTileLayerRenderer extends CanvasTileLayerRenderer {
|
|||||||
const revision = layer.getRevision();
|
const revision = layer.getRevision();
|
||||||
const executorGroups = tile.executorGroups[getUid(layer)];
|
const executorGroups = tile.executorGroups[getUid(layer)];
|
||||||
replayState.renderedTileRevision = revision;
|
replayState.renderedTileRevision = revision;
|
||||||
replayState.renderedTileZ = tile.sourceZ;
|
|
||||||
|
|
||||||
const tileCoord = tile.wrappedTileCoord;
|
const tileCoord = tile.wrappedTileCoord;
|
||||||
const z = tileCoord[0];
|
const z = tileCoord[0];
|
||||||
|
|||||||
+82
-141
@@ -18,8 +18,8 @@ import {
|
|||||||
createXYZ,
|
createXYZ,
|
||||||
extentFromProjection,
|
extentFromProjection,
|
||||||
} from '../tilegrid.js';
|
} from '../tilegrid.js';
|
||||||
import {equals} from '../array.js';
|
|
||||||
import {fromKey, getKeyZXY} from '../tilecoord.js';
|
import {fromKey, getKeyZXY} from '../tilecoord.js';
|
||||||
|
import {isEmpty} from '../obj.js';
|
||||||
import {loadFeaturesXhr} from '../featureloader.js';
|
import {loadFeaturesXhr} from '../featureloader.js';
|
||||||
import {toSize} from '../size.js';
|
import {toSize} from '../size.js';
|
||||||
|
|
||||||
@@ -146,11 +146,6 @@ class VectorTile extends UrlTile {
|
|||||||
*/
|
*/
|
||||||
this.format_ = options.format ? options.format : null;
|
this.format_ = options.format ? options.format : null;
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {Object<string, import("./VectorTile").default>}
|
|
||||||
*/
|
|
||||||
this.loadingTiles_ = {};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
* @type {TileCache}
|
* @type {TileCache}
|
||||||
@@ -253,145 +248,91 @@ class VectorTile extends UrlTile {
|
|||||||
* @return {Array<import("../VectorTile").default>} Tile keys.
|
* @return {Array<import("../VectorTile").default>} Tile keys.
|
||||||
*/
|
*/
|
||||||
getSourceTiles(pixelRatio, projection, tile) {
|
getSourceTiles(pixelRatio, projection, tile) {
|
||||||
const urlTileCoord = tile.wrappedTileCoord;
|
|
||||||
const tileGrid = this.getTileGridForProjection(projection);
|
|
||||||
const extent = tileGrid.getTileCoordExtent(urlTileCoord);
|
|
||||||
const z = urlTileCoord[0];
|
|
||||||
const resolution = tileGrid.getResolution(z);
|
|
||||||
// make extent 1 pixel smaller so we don't load tiles for < 0.5 pixel render space
|
|
||||||
bufferExtent(extent, -resolution, extent);
|
|
||||||
const sourceTileGrid = this.tileGrid;
|
|
||||||
const sourceExtent = sourceTileGrid.getExtent();
|
|
||||||
if (sourceExtent) {
|
|
||||||
getIntersection(extent, sourceExtent, extent);
|
|
||||||
}
|
|
||||||
const sourceZ = sourceTileGrid.getZForResolution(resolution, 1);
|
|
||||||
const minZoom = sourceTileGrid.getMinZoom();
|
|
||||||
|
|
||||||
const previousSourceTiles = tile.sourceTiles;
|
|
||||||
let sourceTiles, covered, loadedZ;
|
|
||||||
if (
|
|
||||||
previousSourceTiles &&
|
|
||||||
previousSourceTiles.length > 0 &&
|
|
||||||
previousSourceTiles[0].tileCoord[0] === sourceZ
|
|
||||||
) {
|
|
||||||
sourceTiles = previousSourceTiles;
|
|
||||||
covered = true;
|
|
||||||
loadedZ = sourceZ;
|
|
||||||
} else {
|
|
||||||
sourceTiles = [];
|
|
||||||
loadedZ = sourceZ + 1;
|
|
||||||
do {
|
|
||||||
--loadedZ;
|
|
||||||
covered = true;
|
|
||||||
sourceTileGrid.forEachTileCoord(
|
|
||||||
extent,
|
|
||||||
loadedZ,
|
|
||||||
function (sourceTileCoord) {
|
|
||||||
const tileUrl = this.tileUrlFunction(
|
|
||||||
sourceTileCoord,
|
|
||||||
pixelRatio,
|
|
||||||
projection
|
|
||||||
);
|
|
||||||
let sourceTile;
|
|
||||||
if (tileUrl !== undefined) {
|
|
||||||
if (this.sourceTileCache.containsKey(tileUrl)) {
|
|
||||||
sourceTile = this.sourceTileCache.get(tileUrl);
|
|
||||||
const state = sourceTile.getState();
|
|
||||||
if (
|
|
||||||
state === TileState.LOADED ||
|
|
||||||
state === TileState.ERROR ||
|
|
||||||
state === TileState.EMPTY
|
|
||||||
) {
|
|
||||||
sourceTiles.push(sourceTile);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else if (loadedZ === sourceZ) {
|
|
||||||
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.sourceTileCache.set(tileUrl, sourceTile);
|
|
||||||
sourceTile.addEventListener(
|
|
||||||
EventType.CHANGE,
|
|
||||||
this.handleTileChange.bind(this)
|
|
||||||
);
|
|
||||||
sourceTile.load();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
covered =
|
|
||||||
covered &&
|
|
||||||
sourceTile &&
|
|
||||||
sourceTile.getState() === TileState.LOADED;
|
|
||||||
if (!sourceTile) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
sourceTile.getState() !== TileState.EMPTY &&
|
|
||||||
tile.getState() === TileState.IDLE
|
|
||||||
) {
|
|
||||||
tile.loadingSourceTiles++;
|
|
||||||
sourceTile.addEventListener(
|
|
||||||
EventType.CHANGE,
|
|
||||||
function listenChange() {
|
|
||||||
const state = sourceTile.getState();
|
|
||||||
const sourceTileKey = sourceTile.getKey();
|
|
||||||
if (state === TileState.LOADED || state === TileState.ERROR) {
|
|
||||||
if (state === TileState.LOADED) {
|
|
||||||
sourceTile.removeEventListener(
|
|
||||||
EventType.CHANGE,
|
|
||||||
listenChange
|
|
||||||
);
|
|
||||||
tile.loadingSourceTiles--;
|
|
||||||
delete tile.errorSourceTileKeys[sourceTileKey];
|
|
||||||
} else if (state === TileState.ERROR) {
|
|
||||||
tile.errorSourceTileKeys[sourceTileKey] = true;
|
|
||||||
}
|
|
||||||
const errorTileCount = Object.keys(tile.errorSourceTileKeys)
|
|
||||||
.length;
|
|
||||||
if (tile.loadingSourceTiles - errorTileCount === 0) {
|
|
||||||
tile.hifi = errorTileCount === 0;
|
|
||||||
tile.sourceZ = sourceZ;
|
|
||||||
tile.setState(TileState.LOADED);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}.bind(this)
|
|
||||||
);
|
|
||||||
if (!covered) {
|
|
||||||
sourceTiles.length = 0;
|
|
||||||
}
|
|
||||||
} while (!covered && loadedZ > minZoom);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tile.getState() === TileState.IDLE) {
|
if (tile.getState() === TileState.IDLE) {
|
||||||
tile.setState(TileState.LOADING);
|
tile.setState(TileState.LOADING);
|
||||||
}
|
const urlTileCoord = tile.wrappedTileCoord;
|
||||||
if (covered) {
|
const tileGrid = this.getTileGridForProjection(projection);
|
||||||
tile.hifi = sourceZ === loadedZ;
|
const extent = tileGrid.getTileCoordExtent(urlTileCoord);
|
||||||
tile.sourceZ = loadedZ;
|
const z = urlTileCoord[0];
|
||||||
if (tile.getState() < TileState.LOADED) {
|
const resolution = tileGrid.getResolution(z);
|
||||||
tile.setState(TileState.LOADED);
|
// make extent 1 pixel smaller so we don't load tiles for < 0.5 pixel render space
|
||||||
} else if (
|
bufferExtent(extent, -resolution, extent);
|
||||||
!previousSourceTiles ||
|
const sourceTileGrid = this.tileGrid;
|
||||||
!equals(sourceTiles, previousSourceTiles)
|
const sourceExtent = sourceTileGrid.getExtent();
|
||||||
) {
|
if (sourceExtent) {
|
||||||
tile.sourceTiles = sourceTiles;
|
getIntersection(extent, sourceExtent, extent);
|
||||||
|
}
|
||||||
|
const sourceZ = sourceTileGrid.getZForResolution(resolution, 1);
|
||||||
|
|
||||||
|
sourceTileGrid.forEachTileCoord(extent, sourceZ, (sourceTileCoord) => {
|
||||||
|
const tileUrl = this.tileUrlFunction(
|
||||||
|
sourceTileCoord,
|
||||||
|
pixelRatio,
|
||||||
|
projection
|
||||||
|
);
|
||||||
|
const sourceTile = this.sourceTileCache.containsKey(tileUrl)
|
||||||
|
? this.sourceTileCache.get(tileUrl)
|
||||||
|
: new this.tileClass(
|
||||||
|
sourceTileCoord,
|
||||||
|
tileUrl ? TileState.IDLE : TileState.EMPTY,
|
||||||
|
tileUrl,
|
||||||
|
this.format_,
|
||||||
|
this.tileLoadFunction
|
||||||
|
);
|
||||||
|
tile.sourceTiles.push(sourceTile);
|
||||||
|
const sourceTileState = sourceTile.getState();
|
||||||
|
if (sourceTileState === TileState.IDLE) {
|
||||||
|
sourceTile.extent = sourceTileGrid.getTileCoordExtent(
|
||||||
|
sourceTileCoord
|
||||||
|
);
|
||||||
|
sourceTile.projection = projection;
|
||||||
|
sourceTile.resolution = sourceTileGrid.getResolution(
|
||||||
|
sourceTileCoord[0]
|
||||||
|
);
|
||||||
|
this.sourceTileCache.set(tileUrl, sourceTile);
|
||||||
|
const listenChange = (event) => {
|
||||||
|
this.handleTileChange(event);
|
||||||
|
const state = sourceTile.getState();
|
||||||
|
if (state === TileState.LOADED || state === TileState.ERROR) {
|
||||||
|
const sourceTileKey = sourceTile.getKey();
|
||||||
|
if (sourceTileKey in tile.errorTileKeys) {
|
||||||
|
if (sourceTile.getState() === TileState.LOADED) {
|
||||||
|
delete tile.errorTileKeys[sourceTileKey];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
tile.loadingSourceTiles--;
|
||||||
|
}
|
||||||
|
if (state === TileState.ERROR) {
|
||||||
|
tile.errorTileKeys[sourceTileKey] = true;
|
||||||
|
} else {
|
||||||
|
sourceTile.removeEventListener(EventType.CHANGE, listenChange);
|
||||||
|
}
|
||||||
|
if (tile.loadingSourceTiles === 0) {
|
||||||
|
tile.setState(
|
||||||
|
isEmpty(tile.errorTileKeys)
|
||||||
|
? TileState.LOADED
|
||||||
|
: TileState.ERROR
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
sourceTile.addEventListener(EventType.CHANGE, listenChange);
|
||||||
|
tile.loadingSourceTiles++;
|
||||||
|
sourceTile.load();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (!tile.loadingSourceTiles) {
|
||||||
|
tile.setState(
|
||||||
|
tile.sourceTiles.some(
|
||||||
|
(sourceTile) => sourceTile.getState() === TileState.ERROR
|
||||||
|
)
|
||||||
|
? TileState.ERROR
|
||||||
|
: TileState.LOADED
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return sourceTiles;
|
|
||||||
|
return tile.sourceTiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -305,7 +305,7 @@ describe('ol.source.VectorTile', function () {
|
|||||||
let count = 0;
|
let count = 0;
|
||||||
let tile = source.getTile(0, 0, 0, 1, map.getView().getProjection());
|
let tile = source.getTile(0, 0, 0, 1, map.getView().getProjection());
|
||||||
tile.addEventListener('change', function onTileChange(e) {
|
tile.addEventListener('change', function onTileChange(e) {
|
||||||
if (e.target.getState() !== TileState.LOADED && !e.target.hifi) {
|
if (e.target.getState() !== TileState.LOADED) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
e.target.removeEventListener('change', onTileChange);
|
e.target.removeEventListener('change', onTileChange);
|
||||||
|
|||||||
@@ -24,19 +24,18 @@ describe('ol.VectorRenderTile', function () {
|
|||||||
listen(tile, 'change', function (e) {
|
listen(tile, 'change', function (e) {
|
||||||
++calls;
|
++calls;
|
||||||
if (calls === 1) {
|
if (calls === 1) {
|
||||||
expect(tile.getState()).to.be(TileState.LOADED);
|
expect(tile.getState()).to.be(TileState.ERROR);
|
||||||
expect(tile.hifi).to.be(false);
|
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
sourceTile.setState(TileState.LOADED);
|
sourceTile.setState(TileState.LOADED);
|
||||||
expect(tile.hifi).to.be(true);
|
|
||||||
}, 0);
|
}, 0);
|
||||||
} else if (calls === 2) {
|
} else if (calls === 2) {
|
||||||
|
expect(tile.getState()).to.be(TileState.LOADED);
|
||||||
done();
|
done();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('sets LOADED state and hifi==false when source tiles fail to load', function (done) {
|
it('sets ERROR state when source tiles fail to load', function (done) {
|
||||||
const source = new VectorTileSource({
|
const source = new VectorTileSource({
|
||||||
format: new GeoJSON(),
|
format: new GeoJSON(),
|
||||||
url: 'spec/ol/data/unavailable.json',
|
url: 'spec/ol/data/unavailable.json',
|
||||||
@@ -46,8 +45,7 @@ describe('ol.VectorRenderTile', function () {
|
|||||||
tile.load();
|
tile.load();
|
||||||
|
|
||||||
listen(tile, 'change', function (e) {
|
listen(tile, 'change', function (e) {
|
||||||
expect(tile.getState()).to.be(TileState.LOADED);
|
expect(tile.getState()).to.be(TileState.ERROR);
|
||||||
expect(tile.hifi).to.be(false);
|
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user