Skip to content

Commit 22f800f

Browse files
authored
COG layers are loading data even if not visible #12360 (#12488)
* Avoid loading hidden COG layers * fix: update with comment
1 parent 5a6540a commit 22f800f

2 files changed

Lines changed: 75 additions & 8 deletions

File tree

web/client/components/map/openlayers/__tests__/Layer-test.jsx

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import '../plugins/TMSLayer';
2323
import '../plugins/WFSLayer';
2424
import '../plugins/ElevationLayer';
2525
import '../plugins/ArcGISLayer';
26+
import '../plugins/COGLayer';
2627
import {
2728
invalidateCappedLoadExtents,
2829
isMeaningfulCappedExtentRefinement,
@@ -3636,6 +3637,56 @@ describe('Openlayers layer', () => {
36363637
expect(loadCount).toBe(1);
36373638
});
36383639

3640+
describe('COG', () => {
3641+
const cogOptions = {
3642+
id: 'cog-layer',
3643+
type: 'cog',
3644+
title: 'COG layer',
3645+
visibility: false,
3646+
sources: [{
3647+
url: 'data:image/tiff;base64,'
3648+
}],
3649+
sourceMetadata: {
3650+
crs: 'EPSG:3857'
3651+
}
3652+
};
3653+
3654+
it('does not create an OpenLayers layer while initially hidden', () => {
3655+
const layer = ReactDOM.render(
3656+
<OpenlayersLayer
3657+
type="cog"
3658+
options={cogOptions}
3659+
map={map}/>,
3660+
document.getElementById("container")
3661+
);
3662+
3663+
expect(layer.layer).toBe(null);
3664+
expect(map.getLayers().getLength()).toBe(0);
3665+
});
3666+
3667+
it('creates the OpenLayers layer when visibility changes from hidden to visible', () => {
3668+
const layer = ReactDOM.render(
3669+
<OpenlayersLayer
3670+
type="cog"
3671+
options={cogOptions}
3672+
map={map}/>,
3673+
document.getElementById("container")
3674+
);
3675+
3676+
ReactDOM.render(
3677+
<OpenlayersLayer
3678+
type="cog"
3679+
options={{...cogOptions, visibility: true}}
3680+
map={map}/>,
3681+
document.getElementById("container")
3682+
);
3683+
3684+
expect(layer.layer).toBeTruthy();
3685+
expect(layer.layer.getSource()).toBeTruthy();
3686+
expect(map.getLayers().getLength()).toBe(1);
3687+
});
3688+
});
3689+
36393690
describe('FlatGeobuf', () => {
36403691
// The fixture's FGB header reports geometryType=3 (Polygon) and
36413692
// covers central US (-106.2..-95.9, 34.6..42.0). The shared

web/client/components/map/openlayers/plugins/COGLayer.js

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import { isProjectionAvailable } from '../../../../utils/ProjectionUtils';
1616
import { getRequestConfigurationByUrl } from '../../../../utils/SecurityUtils';
1717
import { updateUrlParams } from '../../../../utils/URLUtils';
1818

19-
function create(options) {
19+
function getSource(options) {
2020
let sources = [];
2121
let sourceOptions = {};
2222
if (options.sources && options.sources.length > 0) {
@@ -32,17 +32,27 @@ function create(options) {
3232
};
3333
});
3434
}
35+
return new GeoTIFF({
36+
convertToRGB: 'auto', // CMYK, YCbCr, CIELab, and ICCLab images will automatically be converted to RGB
37+
sourceOptions,
38+
sources,
39+
wrapX: true
40+
});
41+
}
42+
43+
function create(options) {
44+
// GeoTIFF sources fetch eagerly on creation (unlike WMS, which loads on demand),
45+
// so `visible: false` won't prevent requests. Skip creating hidden layers;
46+
// `update` recreates them when they become visible.
47+
if (options.visibility === false) {
48+
return null;
49+
}
3550
const layerOl = new TileLayer({
3651
msId: options.id,
3752
style: get(options, 'style.body'),
3853
opacity: options.opacity !== undefined ? options.opacity : 1,
39-
visible: options.visibility,
40-
source: new GeoTIFF({
41-
convertToRGB: 'auto', // CMYK, YCbCr, CIELab, and ICCLab images will automatically be converted to RGB
42-
sourceOptions,
43-
sources,
44-
wrapX: true
45-
}),
54+
visible: true,
55+
source: getSource(options),
4656
enablePickFeatures: true,
4757
zIndex: options.zIndex,
4858
minResolution: options.minResolution,
@@ -55,6 +65,12 @@ function create(options) {
5565
Layers.registerType('cog', {
5666
create,
5767
update(layer, newOptions, oldOptions, map) {
68+
if (!layer && newOptions.visibility !== false) {
69+
return create(newOptions, map);
70+
}
71+
if (!layer) {
72+
return null;
73+
}
5874
if (newOptions.srs !== oldOptions.srs
5975
|| !isEqual(newOptions.style, oldOptions.style)
6076
|| !isEqual(newOptions.security, oldOptions.security)

0 commit comments

Comments
 (0)