Merge pull request #14051 from mike-000/fix-preload-and-empty-reproj
Fix WebGL preload and empty reproj tiles
This commit is contained in:
@@ -181,7 +181,10 @@ class CanvasTileLayerRenderer extends CanvasLayerRenderer {
|
||||
pixelRatio,
|
||||
projection
|
||||
);
|
||||
if (!(tile instanceof ImageTile || tile instanceof ReprojTile)) {
|
||||
if (
|
||||
!(tile instanceof ImageTile || tile instanceof ReprojTile) ||
|
||||
(tile instanceof ReprojTile && tile.getState() === TileState.EMPTY)
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
* @module ol/renderer/webgl/TileLayer
|
||||
*/
|
||||
import LRUCache from '../../structs/LRUCache.js';
|
||||
import ReprojTile from '../../reproj/Tile.js';
|
||||
import TileRange from '../../TileRange.js';
|
||||
import TileState from '../../TileState.js';
|
||||
import TileTexture from '../../webgl/TileTexture.js';
|
||||
@@ -316,8 +317,9 @@ class WebGLTileLayerRenderer extends WebGLLayerRenderer {
|
||||
* @param {import("../../extent.js").Extent} extent The extent to be rendered.
|
||||
* @param {number} initialZ The zoom level.
|
||||
* @param {Object<number, Array<TileTexture>>} tileTexturesByZ The zoom level.
|
||||
* @param {number} preload Number of additional levels to load.
|
||||
*/
|
||||
enqueueTiles(frameState, extent, initialZ, tileTexturesByZ) {
|
||||
enqueueTiles(frameState, extent, initialZ, tileTexturesByZ, preload) {
|
||||
const viewState = frameState.viewState;
|
||||
const tileLayer = this.getLayer();
|
||||
const tileSource = tileLayer.getRenderSource();
|
||||
@@ -330,12 +332,23 @@ class WebGLTileLayerRenderer extends WebGLLayerRenderer {
|
||||
}
|
||||
|
||||
const wantedTiles = frameState.wantedTiles[tileSourceKey];
|
||||
|
||||
const tileTextureCache = this.tileTextureCache_;
|
||||
|
||||
const map = tileLayer.getMapInternal();
|
||||
const minZ = Math.max(
|
||||
initialZ - tileLayer.getPreload(),
|
||||
initialZ - preload,
|
||||
tileGrid.getMinZoom(),
|
||||
tileLayer.getMinZoom()
|
||||
tileGrid.getZForResolution(
|
||||
Math.min(
|
||||
tileLayer.getMaxResolution(),
|
||||
map
|
||||
? map
|
||||
.getView()
|
||||
.getResolutionForZoom(Math.max(tileLayer.getMinZoom(), 0))
|
||||
: tileGrid.getResolution(0)
|
||||
),
|
||||
tileSource.zDirection
|
||||
)
|
||||
);
|
||||
for (let z = initialZ; z >= minZ; --z) {
|
||||
const tileRange = tileGrid.getTileRangeForExtentAndZ(
|
||||
@@ -437,16 +450,34 @@ class WebGLTileLayerRenderer extends WebGLLayerRenderer {
|
||||
*/
|
||||
const tileTexturesByZ = {};
|
||||
|
||||
const preload = tileLayer.getPreload();
|
||||
if (frameState.nextExtent) {
|
||||
const targetZ = tileGrid.getZForResolution(
|
||||
viewState.nextResolution,
|
||||
tileSource.zDirection
|
||||
);
|
||||
const nextExtent = getRenderExtent(frameState, frameState.nextExtent);
|
||||
this.enqueueTiles(frameState, nextExtent, targetZ, tileTexturesByZ);
|
||||
this.enqueueTiles(
|
||||
frameState,
|
||||
nextExtent,
|
||||
targetZ,
|
||||
tileTexturesByZ,
|
||||
preload
|
||||
);
|
||||
}
|
||||
|
||||
this.enqueueTiles(frameState, extent, z, tileTexturesByZ);
|
||||
this.enqueueTiles(frameState, extent, z, tileTexturesByZ, 0);
|
||||
if (preload > 0) {
|
||||
setTimeout(() => {
|
||||
this.enqueueTiles(
|
||||
frameState,
|
||||
extent,
|
||||
z - 1,
|
||||
tileTexturesByZ,
|
||||
preload - 1
|
||||
);
|
||||
}, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* A lookup of alpha values for tiles at the target rendering resolution
|
||||
@@ -465,6 +496,9 @@ class WebGLTileLayerRenderer extends WebGLLayerRenderer {
|
||||
for (let i = 0, ii = tileTextures.length; i < ii; ++i) {
|
||||
const tileTexture = tileTextures[i];
|
||||
const tile = tileTexture.tile;
|
||||
if (tile instanceof ReprojTile && tile.getState() === TileState.EMPTY) {
|
||||
continue;
|
||||
}
|
||||
const tileCoord = tile.tileCoord;
|
||||
|
||||
if (tileTexture.loaded) {
|
||||
@@ -753,6 +787,10 @@ class WebGLTileLayerRenderer extends WebGLLayerRenderer {
|
||||
continue;
|
||||
}
|
||||
const tileTexture = tileTextureCache.get(cacheKey);
|
||||
const tile = tileTexture.tile;
|
||||
if (tile instanceof ReprojTile && tile.getState() === TileState.EMPTY) {
|
||||
return null;
|
||||
}
|
||||
if (!tileTexture.loaded) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import Map from '../../../../../../src/ol/Map.js';
|
||||
import TileQueue from '../../../../../../src/ol/TileQueue.js';
|
||||
import TileState from '../../../../../../src/ol/TileState.js';
|
||||
import View from '../../../../../../src/ol/View.js';
|
||||
import WebGLTileLayer from '../../../../../../src/ol/layer/WebGLTile.js';
|
||||
import {DataTile} from '../../../../../../src/ol/source.js';
|
||||
import {VOID} from '../../../../../../src/ol/functions.js';
|
||||
@@ -15,6 +17,8 @@ describe('ol/renderer/webgl/TileLayer', function () {
|
||||
let tileLayer;
|
||||
/** @type {import('../../../../../../src/ol/Map.js').FrameState} */
|
||||
let frameState;
|
||||
/** @type {Map} */
|
||||
let map;
|
||||
beforeEach(function () {
|
||||
const size = 256;
|
||||
const context = createCanvasContext2D(size, size);
|
||||
@@ -54,10 +58,16 @@ describe('ol/renderer/webgl/TileLayer', function () {
|
||||
tileQueue: new TileQueue(VOID, VOID),
|
||||
renderTargets: {},
|
||||
};
|
||||
|
||||
map = new Map({
|
||||
view: new View(),
|
||||
});
|
||||
tileLayer.set('map', map, true);
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
tileLayer.dispose();
|
||||
map.dispose();
|
||||
});
|
||||
|
||||
it('maintains a cache on the renderer instead of the source', function () {
|
||||
@@ -111,7 +121,7 @@ describe('ol/renderer/webgl/TileLayer', function () {
|
||||
it('enqueues tiles at a single zoom level (preload: 0)', () => {
|
||||
renderer.prepareFrame(frameState);
|
||||
const extent = [-1, -1, 1, 1];
|
||||
renderer.enqueueTiles(frameState, extent, 10, {});
|
||||
renderer.enqueueTiles(frameState, extent, 10, {}, tileLayer.getPreload());
|
||||
|
||||
const source = tileLayer.getSource();
|
||||
const sourceKey = getUid(source);
|
||||
@@ -132,7 +142,7 @@ describe('ol/renderer/webgl/TileLayer', function () {
|
||||
tileLayer.setPreload(2);
|
||||
renderer.prepareFrame(frameState);
|
||||
const extent = [-1, -1, 1, 1];
|
||||
renderer.enqueueTiles(frameState, extent, 10, {});
|
||||
renderer.enqueueTiles(frameState, extent, 10, {}, tileLayer.getPreload());
|
||||
|
||||
const source = tileLayer.getSource();
|
||||
const sourceKey = getUid(source);
|
||||
@@ -162,7 +172,7 @@ describe('ol/renderer/webgl/TileLayer', function () {
|
||||
tileLayer.setMinZoom(9);
|
||||
renderer.prepareFrame(frameState);
|
||||
const extent = [-1, -1, 1, 1];
|
||||
renderer.enqueueTiles(frameState, extent, 10, {});
|
||||
renderer.enqueueTiles(frameState, extent, 10, {}, tileLayer.getPreload());
|
||||
|
||||
const source = tileLayer.getSource();
|
||||
const sourceKey = getUid(source);
|
||||
@@ -182,5 +192,38 @@ describe('ol/renderer/webgl/TileLayer', function () {
|
||||
};
|
||||
expect(wantedTiles).to.eql(expected);
|
||||
});
|
||||
|
||||
it('layer min zoom relates to view zoom levels', () => {
|
||||
map.setView(
|
||||
new View({maxResolution: map.getView().getMaxResolution() * 2})
|
||||
);
|
||||
tileLayer.setPreload(Infinity);
|
||||
tileLayer.setMinZoom(9);
|
||||
renderer.prepareFrame(frameState);
|
||||
const extent = [-1, -1, 1, 1];
|
||||
renderer.enqueueTiles(frameState, extent, 10, {}, tileLayer.getPreload());
|
||||
|
||||
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);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
BIN
test/rendering/cases/webgl-tile-preload/expected.png
Normal file
BIN
test/rendering/cases/webgl-tile-preload/expected.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.6 KiB |
20
test/rendering/cases/webgl-tile-preload/main.js
Normal file
20
test/rendering/cases/webgl-tile-preload/main.js
Normal file
@@ -0,0 +1,20 @@
|
||||
import Map from '../../../../src/ol/Map.js';
|
||||
import TileDebug from '../../../../src/ol/source/TileDebug.js';
|
||||
import TileLayer from '../../../../src/ol/layer/WebGLTile.js';
|
||||
import View from '../../../../src/ol/View.js';
|
||||
|
||||
new Map({
|
||||
target: 'map',
|
||||
layers: [
|
||||
new TileLayer({
|
||||
source: new TileDebug(),
|
||||
preload: Infinity,
|
||||
}),
|
||||
],
|
||||
view: new View({
|
||||
center: [0, 0],
|
||||
zoom: 0.5,
|
||||
}),
|
||||
});
|
||||
|
||||
render();
|
||||
Reference in New Issue
Block a user