@vcmap/ui 6.1.0-rc.6 → 6.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/config/base.config.json +7 -3
- package/config/cluster.config.json +5 -14
- package/config/dev.config.json +175 -56
- package/config/projects.config.json +2 -1
- package/config/splashscreen.config.json +6 -10
- package/config/vectorTile.config.json +42 -1
- package/dist/assets/{cesium-f5e8e354.js → cesium-664ad022.js} +53 -23
- package/dist/assets/cesium.js +1 -1
- package/dist/assets/{core-c134a524.js → core-841b71a4.js} +8458 -5828
- package/dist/assets/core.js +1 -1
- package/dist/assets/{ol-2752311f.js → ol-2e095c08.js} +87 -37
- package/dist/assets/ol.js +1 -1
- package/dist/assets/ui-2fd6f47d.css +1 -0
- package/dist/assets/{ui-83514586.js → ui-2fd6f47d.js} +21376 -20063
- package/dist/assets/ui.js +1 -1
- package/dist/assets/vue.js +1 -1
- package/dist/assets/{vuetify-5dbe2644.css → vuetify-4bc77ff7.css} +2 -2
- package/dist/assets/{vuetify-5dbe2644.js → vuetify-4bc77ff7.js} +7520 -7373
- package/dist/assets/vuetify.js +1 -1
- package/dist/index.html +1 -1
- package/index.d.ts +15 -5
- package/index.html +1 -1
- package/index.js +14 -5
- package/package.json +12 -8
- package/plugins/@vcmap-show-case/theming-example/src/index.js +1 -0
- package/plugins/@vcmap-show-case/vector-properties-example/src/LayerSettings.vue +39 -0
- package/plugins/@vcmap-show-case/vector-properties-example/src/VectorPropertiesExample.vue +3 -0
- package/plugins/@vcmap-show-case/vector-properties-example/src/lib.js +13 -0
- package/plugins/@vcmap-show-case/window-tester/src/WindowExample.vue +9 -0
- package/plugins/package.json +7 -5
- package/src/actions/actionHelper.d.ts +6 -0
- package/src/actions/actionHelper.js +22 -0
- package/src/actions/deepPickingAction.d.ts +23 -0
- package/src/actions/deepPickingAction.js +399 -0
- package/src/application/MapsGroupMobileMenu.vue +105 -0
- package/src/application/MapsGroupMobileMenu.vue.d.ts +7 -0
- package/src/application/VcsApp.vue +51 -24
- package/src/application/VcsApp.vue.d.ts +9 -2
- package/src/application/VcsAttributionsFooter.vue +1 -0
- package/src/application/VcsContainer.vue +36 -13
- package/src/application/VcsContainer.vue.d.ts +7 -0
- package/src/application/VcsMobileMenuList.vue +111 -0
- package/src/application/VcsMobileMenuList.vue.d.ts +2 -0
- package/src/application/VcsNavbar.vue +15 -3
- package/src/application/VcsNavbarMobile.vue +206 -0
- package/src/application/VcsNavbarMobile.vue.d.ts +42 -0
- package/src/application/VcsPositionDisplay.vue +1 -0
- package/src/application/VcsSplashScreen.vue +39 -7
- package/src/application/VcsSplashScreen.vue.d.ts +6 -0
- package/src/application/uiConfigHelper.d.ts +12 -0
- package/src/application/uiConfigHelper.js +37 -0
- package/src/components/buttons/VcsActionButtonList.vue +1 -0
- package/src/components/buttons/VcsToolButton.vue +8 -1
- package/src/components/buttons/VcsToolButton.vue.d.ts +1 -0
- package/src/components/form-inputs-controls/VcsSelect.vue +8 -6
- package/src/components/form-output/VcsTemplateMarkdown.vue +43 -0
- package/src/components/form-output/VcsTemplateMarkdown.vue.d.ts +9 -0
- package/src/components/icons/+all.d.ts +5 -0
- package/src/components/icons/+all.js +14 -0
- package/src/components/lists/VcsActionList.vue +1 -0
- package/src/components/lists/VcsGroupedList.vue +2 -1
- package/src/components/lists/VcsListItemComponent.vue +1 -0
- package/src/components/lists/VcsTreeNode.vue +11 -2
- package/src/components/lists/VcsTreeview.vue +40 -3
- package/src/components/lists/VcsTreeview.vue.d.ts +1 -0
- package/src/components/lists/VcsTreeviewTitle.vue +8 -1
- package/src/components/style/{MenuWrapper.vue → StyleMenuWrapper.vue} +2 -1
- package/src/components/style/VcsFillMenu.vue +4 -4
- package/src/components/style/VcsImageMenu.vue +4 -4
- package/src/components/style/VcsStrokeMenu.vue +4 -4
- package/src/components/style/VcsTextMenu.vue +4 -4
- package/src/contentTree/LayerTree.vue +8 -46
- package/src/contentTree/LayerTree.vue.d.ts +1 -3
- package/src/contentTree/contentTreeCollection.d.ts +7 -0
- package/src/contentTree/contentTreeCollection.js +31 -10
- package/src/contentTree/contentTreeItem.d.ts +4 -4
- package/src/contentTree/contentTreeItem.js +2 -2
- package/src/contentTree/flightContentTreeItem.d.ts +8 -1
- package/src/contentTree/flightContentTreeItem.js +26 -3
- package/src/contentTree/groupContentTreeItem.d.ts +21 -0
- package/src/contentTree/groupContentTreeItem.js +32 -2
- package/src/contentTree/layerContentTreeItem.d.ts +8 -1
- package/src/contentTree/layerContentTreeItem.js +26 -4
- package/src/contentTree/layerGroupContentTreeItem.d.ts +6 -0
- package/src/contentTree/layerGroupContentTreeItem.js +27 -3
- package/src/contentTree/nodeContentTreeItem.d.ts +21 -0
- package/src/contentTree/nodeContentTreeItem.js +31 -2
- package/src/contentTree/obliqueCollectionContentTreeItem.d.ts +6 -0
- package/src/contentTree/obliqueCollectionContentTreeItem.js +22 -2
- package/src/contentTree/wmsChildContentTreeItem.d.ts +56 -0
- package/src/contentTree/wmsChildContentTreeItem.js +159 -0
- package/src/contentTree/wmsGroupContentTreeItem.d.ts +171 -0
- package/src/contentTree/wmsGroupContentTreeItem.js +619 -0
- package/src/featureInfo/BalloonComponent.vue +6 -6
- package/src/featureInfo/ClusterFeatureComponent.vue +47 -11
- package/src/featureInfo/ClusterFeatureComponent.vue.d.ts +1 -0
- package/src/featureInfo/MarkdownBalloonComponent.vue +3 -9
- package/src/featureInfo/MarkdownBalloonComponent.vue.d.ts +1 -11
- package/src/featureInfo/balloonFeatureInfoView.d.ts +3 -0
- package/src/featureInfo/balloonFeatureInfoView.js +78 -11
- package/src/featureInfo/balloonHelper.js +9 -13
- package/src/featureInfo/featureInfo.d.ts +32 -7
- package/src/featureInfo/featureInfo.js +192 -93
- package/src/featureInfo/markdownBalloonFeatureInfoView.d.ts +0 -6
- package/src/featureInfo/markdownBalloonFeatureInfoView.js +5 -14
- package/src/featureInfo/markdownFeatureInfoView.d.ts +2 -8
- package/src/featureInfo/markdownFeatureInfoView.js +6 -15
- package/src/i18n/de.d.ts +64 -50
- package/src/i18n/de.js +9 -0
- package/src/i18n/en.d.ts +64 -50
- package/src/i18n/en.js +9 -0
- package/src/legend/VcsLegend.vue +21 -2
- package/src/legend/VcsLegend.vue.d.ts +1 -0
- package/src/legend/legendHelper.d.ts +0 -13
- package/src/legend/legendHelper.js +3 -27
- package/src/manager/navbarManager.d.ts +14 -1
- package/src/manager/navbarManager.js +22 -2
- package/src/manager/toolbox/GroupToolboxComponent.vue +17 -3
- package/src/manager/toolbox/GroupToolboxComponent.vue.d.ts +1 -0
- package/src/manager/toolbox/SelectToolboxComponent.vue +17 -3
- package/src/manager/toolbox/SelectToolboxComponent.vue.d.ts +1 -0
- package/src/manager/toolbox/ToolboxManagerComponent.vue +45 -14
- package/src/manager/toolbox/ToolboxManagerComponent.vue.d.ts +9 -0
- package/src/manager/toolbox/toolboxManager.d.ts +2 -1
- package/src/manager/toolbox/toolboxManager.js +13 -1
- package/src/manager/window/WindowComponent.vue +3 -2
- package/src/manager/window/WindowComponentHeader.vue +9 -1
- package/src/manager/window/WindowComponentHeader.vue.d.ts +1 -0
- package/src/manager/window/WindowManager.vue +175 -30
- package/src/manager/window/WindowManager.vue.d.ts +5 -0
- package/src/manager/window/windowManager.d.ts +2 -2
- package/src/manager/window/windowManager.js +12 -10
- package/src/navigation/MapNavigation.vue +29 -19
- package/src/navigation/MapNavigation.vue.d.ts +1 -0
- package/src/notifier/NotifierComponent.vue +1 -0
- package/src/search/ResultsComponent.vue +44 -17
- package/src/search/ResultsComponent.vue.d.ts +11 -1
- package/src/search/SearchComponent.vue +60 -9
- package/src/search/SearchComponent.vue.d.ts +2 -0
- package/src/search/search.js +3 -16
- package/src/state.d.ts +2 -1
- package/src/state.js +2 -1
- package/src/uiConfig.d.ts +9 -0
- package/src/uiConfig.js +1 -0
- package/src/vuePlugins/vuetify.d.ts +4 -0
- package/src/vuePlugins/vuetify.js +49 -3
- package/dist/assets/ui-83514586.css +0 -1
- /package/dist/assets/{vue-f8b1b5f8.js → vue-71fd14e8.js} +0 -0
- /package/src/components/style/{MenuWrapper.vue.d.ts → StyleMenuWrapper.vue.d.ts} +0 -0
@@ -0,0 +1,619 @@
|
|
1
|
+
import { markVolatile } from '@vcmap/core';
|
2
|
+
import { getLogger } from '@vcsuite/logger';
|
3
|
+
import { ref } from 'vue';
|
4
|
+
import { parseBoolean } from '@vcsuite/parsers';
|
5
|
+
import deepEqual from 'fast-deep-equal';
|
6
|
+
import WMSCapabilities from 'ol/format/WMSCapabilities';
|
7
|
+
import { StateActionState } from '../actions/stateRefAction.js';
|
8
|
+
import { contentTreeClassRegistry } from './contentTreeItem.js';
|
9
|
+
import WmsChildContentTreeItem from './wmsChildContentTreeItem.js';
|
10
|
+
import VcsObjectContentTreeItem from './vcsObjectContentTreeItem.js';
|
11
|
+
|
12
|
+
/**
|
13
|
+
* @param {string} rawUrl
|
14
|
+
* @param {Record<string, string>} parameters
|
15
|
+
* @returns {Promise<Array<WMSEntry>>} The fetched capabilities.
|
16
|
+
*/
|
17
|
+
async function getWMSEntries(rawUrl, parameters) {
|
18
|
+
const url = new URL(rawUrl);
|
19
|
+
const excludedParameters = [
|
20
|
+
'LAYERS',
|
21
|
+
'TRANSPARENT',
|
22
|
+
'FORMAT',
|
23
|
+
'STYLE',
|
24
|
+
'STYLES',
|
25
|
+
];
|
26
|
+
Object.entries(parameters).forEach(([key, value]) => {
|
27
|
+
if (!excludedParameters.includes(key)) {
|
28
|
+
url.searchParams.set(key, value);
|
29
|
+
}
|
30
|
+
});
|
31
|
+
url.searchParams.set('SERVICE', 'WMS');
|
32
|
+
url.searchParams.set('REQUEST', 'GetCapabilities');
|
33
|
+
|
34
|
+
const res = await fetch(url.toString());
|
35
|
+
if (!res.ok) {
|
36
|
+
throw new Error(`Failed to fetch capabilities: ${res.statusText}`);
|
37
|
+
}
|
38
|
+
const xml = await res.text();
|
39
|
+
const { Capability } = new WMSCapabilities().read(xml);
|
40
|
+
const wmsEntries = Capability.Layer.Layer
|
41
|
+
// layer without Name are not requestable, they are just a Group.
|
42
|
+
.filter((layer) => layer.Name)
|
43
|
+
.map((layer) => {
|
44
|
+
const styles =
|
45
|
+
layer.Style?.map((style) => {
|
46
|
+
return {
|
47
|
+
name: style.Name,
|
48
|
+
title: style.Title,
|
49
|
+
legend: style.LegendURL?.filter(
|
50
|
+
(legend) => legend.OnlineResource,
|
51
|
+
).map((legend) => {
|
52
|
+
const src = legend.OnlineResource;
|
53
|
+
if (legend.size[0] < 25) {
|
54
|
+
return {
|
55
|
+
type: 'StyleLegendItem',
|
56
|
+
colNr: 1,
|
57
|
+
rows: [
|
58
|
+
{
|
59
|
+
type: 'IconLegendRow',
|
60
|
+
title: layer.Title,
|
61
|
+
image: { src },
|
62
|
+
},
|
63
|
+
],
|
64
|
+
};
|
65
|
+
}
|
66
|
+
return {
|
67
|
+
type: 'ImageLegendItem',
|
68
|
+
src,
|
69
|
+
popoutBtn: true,
|
70
|
+
};
|
71
|
+
}),
|
72
|
+
};
|
73
|
+
}) ?? [];
|
74
|
+
return {
|
75
|
+
name: layer.Name,
|
76
|
+
active: ref(false),
|
77
|
+
activeStyle: ref(''),
|
78
|
+
title: layer.Title,
|
79
|
+
extent: layer.EX_GeographicBoundingBox,
|
80
|
+
styles,
|
81
|
+
};
|
82
|
+
});
|
83
|
+
return wmsEntries;
|
84
|
+
}
|
85
|
+
|
86
|
+
/**
|
87
|
+
* @param {import("../vcsUiApp.js").default} app
|
88
|
+
* @param {WMSEntry} wmsEntry
|
89
|
+
* @param {string} parentName
|
90
|
+
* @param {boolean} showStyleSelector
|
91
|
+
* @returns {WmsChildContentTreeItem}
|
92
|
+
*/
|
93
|
+
function createWMSChildContentTreeItem(
|
94
|
+
app,
|
95
|
+
wmsEntry,
|
96
|
+
parentName,
|
97
|
+
showStyleSelector,
|
98
|
+
) {
|
99
|
+
const childItem = new WmsChildContentTreeItem(
|
100
|
+
{
|
101
|
+
name: `${parentName}.${wmsEntry.name.replaceAll('.', '_')}`,
|
102
|
+
wmsEntry,
|
103
|
+
title: wmsEntry.title,
|
104
|
+
showStyleSelector,
|
105
|
+
},
|
106
|
+
app,
|
107
|
+
);
|
108
|
+
markVolatile(childItem);
|
109
|
+
return childItem;
|
110
|
+
}
|
111
|
+
|
112
|
+
/**
|
113
|
+
* @typedef {import('./contentTreeItem.js').ContentTreeItemOptions &
|
114
|
+
* { layerName: string, showWhenNotSupported?: boolean, exclusiveLayers?:boolean, editableStyle?:boolean, allowedWMSLayers?:string[]}} WMSGroupContentTreeItemOptions
|
115
|
+
* @property {boolean} showWhenNotSupported - optional flag to show the item even if it is not supported by the activeMap.
|
116
|
+
* @property {string} layerName - The name of the WMSLayer to show the children of.
|
117
|
+
* @property {boolean} [setWMSLayersExclusive=false] - Whether the WMSlayers are mutually exclusive.
|
118
|
+
* @property {boolean} [showStyleSelector=true] - Whether the layer style can be selected. Will add a StyleSelector action to compatible items if the Layer has more than one style.
|
119
|
+
* @property {string[]} allowedWMSLayers - The list of layers to be shown, other available layers will not be shown.
|
120
|
+
*/
|
121
|
+
|
122
|
+
/**
|
123
|
+
* @typedef {Object} WMSStyleEntry
|
124
|
+
* @property {string} name
|
125
|
+
* @property {string} title
|
126
|
+
* @property {import("../legend/legendHelper.js").LegendItem} legend
|
127
|
+
*/
|
128
|
+
|
129
|
+
/**
|
130
|
+
* @typedef {Object} WMSEntry
|
131
|
+
* @property {string} name
|
132
|
+
* @property {import("vue").Ref<boolean>} active
|
133
|
+
* @property {import("vue").Ref<string>} activeStyle
|
134
|
+
* @property {string} title
|
135
|
+
* @property {import("@vcmap/core").Extent} extent
|
136
|
+
* @property {Array<WMSStyleEntry>} styles
|
137
|
+
*/
|
138
|
+
|
139
|
+
/**
|
140
|
+
* A WMSGroupItem, will take over a WMSLayer and request the Capabilities of the layer to show all available
|
141
|
+
* layers as child Items. The WMSGroupItem will also set the legend on the Layer based on the Capabilities,
|
142
|
+
* if the Layer does not have a legend configured.
|
143
|
+
* @extends {VcsObjectContentTreeItem<import("./vcsObjectContentTreeItem.js").VcsObjectContentTreeItemProperties>}
|
144
|
+
* @class
|
145
|
+
*/
|
146
|
+
class WMSGroupContentTreeItem extends VcsObjectContentTreeItem {
|
147
|
+
static get className() {
|
148
|
+
return 'WMSGroupContentTreeItem';
|
149
|
+
}
|
150
|
+
|
151
|
+
/**
|
152
|
+
* @param {WMSGroupContentTreeItemOptions} options
|
153
|
+
* @param {import("../vcsUiApp.js").default} app
|
154
|
+
*/
|
155
|
+
constructor(options, app) {
|
156
|
+
super(options, app);
|
157
|
+
|
158
|
+
/**
|
159
|
+
* @type {string}
|
160
|
+
* @private
|
161
|
+
*/
|
162
|
+
this._layerName = options.layerName;
|
163
|
+
|
164
|
+
/**
|
165
|
+
* @type {boolean}
|
166
|
+
* @private
|
167
|
+
*/
|
168
|
+
this._showWhenNotSupported = parseBoolean(
|
169
|
+
options.showWhenNotSupported,
|
170
|
+
false,
|
171
|
+
);
|
172
|
+
|
173
|
+
/**
|
174
|
+
* @type {boolean}
|
175
|
+
* @private
|
176
|
+
*/
|
177
|
+
this._setWMSLayersExclusive = parseBoolean(
|
178
|
+
options.setWMSLayersExclusive,
|
179
|
+
false,
|
180
|
+
);
|
181
|
+
// if WMSLayers should be handled exclusive, the item should handle like a NodeContentTreeItem.
|
182
|
+
this.clickable = !this._setWMSLayersExclusive;
|
183
|
+
|
184
|
+
/**
|
185
|
+
* @type {boolean}
|
186
|
+
* @private
|
187
|
+
*/
|
188
|
+
this._showStyleSelector = parseBoolean(options.showStyleSelector, true);
|
189
|
+
|
190
|
+
this.state = this._setWMSLayersExclusive
|
191
|
+
? StateActionState.NONE
|
192
|
+
: StateActionState.INACTIVE;
|
193
|
+
|
194
|
+
/**
|
195
|
+
* @type {boolean}
|
196
|
+
* @private
|
197
|
+
*/
|
198
|
+
this._invalid = false;
|
199
|
+
|
200
|
+
/**
|
201
|
+
* The only allowed layers.
|
202
|
+
* @type {Array<string>|undefined}
|
203
|
+
* @private
|
204
|
+
*/
|
205
|
+
this._allowedWMSLayers = options.allowedWMSLayers;
|
206
|
+
|
207
|
+
/**
|
208
|
+
* @type {Array<WMSEntry>}
|
209
|
+
* @private
|
210
|
+
*/
|
211
|
+
this._availableWMSEntries = [];
|
212
|
+
|
213
|
+
/**
|
214
|
+
* references the current ChildItems, this WMSGroupContentTreeItem manages
|
215
|
+
* @type {Array<WmsChildContentTreeItem>}
|
216
|
+
* @private
|
217
|
+
*/
|
218
|
+
this._childItems = [];
|
219
|
+
|
220
|
+
/**
|
221
|
+
* @type {Array<Function>}
|
222
|
+
* @private
|
223
|
+
*/
|
224
|
+
this._listeners = [];
|
225
|
+
|
226
|
+
/**
|
227
|
+
* this flag is set to true, if the legend is already set, so we do not need to manage the legend
|
228
|
+
* @type {boolean}
|
229
|
+
* @private
|
230
|
+
*/
|
231
|
+
this._legendSet = false;
|
232
|
+
|
233
|
+
/**
|
234
|
+
* pause the stateChangedListener, if the state is set from the Layer to the WMSGroupContentTreeItem
|
235
|
+
* @type {boolean}
|
236
|
+
* @private
|
237
|
+
*/
|
238
|
+
this._pauseStateChangedListener = false;
|
239
|
+
|
240
|
+
this._setup();
|
241
|
+
}
|
242
|
+
|
243
|
+
/**
|
244
|
+
* readonly access, do not manipulate the entries directly.
|
245
|
+
* @type {Array<WMSEntry>}
|
246
|
+
*/
|
247
|
+
get wmsEntries() {
|
248
|
+
return this._availableWMSEntries;
|
249
|
+
}
|
250
|
+
|
251
|
+
/**
|
252
|
+
* @type {boolean}
|
253
|
+
*/
|
254
|
+
get disabled() {
|
255
|
+
return super.disabled;
|
256
|
+
}
|
257
|
+
|
258
|
+
/**
|
259
|
+
* @param {boolean} disabled
|
260
|
+
*/
|
261
|
+
set disabled(disabled) {
|
262
|
+
super.disabled = disabled;
|
263
|
+
this._childItems.forEach((childItem) => {
|
264
|
+
childItem.disabled = this.disabled;
|
265
|
+
});
|
266
|
+
}
|
267
|
+
|
268
|
+
/**
|
269
|
+
* @type {boolean}
|
270
|
+
*/
|
271
|
+
get visible() {
|
272
|
+
return super.visible;
|
273
|
+
}
|
274
|
+
|
275
|
+
/**
|
276
|
+
* @param {boolean} visible
|
277
|
+
*/
|
278
|
+
set visible(visible) {
|
279
|
+
super.visible = visible;
|
280
|
+
this._childItems.forEach((childItem) => {
|
281
|
+
childItem.visible = this.visible;
|
282
|
+
});
|
283
|
+
}
|
284
|
+
|
285
|
+
/**
|
286
|
+
* @type {import("@vcmap/core").WMSLayer|undefined}
|
287
|
+
* @private
|
288
|
+
*/
|
289
|
+
get _layer() {
|
290
|
+
return this._app.layers.getByKey(this._layerName);
|
291
|
+
}
|
292
|
+
|
293
|
+
_setState() {
|
294
|
+
if (this._setWMSLayersExclusive) {
|
295
|
+
this.state = StateActionState.NONE;
|
296
|
+
} else {
|
297
|
+
const activeLayers = this._availableWMSEntries.filter(
|
298
|
+
(wmsEntry) => wmsEntry.active.value,
|
299
|
+
);
|
300
|
+
if (activeLayers.length === this._availableWMSEntries.length) {
|
301
|
+
this.state = StateActionState.ACTIVE;
|
302
|
+
} else if (activeLayers.length === 0) {
|
303
|
+
this.state = StateActionState.INACTIVE;
|
304
|
+
} else {
|
305
|
+
this.state = StateActionState.INDETERMINATE;
|
306
|
+
}
|
307
|
+
}
|
308
|
+
}
|
309
|
+
|
310
|
+
/**
|
311
|
+
* Sets the Legend on the Layer, based on the active WMSLayers and the active Styles.
|
312
|
+
* @private
|
313
|
+
*/
|
314
|
+
_setLegend() {
|
315
|
+
if (!this._legendSet) {
|
316
|
+
const legend = this._availableWMSEntries
|
317
|
+
.filter((wmsEntry) => wmsEntry.active.value)
|
318
|
+
.map((wmsEntry) => {
|
319
|
+
const activeStyle = wmsEntry.activeStyle.value;
|
320
|
+
if (activeStyle === '') {
|
321
|
+
return wmsEntry.styles?.[0]?.legend;
|
322
|
+
} else {
|
323
|
+
return wmsEntry?.styles?.find((style) => style.name === activeStyle)
|
324
|
+
?.legend;
|
325
|
+
}
|
326
|
+
})
|
327
|
+
.flat()
|
328
|
+
.filter((l) => l);
|
329
|
+
if (legend.length > 0) {
|
330
|
+
this._layer.properties.legend = legend;
|
331
|
+
} else {
|
332
|
+
this._layer.properties.legend = undefined;
|
333
|
+
}
|
334
|
+
}
|
335
|
+
this._pauseStateChangedListener = true;
|
336
|
+
this._layer.stateChanged.raiseEvent(this._layer.state); // triggers Legend update;
|
337
|
+
this._pauseStateChangedListener = false;
|
338
|
+
}
|
339
|
+
|
340
|
+
/**
|
341
|
+
* sets the State of to the underlying Layer
|
342
|
+
* @private
|
343
|
+
*/
|
344
|
+
async _setStateToLayer() {
|
345
|
+
this._setState();
|
346
|
+
const layersOnLayer = this._layer.getLayers();
|
347
|
+
const stylesOnLayer = this._layer.parameters.STYLES?.split(',') ?? [];
|
348
|
+
const activeLayers = this._availableWMSEntries.filter(
|
349
|
+
(wmsEntry) => wmsEntry.active.value,
|
350
|
+
);
|
351
|
+
const currentStyles = activeLayers.map(
|
352
|
+
(wmsEntry) => wmsEntry.activeStyle.value,
|
353
|
+
);
|
354
|
+
const currentLayers = activeLayers.map((wmsEntry) => wmsEntry.name);
|
355
|
+
this._pauseStateChangedListener = true;
|
356
|
+
try {
|
357
|
+
if (
|
358
|
+
!deepEqual(currentLayers, layersOnLayer) ||
|
359
|
+
!deepEqual(stylesOnLayer, currentStyles)
|
360
|
+
) {
|
361
|
+
this._layer.parameters.STYLES = currentStyles.join(',');
|
362
|
+
await this._layer.setLayers(currentLayers);
|
363
|
+
}
|
364
|
+
if (currentLayers.length > 0 && !this._layer.active) {
|
365
|
+
await this._layer.activate();
|
366
|
+
} else if (currentLayers.length === 0) {
|
367
|
+
this._layer.deactivate();
|
368
|
+
}
|
369
|
+
} catch (e) {
|
370
|
+
getLogger(this.className).error(
|
371
|
+
`An error occured while setting the state to the Layer: $(this._layerName)`,
|
372
|
+
e,
|
373
|
+
);
|
374
|
+
}
|
375
|
+
this._pauseStateChangedListener = false;
|
376
|
+
this._setLegend();
|
377
|
+
}
|
378
|
+
|
379
|
+
/**
|
380
|
+
* this reacts to clickEvents from the ChildItem, and sets internal State correspondingly,
|
381
|
+
* and also sets the State to the Layer and the children.
|
382
|
+
* @param {WmsChildContentTreeItem} item
|
383
|
+
*/
|
384
|
+
_handleChildClickedEvent(item) {
|
385
|
+
if (item.wmsEntry.active.value) {
|
386
|
+
item.wmsEntry.active.value = false;
|
387
|
+
} else {
|
388
|
+
if (this._setWMSLayersExclusive) {
|
389
|
+
this._availableWMSEntries.forEach((wmsEntry) => {
|
390
|
+
wmsEntry.active.value = false;
|
391
|
+
});
|
392
|
+
}
|
393
|
+
item.wmsEntry.active.value = true;
|
394
|
+
}
|
395
|
+
this._setStateToLayer();
|
396
|
+
}
|
397
|
+
|
398
|
+
/**
|
399
|
+
* @param {WmsChildContentTreeItem} item
|
400
|
+
* @param {string} style
|
401
|
+
* @private
|
402
|
+
*/
|
403
|
+
_handleStyleSelectedEvent(item, style) {
|
404
|
+
item.wmsEntry.activeStyle.value = style;
|
405
|
+
this._setStateToLayer();
|
406
|
+
}
|
407
|
+
|
408
|
+
/**
|
409
|
+
* @private
|
410
|
+
*/
|
411
|
+
_clear() {
|
412
|
+
this._childItems.forEach((childItem) => {
|
413
|
+
this._app.contentTree.remove(childItem);
|
414
|
+
childItem.destroy();
|
415
|
+
});
|
416
|
+
this._childItems = [];
|
417
|
+
this._listeners.forEach((cb) => {
|
418
|
+
cb();
|
419
|
+
});
|
420
|
+
this._listeners.splice(0);
|
421
|
+
this._availableWMSEntries = [];
|
422
|
+
this._legendSet = false;
|
423
|
+
}
|
424
|
+
|
425
|
+
/**
|
426
|
+
* syncs the State from the Layer to the WMSGroupContentTreeItem
|
427
|
+
* @private
|
428
|
+
*/
|
429
|
+
_setStateFromLayer() {
|
430
|
+
if (this._layer) {
|
431
|
+
if (this._layer.active) {
|
432
|
+
const activeWMSLayers = this._layer.getLayers();
|
433
|
+
if (this._setWMSLayersExclusive) {
|
434
|
+
this._availableWMSEntries.forEach((wmsEntry) => {
|
435
|
+
wmsEntry.active.value = false;
|
436
|
+
if (activeWMSLayers?.[0] === wmsEntry.name) {
|
437
|
+
wmsEntry.active.value = true;
|
438
|
+
}
|
439
|
+
});
|
440
|
+
} else {
|
441
|
+
this._availableWMSEntries.forEach((wmsEntry) => {
|
442
|
+
wmsEntry.active.value = activeWMSLayers.includes(wmsEntry.name);
|
443
|
+
});
|
444
|
+
}
|
445
|
+
} else {
|
446
|
+
this._availableWMSEntries.forEach((wmsEntry) => {
|
447
|
+
wmsEntry.active.value = false;
|
448
|
+
});
|
449
|
+
}
|
450
|
+
if (this._layer.parameters.STYLES) {
|
451
|
+
const activeWMSLayers = this._layer.getLayers();
|
452
|
+
const activeStyles = this._layer.parameters.STYLES.split(',');
|
453
|
+
if (activeWMSLayers.length === activeStyles.length) {
|
454
|
+
this._availableWMSEntries.forEach((wmsEntry) => {
|
455
|
+
if (activeWMSLayers.includes(wmsEntry.name)) {
|
456
|
+
const styleIndex = activeWMSLayers.indexOf(wmsEntry.name);
|
457
|
+
wmsEntry.activeStyle.value = activeStyles[styleIndex];
|
458
|
+
}
|
459
|
+
});
|
460
|
+
}
|
461
|
+
}
|
462
|
+
}
|
463
|
+
}
|
464
|
+
|
465
|
+
/**
|
466
|
+
* @returns {Promise<void>}
|
467
|
+
* @private
|
468
|
+
*/
|
469
|
+
async _setup() {
|
470
|
+
this._clear();
|
471
|
+
/**
|
472
|
+
* Called when a layer is added or removed to reset the item if needed
|
473
|
+
* @param {import("@vcmap/core").Layer} layer
|
474
|
+
*/
|
475
|
+
const resetHandler = (layer) => {
|
476
|
+
if (layer.name === this._layerName) {
|
477
|
+
this._setup();
|
478
|
+
}
|
479
|
+
};
|
480
|
+
if (!this._layer) {
|
481
|
+
this.visible = false;
|
482
|
+
this._listeners.push(
|
483
|
+
this._app.layers.added.addEventListener(resetHandler),
|
484
|
+
);
|
485
|
+
} else {
|
486
|
+
let isSupported = this._layer.isSupported(this._app.maps.activeMap);
|
487
|
+
this.visible = isSupported || this._showWhenNotSupported;
|
488
|
+
if (this._showWhenNotSupported) {
|
489
|
+
this.disabled = !isSupported;
|
490
|
+
}
|
491
|
+
this.state = StateActionState.LOADING;
|
492
|
+
this.setPropertiesFromObject(this._layer);
|
493
|
+
|
494
|
+
this._listeners.push(
|
495
|
+
this._app.layers.removed.addEventListener(resetHandler),
|
496
|
+
);
|
497
|
+
this._listeners.push(
|
498
|
+
this._app.layers.added.addEventListener(resetHandler),
|
499
|
+
);
|
500
|
+
this._listeners.push(
|
501
|
+
this._layer.stateChanged.addEventListener(() => {
|
502
|
+
if (!this._pauseStateChangedListener) {
|
503
|
+
this._setStateFromLayer();
|
504
|
+
this._setState();
|
505
|
+
this._setLegend();
|
506
|
+
}
|
507
|
+
}),
|
508
|
+
);
|
509
|
+
this._listeners.push(
|
510
|
+
this._app.maps.mapActivated.addEventListener(() => {
|
511
|
+
isSupported = this._layer.isSupported(this._app.maps.activeMap);
|
512
|
+
this.visible =
|
513
|
+
(isSupported || this._showWhenNotSupported) && !this._invalid;
|
514
|
+
if (this._showWhenNotSupported) {
|
515
|
+
this.disabled = !isSupported;
|
516
|
+
}
|
517
|
+
}),
|
518
|
+
);
|
519
|
+
try {
|
520
|
+
const availableWMSEntries = await getWMSEntries(
|
521
|
+
this._layer.url,
|
522
|
+
this._layer.parameters,
|
523
|
+
);
|
524
|
+
this._availableWMSEntries = availableWMSEntries.filter((wmsEntry) => {
|
525
|
+
return this._allowedWMSLayers
|
526
|
+
? this._allowedWMSLayers.includes(wmsEntry.name)
|
527
|
+
: true;
|
528
|
+
});
|
529
|
+
const childItems = this._availableWMSEntries.map((wmsEntry) => {
|
530
|
+
return createWMSChildContentTreeItem(
|
531
|
+
this._app,
|
532
|
+
wmsEntry,
|
533
|
+
this.name,
|
534
|
+
this._showStyleSelector,
|
535
|
+
);
|
536
|
+
});
|
537
|
+
childItems.forEach((childItem) => {
|
538
|
+
this._app.contentTree.add(childItem);
|
539
|
+
this._listeners.push(
|
540
|
+
childItem.clickedEvent.addEventListener(() => {
|
541
|
+
this._handleChildClickedEvent(childItem);
|
542
|
+
}),
|
543
|
+
childItem.styleSelected.addEventListener((style) => {
|
544
|
+
this._handleStyleSelectedEvent(childItem, style);
|
545
|
+
}),
|
546
|
+
);
|
547
|
+
});
|
548
|
+
this._childItems = childItems;
|
549
|
+
// check if we do have a legend already configured, if yes we set a flag, that we do not need to set the legend.
|
550
|
+
if (this._layer.properties.legend) {
|
551
|
+
this._legendSet = true;
|
552
|
+
}
|
553
|
+
// we need to get the Initial State from the Layer, to set the correct State to the children.
|
554
|
+
this._setStateFromLayer();
|
555
|
+
// the layer State maybe incomplete or does not fit to the wmsGroupContentTreeItem, so we need to set the State to the Layer.
|
556
|
+
this._setState();
|
557
|
+
this._setLegend();
|
558
|
+
} catch (e) {
|
559
|
+
this._layer.deactivate();
|
560
|
+
this.visible = false;
|
561
|
+
this._invalid = true;
|
562
|
+
getLogger(this.className).error(
|
563
|
+
`An error occured while fetching the ${this._layerName} capabilities:`,
|
564
|
+
e,
|
565
|
+
);
|
566
|
+
}
|
567
|
+
}
|
568
|
+
}
|
569
|
+
|
570
|
+
async clicked() {
|
571
|
+
await super.clicked();
|
572
|
+
if (this.state === StateActionState.NONE || this._setWMSLayersExclusive) {
|
573
|
+
return;
|
574
|
+
}
|
575
|
+
const activeLayers = this._availableWMSEntries.filter(
|
576
|
+
(wmsEntry) => wmsEntry.active.value,
|
577
|
+
);
|
578
|
+
const newState = activeLayers.length !== this._availableWMSEntries.length;
|
579
|
+
this._availableWMSEntries.forEach((wmsEntry) => {
|
580
|
+
wmsEntry.active.value = newState;
|
581
|
+
});
|
582
|
+
await this._setStateToLayer();
|
583
|
+
}
|
584
|
+
|
585
|
+
/**
|
586
|
+
* @returns {WMSGroupContentTreeItemOptions}
|
587
|
+
*/
|
588
|
+
toJSON() {
|
589
|
+
const config = super.toJSON();
|
590
|
+
config.layerName = this._layerName;
|
591
|
+
if (this._showWhenNotSupported) {
|
592
|
+
config.showWhenNotSupported = this._showWhenNotSupported;
|
593
|
+
}
|
594
|
+
if (this._setWMSLayersExclusive) {
|
595
|
+
config.setWMSLayersExclusive = this._setWMSLayersExclusive;
|
596
|
+
}
|
597
|
+
if (!this._showStyleSelector) {
|
598
|
+
config.showStyleSelector = this._showStyleSelector;
|
599
|
+
}
|
600
|
+
if (this._allowedWMSLayers?.length > 0) {
|
601
|
+
config.allowedWMSLayers = this._allowedWMSLayers;
|
602
|
+
}
|
603
|
+
return config;
|
604
|
+
}
|
605
|
+
|
606
|
+
destroy() {
|
607
|
+
super.destroy();
|
608
|
+
this._listeners.forEach((cb) => {
|
609
|
+
cb();
|
610
|
+
});
|
611
|
+
this._listeners.splice(0);
|
612
|
+
}
|
613
|
+
}
|
614
|
+
|
615
|
+
export default WMSGroupContentTreeItem;
|
616
|
+
contentTreeClassRegistry.registerClass(
|
617
|
+
WMSGroupContentTreeItem.className,
|
618
|
+
WMSGroupContentTreeItem,
|
619
|
+
);
|
@@ -177,13 +177,13 @@
|
|
177
177
|
</script>
|
178
178
|
|
179
179
|
<style lang="scss">
|
180
|
-
.balloon {
|
180
|
+
:not(.mobile) > .balloon {
|
181
181
|
z-index: 0 !important;
|
182
182
|
}
|
183
|
-
.balloon hr:first-child {
|
183
|
+
:not(.mobile) > .balloon hr:first-child {
|
184
184
|
display: none;
|
185
185
|
}
|
186
|
-
.balloon:after {
|
186
|
+
:not(.mobile) > .balloon:after {
|
187
187
|
content: '';
|
188
188
|
position: absolute;
|
189
189
|
bottom: -12px;
|
@@ -194,11 +194,11 @@
|
|
194
194
|
width: 0;
|
195
195
|
filter: drop-shadow(1px 2px 1px rgba(0, 0, 0, 0.3));
|
196
196
|
}
|
197
|
-
.balloon:after {
|
197
|
+
:not(.mobile) > .balloon:after {
|
198
198
|
border-color: rgb(var(--v-theme-surface-light)) transparent;
|
199
199
|
}
|
200
|
-
.balloon .v-list-item .v-list-item__title,
|
201
|
-
.balloon .v-list-item .v-list-item__subtitle {
|
200
|
+
:not(.mobile) > .balloon .v-list-item .v-list-item__title,
|
201
|
+
:not(.mobile) > .balloon .v-list-item .v-list-item__subtitle {
|
202
202
|
line-height: 18px;
|
203
203
|
}
|
204
204
|
</style>
|