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);
}
}
}
}