Merge pull request #13863 from ahocevar/tile-error-handling
Fix reloading tiles in case of an error with tile.load()
This commit is contained in:
@@ -112,7 +112,40 @@ class ImageTile extends Tile {
|
||||
}
|
||||
|
||||
/**
|
||||
* Load not yet loaded URI.
|
||||
* Load the image or retry if loading previously failed.
|
||||
* Loading is taken care of by the tile queue, and calling this method is
|
||||
* only needed for preloading or for reloading in case of an error.
|
||||
*
|
||||
* To retry loading tiles on failed requests, use a custom `tileLoadFunction`
|
||||
* that checks for error status codes and reloads only when the status code is
|
||||
* 408, 429, 500, 502, 503 and 504, and only when not too many retries have been
|
||||
* made already:
|
||||
*
|
||||
* ```js
|
||||
* const retryCodes = [408, 429, 500, 502, 503, 504];
|
||||
* const retries = {};
|
||||
* source.setTileLoadFunction((tile, src) => {
|
||||
* const image = tile.getImage();
|
||||
* fetch(src)
|
||||
* .then((response) => {
|
||||
* if (retryCodes.includes(response.status)) {
|
||||
* retries[src] = (retries[src] || 0) + 1;
|
||||
* if (retries[src] <= 3) {
|
||||
* setTimeout(() => tile.load(), retries[src] * 1000);
|
||||
* }
|
||||
* return Promise.reject();
|
||||
* }
|
||||
* return response.blob();
|
||||
* })
|
||||
* .then((blob) => {
|
||||
* const imageUrl = URL.createObjectURL(blob);
|
||||
* image.src = imageUrl;
|
||||
* setTimeout(() => URL.revokeObjectURL(imageUrl), 5000);
|
||||
* })
|
||||
* .catch(() => tile.setState(3)); // error
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
load() {
|
||||
|
||||
@@ -142,7 +142,12 @@ class Tile extends EventTarget {
|
||||
/**
|
||||
* Called by the tile cache when the tile is removed from the cache due to expiry
|
||||
*/
|
||||
release() {}
|
||||
release() {
|
||||
if (this.state === TileState.ERROR) {
|
||||
// to remove the `change` listener on this tile in `ol/TileQueue#handleTileChange`
|
||||
this.setState(TileState.EMPTY);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {string} Key.
|
||||
|
||||
@@ -5,6 +5,13 @@ import LRUCache from './structs/LRUCache.js';
|
||||
import {fromKey, getKey} from './tilecoord.js';
|
||||
|
||||
class TileCache extends LRUCache {
|
||||
clear() {
|
||||
while (this.getCount() > 0) {
|
||||
this.pop().release();
|
||||
}
|
||||
super.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {!Object<string, boolean>} usedTiles Used tiles.
|
||||
*/
|
||||
|
||||
@@ -86,7 +86,9 @@ class TileQueue extends PriorityQueue {
|
||||
state === TileState.ERROR ||
|
||||
state === TileState.EMPTY
|
||||
) {
|
||||
tile.removeEventListener(EventType.CHANGE, this.boundHandleTileChange_);
|
||||
if (state !== TileState.ERROR) {
|
||||
tile.removeEventListener(EventType.CHANGE, this.boundHandleTileChange_);
|
||||
}
|
||||
const tileKey = tile.getKey();
|
||||
if (tileKey in this.tilesLoadingKeys_) {
|
||||
delete this.tilesLoadingKeys_[tileKey];
|
||||
|
||||
@@ -129,10 +129,7 @@ class CanvasTileLayerRenderer extends CanvasLayerRenderer {
|
||||
const tileSource = tileLayer.getSource();
|
||||
let tile = tileSource.getTile(z, x, y, pixelRatio, projection);
|
||||
if (tile.getState() == TileState.ERROR) {
|
||||
if (!tileLayer.getUseInterimTilesOnError()) {
|
||||
// When useInterimTilesOnError is false, we consider the error tile as loaded.
|
||||
tile.setState(TileState.LOADED);
|
||||
} else if (tileLayer.getPreload() > 0) {
|
||||
if (tileLayer.getUseInterimTilesOnError() && tileLayer.getPreload() > 0) {
|
||||
// Preloaded tiles for lower resolutions might have finished loading.
|
||||
this.newTiles_ = true;
|
||||
}
|
||||
|
||||
@@ -22,7 +22,9 @@ export default {
|
||||
TILELOADEND: 'tileloadend',
|
||||
|
||||
/**
|
||||
* Triggered if tile loading results in an error.
|
||||
* Triggered if tile loading results in an error. Note that this is not the
|
||||
* right place to re-fetch tiles. See {@link module:ol/ImageTile~ImageTile#load}
|
||||
* for details.
|
||||
* @event module:ol/source/Tile.TileSourceEvent#tileloaderror
|
||||
* @api
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user