/**
* @module action/Symbology.js
* @name SymbologyAction
* @copyright 2023 3Liz
* @author DHONT René-Luc
* @license MPL-2.0
*/
import { HttpError } from '../Errors.js';
import WMS from './../WMS.js';
import {LayerTreeLayerState, LayerTreeGroupState} from './../state/LayerTree.js'
/**
* Update the symbology of the tree layers
* @param {LayerTreeLayerState[]} treeLayers - The tree layer group in which tree layers will be updated
* @returns {Promise} Promise object represents the tree layers updated
*/
export async function updateLayerTreeLayersSymbology(treeLayers) {
if (!Array.isArray(treeLayers)) {
throw new TypeError('`updateLayerTreeLayersSymbology` method required an array as parameter!');
}
// If the tree layers is empty
// nothing to do
if (treeLayers.length == 0) {
return treeLayers;
}
const wmsNames = treeLayers.map(layer => layer.wmsName);
const wmsStyles = treeLayers.map(layer => layer.wmsSelectedStyleName);
let treeLayersByName = {};
treeLayers.forEach(treeLayer => treeLayersByName[treeLayer.wmsName] = treeLayer);
const wms = new WMS();
const wmsParams = {
LAYER: wmsNames,
STYLES: wmsStyles,
};
await wms.getLegendGraphic(wmsParams).then((response) => {
for (const node of response.nodes) {
// If the layer has no symbology, there is no type property
if (node.hasOwnProperty('type')) {
treeLayersByName[node.name].symbology = node;
}
}
}).catch((error) => {
console.error(error);
// If the request failed, try to get the legend graphic for each layer separately
// This is a workaround for the issue when QGIS server timed out when requesting
// the legend graphic for multiple layers at once (LAYER parameter with multiple values)
if (treeLayers.length == 1) {
// If there is only one layer, there is no need to try to get the legend graphic
// for each layer separately
return treeLayers;
}
if (!(error instanceof HttpError) || error.statusCode != 504) {
// If the error is not a timeout, there is no need to try to get the legend graphic
// for each layer separately
return treeLayers;
}
// Try to get the legend graphic for each layer separately
Promise.all(
treeLayers.map(treeLayer => updateLayerTreeLayerSymbology(treeLayer))
).then((treeLayers) => {
return treeLayers;
});
});
return treeLayers;
}
/**
* Update the symbology of the tree layer
* @param {LayerTreeLayerState} treeLayer - The tree layer to be updated
* @returns {Promise} Promise object represents the tree layer updated
*/
export async function updateLayerTreeLayerSymbology(treeLayer) {
if (!(treeLayer instanceof LayerTreeLayerState)) {
throw new TypeError('`updateLayerTreeLayerSymbology` method required a LayerTreeLayerState as parameter!');
}
return updateLayerTreeLayersSymbology([treeLayer])[0];
}
/**
* Update the symbology of the tree layers in the tree group
* @param {LayerTreeGroupState} treeGroup - The tree layer group in which tree layers will be updated
* @returns {Promise} Promise object represents the tree layers updated
*/
export async function updateLayerTreeGroupLayersSymbology(treeGroup) {
if (!(treeGroup instanceof LayerTreeGroupState)) {
throw new TypeError(
'`updateLayerTreeGroupLayersSymbology` method required a LayerTreeGroupState as parameter!'
);
}
return updateLayerTreeLayersSymbology(treeGroup.findTreeLayers());
}