@geogirafe/lib-geoportal
Version:
GeoGirafe is a flexible application to build online geoportals.
238 lines (237 loc) • 24.7 kB
JavaScript
import { html as uHtml } from 'uhtml';
// SPDX-License-Identifier: Apache-2.0
import tippy from 'tippy.js';
import LayerWms from '../../../models/layers/layerwms.js';
import LayerLocalFile from '../../../models/layers/layerlocalfile.js';
import QueryBuilderComponent from '../../querybuilder/component.js';
import LayerWmts from '../../../models/layers/layerwmts.js';
import TreeViewElement from '../tools/treeviewelement.js';
import { isSnappableLayer } from '../../../models/layers/snappablelayer.js';
import WmsLegendHelper from '../../../tools/wms/wmslegendhelper.js';
class TreeViewItemComponent extends TreeViewElement {
templateUrl = null;
styleUrls = null;
template = () => {
return uHtml `<style>
header{border-top:1px solid #ddd;align-items:center;height:2rem;display:flex}.tool{display:none}header:hover .tool{display:flex}.tool.active{order:100;opacity:1;display:flex}.label-container{flex-grow:1;align-items:center;display:flex;overflow:auto}.label-out-resolution span{font-style:italic}.resolution-tool{margin-left:.5rem}.legend{display:flex}.legend img{background:var(--svg-legend-bkg);height:fit-content;filter:var(--svg-map-filter)}.legend-icon{background:var(--svg-legend-bkg);max-height:1.5rem;filter:var(--svg-map-filter);margin-left:.5rem}.children{flex-basis:100%;order:10;padding-left:1.3rem}.dragAfter{border-bottom:1rem dashed #ccc}.dragBefore{border-top:1rem dashed #ccc}.gg-checkbox{width:1.2rem}.gg-caret,.gg-spacer{text-align:center;width:1.5rem;padding:0}.gg-caret{transform:scale(1.3)}.gg-caret.gg-rotate90{transform:scale(1.3)rotate(90deg)}.gg-small.gg-lock{min-width:1rem}.gg-opacity.gg-lock:hover{opacity:.5}.gg-tree-label{text-align:left;white-space:nowrap;text-overflow:ellipsis;padding-left:0;overflow:hidden}.gg-grab:hover{cursor:grab}.gg-selected{opacity:1}.legend-file{color:var(--text-color);font-style:italic;display:flex}@keyframes headerFade{0%{background-color:var(--highlight-color)}to{background-color:#0000}}.highlight{animation:3s ease-in-out forwards headerFade}
</style><style>
.hidden{display:none}.gg-rotate90{transform:rotate(90deg)}.gg-rotate180{transform:rotate(180deg)}.gg-rotate270{transform:rotate(270deg)}img{filter:var(--svg-filter)}img.legend-image{filter:var(--svg-map-filter);background:var(--svg-legend-bkg)}div{scrollbar-width:thin}a,a:visited{color:var(--link-color)}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}@keyframes spin-wait{0%{transform:rotate(0)}7%{transform:rotate(360deg)}to{transform:rotate(360deg)}}.gg-spin{animation-name:spin;animation-duration:2s;animation-timing-function:linear;animation-iteration-count:infinite}.gg-spin-wait{animation-name:spin-wait;animation-duration:10s;animation-timing-function:linear;animation-iteration-count:infinite}::-webkit-scrollbar{width:5px}::-webkit-scrollbar-thumb{background:#999}button,input,select,textarea{font:inherit}.gg-button,.gg-select,.gg-input,.gg-textarea{background-color:var(--bkg-color);color:var(--text-color);border:var(--app-standard-border);box-sizing:border-box;cursor:pointer;border-radius:3px;outline:0;margin:0;padding:0 0 0 .5rem;display:inline-block}.gg-label{background-color:var(--bkg-color);color:var(--text-color);border:none;align-items:center;margin:0;padding:0;display:flex}.gg-button,.gg-select,.gg-input,.gg-label{min-height:calc(var(--app-standard-height) / 1.5)}.gg-textarea{max-height:initial;resize:vertical;height:6rem;padding:.5rem;line-height:1.3rem}.gg-input{cursor:text}.gg-checkbox{accent-color:var(--text-color);width:1.2rem}.gg-range{accent-color:var(--text-color)}.gg-button{padding:0 .5rem}.gg-button.active{border:solid 1px var(--text-color-grad1);background-color:var(--bkg-color-grad2)}.gg-button:disabled{background-color:var(--bkg-color-grad1);color:var(--text-color-grad2);cursor:not-allowed;border:none}.gg-button:disabled img{filter:opacity(.6)}.gg-input:disabled,.gg-select:disabled,.gg-textarea:disabled{background-color:var(--bkg-color-grad1);color:var(--text-color-grad2);cursor:not-allowed}.gg-button>img{vertical-align:middle}.gg-icon-button{color:var(--text-color);cursor:pointer;background-color:#0000;border:none;flex-direction:column;justify-content:center;align-items:center;padding:0;display:flex}.gg-icon{justify-content:center;align-items:center;display:flex}.gg-big,.gg-big-withtext{min-width:var(--app-standard-height);min-height:var(--app-standard-height);max-height:var(--app-standard-height)}.gg-big img,.gg-big-withtext img{width:calc(var(--app-standard-height) - 1.5rem);margin:0}.gg-big-withtext span{font-variant:small-caps;padding:0 1rem;font-size:.9rem}.gg-medium,.gg-medium-withtext{min-width:calc(var(--app-standard-height) / 1.2);min-height:calc(var(--app-standard-height) / 1.2);max-height:calc(var(--app-standard-height) / 1.2);flex-direction:row}.gg-medium img{width:calc(var(--app-standard-height) / 2.4);margin:0}.gg-medium-withtext img{width:calc(var(--app-standard-height) / 2.4);margin-left:.5rem}.gg-medium-withtext span{padding:0 1rem 0 .5rem;font-size:.9rem}.gg-small,.gg-small-withtext{min-width:calc(var(--app-standard-height) / 2);min-height:calc(var(--app-standard-height) / 2);max-height:calc(var(--app-standard-height) / 2);flex-direction:row}.gg-small img{width:calc(var(--app-standard-height) / 3);margin:0}.gg-small-withtext img{width:calc(var(--app-standard-height) / 3);margin-left:.5rem}.gg-small-withtext span{padding:0 .5rem 0 .3rem;font-size:.9rem}.gg-button:hover:not(:disabled),.gg-select:hover:not(:disabled),.gg-input:hover:not(:disabled),.gg-textarea:hover:not(:disabled),.gg-icon-button:hover:not(:disabled){background-color:var(--bkg-color-grad1)}.gg-opacity{opacity:.5}.gg-opacity:hover{opacity:1;background-color:#0000}.gg-tabs{cursor:pointer;grid-auto-flow:column;padding-bottom:1rem;font-size:1rem;display:grid}.gg-tab{border:none;border-bottom:var(--app-standard-border);cursor:pointer;color:var(--text-color);background:0 0;padding:.5rem}.gg-tab.active{border-bottom:solid 1px var(--text-color)}.girafe-button-big,.girafe-button-large,.girafe-button-small,.girafe-button-tiny{color:var(--text-color);background-color:#0000;border:none;flex-direction:column;display:flex}.girafe-button-big:hover,.girafe-button-large:hover,.girafe-button-small:hover,.girafe-button-tiny:hover{background-color:var(--bkg-color-grad1);cursor:pointer}.girafe-button-big.dark,.girafe-button-large.dark,.girafe-button-small.dark,.girafe-button-tiny.dark{background-color:var(--bkg-color);filter:invert()}.girafe-button-big{width:var(--app-standard-height);height:var(--app-standard-height);align-items:center;padding:1rem}.girafe-button-big img{overflow:hidden}.girafe-button-large{flex-direction:row}.girafe-button-large img{height:2rem;margin:.3rem}.girafe-button-large span{height:2rem;margin:.3rem;line-height:2rem}.girafe-button-small{min-width:calc(var(--app-standard-height) / 2);height:calc(var(--app-standard-height) / 2);align-items:center;padding:.5rem}.girafe-button-small img{overflow:hidden}.girafe-button-small span{text-align:left;text-overflow:ellipsis;width:100%;overflow:hidden}.girafe-button-tiny{align-items:center;width:1rem;height:1rem;padding:0}.girafe-button-tiny img{overflow:hidden}.girafe-onboarding-theme{background-color:var(--bkg-color);color:var(--text-color)}.girafe-onboarding-theme button{background-color:var(--bkg-color);color:var(--text-color);text-shadow:none}.girafe-onboarding-theme button.driver-popover-close-btn{z-index:10000}.tippy-box{background-color:var(--bkg-color);border:var(--app-standard-border)}.tippy-content{color:var(--text-color)}.tippy-arrow{color:var(--bkg-color)}.tippy-box[data-theme~=error]{background-color:var(--error-color);white-space:pre-line}div.tippy-box[data-theme=image-popup]{border:var(--app-standard-border);& div.tippy-content{background-color:var(--bkg-color);& img{max-width:20rem;max-height:20rem}}& div.tippy-arrow{color:var(--bkg-color)}}
</style>
<style>${this.customStyle}</style>
<link rel="stylesheet" href="lib/tippy.js/tippy.css"><link rel="stylesheet" href="lib/tippy.js/backdrop.css"><link rel="stylesheet" href="lib/tippy.js/border.css"><link rel="stylesheet" href="lib/tippy.js/svg-arrow.css"><div id="container"><header><div class="gg-spacer gg-small"><img class="${this.layer.restricted ? (this.layer.active ? 'gg-small gg-lock gg-selected' : 'gg-small gg-lock gg-opacity') : 'hidden'}" alt="Protected layer" src="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICA8bWFzayBpZD0ibWFzazBfMzdfNDUxNyIgc3R5bGU9Im1hc2stdHlwZTphbHBoYSIgbWFza1VuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeD0iMCIgeT0iMCIgd2lkdGg9IjI0IiBoZWlnaHQ9IjI0Ij4KICA8cmVjdCB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIGZpbGw9IiNEOUQ5RDkiLz4KICA8L21hc2s+CiAgPGcgbWFzaz0idXJsKCNtYXNrMF8zN180NTE3KSI+CiAgPHBhdGggZD0iTTYgMjJDNS40NSAyMiA0Ljk3OTE3IDIxLjgwNDIgNC41ODc1IDIxLjQxMjVDNC4xOTU4MyAyMS4wMjA4IDQgMjAuNTUgNCAyMFYxMEM0IDkuNDUgNC4xOTU4MyA4Ljk3OTE3IDQuNTg3NSA4LjU4NzVDNC45NzkxNyA4LjE5NTgzIDUuNDUgOCA2IDhIN1Y2QzcgNC42MTY2NyA3LjQ4NzUgMy40Mzc1IDguNDYyNSAyLjQ2MjVDOS40Mzc1IDEuNDg3NSAxMC42MTY3IDEgMTIgMUMxMy4zODMzIDEgMTQuNTYyNSAxLjQ4NzUgMTUuNTM3NSAyLjQ2MjVDMTYuNTEyNSAzLjQzNzUgMTcgNC42MTY2NyAxNyA2VjhIMThDMTguNTUgOCAxOS4wMjA4IDguMTk1ODMgMTkuNDEyNSA4LjU4NzVDMTkuODA0MiA4Ljk3OTE3IDIwIDkuNDUgMjAgMTBWMjBDMjAgMjAuNTUgMTkuODA0MiAyMS4wMjA4IDE5LjQxMjUgMjEuNDEyNUMxOS4wMjA4IDIxLjgwNDIgMTguNTUgMjIgMTggMjJINlpNNiAyMEgxOFYxMEg2VjIwWk0xMiAxN0MxMi41NSAxNyAxMy4wMjA4IDE2LjgwNDIgMTMuNDEyNSAxNi40MTI1QzEzLjgwNDIgMTYuMDIwOCAxNCAxNS41NSAxNCAxNUMxNCAxNC40NSAxMy44MDQyIDEzLjk3OTIgMTMuNDEyNSAxMy41ODc1QzEzLjAyMDggMTMuMTk1OCAxMi41NSAxMyAxMiAxM0MxMS40NSAxMyAxMC45NzkyIDEzLjE5NTggMTAuNTg3NSAxMy41ODc1QzEwLjE5NTggMTMuOTc5MiAxMCAxNC40NSAxMCAxNUMxMCAxNS41NSAxMC4xOTU4IDE2LjAyMDggMTAuNTg3NSAxNi40MTI1QzEwLjk3OTIgMTYuODA0MiAxMS40NSAxNyAxMiAxN1pNOSA4SDE1VjZDMTUgNS4xNjY2NyAxNC43MDgzIDQuNDU4MzMgMTQuMTI1IDMuODc1QzEzLjU0MTcgMy4yOTE2NyAxMi44MzMzIDMgMTIgM0MxMS4xNjY3IDMgMTAuNDU4MyAzLjI5MTY3IDkuODc1IDMuODc1QzkuMjkxNjcgNC40NTgzMyA5IDUuMTY2NjcgOSA2VjhaIiBmaWxsPSIjMUMxQjFGIi8+CiAgPC9nPgo8L3N2Zz4KICA="></div><button class="${this.layer.active ? 'gg-icon-button gg-small gg-selected' : 'gg-icon-button gg-small gg-opacity'}" tip="Activate / Deactivate" onclick="${() => this.toggle()}"><img class="${this.layer.active ? 'gg-checkbox' : 'hidden'}" alt="Expand/Collapse button" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0NDggNTEyIj48IS0tIUZvbnQgQXdlc29tZSBGcmVlIDYuNi4wIGJ5IEBmb250YXdlc29tZSAtIGh0dHBzOi8vZm9udGF3ZXNvbWUuY29tIExpY2Vuc2UgLSBodHRwczovL2ZvbnRhd2Vzb21lLmNvbS9saWNlbnNlL2ZyZWUgQ29weXJpZ2h0IDIwMjQgRm9udGljb25zLCBJbmMuLS0+PHBhdGggZD0iTTY0IDMyQzI4LjcgMzIgMCA2MC43IDAgOTZMMCA0MTZjMCAzNS4zIDI4LjcgNjQgNjQgNjRsMzIwIDBjMzUuMyAwIDY0LTI4LjcgNjQtNjRsMC0zMjBjMC0zNS4zLTI4LjctNjQtNjQtNjRMNjQgMzJ6TTMzNyAyMDlMMjA5IDMzN2MtOS40IDkuNC0yNC42IDkuNC0zMy45IDBsLTY0LTY0Yy05LjQtOS40LTkuNC0yNC42IDAtMzMuOXMyNC42LTkuNCAzMy45IDBsNDcgNDdMMzAzIDE3NWM5LjQtOS40IDI0LjYtOS40IDMzLjkgMHM5LjQgMjQuNiAwIDMzLjl6Ii8+PC9zdmc+"> <img class="${!this.layer.active ? 'gg-checkbox' : 'hidden'}" alt="Expand/Collapse button" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0NDggNTEyIj48IS0tIUZvbnQgQXdlc29tZSBGcmVlIDYuNi4wIGJ5IEBmb250YXdlc29tZSAtIGh0dHBzOi8vZm9udGF3ZXNvbWUuY29tIExpY2Vuc2UgLSBodHRwczovL2ZvbnRhd2Vzb21lLmNvbS9saWNlbnNlL2ZyZWUgQ29weXJpZ2h0IDIwMjQgRm9udGljb25zLCBJbmMuLS0+PHBhdGggZD0iTTM4NCA4MGM4LjggMCAxNiA3LjIgMTYgMTZsMCAzMjBjMCA4LjgtNy4yIDE2LTE2IDE2TDY0IDQzMmMtOC44IDAtMTYtNy4yLTE2LTE2TDQ4IDk2YzAtOC44IDcuMi0xNiAxNi0xNmwzMjAgMHpNNjQgMzJDMjguNyAzMiAwIDYwLjcgMCA5NkwwIDQxNmMwIDM1LjMgMjguNyA2NCA2NCA2NGwzMjAgMGMzNS4zIDAgNjQtMjguNyA2NC02NGwwLTMyMGMwLTM1LjMtMjguNy02NC02NC02NEw2NCAzMnoiLz48L3N2Zz4="></button><div class="${this.layer.hasError ? 'gg-icon gg-small gg-opacity' : 'hidden'}" tip="${this.layer.errorMessage ? this.layer.errorMessage : 'Error on layer'}"><img alt="Error on layer" src="icons/error.svg"></div><div class="${this.isVisibleInCurrentResolution() ? 'label-container' : 'label-container label-out-resolution'}"><button class="${this.layer.active ? 'gg-icon-button gg-small gg-selected' : 'gg-icon-button gg-small gg-opacity'}" onclick="${() => this.toggle()}"><span i18n="${this.layer.name}" class="gg-tree-label">${this.layer.name}</span></button> <button class="${this.layer.active && this.layer instanceof LayerWms && !this.isVisibleInCurrentResolution() ? 'gg-icon-button gg-small resolution-tool' : 'hidden'}" tip="Zoom to visible resolution" onclick="${() => this.zoomToVisibleResolution()}"><img alt="Zoom to visible resolution" src="icons/zoom.svg"></button> <img class="${this.layer.active && this.iconUrl ? 'legend-icon' : 'hidden'}" alt="${'Icon for ' + this.layer.name}" src="${this.iconUrl}" loading="lazy" crossorigin="${this.getCrossOrigin(this.iconUrl)}"></div><button class="${this.layer.active && this.layer instanceof LayerLocalFile ? 'gg-icon-button gg-small gg-opacity tool' : 'hidden'}" tip="Zoom to full extent" onclick="${() => this.zoomToFullExtent()}"><img alt="Zoom to full extent" src="icons/zoom.svg"></button> <button class="${this.getButtonClass('swipedLeft')}" tip="Swipe layer to the left" onclick="${() => this.layer.swiped = (this.layer.swiped === 'left') ? 'no' : 'left'}"><img alt="Swipe layer to the left" src="icons/swipe-left.svg"></button> <button class="${this.getButtonClass('swipedRight')}" tip="Swipe layer to the right" onclick="${() => this.layer.swiped = (this.layer.swiped === 'right') ? 'no' : 'right'}"><img alt="Swipe layer to the right" src="icons/swipe-right.svg"></button> <button id="opacity" class="${this.getButtonClass('opacity')}" tip="Control opacity"><img alt="Control opacity" src="icons/opacity.svg"></button> <button id="filter" class="${this.getButtonClass('filter')}" tip="Filter layer"><img alt="Filter layer" src="icons/filter.svg"></button> <button id="advanced-filter" class="${this.getButtonClass('advanced-filter')}" tip="Open advanced filter tool" onclick="${() => this.state.interface.advancedFilterPanelVisible = !this.state.interface.advancedFilterPanelVisible}"><img alt="Advanced filter" src="icons/advanced-filter.svg"></button> <button id="timeRestriction" class="${this.getButtonClass('timeRestriction')}" tip="Define time restriction on layer"><img alt="Define time restriction on layer" src="icons/clock.svg"></button> <button class="${this.getButtonClass('snappable')}" onclick="${() => this.toggleSnap()}" tip="Snap to layer features"><img alt="Enable snapping" src="icons/snapping.svg"></button> <button class="${this.hasLegend ? (this.layer.isLegendExpanded ? 'gg-icon-button gg-small tool' : 'gg-icon-button gg-small gg-opacity tool') : 'hidden'}" tip="Toggle legend" onclick="${() => this.toggleLegend()}"><img alt="Toggle legend" src="icons/legend.svg" loading="lazy"></button> <button class="${this.layer.hasMetadata ? 'metadata gg-icon-button gg-small gg-opacity tool' : 'hidden'}" onclick="${() => this.showMetadata()}"><img alt="Metadata" src="icons/info.svg"></button> <button id="drag-button" class="${this.getButtonClass('draggable')}" tip="Move"><img alt="Move layer" src="icons/drag.svg"></button> <button class="${this.getButtonClass('removable')}" tip="Remove layer" onclick="${() => this.deleteLayer()}"><img alt="Remove layer" src="icons/trash.svg"></button></header>${Object.keys(this.legendUrls).map((l) => uHtml `<div class="${this.isLegendExpanded ? 'legend' : 'hidden'}"><div class="gg-spacer gg-small"></div><img alt="${'Legend for ' + l}" src="${this.legendUrls[l]}" loading="lazy" crossorigin="${this.getCrossOrigin(this.legendUrls[l])}"></div>`)}<div class="${this.layer instanceof LayerLocalFile && this.isLegendExpanded ? 'legend-file' : 'legend-file hidden'}"><div class="gg-spacer gg-small"></div><div class="gg-spacer gg-small"></div><div><span i18n="File from">File from</span> <span>${this.layer.lastModifiedDate}</span> <span>[</span> <span>${this.layer._features?.length}</span> <span i18n="features">features</span> <span>]</span></div></div></div>
${this.htmlUnsafe(this.feedbackTemplateHtml ?? '')}`;
};
iconUrl = null;
legendUrls = {};
wmsLegendHelper;
layer;
get hasLegend() {
return this.context.layerManager.isLayerWithLegend(this.layer) && this.layer.legend;
}
get isLegendExpanded() {
if (this.context.layerManager.isLayerWithLegend(this.layer)) {
return this.layer.isLegendExpanded;
}
return false;
}
toggleLegend() {
if (this.context.layerManager.isLayerWithLegend(this.layer)) {
this.layer.isLegendExpanded = !this.layer.isLegendExpanded;
}
}
toggleSnap() {
if (isSnappableLayer(this.layer)) {
this.layer.snapActive = !this.layer.snapActive;
}
}
constructor(layer) {
super(layer, 'treeviewitem');
this.layer = layer;
}
render() {
// If we come from a html element, the layer was not defined in the constructor
// And we have to set the layer using the id passed to the layerid attribute
const layerId = this.getAttribute('layerid');
if (layerId) {
this.layer = this.context.layerManager.getTreeItem(layerId);
if (this.layer instanceof LayerWms) {
// Manage Legend icons for WMS
this.setWmsLegend();
}
if (this.layer instanceof LayerWmts) {
this.setWmtsLegend();
}
}
super.render();
this.createOpacityTooltip();
this.createFilterTooltip();
}
setWmsLegend() {
if (!(this.layer instanceof LayerWms)) {
// nothing to do if it's not a WMS
return;
}
this.iconUrl = this.wmsLegendHelper.getIconUrl(this.layer);
if (this.isVisibleInCurrentResolution()) {
this.legendUrls = this.wmsLegendHelper.getLegendUrls(this.layer);
}
else {
this.legendUrls = {};
}
}
setWmtsLegend() {
if (!(this.layer instanceof LayerWmts)) {
// nothing to do if it's not a WMS
return;
}
if (this.layer.legend) {
if (this.layer.legendImage) {
this.legendUrls[this.layer.name] = this.layer.legendImage;
}
else {
this.layer.hasError = true;
this.layer.errorMessage = `The WMTS Layer ${this.layer.name} has no legendImage.`;
}
}
}
getCrossOrigin(url) {
if (!url) {
return 'anonymous';
}
const hostname = new URL(url).hostname;
return this.state.oauth.audience.includes(hostname) ? 'use-credentials' : 'anonymous';
}
createOpacityTooltip() {
const el = this.shadow.getElementById('opacity');
if (!el) {
return;
}
tippy(el, {
trigger: 'click',
arrow: true,
interactive: true,
theme: 'light',
placement: 'right',
content: (_reference) => {
const slider = document.createElement('input');
slider.type = 'range';
slider.className = 'slider';
slider.min = '0';
slider.max = '20';
slider.value = (this.layer.opacity * 20).toString();
slider.oninput = () => (this.layer.opacity = Number.parseInt(slider.value) / 20);
return slider;
}
});
}
createFilterTooltip() {
const el = this.shadow.getElementById('filter');
if (!el) {
return;
}
tippy(el, {
trigger: 'click',
arrow: true,
interactive: true,
theme: 'light',
placement: 'right',
appendTo: document.body,
content: (_reference) => {
const filterbox = new QueryBuilderComponent(this.layer, this.context);
return filterbox;
}
});
}
registerEvents() {
this.subscribe(/layers\..*\.isLegendExpanded/, (_oldValue, _newValue, layer) => {
this.refreshLegendsAndStyle();
this.refreshRender(layer);
});
this.subscribe(/layers\.layersList\..*\.activeState/, (_oldValue, _newValue, layer) => {
this.refreshLegendsAndStyle();
this.refreshRender(layer);
});
this.subscribe(/layers\.layersList\..*\.hasError/, (_oldValue, _newValue, layer) => this.refreshRender(layer));
this.subscribe(/layers\.layersList\..*\.errorMessage/, (_oldValue, _newValue, layer) => this.refreshRender(layer));
this.subscribe(/layers\.layersList\..*\.filter/, (_oldValue, _newValue, layer) => this.refreshRender(layer));
this.subscribe(/layers\.layersList\..*\.snapActive/, (_oldValue, _newValue, layer) => this.refreshRender(layer));
this.subscribe(/layers\.layersList\..*\.timeRestriction/, (_old, _new, layer) => {
if (layer === this.layer || layer === this.layer.parent)
this.refreshRender(this.layer);
});
this.subscribe(/layers\.layersList\..*\.opacity/, (_oldValue, _newValue, layer) => this.refreshRender(layer));
this.subscribe(/layers\.layersList\..*\.swiped/, (_oldValue, _newValue, layer) => this.refreshRender(layer));
this.subscribe('treeview.advanced', () => this.refreshRender(this.layer));
this.subscribe('position', () => this.refreshLegendsAndStyle());
}
refreshLegendsAndStyle() {
if (!this.layer.parent.isExpanded) {
// Not visible, nothing to refresh
return;
}
let refresh = false;
if (this.layer instanceof LayerWms && this.layer.legend && this.layer.isLegendExpanded) {
this.setWmsLegend();
refresh = true;
}
if ((this.layer instanceof LayerWms || this.layer instanceof LayerWmts) && this.layer.hasRestrictedResolution()) {
// Restricted resolution, maybe the layername should be written italic
refresh = true;
}
if (refresh) {
super.refreshRender();
}
}
toggle(state) {
this.context.layerManager.toggleLayer(this.layer, state);
}
zoomToVisibleResolution() {
if (!(this.layer instanceof LayerWms)) {
throw new Error(`${this.layer.name} is not a WMS layer, this method should not be called here.`);
}
if (this.layer.maxResolution) {
if (this.context.configManager.Config.map.constrainScales) {
// We have to find the right resolution
const allowedResolutions = this.context.mapManager.getMap().getView().getResolutions();
const maxResolution = this.layer.maxResolution;
const newResolution = allowedResolutions.find((r) => r < maxResolution);
this.state.position.resolution = newResolution;
}
else {
// We can just zoom to the correct resolution.
// But because of rounding errors (for example 1.59 becomes 1.589999999999998),
// we zoom a bit more than just the max resolution (5% more)
const resolution = this.layer.maxResolution * 0.95;
this.state.position.resolution = resolution;
}
}
}
isVisibleInCurrentResolution() {
if (!(this.layer instanceof LayerWms) && !(this.layer instanceof LayerWmts)) {
// Always true for not WMS/WMTS layers
return true;
}
const currentResolution = this.state.position.resolution;
if (currentResolution) {
return this.layer.isVisibleAtResolution(currentResolution);
}
return false;
}
zoomToFullExtent() {
if (!(this.layer instanceof LayerLocalFile)) {
throw new Error(`${this.layer.name} is not a LocalFile layer, this method should not be called here.`);
}
this.context.mapManager.zoomToExtent(this.layer.extent);
}
deleteLayer() {
this.context.layerManager.toggleLayer(this.layer, 'off');
this.removeFromParent();
}
connectedCallback() {
super.connectedCallback();
this.wmsLegendHelper = new WmsLegendHelper(this.context);
this.render();
this.registerEvents();
}
}
export default TreeViewItemComponent;