UNPKG

@geogirafe/lib-geoportal

Version:

GeoGirafe is a flexible application to build online geoportals.

68 lines (67 loc) 3.08 kB
// SPDX-License-Identifier: Apache-2.0 import GirafeSingleton from '../../base/GirafeSingleton.js'; import GroupLayer from '../../models/layers/grouplayer.js'; import ThemeLayer from '../../models/layers/themelayer.js'; export const LayerTreeStartOrder = 1000; export default class OrderingManager extends GirafeSingleton { timeoutId; get state() { return this.context.stateManager.state; } initializeSingleton() { this.registerEvents(); } registerEvents() { this.context.stateManager.subscribe('layers.layersList', (oldLayers, newLayers) => this.onLayerListChanged(oldLayers, newLayers)); this.context.stateManager.subscribe(/layers\.layersList\..*\.children/, (oldLayers, newLayers) => this.onLayerListChanged(oldLayers, newLayers)); this.context.stateManager.subscribe(/layers\.layersList\..*\.order/, () => this.reorderLayers()); } onLayerListChanged(oldLayers, newLayers) { // Need to reorder only if new layers were added. const addedLayers = newLayers.filter((newChild) => !oldLayers.find((oldChild) => oldChild.treeItemId === newChild.treeItemId)); if (addedLayers.length > 0) { this.reorderLayers(); } } /** * This method do a reorder of all layers present in the treeview * in order to keep a order attribut corresponding to what the use wants. * This order will be used by the map component to calculate the list of layers in the right order */ reorderLayers() { // Use a debouncing to prevent multiple execution of this method // If multiple order attributes are modified at the same time. if (this.timeoutId) { clearTimeout(this.timeoutId); } this.timeoutId = setTimeout(() => { const orderedLayers = this.getSortedLayers(this.state.layers.layersList); const counter = { index: LayerTreeStartOrder }; this.context.stateManager.batchChanges(() => this.reorderLayersRecursively(orderedLayers, counter)); }); } reorderLayersRecursively(orderedLayers, counter) { // Traverse the layertree in depth first to renumber all the elements for (const layer of orderedLayers) { console.debug(`Setting layer ${layer.name} to order=${counter.index}`); layer.order = counter.index++; if (layer instanceof GroupLayer || layer instanceof ThemeLayer) { const orderedChilds = this.getSortedLayers(layer.children); this.reorderLayersRecursively(orderedChilds, counter); } } } getSortedLayers(layers) { const orderedLayers = layers.slice().sort((l1, l2) => { // Make sure pinned layers are always on top if (l1.isPinned && !l2.isPinned) return -1; if (!l1.isPinned && l2.isPinned) return 1; if (l1.isPinned && l2.isPinned) return 0; return l1.order - l2.order; }); return orderedLayers; } }