Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG-3.11.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ with some extra keywords: backend, tests, test, translation, funders, important
### Added

* Edition - Support QGIS dynamic default-value expressions in edit forms, including geometry-based (`$x`, `$y`, `$area`, `$length`, `$geometry`) and field-referencing expressions (e.g. `"firstname" || ' ' || "lastname"`). Defaults are re-evaluated when the geometry is drawn/edited and when a referenced field changes, honoring QGIS's `applyOnUpdate` flag.
* New per-layer option `excludeFromSingleWMS` to exclude a layer from the bundled "Load layers as a single WMS layer" request. The excluded layer is fetched individually (directly from its WMS server if `externalWmsToggle` is set, otherwise via QGIS Server). Useful for keeping slow third-party WMS layers out of the bundle. Requires the Lizmap plugin ≥ 5.x to expose the toggle in the UI. ([#6631](https://github.com/3liz/lizmap-web-client/issues/6631))

### Changed

Expand Down
11 changes: 11 additions & 0 deletions assets/src/modules/config/Layer.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ const optionalProperties = {
'mutuallyExclusive': {type: 'boolean', default: false},
'externalWmsToggle': {type: 'boolean', default: false},
'externalAccess': {type: 'object'},
'excludeFromSingleWMS': {type: 'boolean', default: false},
};

/**
Expand Down Expand Up @@ -91,6 +92,7 @@ export class LayerConfig extends BaseObjectConfig {
* @param {boolean} [cfg.mutuallyExclusive] - the layer mutuallyExclusive (only group type)
* @param {boolean} [cfg.externalWmsToggle] - the layer provides parameters for external access
* @param {object} [cfg.externalAccess] - the layer external access
* @param {boolean} [cfg.excludeFromSingleWMS] - exclude this layer from the project-level single WMS request bundle (no effect when single WMS is not enabled at project level)
*/
constructor(cfg) {
super(cfg, requiredProperties, optionalProperties)
Expand Down Expand Up @@ -361,6 +363,15 @@ export class LayerConfig extends BaseObjectConfig {
get externalAccess() {
return this._externalAccess;
}

/**
* Exclude the layer from the project-level single WMS request bundle.
* No effect when the project-level "single WMS layer" option is disabled.
* @type {boolean}
*/
get excludeFromSingleWMS() {
return this._excludeFromSingleWMS;
}
}

/**
Expand Down
2 changes: 1 addition & 1 deletion assets/src/modules/map.js
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ export default class map extends olMap {
});
}
} else {
if(mapState.singleWMSLayer){
if(mapState.singleWMSLayer && !node.layerConfig.excludeFromSingleWMS){
this._statesSingleWMSLayers.set(node.name,node);
node.singleWMSLayer = true;
return
Expand Down
47 changes: 47 additions & 0 deletions tests/end2end/playwright/singleWMS.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,53 @@ test.describe('Single WMS layer', () => {
await requestSecondBaseLayer.response();
});

test('Layer with excludeFromSingleWMS is removed from the bundle and requested individually',
{
tag:['@readonly']
}, async ({ page }) => {
// Mark single_wms_lines as excluded from the single WMS request stack.
// It should then be requested as its own GetMap (still via QGIS Server,
// since no externalAccess is configured on it).
await page.route('**/service/getProjectConfig*', async route => {
const response = await route.fetch();
const json = await response.json();
json.layers['single_wms_lines']['excludeFromSingleWMS'] = true;
await route.fulfill({ response, json });
});

const project = new ProjectPage(page, 'single_wms_image');
const requestBundlePromise = project.waitForSingleWMSGetMapRequest();
const requestExcludedPromise = project.waitForGetMapRequest('single_wms_lines');
await project.open();

// Stop intercepting once the project is loaded.
await page.unroute('**/service/getProjectConfig*');

const requestBundle = await requestBundlePromise;
const expectedBundleParameters = {
'SERVICE': 'WMS',
'VERSION': '1.3.0',
'REQUEST': 'GetMap',
'FORMAT': 'image/png',
// single_wms_lines is dropped from the bundle, others kept in order
'STYLES':'default,default,default,',
'LAYERS':'single_wms_points,single_wms_points_group,single_wms_lines_group,GroupAsLayer',
}
requestExpect(requestBundle).toContainParametersInUrl(expectedBundleParameters);
await requestBundle.response();

const requestExcluded = await requestExcludedPromise;
const expectedExcludedParameters = {
'SERVICE': 'WMS',
'VERSION': '1.3.0',
'REQUEST': 'GetMap',
'FORMAT': 'image/png',
'LAYERS': 'single_wms_lines',
}
requestExpect(requestExcluded).toContainParametersInUrl(expectedExcludedParameters);
await requestExcluded.response();
});

test('Edit a layer',
{
tag:['@write']
Expand Down
29 changes: 29 additions & 0 deletions tests/js-units/node/config/layer.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ describe('LayerConfig', function () {
expect(group.cached).to.be.false
expect(group.clientCacheExpiration).to.be.eq(300)
expect(group.mutuallyExclusive).to.be.true
expect(group.excludeFromSingleWMS).to.be.false

const layer1 = new LayerConfig({
"id": "null_island20200414115730489",
Expand Down Expand Up @@ -128,6 +129,7 @@ describe('LayerConfig', function () {
expect(layer1.cached).to.be.false
expect(layer1.clientCacheExpiration).to.be.eq(300)
expect(layer1.mutuallyExclusive).to.be.false
expect(layer1.excludeFromSingleWMS).to.be.false

const layer2 = new LayerConfig({
"abstract": "",
Expand Down Expand Up @@ -196,6 +198,33 @@ describe('LayerConfig', function () {
expect(layer2.cached).to.be.false
expect(layer2.clientCacheExpiration).to.be.eq(300)
expect(layer2.mutuallyExclusive).to.be.false
expect(layer2.excludeFromSingleWMS).to.be.false

const excludedLayer = new LayerConfig({
"id": "excluded_wms_layer",
"name": "excluded_wms_layer",
"type": "layer",
"title": "Excluded layer",
"abstract": "",
"link": "",
"minScale": 1,
"maxScale": 1000000000000,
"toggled": "True",
"popup": "False",
"popupSource": "auto",
"popupTemplate": "",
"popupMaxFeatures": 10,
"popupDisplayChildren": "False",
"groupAsLayer": "False",
"baseLayer": "False",
"displayInLegend": "True",
"singleTile": "True",
"imageFormat": "image/png",
"cached": "False",
"clientCacheExpiration": 300,
"excludeFromSingleWMS": true,
});
expect(excludedLayer.excludeFromSingleWMS).to.be.true
})

it('ValidationError', function () {
Expand Down
Loading