@geogirafe/lib-geoportal
Version:
GeoGirafe is a flexible application to build online geoportals.
119 lines (118 loc) • 4.58 kB
JavaScript
// SPDX-License-Identifier: Apache-2.0
import GirafeSingleton from '../../base/GirafeSingleton.js';
import ThemeLayer from '../../models/layers/themelayer.js';
import LayerDrawing from '../../models/layers/layerdrawing.js';
import LayerLocalFile from '../../models/layers/layerlocalfile.js';
/**
* Manages layers that hold user-derived data such as drawings or local files. Each type of user data layer is
* grouped under a theme layer in the layer tree.
* This manager provides functionality for adding, organizing, and toggling visibility of user data layers
* in the layer tree.
*/
export default class UserLayerManager extends GirafeSingleton {
themeLayerItemIds = {};
userThemeConfig = {
drawing: {
name: 'Drawings',
isRemovable: false,
isSwipeable: false,
isDraggable: false,
isPinned: true
},
localFile: {
name: 'Local Files',
isRemovable: true,
isSwipeable: false,
isDraggable: false,
isPinned: true
},
default: {
name: 'User data',
isRemovable: true,
isSwipeable: false,
isDraggable: false,
isPinned: true
}
};
get state() {
return this.context.stateManager.state;
}
getThemeLayerByTreeId(treeItemId) {
try {
return this.context.stateManager.state.layers.layersList.find((l) => l.treeItemId === treeItemId);
}
catch {
return null;
}
}
getUserLayerByTreeId(treeItemId) {
for (const theme of this.state.layers.layersList) {
if (theme instanceof ThemeLayer) {
for (const layer of theme.children) {
if (layer.treeItemId === treeItemId) {
return layer;
}
}
}
}
return null;
}
getOrCreateThemeLayer(config) {
let themeLayer = this.getThemeLayerByTreeId(this.themeLayerItemIds[config.name]);
if (!themeLayer) {
themeLayer = new ThemeLayer(0, config.name, 0, '', { isDefaultChecked: true, isDefaultExpanded: true });
themeLayer.order = this.context.themesHelper.getInitialOrderForNewTheme();
themeLayer.isPinned = config.isPinned;
themeLayer.isRemovable = config.isRemovable;
themeLayer.isSwipeable = config.isSwipeable;
themeLayer.isDraggable = config.isDraggable;
}
return themeLayer;
}
getThemeConfig(layer) {
if (layer instanceof LayerDrawing) {
return this.userThemeConfig.drawing;
}
else if (layer instanceof LayerLocalFile) {
return this.userThemeConfig.localFile;
}
return this.userThemeConfig.default;
}
/**
* Adds a user data layer to the layer tree. Each layer is added to the corresponding theme.
* If the theme layer does not exist yet, it is created according to a set of pre-defined configuration values.
*/
addUserLayerToTree(layer) {
const config = this.getThemeConfig(layer);
const theme = this.getOrCreateThemeLayer(config);
const userLayerInTree = this.getUserLayerByTreeId(layer.treeItemId);
if (userLayerInTree) {
this.context.layerManager.toggleLayer(userLayerInTree, 'on');
}
else {
layer.parent = theme;
theme.children.push(layer);
if (!this.getThemeLayerByTreeId(theme.treeItemId)) {
this.context.stateManager.state.layers.layersList.push(theme);
this.themeLayerItemIds[config.name] = theme.treeItemId;
}
}
}
/**
* Removes a user data layer from the layer tree.
* If the associated theme layer becomes empty after the user layer is removed, the theme layer is also removed.
*/
removeUserLayerFromTree(layer) {
const config = this.getThemeConfig(layer);
const theme = this.getThemeLayerByTreeId(this.themeLayerItemIds[config.name]);
const userLayer = this.getUserLayerByTreeId(layer.treeItemId);
if (userLayer) {
this.context.themesHelper.removeLayersFromLayerTree([userLayer]);
if (theme?.children.length === 0) {
// Remove the theme layer if it's empty
this.context.themesHelper.removeLayersFromLayerTree([theme]);
delete this.themeLayerItemIds[config.name];
}
}
}
}