Load layers for pyramid on demand

This commit is contained in:
Andreas Hocevar
2021-08-12 22:49:53 +02:00
parent 283aed2dc9
commit 011c14c7df
2 changed files with 25 additions and 7 deletions

View File

@@ -5,8 +5,8 @@ shortdesc: Rendering a COG tile pyramid as layer group.
docs: >
Data from a Cloud Optimized GeoTIFF (COG) tile pyramid can be rendered as a set of layers. In this
example, a pyramid of 3-band GeoTIFFs is used to render RGB data. For each tile of the pyramid, a
separate layer is created. The lowest resolution layer serves as preview while higher resolutions are
separate layer is created on demand. The lowest resolution layer serves as preview while higher resolutions are
loading.
tags: "cog, tile pyramid"
tags: "cog, tilepyramid, stac"
---
<div id="map" class="map"></div>

View File

@@ -4,6 +4,7 @@ import Map from '../src/ol/Map.js';
import TileGrid from '../src/ol/tilegrid/TileGrid.js';
import View from '../src/ol/View.js';
import WebGLTileLayer from '../src/ol/layer/WebGLTile.js';
import {getIntersection} from '../src/ol/extent.js';
// Metadata from https://s2downloads.eox.at/demo/EOxCloudless/2019/rgb/2019_EOxCloudless_rgb.json
@@ -19,11 +20,14 @@ const tileGrid = new TileGrid({
[4096, 4096],
],
});
// Add a separate layer for each pyramid tile to a layer group
const pyramid = new LayerGroup();
const layerForUrl = {};
const zs = tileGrid.getResolutions().length;
for (let z = 0; z < zs; ++z) {
tileGrid.forEachTileCoord([-180, -90, 180, 90], z, ([z, x, y]) => {
function useLayer(z, x, y) {
const url = `https://s2downloads.eox.at/demo/EOxCloudless/2019/rgb/${z}/${y}/${x}.tif`;
if (!(url in layerForUrl)) {
pyramid.getLayers().push(
new WebGLTileLayer({
minZoom: z,
@@ -32,13 +36,14 @@ for (let z = 0; z < zs; ++z) {
source: new GeoTIFF({
sources: [
{
url: `https://s2downloads.eox.at/demo/EOxCloudless/2019/rgb/${z}/${y}/${x}.tif`,
url: url,
},
],
}),
})
);
});
layerForUrl[url] = true;
}
}
const map = new Map({
@@ -51,3 +56,16 @@ const map = new Map({
showFullExtent: true,
}),
});
// Add overview layer
useLayer(0, 0, 0);
// Add layer for specific extent on demand
map.on('moveend', () => {
const view = map.getView();
tileGrid.forEachTileCoord(
getIntersection([-180, -90, 180, 90], view.calculateExtent()),
tileGrid.getZForResolution(view.getResolution()),
([z, x, y]) => useLayer(z, x, y)
);
});