@vcmap/ui 6.2.2 → 6.2.4
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/dev.config.json +366 -2
- package/dist/assets/cesium.js +1 -1
- package/dist/assets/{core-4cd2e30d.js → core-b61fb7c0.js} +10577 -8847
- package/dist/assets/core-workers/panoramaImageWorker.js +1 -1
- package/dist/assets/core.js +1 -1
- package/dist/assets/ol.js +1 -1
- package/dist/assets/{ui-b13e28a1.css → ui-f33a5ee2.css} +1 -1
- package/dist/assets/{ui-b13e28a1.js → ui-f33a5ee2.js} +6864 -6737
- package/dist/assets/ui.js +1 -1
- package/dist/assets/vue.js +1 -1
- package/dist/assets/{vuetify-a1930526.js → vuetify-2fc014c4.js} +1 -1
- package/dist/assets/vuetify.js +1 -1
- package/index.d.ts +5 -1
- package/index.js +2 -1
- package/package.json +1 -1
- package/plugins/@vcmap-show-case/extent-example/src/ExtentExample.vue +28 -0
- package/plugins/@vcmap-show-case/extent-example/src/index.js +3 -14
- package/src/actions/actionHelper.d.ts +0 -1
- package/src/actions/actionHelper.js +3 -3
- package/src/application/VcsSettings.vue +4 -0
- package/src/components/extent/VcsExtent.vue +12 -1
- package/src/components/extent/VcsExtent.vue.d.ts +1 -0
- package/src/components/flight/VcsFlightAnchorsComponent.vue +2 -2
- package/src/components/lists/VcsList.vue +10 -18
- package/src/components/lists/VcsTreeNode.vue +8 -3
- package/src/components/lists/VcsTreeNode.vue.d.ts +4 -0
- package/src/components/lists/VcsTreeview.vue +2 -6
- package/src/components/lists/VcsTreeview.vue.d.ts +0 -1
- package/src/components/lists/dragHelper.d.ts +9 -2
- package/src/components/lists/dragHelper.js +47 -21
- package/src/contentTree/LayerSwap.vue +15 -4
- package/src/contentTree/LayerSwap.vue.d.ts +4 -4
- package/src/contentTree/contentTreeItem.js +1 -1
- package/src/contentTree/wmsGroupContentTreeItem.d.ts +74 -9
- package/src/contentTree/wmsGroupContentTreeItem.js +250 -88
- package/src/i18n/de.d.ts +1 -0
- package/src/i18n/de.js +1 -0
- package/src/i18n/en.d.ts +1 -0
- package/src/i18n/en.js +1 -0
- package/src/manager/collectionManager/CollectionComponentContent.vue +4 -4
- package/src/manager/collectionManager/CollectionComponentList.vue +2 -24
- package/src/manager/collectionManager/CollectionComponentList.vue.d.ts +0 -8
- package/src/manager/collectionManager/CollectionManager.vue +14 -1
- package/src/search/SearchComponent.vue +9 -11
- package/src/search/SearchComponent.vue.d.ts +2 -1
- package/src/state.d.ts +14 -0
- package/src/state.js +41 -0
- package/src/vcsUiApp.d.ts +9 -36
- package/src/vcsUiApp.js +45 -11
- /package/dist/assets/{cesium-b021f072.js → cesium-bc979301.js} +0 -0
- /package/dist/assets/core-workers/{panoramaImageWorker.js-90c60e81.js → panoramaImageWorker.js-2cf50d2d.js} +0 -0
- /package/dist/assets/{ol-c927b883.js → ol-28f9c83c.js} +0 -0
- /package/dist/assets/{vue-6a295c0b.js → vue-004523e0.js} +0 -0
- /package/dist/assets/{vuetify-a1930526.css → vuetify-2fc014c4.css} +0 -0
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export default WMSGroupContentTreeItem;
|
|
2
2
|
export type WMSGroupContentTreeItemOptions = import('./contentTreeItem.js').ContentTreeItemOptions & {
|
|
3
3
|
layerName: string;
|
|
4
|
+
loadOnStartup?: boolean;
|
|
4
5
|
showWhenNotSupported?: boolean;
|
|
5
6
|
setWMSLayersExclusive?: boolean;
|
|
6
7
|
hideStyleSelector?: boolean;
|
|
@@ -15,18 +16,41 @@ export type WMSEntry = {
|
|
|
15
16
|
name: string;
|
|
16
17
|
active: import("vue").Ref<boolean>;
|
|
17
18
|
activeStyle: import("vue").Ref<string>;
|
|
18
|
-
title
|
|
19
|
-
extent
|
|
20
|
-
styles
|
|
19
|
+
title?: string | undefined;
|
|
20
|
+
extent?: import("@vcmap/core").Extent | undefined;
|
|
21
|
+
styles?: WMSStyleEntry[] | undefined;
|
|
22
|
+
};
|
|
23
|
+
export type SerializedWMSLegend = {
|
|
24
|
+
url: string;
|
|
25
|
+
width: number;
|
|
26
|
+
height: number;
|
|
27
|
+
};
|
|
28
|
+
export type SerializedWMSStyle = {
|
|
29
|
+
name: string;
|
|
30
|
+
title?: string | undefined;
|
|
31
|
+
legend?: SerializedWMSLegend[] | undefined;
|
|
32
|
+
};
|
|
33
|
+
export type SerializedWMSLayer = {
|
|
34
|
+
name: string;
|
|
35
|
+
title?: string | undefined;
|
|
36
|
+
/**
|
|
37
|
+
* Layer extent, in WGS84 coordinates
|
|
38
|
+
*/
|
|
39
|
+
extent?: number[] | undefined;
|
|
40
|
+
styles?: SerializedWMSStyle[] | undefined;
|
|
41
|
+
};
|
|
42
|
+
export type SerializedWMSCapabilities = {
|
|
43
|
+
layers: Array<SerializedWMSLayer>;
|
|
21
44
|
};
|
|
22
45
|
/**
|
|
23
46
|
* @typedef {import('./contentTreeItem.js').ContentTreeItemOptions &
|
|
24
|
-
* { layerName: string, showWhenNotSupported?: boolean, setWMSLayersExclusive?:boolean, hideStyleSelector?:boolean, allowedWMSLayers?:string[]}} WMSGroupContentTreeItemOptions
|
|
25
|
-
* @property {boolean} showWhenNotSupported - optional flag to show the item even if it is not supported by the activeMap.
|
|
47
|
+
* { layerName: string, loadOnStartup?: boolean, showWhenNotSupported?: boolean, setWMSLayersExclusive?:boolean, hideStyleSelector?:boolean, allowedWMSLayers?:string[]}} WMSGroupContentTreeItemOptions
|
|
26
48
|
* @property {string} layerName - The name of the WMSLayer to show the children of.
|
|
49
|
+
* @property {boolean} [loadOnStartup=false] - optional flag to load the capabilities on startup, will be loaded on click otherwise. Leads to an inherent "initOpen" flag if not true.
|
|
50
|
+
* @property {boolean} [showWhenNotSupported=false] - optional flag to show the item even if it is not supported by the activeMap.
|
|
27
51
|
* @property {boolean} [setWMSLayersExclusive=false] - Whether the WMSlayers are mutually exclusive.
|
|
28
52
|
* @property {boolean} [hideStyleSelector=false] - Whether the layer style can be selected. Will add a StyleSelector action to compatible items if the Layer has more than one style.
|
|
29
|
-
* @property {string[]} allowedWMSLayers - The list of layers to be shown, other available layers will not be shown.
|
|
53
|
+
* @property {string[]} [allowedWMSLayers] - The list of layers to be shown, other available layers will not be shown.
|
|
30
54
|
*/
|
|
31
55
|
/**
|
|
32
56
|
* @typedef {Object} WMSStyleEntry
|
|
@@ -39,9 +63,33 @@ export type WMSEntry = {
|
|
|
39
63
|
* @property {string} name
|
|
40
64
|
* @property {import("vue").Ref<boolean>} active
|
|
41
65
|
* @property {import("vue").Ref<string>} activeStyle
|
|
42
|
-
* @property {string} title
|
|
43
|
-
* @property {import("@vcmap/core").Extent} extent
|
|
44
|
-
* @property {Array<WMSStyleEntry>} styles
|
|
66
|
+
* @property {string} [title]
|
|
67
|
+
* @property {import("@vcmap/core").Extent} [extent]
|
|
68
|
+
* @property {Array<WMSStyleEntry>} [styles]
|
|
69
|
+
*/
|
|
70
|
+
/**
|
|
71
|
+
* @typedef {Object} SerializedWMSLegend
|
|
72
|
+
* @property {string} url
|
|
73
|
+
* @property {number} width
|
|
74
|
+
* @property {number} height
|
|
75
|
+
*/
|
|
76
|
+
/**
|
|
77
|
+
* @typedef {Object} SerializedWMSStyle
|
|
78
|
+
* @property {string} name
|
|
79
|
+
* @property {string} [title]
|
|
80
|
+
* @property {SerializedWMSLegend[]} [legend]
|
|
81
|
+
*/
|
|
82
|
+
/**
|
|
83
|
+
* @typedef {Object} SerializedWMSLayer
|
|
84
|
+
* @property {string} name
|
|
85
|
+
* @property {string} [title]
|
|
86
|
+
* @property {number[]} [extent] Layer extent, in WGS84 coordinates
|
|
87
|
+
* @property {SerializedWMSStyle[]} [styles]
|
|
88
|
+
*/
|
|
89
|
+
/**
|
|
90
|
+
* @description The serialized form of WMS Capabilities are used in the configuration to avoid fetching the capabilities on every startup.
|
|
91
|
+
* @typedef {Object} SerializedWMSCapabilities
|
|
92
|
+
* @property {Array<SerializedWMSLayer>} layers
|
|
45
93
|
*/
|
|
46
94
|
/**
|
|
47
95
|
* A WMSGroupItem, will take over a WMSLayer and request the Capabilities of the layer to show all available
|
|
@@ -61,6 +109,11 @@ declare class WMSGroupContentTreeItem extends VcsObjectContentTreeItem<import(".
|
|
|
61
109
|
* @private
|
|
62
110
|
*/
|
|
63
111
|
private _layerName;
|
|
112
|
+
/**
|
|
113
|
+
* @type {boolean}
|
|
114
|
+
* @private
|
|
115
|
+
*/
|
|
116
|
+
private _loadOnStartup;
|
|
64
117
|
/**
|
|
65
118
|
* @type {boolean}
|
|
66
119
|
* @private
|
|
@@ -115,6 +168,12 @@ declare class WMSGroupContentTreeItem extends VcsObjectContentTreeItem<import(".
|
|
|
115
168
|
* @private
|
|
116
169
|
*/
|
|
117
170
|
private _pauseStateChangedListener;
|
|
171
|
+
/**
|
|
172
|
+
* Flag to track if children have been loaded
|
|
173
|
+
* @type {boolean}
|
|
174
|
+
* @private
|
|
175
|
+
*/
|
|
176
|
+
private _childrenLoaded;
|
|
118
177
|
/**
|
|
119
178
|
* readonly access, do not manipulate the entries directly.
|
|
120
179
|
* @type {Array<WMSEntry>}
|
|
@@ -157,6 +216,12 @@ declare class WMSGroupContentTreeItem extends VcsObjectContentTreeItem<import(".
|
|
|
157
216
|
* @private
|
|
158
217
|
*/
|
|
159
218
|
private _setStateFromLayer;
|
|
219
|
+
/**
|
|
220
|
+
* Loads WMS entries and creates child items
|
|
221
|
+
* @returns {Promise<void>}
|
|
222
|
+
* @private
|
|
223
|
+
*/
|
|
224
|
+
private _loadWMSChildren;
|
|
160
225
|
/**
|
|
161
226
|
* @returns {Promise<void>}
|
|
162
227
|
* @private
|
|
@@ -2,6 +2,7 @@ import { markVolatile } from '@vcmap/core';
|
|
|
2
2
|
import { getLogger } from '@vcsuite/logger';
|
|
3
3
|
import { ref } from 'vue';
|
|
4
4
|
import { parseBoolean } from '@vcsuite/parsers';
|
|
5
|
+
import { is } from '@vcsuite/check';
|
|
5
6
|
import deepEqual from 'fast-deep-equal';
|
|
6
7
|
import WMSCapabilities from 'ol/format/WMSCapabilities';
|
|
7
8
|
import { StateActionState } from '../actions/stateRefAction.js';
|
|
@@ -10,6 +11,90 @@ import WmsChildContentTreeItem from './wmsChildContentTreeItem.js';
|
|
|
10
11
|
import VcsObjectContentTreeItem from './vcsObjectContentTreeItem.js';
|
|
11
12
|
import { legendSymbol } from '../legend/legendHelper.js';
|
|
12
13
|
|
|
14
|
+
/**
|
|
15
|
+
*
|
|
16
|
+
* @param {string} src The OnlineRessource property of the legend
|
|
17
|
+
* @param {number} width The width of the image
|
|
18
|
+
* @param {string} title The title of the layer.
|
|
19
|
+
* @returns {import('../legend/legendHelper.js').StyleLegendItem}
|
|
20
|
+
*/
|
|
21
|
+
function parseLegend(src, width, title) {
|
|
22
|
+
if (width < 25) {
|
|
23
|
+
return {
|
|
24
|
+
type: 'StyleLegendItem',
|
|
25
|
+
colNr: 1,
|
|
26
|
+
rows: [{ type: 'IconLegendRow', title, image: { src } }],
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
return { type: 'ImageLegendItem', popoutBtn: true, src };
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
*
|
|
34
|
+
* @param {SerializedWMSCapabilities} capabilities
|
|
35
|
+
* @returns {WMSEntry[]}
|
|
36
|
+
*/
|
|
37
|
+
function parseSerializedCapabilities(capabilities) {
|
|
38
|
+
if (capabilities?.layers?.length > 0) {
|
|
39
|
+
return capabilities.layers
|
|
40
|
+
.filter((layer) => {
|
|
41
|
+
if (!is(layer, { name: String })) {
|
|
42
|
+
getLogger(this.className).warn(
|
|
43
|
+
`Ignoring WMS Layer without name in layer ${this._layerName}`,
|
|
44
|
+
);
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
return true;
|
|
48
|
+
})
|
|
49
|
+
.map((layer) => {
|
|
50
|
+
const styles = layer.styles
|
|
51
|
+
?.filter((s) => {
|
|
52
|
+
if (!is(s, { name: String })) {
|
|
53
|
+
getLogger(this.className).warn(
|
|
54
|
+
`Ignoring WMS Style without name in layer ${this._layerName}`,
|
|
55
|
+
);
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
return true;
|
|
59
|
+
})
|
|
60
|
+
.map((s) => ({
|
|
61
|
+
name: s.name,
|
|
62
|
+
title: s.title,
|
|
63
|
+
legend:
|
|
64
|
+
s.legend
|
|
65
|
+
?.filter((l) => {
|
|
66
|
+
if (!is(l, { url: String, width: Number, height: Number })) {
|
|
67
|
+
getLogger(this.className).warn(
|
|
68
|
+
`Ignoring invalid WMS Legend in style ${s.name} in layer ${this._layerName}`,
|
|
69
|
+
);
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
return true;
|
|
73
|
+
})
|
|
74
|
+
.map((l) => parseLegend(l.url, l.width, s.title || '')) || [],
|
|
75
|
+
}));
|
|
76
|
+
|
|
77
|
+
const wmsEntry = {
|
|
78
|
+
name: layer.name,
|
|
79
|
+
active: ref(false),
|
|
80
|
+
activeStyle: ref(''),
|
|
81
|
+
};
|
|
82
|
+
if (layer.title) {
|
|
83
|
+
wmsEntry.title = layer.title;
|
|
84
|
+
}
|
|
85
|
+
if (layer.extent) {
|
|
86
|
+
wmsEntry.extent = layer.extent;
|
|
87
|
+
}
|
|
88
|
+
if (styles?.length > 0) {
|
|
89
|
+
wmsEntry.styles = styles;
|
|
90
|
+
}
|
|
91
|
+
return wmsEntry;
|
|
92
|
+
});
|
|
93
|
+
} else {
|
|
94
|
+
return [];
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
13
98
|
/**
|
|
14
99
|
* @param {string} rawUrl
|
|
15
100
|
* @param {Record<string, string>} parameters
|
|
@@ -49,27 +134,9 @@ async function getWMSEntries(rawUrl, parameters) {
|
|
|
49
134
|
title: style.Title,
|
|
50
135
|
legend: style.LegendURL?.filter(
|
|
51
136
|
(legend) => legend.OnlineResource,
|
|
52
|
-
).map((legend) =>
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
return {
|
|
56
|
-
type: 'StyleLegendItem',
|
|
57
|
-
colNr: 1,
|
|
58
|
-
rows: [
|
|
59
|
-
{
|
|
60
|
-
type: 'IconLegendRow',
|
|
61
|
-
title: layer.Title,
|
|
62
|
-
image: { src },
|
|
63
|
-
},
|
|
64
|
-
],
|
|
65
|
-
};
|
|
66
|
-
}
|
|
67
|
-
return {
|
|
68
|
-
type: 'ImageLegendItem',
|
|
69
|
-
src,
|
|
70
|
-
popoutBtn: true,
|
|
71
|
-
};
|
|
72
|
-
}),
|
|
137
|
+
).map((legend) =>
|
|
138
|
+
parseLegend(legend.OnlineResource, legend.size[0], layer.Title),
|
|
139
|
+
),
|
|
73
140
|
};
|
|
74
141
|
}) ?? [];
|
|
75
142
|
return {
|
|
@@ -112,12 +179,13 @@ function createWMSChildContentTreeItem(
|
|
|
112
179
|
|
|
113
180
|
/**
|
|
114
181
|
* @typedef {import('./contentTreeItem.js').ContentTreeItemOptions &
|
|
115
|
-
* { layerName: string, showWhenNotSupported?: boolean, setWMSLayersExclusive?:boolean, hideStyleSelector?:boolean, allowedWMSLayers?:string[]}} WMSGroupContentTreeItemOptions
|
|
116
|
-
* @property {boolean} showWhenNotSupported - optional flag to show the item even if it is not supported by the activeMap.
|
|
182
|
+
* { layerName: string, loadOnStartup?: boolean, showWhenNotSupported?: boolean, setWMSLayersExclusive?:boolean, hideStyleSelector?:boolean, allowedWMSLayers?:string[]}} WMSGroupContentTreeItemOptions
|
|
117
183
|
* @property {string} layerName - The name of the WMSLayer to show the children of.
|
|
184
|
+
* @property {boolean} [loadOnStartup=false] - optional flag to load the capabilities on startup, will be loaded on click otherwise. Leads to an inherent "initOpen" flag if not true.
|
|
185
|
+
* @property {boolean} [showWhenNotSupported=false] - optional flag to show the item even if it is not supported by the activeMap.
|
|
118
186
|
* @property {boolean} [setWMSLayersExclusive=false] - Whether the WMSlayers are mutually exclusive.
|
|
119
187
|
* @property {boolean} [hideStyleSelector=false] - Whether the layer style can be selected. Will add a StyleSelector action to compatible items if the Layer has more than one style.
|
|
120
|
-
* @property {string[]} allowedWMSLayers - The list of layers to be shown, other available layers will not be shown.
|
|
188
|
+
* @property {string[]} [allowedWMSLayers] - The list of layers to be shown, other available layers will not be shown.
|
|
121
189
|
*/
|
|
122
190
|
|
|
123
191
|
/**
|
|
@@ -132,9 +200,34 @@ function createWMSChildContentTreeItem(
|
|
|
132
200
|
* @property {string} name
|
|
133
201
|
* @property {import("vue").Ref<boolean>} active
|
|
134
202
|
* @property {import("vue").Ref<string>} activeStyle
|
|
135
|
-
* @property {string} title
|
|
136
|
-
* @property {import("@vcmap/core").Extent} extent
|
|
137
|
-
* @property {Array<WMSStyleEntry>} styles
|
|
203
|
+
* @property {string} [title]
|
|
204
|
+
* @property {import("@vcmap/core").Extent} [extent]
|
|
205
|
+
* @property {Array<WMSStyleEntry>} [styles]
|
|
206
|
+
*/
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* @typedef {Object} SerializedWMSLegend
|
|
210
|
+
* @property {string} url
|
|
211
|
+
* @property {number} width
|
|
212
|
+
* @property {number} height
|
|
213
|
+
*/
|
|
214
|
+
/**
|
|
215
|
+
* @typedef {Object} SerializedWMSStyle
|
|
216
|
+
* @property {string} name
|
|
217
|
+
* @property {string} [title]
|
|
218
|
+
* @property {SerializedWMSLegend[]} [legend]
|
|
219
|
+
*/
|
|
220
|
+
/**
|
|
221
|
+
* @typedef {Object} SerializedWMSLayer
|
|
222
|
+
* @property {string} name
|
|
223
|
+
* @property {string} [title]
|
|
224
|
+
* @property {number[]} [extent] Layer extent, in WGS84 coordinates
|
|
225
|
+
* @property {SerializedWMSStyle[]} [styles]
|
|
226
|
+
*/
|
|
227
|
+
/**
|
|
228
|
+
* @description The serialized form of WMS Capabilities are used in the configuration to avoid fetching the capabilities on every startup.
|
|
229
|
+
* @typedef {Object} SerializedWMSCapabilities
|
|
230
|
+
* @property {Array<SerializedWMSLayer>} layers
|
|
138
231
|
*/
|
|
139
232
|
|
|
140
233
|
/**
|
|
@@ -154,7 +247,7 @@ class WMSGroupContentTreeItem extends VcsObjectContentTreeItem {
|
|
|
154
247
|
* @param {import("../vcsUiApp.js").default} app
|
|
155
248
|
*/
|
|
156
249
|
constructor(options, app) {
|
|
157
|
-
super(options, app);
|
|
250
|
+
super({ initOpen: !options.loadOnStartup, ...options }, app);
|
|
158
251
|
|
|
159
252
|
/**
|
|
160
253
|
* @type {string}
|
|
@@ -162,6 +255,12 @@ class WMSGroupContentTreeItem extends VcsObjectContentTreeItem {
|
|
|
162
255
|
*/
|
|
163
256
|
this._layerName = options.layerName;
|
|
164
257
|
|
|
258
|
+
/**
|
|
259
|
+
* @type {boolean}
|
|
260
|
+
* @private
|
|
261
|
+
*/
|
|
262
|
+
this._loadOnStartup = parseBoolean(options.loadOnStartup, false);
|
|
263
|
+
|
|
165
264
|
/**
|
|
166
265
|
* @type {boolean}
|
|
167
266
|
* @private
|
|
@@ -180,7 +279,7 @@ class WMSGroupContentTreeItem extends VcsObjectContentTreeItem {
|
|
|
180
279
|
false,
|
|
181
280
|
);
|
|
182
281
|
// if WMSLayers should be handled exclusive, the item should handle like a NodeContentTreeItem.
|
|
183
|
-
this.clickable = !this._setWMSLayersExclusive;
|
|
282
|
+
this.clickable = !this._setWMSLayersExclusive || !this._loadOnStartup;
|
|
184
283
|
|
|
185
284
|
/**
|
|
186
285
|
* @type {boolean}
|
|
@@ -188,9 +287,10 @@ class WMSGroupContentTreeItem extends VcsObjectContentTreeItem {
|
|
|
188
287
|
*/
|
|
189
288
|
this._hideStyleSelector = parseBoolean(options.hideStyleSelector, false);
|
|
190
289
|
|
|
191
|
-
this.state =
|
|
192
|
-
|
|
193
|
-
|
|
290
|
+
this.state =
|
|
291
|
+
this._setWMSLayersExclusive || !this._loadOnStartup
|
|
292
|
+
? StateActionState.NONE
|
|
293
|
+
: StateActionState.INACTIVE;
|
|
194
294
|
|
|
195
295
|
/**
|
|
196
296
|
* @type {boolean}
|
|
@@ -238,6 +338,13 @@ class WMSGroupContentTreeItem extends VcsObjectContentTreeItem {
|
|
|
238
338
|
*/
|
|
239
339
|
this._pauseStateChangedListener = false;
|
|
240
340
|
|
|
341
|
+
/**
|
|
342
|
+
* Flag to track if children have been loaded
|
|
343
|
+
* @type {boolean}
|
|
344
|
+
* @private
|
|
345
|
+
*/
|
|
346
|
+
this._childrenLoaded = false;
|
|
347
|
+
|
|
241
348
|
this._setup();
|
|
242
349
|
}
|
|
243
350
|
|
|
@@ -421,6 +528,10 @@ class WMSGroupContentTreeItem extends VcsObjectContentTreeItem {
|
|
|
421
528
|
this._listeners.splice(0);
|
|
422
529
|
this._availableWMSEntries = [];
|
|
423
530
|
this._legendSet = false;
|
|
531
|
+
this._childrenLoaded = false;
|
|
532
|
+
|
|
533
|
+
// Reset clickable state based on initial configuration
|
|
534
|
+
this.clickable = !this._setWMSLayersExclusive || !this._loadOnStartup;
|
|
424
535
|
}
|
|
425
536
|
|
|
426
537
|
/**
|
|
@@ -463,6 +574,90 @@ class WMSGroupContentTreeItem extends VcsObjectContentTreeItem {
|
|
|
463
574
|
}
|
|
464
575
|
}
|
|
465
576
|
|
|
577
|
+
/**
|
|
578
|
+
* Loads WMS entries and creates child items
|
|
579
|
+
* @returns {Promise<void>}
|
|
580
|
+
* @private
|
|
581
|
+
*/
|
|
582
|
+
async _loadWMSChildren() {
|
|
583
|
+
if (this._childrenLoaded || !this._layer) {
|
|
584
|
+
return;
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
this.state = StateActionState.LOADING;
|
|
588
|
+
this.clickable = !this._setWMSLayersExclusive;
|
|
589
|
+
|
|
590
|
+
try {
|
|
591
|
+
let availableWMSEntries = [];
|
|
592
|
+
if (this._layer.properties.capabilities) {
|
|
593
|
+
availableWMSEntries = parseSerializedCapabilities(
|
|
594
|
+
this._layer.properties.capabilities,
|
|
595
|
+
);
|
|
596
|
+
} else {
|
|
597
|
+
availableWMSEntries = await getWMSEntries(
|
|
598
|
+
this._layer.url,
|
|
599
|
+
this._layer.parameters,
|
|
600
|
+
);
|
|
601
|
+
}
|
|
602
|
+
// check if the layer still exists, it can happen that the layer was removed while fetching the capabilities.
|
|
603
|
+
if (!this._layer) {
|
|
604
|
+
return;
|
|
605
|
+
}
|
|
606
|
+
this._availableWMSEntries = availableWMSEntries.filter((wmsEntry) => {
|
|
607
|
+
return this._allowedWMSLayers
|
|
608
|
+
? this._allowedWMSLayers.includes(wmsEntry.name)
|
|
609
|
+
: true;
|
|
610
|
+
});
|
|
611
|
+
const childItems = this._availableWMSEntries.map((wmsEntry) =>
|
|
612
|
+
createWMSChildContentTreeItem(
|
|
613
|
+
this._app,
|
|
614
|
+
wmsEntry,
|
|
615
|
+
this.name,
|
|
616
|
+
this._hideStyleSelector,
|
|
617
|
+
),
|
|
618
|
+
);
|
|
619
|
+
childItems.forEach((childItem) => {
|
|
620
|
+
this._app.contentTree.add(childItem);
|
|
621
|
+
childItem.disabled = this.disabled;
|
|
622
|
+
this._listeners.push(
|
|
623
|
+
childItem.clickedEvent.addEventListener(() => {
|
|
624
|
+
this._handleChildClickedEvent(childItem);
|
|
625
|
+
}),
|
|
626
|
+
childItem.styleSelected.addEventListener((style) => {
|
|
627
|
+
this._handleStyleSelectedEvent(childItem, style);
|
|
628
|
+
}),
|
|
629
|
+
);
|
|
630
|
+
});
|
|
631
|
+
this._childItems = childItems;
|
|
632
|
+
// check if we do have a legend already configured, if yes we set a flag, that we do not need to set the legend.
|
|
633
|
+
if (this._layer.properties.legend) {
|
|
634
|
+
this._legendSet = true;
|
|
635
|
+
}
|
|
636
|
+
// we need to get the Initial State from the Layer, to set the correct State to the children.
|
|
637
|
+
this._setStateFromLayer();
|
|
638
|
+
// the layer State maybe incomplete or does not fit to the wmsGroupContentTreeItem, so we need to set the State to the Layer.
|
|
639
|
+
this._setState();
|
|
640
|
+
this._setLegend();
|
|
641
|
+
this._childrenLoaded = true;
|
|
642
|
+
|
|
643
|
+
// Update clickable state after children are loaded
|
|
644
|
+
if (!this._setWMSLayersExclusive) {
|
|
645
|
+
this.clickable = true;
|
|
646
|
+
}
|
|
647
|
+
} catch (e) {
|
|
648
|
+
// if the layer is not there it has been removed while fetching the capabilities.
|
|
649
|
+
if (this._layer) {
|
|
650
|
+
this._layer.deactivate();
|
|
651
|
+
this.visible = false;
|
|
652
|
+
this._invalid = true;
|
|
653
|
+
}
|
|
654
|
+
getLogger(this.className).error(
|
|
655
|
+
`An error occured while fetching the ${this._layerName} capabilities:`,
|
|
656
|
+
e,
|
|
657
|
+
);
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
|
|
466
661
|
/**
|
|
467
662
|
* @returns {Promise<void>}
|
|
468
663
|
* @private
|
|
@@ -489,7 +684,6 @@ class WMSGroupContentTreeItem extends VcsObjectContentTreeItem {
|
|
|
489
684
|
if (this._showWhenNotSupported) {
|
|
490
685
|
this.disabled = !isSupported;
|
|
491
686
|
}
|
|
492
|
-
this.state = StateActionState.LOADING;
|
|
493
687
|
this.setPropertiesFromObject(this._layer);
|
|
494
688
|
|
|
495
689
|
this._listeners.push(
|
|
@@ -517,67 +711,19 @@ class WMSGroupContentTreeItem extends VcsObjectContentTreeItem {
|
|
|
517
711
|
}
|
|
518
712
|
}),
|
|
519
713
|
);
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
this._layer.parameters,
|
|
524
|
-
);
|
|
525
|
-
// check if the layer still exists, it can happen that the layer was removed while fetching the capabilities.
|
|
526
|
-
if (!this._layer) {
|
|
527
|
-
return;
|
|
528
|
-
}
|
|
529
|
-
this._availableWMSEntries = availableWMSEntries.filter((wmsEntry) => {
|
|
530
|
-
return this._allowedWMSLayers
|
|
531
|
-
? this._allowedWMSLayers.includes(wmsEntry.name)
|
|
532
|
-
: true;
|
|
533
|
-
});
|
|
534
|
-
const childItems = this._availableWMSEntries.map((wmsEntry) => {
|
|
535
|
-
return createWMSChildContentTreeItem(
|
|
536
|
-
this._app,
|
|
537
|
-
wmsEntry,
|
|
538
|
-
this.name,
|
|
539
|
-
this._hideStyleSelector,
|
|
540
|
-
);
|
|
541
|
-
});
|
|
542
|
-
childItems.forEach((childItem) => {
|
|
543
|
-
this._app.contentTree.add(childItem);
|
|
544
|
-
childItem.disabled = this.disabled;
|
|
545
|
-
this._listeners.push(
|
|
546
|
-
childItem.clickedEvent.addEventListener(() => {
|
|
547
|
-
this._handleChildClickedEvent(childItem);
|
|
548
|
-
}),
|
|
549
|
-
childItem.styleSelected.addEventListener((style) => {
|
|
550
|
-
this._handleStyleSelectedEvent(childItem, style);
|
|
551
|
-
}),
|
|
552
|
-
);
|
|
553
|
-
});
|
|
554
|
-
this._childItems = childItems;
|
|
555
|
-
// check if we do have a legend already configured, if yes we set a flag, that we do not need to set the legend.
|
|
556
|
-
if (this._layer.properties.legend) {
|
|
557
|
-
this._legendSet = true;
|
|
558
|
-
}
|
|
559
|
-
// we need to get the Initial State from the Layer, to set the correct State to the children.
|
|
560
|
-
this._setStateFromLayer();
|
|
561
|
-
// the layer State maybe incomplete or does not fit to the wmsGroupContentTreeItem, so we need to set the State to the Layer.
|
|
562
|
-
this._setState();
|
|
563
|
-
this._setLegend();
|
|
564
|
-
} catch (e) {
|
|
565
|
-
// if the layer is not there it has been removed while fetching the capabilities.
|
|
566
|
-
if (this._layer) {
|
|
567
|
-
this._layer.deactivate();
|
|
568
|
-
this.visible = false;
|
|
569
|
-
this._invalid = true;
|
|
570
|
-
}
|
|
571
|
-
getLogger(this.className).error(
|
|
572
|
-
`An error occured while fetching the ${this._layerName} capabilities:`,
|
|
573
|
-
e,
|
|
574
|
-
);
|
|
714
|
+
|
|
715
|
+
if (this._loadOnStartup) {
|
|
716
|
+
await this._loadWMSChildren();
|
|
575
717
|
}
|
|
576
718
|
}
|
|
577
719
|
}
|
|
578
720
|
|
|
579
721
|
async clicked() {
|
|
580
722
|
await super.clicked();
|
|
723
|
+
if (!this._childrenLoaded) {
|
|
724
|
+
await this._loadWMSChildren();
|
|
725
|
+
return;
|
|
726
|
+
}
|
|
581
727
|
if (this.state === StateActionState.NONE || this._setWMSLayersExclusive) {
|
|
582
728
|
return;
|
|
583
729
|
}
|
|
@@ -591,12 +737,28 @@ class WMSGroupContentTreeItem extends VcsObjectContentTreeItem {
|
|
|
591
737
|
await this._setStateToLayer();
|
|
592
738
|
}
|
|
593
739
|
|
|
740
|
+
/**
|
|
741
|
+
* Returns a readonly TreeViewItem used for rendering the current item.
|
|
742
|
+
* @returns {import('./contentTreeItem.js').TreeViewItem}
|
|
743
|
+
*/
|
|
744
|
+
getTreeViewItem() {
|
|
745
|
+
const item = super.getTreeViewItem();
|
|
746
|
+
item.forceNodeDisplay = !this._loadOnStartup;
|
|
747
|
+
return item;
|
|
748
|
+
}
|
|
594
749
|
/**
|
|
595
750
|
* @returns {WMSGroupContentTreeItemOptions}
|
|
596
751
|
*/
|
|
597
752
|
toJSON() {
|
|
598
753
|
const config = super.toJSON();
|
|
599
754
|
config.layerName = this._layerName;
|
|
755
|
+
const defaultInitOpen = !this._loadOnStartup;
|
|
756
|
+
if (this.initOpen !== defaultInitOpen) {
|
|
757
|
+
config.initOpen = this.initOpen;
|
|
758
|
+
}
|
|
759
|
+
if (this._loadOnStartup) {
|
|
760
|
+
config.loadOnStartup = this._loadOnStartup;
|
|
761
|
+
}
|
|
600
762
|
if (this._showWhenNotSupported) {
|
|
601
763
|
config.showWhenNotSupported = this._showWhenNotSupported;
|
|
602
764
|
}
|
package/src/i18n/de.d.ts
CHANGED
|
@@ -527,6 +527,7 @@ declare namespace messages {
|
|
|
527
527
|
export let select: string;
|
|
528
528
|
let placeholder_1: string;
|
|
529
529
|
export { placeholder_1 as placeholder };
|
|
530
|
+
export let hideWindow: string;
|
|
530
531
|
export let zoomToFeatureAction: string;
|
|
531
532
|
export let zoomToAll: string;
|
|
532
533
|
export let zoomToAllMobile: string;
|
package/src/i18n/de.js
CHANGED
|
@@ -372,6 +372,7 @@ const messages = {
|
|
|
372
372
|
tooltip: 'Suche',
|
|
373
373
|
select: 'Suchergebnis auswählen',
|
|
374
374
|
placeholder: 'Suche nach Adresse oder Ort/Sehenswürdigkeit',
|
|
375
|
+
hideWindow: 'Suche ausblenden',
|
|
375
376
|
zoomToFeatureAction: 'Auf Ergebnis zoomen',
|
|
376
377
|
zoomToAll: 'Auf alle Ergebnisse zoomen',
|
|
377
378
|
zoomToAllMobile: 'Auf alle zoomen',
|
package/src/i18n/en.d.ts
CHANGED
|
@@ -527,6 +527,7 @@ declare namespace messages {
|
|
|
527
527
|
export let select: string;
|
|
528
528
|
let placeholder_1: string;
|
|
529
529
|
export { placeholder_1 as placeholder };
|
|
530
|
+
export let hideWindow: string;
|
|
530
531
|
export let zoomToFeatureAction: string;
|
|
531
532
|
export let zoomToAllMobile: string;
|
|
532
533
|
export let zoomToAll: string;
|
package/src/i18n/en.js
CHANGED
|
@@ -372,6 +372,7 @@ const messages = {
|
|
|
372
372
|
tooltip: 'Search',
|
|
373
373
|
select: 'Select result item',
|
|
374
374
|
placeholder: 'Search for address or landmark/point of interest',
|
|
375
|
+
hideWindow: 'Hide search',
|
|
375
376
|
zoomToFeatureAction: 'Zoom to result',
|
|
376
377
|
zoomToAllMobile: 'Zoom to all',
|
|
377
378
|
zoomToAll: 'Zoom to all',
|
|
@@ -9,9 +9,9 @@
|
|
|
9
9
|
:show-title="false"
|
|
10
10
|
@item-moved="move"
|
|
11
11
|
/>
|
|
12
|
-
<v-sheet v-if="page && pageSize && totalCount
|
|
12
|
+
<v-sheet v-if="page && pageSize && totalCount > pageSize">
|
|
13
13
|
<v-pagination
|
|
14
|
-
class="px-
|
|
14
|
+
class="px-4"
|
|
15
15
|
v-model="page"
|
|
16
16
|
:length="Math.ceil(totalCount / pageSize)"
|
|
17
17
|
density="compact"
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
import { createSelectionActions } from '../../components/lists/listHelper.js';
|
|
36
36
|
import VcsList from '../../components/lists/VcsList.vue';
|
|
37
37
|
import VcsButton from '../../components/buttons/VcsButton.vue';
|
|
38
|
-
import { moveItem } from '
|
|
38
|
+
import { moveItem } from '../../components/lists/dragHelper.js';
|
|
39
39
|
|
|
40
40
|
/**
|
|
41
41
|
* @description
|
|
@@ -137,7 +137,7 @@
|
|
|
137
137
|
return actions.value;
|
|
138
138
|
}),
|
|
139
139
|
move(event) {
|
|
140
|
-
moveItem(collectionComponent, event);
|
|
140
|
+
moveItem(collectionComponent.collection, event);
|
|
141
141
|
},
|
|
142
142
|
openCollectionComponentList() {
|
|
143
143
|
emit('openList', collectionComponent.id);
|
|
@@ -36,34 +36,12 @@
|
|
|
36
36
|
|
|
37
37
|
<script>
|
|
38
38
|
import { computed, inject } from 'vue';
|
|
39
|
-
import { IndexedCollection } from '@vcmap/core';
|
|
40
39
|
import { VSheet } from 'vuetify/components';
|
|
41
40
|
import { createSelectionActions } from '../../components/lists/listHelper.js';
|
|
42
41
|
import VcsList from '../../components/lists/VcsList.vue';
|
|
43
42
|
import VcsActionButtonList from '../../components/buttons/VcsActionButtonList.vue';
|
|
44
43
|
import VcsButton from '../../components/buttons/VcsButton.vue';
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Moves an item to a new position.
|
|
48
|
-
* New position is derived from a target item in the collection.
|
|
49
|
-
* This ensures correct movement, if rendered list is only a subset of the collection.
|
|
50
|
-
* @param {import("./collectionComponentClass.js").default<Object>} collectionComponent
|
|
51
|
-
* @param {import("../../components/lists/dragHelper.js").ItemMovedEvent} event
|
|
52
|
-
*/
|
|
53
|
-
export function moveItem(
|
|
54
|
-
collectionComponent,
|
|
55
|
-
{ item, targetItem, position },
|
|
56
|
-
) {
|
|
57
|
-
const { collection } = collectionComponent;
|
|
58
|
-
if (collection instanceof IndexedCollection) {
|
|
59
|
-
const collectionItem = collection.getByKey(item.name);
|
|
60
|
-
const keyProperty = collection.uniqueKey;
|
|
61
|
-
const targetIndexCol = [...collection].findIndex(
|
|
62
|
-
(i) => i[keyProperty] === targetItem.name,
|
|
63
|
-
);
|
|
64
|
-
collection.moveTo(collectionItem, targetIndexCol + position);
|
|
65
|
-
}
|
|
66
|
-
}
|
|
44
|
+
import { moveItem } from '../../components/lists/dragHelper.js';
|
|
67
45
|
|
|
68
46
|
/**
|
|
69
47
|
* @description
|
|
@@ -124,7 +102,7 @@
|
|
|
124
102
|
return actions.value;
|
|
125
103
|
}),
|
|
126
104
|
move(event) {
|
|
127
|
-
moveItem(collectionComponent, event);
|
|
105
|
+
moveItem(collectionComponent.collection, event);
|
|
128
106
|
},
|
|
129
107
|
closeList() {
|
|
130
108
|
emit('closeList', collectionComponent.id);
|