@geogirafe/lib-geoportal
Version:
GeoGirafe is a flexible application to build online geoportals.
68 lines (67 loc) • 3.08 kB
JavaScript
// 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;
}
}