I've got an Openlayers map with a custom tileUrlFunction
loading tiles from a custom tile server. Sometimes it can happen that the tileUrlFunction
returns an adress that, deliberately, does not contain a tile. There can be two use cases for this:
- Empty tiles. That would be comparable to a completely blue tile in OpenStreetMap, which shows nothing but the sea.
- Default tiles. The tile would look exactly like another tile from some kind of default layer. For example, the map might have two raster tile layers, a default satellite view and a satellite view with certain structures highlighted. If a place has no highlighted structures, the tile from the highlighted view would look exactly like the one from the default view.
To reduce the number of files, my custom tile server does not contain such tiles, i. e. the paths simply do not exist. Whenever I try to load a tile from such an empty path, there is (of course) a tile error. I would like to use a fallback tile from another path. Depending on the adress of the tile that had failed to load, the new tile might use different paths.
Here's my solution so far:
var rasterLayer = new TileLayer({
source: new XYZ({
tileGrid: ... ,
tileUrlFunction: ...,
}),
useInterimTilesOnError: false
});
// Error handling
rasterLayer_tiles.getSource().on("tileloaderror", errorFunction);
function errorFunction(e) {
console.log("tile:", e.tile); // erroneous tile
console.log("src:", e.tile.src_); // path that did not exist
console.log("tileCoord:", e.tile.tileCoord); // tile coordinates
var tileCoord = e.tile.tileCoord;
var replacement_Tile;
if( ... ) { // retrieve the path of fallback tile, potentially using information from e.tile
// ...
replacement_Tile = "errorTiles/blank.jpg";
} else {
// ...
replacement_Tile = "defaultTiles/" + tileCoord[0] + "/" + tileCoord[1] + "/" + tileCoord[2] + ".jpg";
}
e.tile.src_ = replacement_Tile;
e.tile.load();
}
This can be used to load the correct tiles; however there are several problems with that method:
- The initial tile load error will still propagate to the console.
- Apparently, there's no way to distinguish between errors where the path just didn't contain a tile and actual network errors. Possibly, this could also lead to an endless loop.
- The solution relies on the private source attribute to be exposed (see also here).
Is there a more elegant solution? I am looking for some kind of customizable errorTileUrlFunction here.