From 214a384adf02a60524bdccab9fe7182a655513a1 Mon Sep 17 00:00:00 2001 From: mike-000 <49240900+mike-000@users.noreply.github.com> Date: Sat, 28 May 2022 11:36:35 +0100 Subject: [PATCH 1/3] Fix tile pyramid getData() --- src/ol/renderer/webgl/TileLayer.js | 33 ++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/src/ol/renderer/webgl/TileLayer.js b/src/ol/renderer/webgl/TileLayer.js index 58de80bad0..93b3f77e5b 100644 --- a/src/ol/renderer/webgl/TileLayer.js +++ b/src/ol/renderer/webgl/TileLayer.js @@ -18,7 +18,12 @@ import { scale as scaleTransform, translate as translateTransform, } from '../../transform.js'; -import {containsCoordinate, getIntersection, isEmpty} from '../../extent.js'; +import { + boundingExtent, + containsCoordinate, + getIntersection, + isEmpty, +} from '../../extent.js'; import { create as createMat4, fromTransform as mat4FromTransform, @@ -713,16 +718,28 @@ class WebGLTileLayerRenderer extends WebGLLayerRenderer { } } - const source = layer.getRenderSource(); - const tileGrid = source.getTileGridForProjection(viewState.projection); - if (!source.getWrapX()) { - const gridExtent = tileGrid.getExtent(); - if (gridExtent) { - if (!containsCoordinate(gridExtent, coordinate)) { - return null; + // determine last source suitable for rendering at coordinate + const sources = layer.getSources( + boundingExtent([coordinate]), + viewState.resolution + ); + let i, source, tileGrid; + for (i = sources.length - 1; i >= 0; --i) { + source = sources[i]; + if (source.getState() === State.READY) { + tileGrid = source.getTileGridForProjection(viewState.projection); + if (source.getWrapX()) { + break; + } + const gridExtent = tileGrid.getExtent(); + if (!gridExtent || containsCoordinate(gridExtent, coordinate)) { + break; } } } + if (i < 0) { + return null; + } const tileTextureCache = this.tileTextureCache_; for ( From bbfcf42daff3cc31c037272428c1c4cc6bd43f43 Mon Sep 17 00:00:00 2001 From: mike-000 <49240900+mike-000@users.noreply.github.com> Date: Sat, 28 May 2022 11:43:46 +0100 Subject: [PATCH 2/3] Test tile pyramid getData() --- test/browser/spec/ol/layer/WebGLTile.test.js | 57 ++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/test/browser/spec/ol/layer/WebGLTile.test.js b/test/browser/spec/ol/layer/WebGLTile.test.js index bd4b8832ab..8577aa8856 100644 --- a/test/browser/spec/ol/layer/WebGLTile.test.js +++ b/test/browser/spec/ol/layer/WebGLTile.test.js @@ -8,6 +8,7 @@ import {createCanvasContext2D} from '../../../../../src/ol/dom.js'; import {createXYZ} from '../../../../../src/ol/tilegrid.js'; import {getForViewAndSize} from '../../../../../src/ol/extent.js'; import {getRenderPixel} from '../../../../../src/ol/render.js'; +import {sourcesFromTileGrid} from '../../../../../src/ol/source.js'; describe('ol/layer/WebGLTile', function () { /** @type {WebGLTileLayer} */ @@ -105,6 +106,62 @@ describe('ol/layer/WebGLTile', function () { }); }); + it('retrieves pixel data from pyramid', (done) => { + const pyramidGrid = createXYZ({minZoom: 1, maxZoom: 1}); + const layer = new WebGLTileLayer({ + sources: sourcesFromTileGrid( + pyramidGrid, + ([z1, x1, y1]) => + new DataTileSource({ + tileSize: 1, + tileGrid: createXYZ({ + extent: pyramidGrid.getTileCoordExtent([z1, x1, y1]), + minZoom: 1, + maxZoom: 1, + }), + loader(z2, x2, y2) { + return new Uint8Array([x1, y1, x2, y2]); + }, + }) + ), + }); + + map.addLayer(layer); + + map.once('rendercomplete', () => { + let data; + data = layer.getData([25, 25]); + expect(data).to.be.a(Uint8Array); + expect(data.length).to.be(4); + expect(data[0]).to.be(0); + expect(data[1]).to.be(0); + expect(data[2]).to.be(1); + expect(data[3]).to.be(1); + data = layer.getData([75, 25]); + expect(data).to.be.a(Uint8Array); + expect(data.length).to.be(4); + expect(data[0]).to.be(1); + expect(data[1]).to.be(0); + expect(data[2]).to.be(0); + expect(data[3]).to.be(1); + data = layer.getData([25, 75]); + expect(data).to.be.a(Uint8Array); + expect(data.length).to.be(4); + expect(data[0]).to.be(0); + expect(data[1]).to.be(1); + expect(data[2]).to.be(1); + expect(data[3]).to.be(0); + data = layer.getData([75, 75]); + expect(data).to.be.a(Uint8Array); + expect(data.length).to.be(4); + expect(data[0]).to.be(1); + expect(data[1]).to.be(1); + expect(data[2]).to.be(0); + expect(data[3]).to.be(0); + done(); + }); + }); + it('preserves the original data type', (done) => { const layer = new WebGLTileLayer({ source: new DataTileSource({ From 0affb38890f3342954d62e902f469bc463fcfa82 Mon Sep 17 00:00:00 2001 From: mike-000 <49240900+mike-000@users.noreply.github.com> Date: Sun, 29 May 2022 14:08:44 +0100 Subject: [PATCH 3/3] Correct name in docs --- src/ol/source.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ol/source.js b/src/ol/source.js index cd2f467262..381f57f7d4 100644 --- a/src/ol/source.js +++ b/src/ol/source.js @@ -43,7 +43,7 @@ export {default as Zoomify} from './source/Zoomify.js'; * This function takes a {@link module:ol/tilecoord~TileCoord} as argument and is expected to return a * {@link module:ol/source/Source~Source}. **Note**: The returned sources should have a tile grid with * a limited set of resolutions, matching the resolution range of a single zoom level of the pyramid - * `tileGrid` that `createFromTileGrid` was called with. + * `tileGrid` that `sourcesFromTileGrid` was called with. * @return {function(import("./extent.js").Extent, number): Array} Sources function. * @api */