Source: viewer/loader/LayerTree.js

import { LayerTree as LayerTreeClass } from '../../map/LayerTree.js';
import { displayMessage } from '../../utils/utils.js';
import { Layer } from '../../map/layer/Layer/Layer.js';
import { Folder } from '../../map/layer/Folder/Folder.js';

/**
 * A function that loads the LayerTree
 * 
 * @memberof vef.viewer.loader
 * 
 * @param {object} options 
 * @param {Viewer} viewer 
 */
export function LayerTree(options, viewer) {
    const tree = new LayerTreeClass(null, viewer.layerManager, options);
    const map = viewer.elements[options.targetMap];

    initLayerEvents(tree, viewer, options);
    initZoomLayer(tree, map);
    initLayerInfo(tree, viewer, options);
    initSelectEvents(tree, map);
    initMapEvents(map, tree);

    viewer.addElement(options.id, tree);
};

/**
 * @private
 */
function initSelectEvents(tree, map) {

    const selectLayer = layer => {
        if (layer instanceof Folder) return;
        map.addLayer(layer);
        layer.active = true;
        layer.fire("layer_select", layer);
        tree.layerManager_.fire("layermanager_toggle_selection", layer);
    }

    const deselectLayer = layer => {
        if (layer instanceof Folder) return;
        map.removeLayer(layer);
        layer.active = false;
        tree.hideLoadingIcon(layer.uniqueId);
        layer.fire("layer_deselect", layer);
        tree.layerManager_.fire("layermanager_toggle_selection", layer);
    }

    tree.on("layertree_select", (layer) => selectLayer(layer, map));
    tree.on("layertree_deselect", (layer) => deselectLayer(layer, map));

    // select active layers
    const items = tree.getSelectedItems();
    for (let i = 0; i < items.length; ++i) {
        selectLayer(items[i].layer, map);
    }
}

/**
 * @private
 */
function initLayerEvents(tree, viewer, options) {
    const initLayerEvents = layer => {
        // layer loading icon
        if (layer instanceof Layer) {
            layer.on("layer_loading", () => tree.showLoadingIcon(layer.uniqueId));
            layer.on("layer_loaded", () => tree.hideLoadingIcon(layer.uniqueId));
        }
    }

    // call for each layer and for newly added layers
    viewer.layerManager.forEach(layer => initLayerEvents(layer));
    tree.on("layertree_add_layer", layer => initLayerEvents(layer));
}

/**
 * @private
 */
function initZoomLayer(tree, map) {
    tree.on('layertree_zoom_layer', (layer) => {
        map.fitBounds(layer.getBounds());
    });
}

/**
 * @private
 */
function initLayerInfo(tree, viewer, options) {
    if (!options.targetSidebar || !options.infoSidebarGroup) return;

    const sidebar = viewer.elements[options.targetSidebar];
    let currentLayer, currentGroup;

    sidebar.on("show", group => { currentGroup = group; });
    sidebar.on("close", () => { currentGroup = null; });

    const updateSidebarContent = () => {
        sidebar.setContent(options.infoSidebarGroup, currentLayer.printMetadata());
        sidebar.setTitle(options.infoSidebarGroup, currentLayer.title);
    };

    tree.on("layertree_show_info", (layer) => {
        currentLayer = layer;
        updateSidebarContent();
        sidebar.show(options.infoSidebarGroup);
    });

    tree.on('layertree_rename_layer', (layer) => {
        if ((currentGroup === options.infoSidebarGroup) && (currentLayer === layer)) {
            updateSidebarContent();
        }
    });
}

/**
 * Init events on the map (e.g. adding drawn layers)
 * @private
 */
function initMapEvents(map, tree) {
    map.on("create_layer", layer => {
        tree.addLayer("#", layer, "top");
        tree.selectNodes(layer.uniqueId);
        displayMessage("Added Geometry to the Layer Tree.", 7000);
    });

    map.on("projection_change", e => checkLayerProjections(tree, e.crs));
    tree.on("layertree_add_layer", layer => {
        if (!layer.availableCrs.includes(map.options.crs)) {
            tree.deselectNodes(layer.uniqueId);
            tree.disableNodes(layer.uniqueId);
        }
    });

    checkLayerProjections(tree, map.options.crs);
}

/**
 * @private
 */
function checkLayerProjections(tree, crs) {
    const items = tree.getItems();
    for (let i = 0; i < items.length; ++i) {
        const node = items[i].element;
        const layer = items[i].layer;
        if (layer.availableCrs && node.getAttribute("role") == "layer") {
            const selected = (node.getAttribute("selected") == "true") ? true : false;
            const disabled = (node.getAttribute("disabled") == "true") ? true : false;
            if (layer.availableCrs.includes(crs)) {
                if (disabled) tree.enableNodes(node);
            } else {
                if (selected) tree.deselectNodes(node);
                if (!disabled) tree.disableNodes(node);
            }
        }
    }
}