Preload tiles for WebGL tile layers
This commit is contained in:
@@ -307,10 +307,10 @@ class WebGLTileLayerRenderer extends WebGLLayerRenderer {
|
|||||||
/**
|
/**
|
||||||
* @param {import("../../PluggableMap.js").FrameState} frameState Frame state.
|
* @param {import("../../PluggableMap.js").FrameState} frameState Frame state.
|
||||||
* @param {import("../../extent.js").Extent} extent The extent to be rendered.
|
* @param {import("../../extent.js").Extent} extent The extent to be rendered.
|
||||||
* @param {number} z The zoom level.
|
* @param {number} initialZ The zoom level.
|
||||||
* @param {Object<number, Array<TileTexture>>} tileTexturesByZ The zoom level.
|
* @param {Object<number, Array<TileTexture>>} tileTexturesByZ The zoom level.
|
||||||
*/
|
*/
|
||||||
enqueueTiles(frameState, extent, z, tileTexturesByZ) {
|
enqueueTiles(frameState, extent, initialZ, tileTexturesByZ) {
|
||||||
const viewState = frameState.viewState;
|
const viewState = frameState.viewState;
|
||||||
const tileLayer = this.getLayer();
|
const tileLayer = this.getLayer();
|
||||||
const tileSource = tileLayer.getRenderSource();
|
const tileSource = tileLayer.getRenderSource();
|
||||||
@@ -318,13 +318,6 @@ class WebGLTileLayerRenderer extends WebGLLayerRenderer {
|
|||||||
const tilePixelRatio = tileSource.getTilePixelRatio(frameState.pixelRatio);
|
const tilePixelRatio = tileSource.getTilePixelRatio(frameState.pixelRatio);
|
||||||
const gutter = tileSource.getGutterForProjection(viewState.projection);
|
const gutter = tileSource.getGutterForProjection(viewState.projection);
|
||||||
|
|
||||||
const tileTextureCache = this.tileTextureCache_;
|
|
||||||
const tileRange = tileGrid.getTileRangeForExtentAndZ(
|
|
||||||
extent,
|
|
||||||
z,
|
|
||||||
this.tempTileRange_
|
|
||||||
);
|
|
||||||
|
|
||||||
const tileSourceKey = getUid(tileSource);
|
const tileSourceKey = getUid(tileSource);
|
||||||
if (!(tileSourceKey in frameState.wantedTiles)) {
|
if (!(tileSourceKey in frameState.wantedTiles)) {
|
||||||
frameState.wantedTiles[tileSourceKey] = {};
|
frameState.wantedTiles[tileSourceKey] = {};
|
||||||
@@ -332,70 +325,80 @@ class WebGLTileLayerRenderer extends WebGLLayerRenderer {
|
|||||||
|
|
||||||
const wantedTiles = frameState.wantedTiles[tileSourceKey];
|
const wantedTiles = frameState.wantedTiles[tileSourceKey];
|
||||||
|
|
||||||
const tileResolution = tileGrid.getResolution(z);
|
const tileTextureCache = this.tileTextureCache_;
|
||||||
|
const minZ = Math.max(
|
||||||
|
initialZ - tileLayer.getPreload(),
|
||||||
|
tileGrid.getMinZoom(),
|
||||||
|
tileLayer.getMinZoom()
|
||||||
|
);
|
||||||
|
for (let z = initialZ; z >= minZ; --z) {
|
||||||
|
const tileRange = tileGrid.getTileRangeForExtentAndZ(
|
||||||
|
extent,
|
||||||
|
z,
|
||||||
|
this.tempTileRange_
|
||||||
|
);
|
||||||
|
|
||||||
for (let x = tileRange.minX; x <= tileRange.maxX; ++x) {
|
const tileResolution = tileGrid.getResolution(z);
|
||||||
for (let y = tileRange.minY; y <= tileRange.maxY; ++y) {
|
|
||||||
const tileCoord = createTileCoord(z, x, y, this.tempTileCoord_);
|
|
||||||
const cacheKey = getCacheKey(tileSource, tileCoord);
|
|
||||||
|
|
||||||
/**
|
for (let x = tileRange.minX; x <= tileRange.maxX; ++x) {
|
||||||
* @type {TileTexture}
|
for (let y = tileRange.minY; y <= tileRange.maxY; ++y) {
|
||||||
*/
|
const tileCoord = createTileCoord(z, x, y, this.tempTileCoord_);
|
||||||
let tileTexture;
|
const cacheKey = getCacheKey(tileSource, tileCoord);
|
||||||
|
|
||||||
/**
|
/** @type {TileTexture} */
|
||||||
* @type {import("../../webgl/TileTexture").TileType}
|
let tileTexture;
|
||||||
*/
|
|
||||||
let tile;
|
|
||||||
|
|
||||||
if (tileTextureCache.containsKey(cacheKey)) {
|
/** @type {import("../../webgl/TileTexture").TileType} */
|
||||||
tileTexture = tileTextureCache.get(cacheKey);
|
let tile;
|
||||||
tile = tileTexture.tile;
|
|
||||||
}
|
if (tileTextureCache.containsKey(cacheKey)) {
|
||||||
if (!tileTexture || tileTexture.tile.key !== tileSource.getKey()) {
|
tileTexture = tileTextureCache.get(cacheKey);
|
||||||
tile = tileSource.getTile(
|
tile = tileTexture.tile;
|
||||||
z,
|
}
|
||||||
x,
|
if (!tileTexture || tileTexture.tile.key !== tileSource.getKey()) {
|
||||||
y,
|
tile = tileSource.getTile(
|
||||||
frameState.pixelRatio,
|
z,
|
||||||
viewState.projection
|
x,
|
||||||
);
|
y,
|
||||||
if (!tileTexture) {
|
frameState.pixelRatio,
|
||||||
tileTexture = new TileTexture({
|
viewState.projection
|
||||||
tile: tile,
|
);
|
||||||
grid: tileGrid,
|
if (!tileTexture) {
|
||||||
helper: this.helper,
|
tileTexture = new TileTexture({
|
||||||
tilePixelRatio: tilePixelRatio,
|
tile: tile,
|
||||||
gutter: gutter,
|
grid: tileGrid,
|
||||||
});
|
helper: this.helper,
|
||||||
tileTextureCache.set(cacheKey, tileTexture);
|
tilePixelRatio: tilePixelRatio,
|
||||||
} else {
|
gutter: gutter,
|
||||||
if (this.isDrawableTile_(tile)) {
|
});
|
||||||
tileTexture.setTile(tile);
|
tileTextureCache.set(cacheKey, tileTexture);
|
||||||
} else {
|
} else {
|
||||||
const interimTile =
|
if (this.isDrawableTile_(tile)) {
|
||||||
/** @type {import("../../webgl/TileTexture").TileType} */ (
|
tileTexture.setTile(tile);
|
||||||
tile.getInterimTile()
|
} else {
|
||||||
);
|
const interimTile =
|
||||||
tileTexture.setTile(interimTile);
|
/** @type {import("../../webgl/TileTexture").TileType} */ (
|
||||||
|
tile.getInterimTile()
|
||||||
|
);
|
||||||
|
tileTexture.setTile(interimTile);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
addTileTextureToLookup(tileTexturesByZ, tileTexture, z);
|
addTileTextureToLookup(tileTexturesByZ, tileTexture, z);
|
||||||
|
|
||||||
const tileQueueKey = tile.getKey();
|
const tileQueueKey = tile.getKey();
|
||||||
wantedTiles[tileQueueKey] = true;
|
wantedTiles[tileQueueKey] = true;
|
||||||
|
|
||||||
if (tile.getState() === TileState.IDLE) {
|
if (tile.getState() === TileState.IDLE) {
|
||||||
if (!frameState.tileQueue.isKeyQueued(tileQueueKey)) {
|
if (!frameState.tileQueue.isKeyQueued(tileQueueKey)) {
|
||||||
frameState.tileQueue.enqueue([
|
frameState.tileQueue.enqueue([
|
||||||
tile,
|
tile,
|
||||||
tileSourceKey,
|
tileSourceKey,
|
||||||
tileGrid.getTileCoordCenter(tileCoord),
|
tileGrid.getTileCoordCenter(tileCoord),
|
||||||
tileResolution,
|
tileResolution,
|
||||||
]);
|
]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import {VOID} from '../../../../../../src/ol/functions.js';
|
|||||||
import {create} from '../../../../../../src/ol/transform.js';
|
import {create} from '../../../../../../src/ol/transform.js';
|
||||||
import {createCanvasContext2D} from '../../../../../../src/ol/dom.js';
|
import {createCanvasContext2D} from '../../../../../../src/ol/dom.js';
|
||||||
import {get} from '../../../../../../src/ol/proj.js';
|
import {get} from '../../../../../../src/ol/proj.js';
|
||||||
|
import {getUid} from '../../../../../../src/ol/util.js';
|
||||||
|
|
||||||
describe('ol/renderer/webgl/TileLayer', function () {
|
describe('ol/renderer/webgl/TileLayer', function () {
|
||||||
/** @type {import("../../../../../../src/ol/renderer/webgl/TileLayer.js").default} */
|
/** @type {import("../../../../../../src/ol/renderer/webgl/TileLayer.js").default} */
|
||||||
@@ -105,4 +106,81 @@ describe('ol/renderer/webgl/TileLayer', function () {
|
|||||||
tileLayer.setUseInterimTilesOnError(true);
|
tileLayer.setUseInterimTilesOnError(true);
|
||||||
expect(renderer.isDrawableTile_(errorTile)).to.be(false);
|
expect(renderer.isDrawableTile_(errorTile)).to.be(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('enqueueTiles()', () => {
|
||||||
|
it('enqueues tiles at a single zoom level (preload: 0)', () => {
|
||||||
|
renderer.prepareFrame(frameState);
|
||||||
|
const extent = [-1, -1, 1, 1];
|
||||||
|
renderer.enqueueTiles(frameState, extent, 10, {});
|
||||||
|
|
||||||
|
const source = tileLayer.getSource();
|
||||||
|
const sourceKey = getUid(source);
|
||||||
|
expect(frameState.wantedTiles[sourceKey]).to.be.an(Object);
|
||||||
|
|
||||||
|
const wantedTiles = frameState.wantedTiles[sourceKey];
|
||||||
|
|
||||||
|
const expected = {
|
||||||
|
'/10,511,511': true,
|
||||||
|
'/10,511,512': true,
|
||||||
|
'/10,512,511': true,
|
||||||
|
'/10,512,512': true,
|
||||||
|
};
|
||||||
|
expect(wantedTiles).to.eql(expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('enqueues tiles at multiple zoom levels (preload: 2)', () => {
|
||||||
|
tileLayer.setPreload(2);
|
||||||
|
renderer.prepareFrame(frameState);
|
||||||
|
const extent = [-1, -1, 1, 1];
|
||||||
|
renderer.enqueueTiles(frameState, extent, 10, {});
|
||||||
|
|
||||||
|
const source = tileLayer.getSource();
|
||||||
|
const sourceKey = getUid(source);
|
||||||
|
expect(frameState.wantedTiles[sourceKey]).to.be.an(Object);
|
||||||
|
|
||||||
|
const wantedTiles = frameState.wantedTiles[sourceKey];
|
||||||
|
|
||||||
|
const expected = {
|
||||||
|
'/10,511,511': true,
|
||||||
|
'/10,511,512': true,
|
||||||
|
'/10,512,511': true,
|
||||||
|
'/10,512,512': true,
|
||||||
|
'/9,255,255': true,
|
||||||
|
'/9,255,256': true,
|
||||||
|
'/9,256,255': true,
|
||||||
|
'/9,256,256': true,
|
||||||
|
'/8,127,127': true,
|
||||||
|
'/8,127,128': true,
|
||||||
|
'/8,128,127': true,
|
||||||
|
'/8,128,128': true,
|
||||||
|
};
|
||||||
|
expect(wantedTiles).to.eql(expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not go below layer min zoom', () => {
|
||||||
|
tileLayer.setPreload(Infinity);
|
||||||
|
tileLayer.setMinZoom(9);
|
||||||
|
renderer.prepareFrame(frameState);
|
||||||
|
const extent = [-1, -1, 1, 1];
|
||||||
|
renderer.enqueueTiles(frameState, extent, 10, {});
|
||||||
|
|
||||||
|
const source = tileLayer.getSource();
|
||||||
|
const sourceKey = getUid(source);
|
||||||
|
expect(frameState.wantedTiles[sourceKey]).to.be.an(Object);
|
||||||
|
|
||||||
|
const wantedTiles = frameState.wantedTiles[sourceKey];
|
||||||
|
|
||||||
|
const expected = {
|
||||||
|
'/10,511,511': true,
|
||||||
|
'/10,511,512': true,
|
||||||
|
'/10,512,511': true,
|
||||||
|
'/10,512,512': true,
|
||||||
|
'/9,255,255': true,
|
||||||
|
'/9,255,256': true,
|
||||||
|
'/9,256,255': true,
|
||||||
|
'/9,256,256': true,
|
||||||
|
};
|
||||||
|
expect(wantedTiles).to.eql(expected);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user