@vcmap/ui 6.2.1 → 6.2.3
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/build/postInstall.js +1 -1
- package/config/dev.config.json +1 -1
- package/dist/assets/{cesium-607748ca.js → cesium-dcdef786.js} +1513 -1313
- package/dist/assets/cesium.js +1 -1
- package/dist/assets/{core-ea8a27bd.js → core-f4ee6bea.js} +1554 -1551
- package/dist/assets/core-workers/panoramaImageWorker.js +1 -1
- package/dist/assets/core.js +1 -1
- package/dist/assets/{ol-8fe80c53.js → ol-f7a5160f.js} +1 -1
- package/dist/assets/ol.js +1 -1
- package/dist/assets/ui-d3a7bd39.css +1 -0
- package/dist/assets/{ui-ffa735dc.js → ui-d3a7bd39.js} +7725 -7494
- package/dist/assets/ui.js +1 -1
- package/dist/assets/vue.js +1 -1
- package/dist/assets/{vuetify-def19d80.js → vuetify-8e1623b2.js} +1 -1
- package/dist/assets/vuetify.js +1 -1
- package/index.d.ts +3 -1
- package/index.js +2 -0
- package/package.json +4 -3
- package/plugins/@vcmap-show-case/category-tester/src/CollectionComponentOptions.vue +41 -2
- package/plugins/@vcmap-show-case/category-tester/src/index.js +2 -0
- package/src/application/VcsSettings.vue +4 -0
- package/src/application/VcsSplashScreen.vue +9 -1
- package/src/components/flight/VcsFlightAnchorsComponent.vue +2 -2
- package/src/components/lists/VcsList.vue +10 -18
- package/src/components/lists/VcsTreeNode.vue +10 -4
- package/src/components/lists/VcsTreeNode.vue.d.ts +8 -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 +24 -4
- package/src/contentTree/LayerSwap.vue.d.ts +18 -4
- package/src/contentTree/wmsGroupContentTreeItem.d.ts +22 -3
- package/src/contentTree/wmsGroupContentTreeItem.js +126 -64
- package/src/featureInfo/balloonFeatureInfoView.d.ts +15 -2
- package/src/featureInfo/balloonFeatureInfoView.js +8 -103
- package/src/featureInfo/balloonHelper.d.ts +13 -0
- package/src/featureInfo/balloonHelper.js +77 -0
- package/src/featureInfo/featureInfo.d.ts +2 -1
- package/src/featureInfo/featureInfo.js +11 -3
- package/src/featureInfo/featureInfoInteraction.js +4 -1
- package/src/featureInfo/iframeWmsFeatureInfoView.js +12 -2
- package/src/i18n/de.d.ts +3 -0
- package/src/i18n/de.js +3 -0
- package/src/i18n/en.d.ts +3 -0
- package/src/i18n/en.js +3 -0
- package/src/legend/legendHelper.js +5 -0
- package/src/manager/collectionManager/CollectionComponentContent.vue +69 -5
- package/src/manager/collectionManager/CollectionComponentContent.vue.d.ts +3 -0
- package/src/manager/collectionManager/CollectionComponentList.vue +2 -24
- package/src/manager/collectionManager/CollectionComponentList.vue.d.ts +0 -8
- package/src/manager/collectionManager/collectionComponentClass.d.ts +44 -1
- package/src/manager/collectionManager/collectionComponentClass.js +152 -2
- package/src/manager/panel/PanelComponent.vue +9 -1
- package/src/state.d.ts +14 -0
- package/src/state.js +60 -6
- package/src/vcsUiApp.d.ts +9 -36
- package/src/vcsUiApp.js +45 -11
- package/dist/assets/ui-ffa735dc.css +0 -1
- /package/dist/assets/core-workers/{panoramaImageWorker.js-a3ad230c.js → panoramaImageWorker.js-a6bb36f6.js} +0 -0
- /package/dist/assets/{vue-09a72820.js → vue-cbd2bd60.js} +0 -0
- /package/dist/assets/{vuetify-def19d80.css → vuetify-8e1623b2.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;
|
|
@@ -21,12 +22,13 @@ export type WMSEntry = {
|
|
|
21
22
|
};
|
|
22
23
|
/**
|
|
23
24
|
* @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.
|
|
25
|
+
* { layerName: string, loadOnStartup?: boolean, showWhenNotSupported?: boolean, setWMSLayersExclusive?:boolean, hideStyleSelector?:boolean, allowedWMSLayers?:string[]}} WMSGroupContentTreeItemOptions
|
|
26
26
|
* @property {string} layerName - The name of the WMSLayer to show the children of.
|
|
27
|
+
* @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.
|
|
28
|
+
* @property {boolean} [showWhenNotSupported=false] - optional flag to show the item even if it is not supported by the activeMap.
|
|
27
29
|
* @property {boolean} [setWMSLayersExclusive=false] - Whether the WMSlayers are mutually exclusive.
|
|
28
30
|
* @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.
|
|
31
|
+
* @property {string[]} [allowedWMSLayers] - The list of layers to be shown, other available layers will not be shown.
|
|
30
32
|
*/
|
|
31
33
|
/**
|
|
32
34
|
* @typedef {Object} WMSStyleEntry
|
|
@@ -61,6 +63,11 @@ declare class WMSGroupContentTreeItem extends VcsObjectContentTreeItem<import(".
|
|
|
61
63
|
* @private
|
|
62
64
|
*/
|
|
63
65
|
private _layerName;
|
|
66
|
+
/**
|
|
67
|
+
* @type {boolean}
|
|
68
|
+
* @private
|
|
69
|
+
*/
|
|
70
|
+
private _loadOnStartup;
|
|
64
71
|
/**
|
|
65
72
|
* @type {boolean}
|
|
66
73
|
* @private
|
|
@@ -115,6 +122,12 @@ declare class WMSGroupContentTreeItem extends VcsObjectContentTreeItem<import(".
|
|
|
115
122
|
* @private
|
|
116
123
|
*/
|
|
117
124
|
private _pauseStateChangedListener;
|
|
125
|
+
/**
|
|
126
|
+
* Flag to track if children have been loaded
|
|
127
|
+
* @type {boolean}
|
|
128
|
+
* @private
|
|
129
|
+
*/
|
|
130
|
+
private _childrenLoaded;
|
|
118
131
|
/**
|
|
119
132
|
* readonly access, do not manipulate the entries directly.
|
|
120
133
|
* @type {Array<WMSEntry>}
|
|
@@ -157,6 +170,12 @@ declare class WMSGroupContentTreeItem extends VcsObjectContentTreeItem<import(".
|
|
|
157
170
|
* @private
|
|
158
171
|
*/
|
|
159
172
|
private _setStateFromLayer;
|
|
173
|
+
/**
|
|
174
|
+
* Loads WMS entries and creates child items
|
|
175
|
+
* @returns {Promise<void>}
|
|
176
|
+
* @private
|
|
177
|
+
*/
|
|
178
|
+
private _loadWMSChildren;
|
|
160
179
|
/**
|
|
161
180
|
* @returns {Promise<void>}
|
|
162
181
|
* @private
|
|
@@ -112,12 +112,13 @@ function createWMSChildContentTreeItem(
|
|
|
112
112
|
|
|
113
113
|
/**
|
|
114
114
|
* @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.
|
|
115
|
+
* { layerName: string, loadOnStartup?: boolean, showWhenNotSupported?: boolean, setWMSLayersExclusive?:boolean, hideStyleSelector?:boolean, allowedWMSLayers?:string[]}} WMSGroupContentTreeItemOptions
|
|
117
116
|
* @property {string} layerName - The name of the WMSLayer to show the children of.
|
|
117
|
+
* @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.
|
|
118
|
+
* @property {boolean} [showWhenNotSupported=false] - optional flag to show the item even if it is not supported by the activeMap.
|
|
118
119
|
* @property {boolean} [setWMSLayersExclusive=false] - Whether the WMSlayers are mutually exclusive.
|
|
119
120
|
* @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.
|
|
121
|
+
* @property {string[]} [allowedWMSLayers] - The list of layers to be shown, other available layers will not be shown.
|
|
121
122
|
*/
|
|
122
123
|
|
|
123
124
|
/**
|
|
@@ -154,7 +155,7 @@ class WMSGroupContentTreeItem extends VcsObjectContentTreeItem {
|
|
|
154
155
|
* @param {import("../vcsUiApp.js").default} app
|
|
155
156
|
*/
|
|
156
157
|
constructor(options, app) {
|
|
157
|
-
super(options, app);
|
|
158
|
+
super({ initOpen: !options.loadOnStartup, ...options }, app);
|
|
158
159
|
|
|
159
160
|
/**
|
|
160
161
|
* @type {string}
|
|
@@ -162,6 +163,12 @@ class WMSGroupContentTreeItem extends VcsObjectContentTreeItem {
|
|
|
162
163
|
*/
|
|
163
164
|
this._layerName = options.layerName;
|
|
164
165
|
|
|
166
|
+
/**
|
|
167
|
+
* @type {boolean}
|
|
168
|
+
* @private
|
|
169
|
+
*/
|
|
170
|
+
this._loadOnStartup = parseBoolean(options.loadOnStartup, false);
|
|
171
|
+
|
|
165
172
|
/**
|
|
166
173
|
* @type {boolean}
|
|
167
174
|
* @private
|
|
@@ -180,7 +187,7 @@ class WMSGroupContentTreeItem extends VcsObjectContentTreeItem {
|
|
|
180
187
|
false,
|
|
181
188
|
);
|
|
182
189
|
// if WMSLayers should be handled exclusive, the item should handle like a NodeContentTreeItem.
|
|
183
|
-
this.clickable = !this._setWMSLayersExclusive;
|
|
190
|
+
this.clickable = !this._setWMSLayersExclusive || !this._loadOnStartup;
|
|
184
191
|
|
|
185
192
|
/**
|
|
186
193
|
* @type {boolean}
|
|
@@ -188,9 +195,10 @@ class WMSGroupContentTreeItem extends VcsObjectContentTreeItem {
|
|
|
188
195
|
*/
|
|
189
196
|
this._hideStyleSelector = parseBoolean(options.hideStyleSelector, false);
|
|
190
197
|
|
|
191
|
-
this.state =
|
|
192
|
-
|
|
193
|
-
|
|
198
|
+
this.state =
|
|
199
|
+
this._setWMSLayersExclusive || !this._loadOnStartup
|
|
200
|
+
? StateActionState.NONE
|
|
201
|
+
: StateActionState.INACTIVE;
|
|
194
202
|
|
|
195
203
|
/**
|
|
196
204
|
* @type {boolean}
|
|
@@ -238,6 +246,13 @@ class WMSGroupContentTreeItem extends VcsObjectContentTreeItem {
|
|
|
238
246
|
*/
|
|
239
247
|
this._pauseStateChangedListener = false;
|
|
240
248
|
|
|
249
|
+
/**
|
|
250
|
+
* Flag to track if children have been loaded
|
|
251
|
+
* @type {boolean}
|
|
252
|
+
* @private
|
|
253
|
+
*/
|
|
254
|
+
this._childrenLoaded = false;
|
|
255
|
+
|
|
241
256
|
this._setup();
|
|
242
257
|
}
|
|
243
258
|
|
|
@@ -421,6 +436,10 @@ class WMSGroupContentTreeItem extends VcsObjectContentTreeItem {
|
|
|
421
436
|
this._listeners.splice(0);
|
|
422
437
|
this._availableWMSEntries = [];
|
|
423
438
|
this._legendSet = false;
|
|
439
|
+
this._childrenLoaded = false;
|
|
440
|
+
|
|
441
|
+
// Reset clickable state based on initial configuration
|
|
442
|
+
this.clickable = !this._setWMSLayersExclusive || !this._loadOnStartup;
|
|
424
443
|
}
|
|
425
444
|
|
|
426
445
|
/**
|
|
@@ -463,6 +482,83 @@ class WMSGroupContentTreeItem extends VcsObjectContentTreeItem {
|
|
|
463
482
|
}
|
|
464
483
|
}
|
|
465
484
|
|
|
485
|
+
/**
|
|
486
|
+
* Loads WMS entries and creates child items
|
|
487
|
+
* @returns {Promise<void>}
|
|
488
|
+
* @private
|
|
489
|
+
*/
|
|
490
|
+
async _loadWMSChildren() {
|
|
491
|
+
if (this._childrenLoaded || !this._layer) {
|
|
492
|
+
return;
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
this.state = StateActionState.LOADING;
|
|
496
|
+
this.clickable = !this._setWMSLayersExclusive;
|
|
497
|
+
|
|
498
|
+
try {
|
|
499
|
+
const availableWMSEntries = await getWMSEntries(
|
|
500
|
+
this._layer.url,
|
|
501
|
+
this._layer.parameters,
|
|
502
|
+
);
|
|
503
|
+
// check if the layer still exists, it can happen that the layer was removed while fetching the capabilities.
|
|
504
|
+
if (!this._layer) {
|
|
505
|
+
return;
|
|
506
|
+
}
|
|
507
|
+
this._availableWMSEntries = availableWMSEntries.filter((wmsEntry) => {
|
|
508
|
+
return this._allowedWMSLayers
|
|
509
|
+
? this._allowedWMSLayers.includes(wmsEntry.name)
|
|
510
|
+
: true;
|
|
511
|
+
});
|
|
512
|
+
const childItems = this._availableWMSEntries.map((wmsEntry) =>
|
|
513
|
+
createWMSChildContentTreeItem(
|
|
514
|
+
this._app,
|
|
515
|
+
wmsEntry,
|
|
516
|
+
this.name,
|
|
517
|
+
this._hideStyleSelector,
|
|
518
|
+
),
|
|
519
|
+
);
|
|
520
|
+
childItems.forEach((childItem) => {
|
|
521
|
+
this._app.contentTree.add(childItem);
|
|
522
|
+
childItem.disabled = this.disabled;
|
|
523
|
+
this._listeners.push(
|
|
524
|
+
childItem.clickedEvent.addEventListener(() => {
|
|
525
|
+
this._handleChildClickedEvent(childItem);
|
|
526
|
+
}),
|
|
527
|
+
childItem.styleSelected.addEventListener((style) => {
|
|
528
|
+
this._handleStyleSelectedEvent(childItem, style);
|
|
529
|
+
}),
|
|
530
|
+
);
|
|
531
|
+
});
|
|
532
|
+
this._childItems = childItems;
|
|
533
|
+
// check if we do have a legend already configured, if yes we set a flag, that we do not need to set the legend.
|
|
534
|
+
if (this._layer.properties.legend) {
|
|
535
|
+
this._legendSet = true;
|
|
536
|
+
}
|
|
537
|
+
// we need to get the Initial State from the Layer, to set the correct State to the children.
|
|
538
|
+
this._setStateFromLayer();
|
|
539
|
+
// the layer State maybe incomplete or does not fit to the wmsGroupContentTreeItem, so we need to set the State to the Layer.
|
|
540
|
+
this._setState();
|
|
541
|
+
this._setLegend();
|
|
542
|
+
this._childrenLoaded = true;
|
|
543
|
+
|
|
544
|
+
// Update clickable state after children are loaded
|
|
545
|
+
if (!this._setWMSLayersExclusive) {
|
|
546
|
+
this.clickable = true;
|
|
547
|
+
}
|
|
548
|
+
} catch (e) {
|
|
549
|
+
// if the layer is not there it has been removed while fetching the capabilities.
|
|
550
|
+
if (this._layer) {
|
|
551
|
+
this._layer.deactivate();
|
|
552
|
+
this.visible = false;
|
|
553
|
+
this._invalid = true;
|
|
554
|
+
}
|
|
555
|
+
getLogger(this.className).error(
|
|
556
|
+
`An error occured while fetching the ${this._layerName} capabilities:`,
|
|
557
|
+
e,
|
|
558
|
+
);
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
|
|
466
562
|
/**
|
|
467
563
|
* @returns {Promise<void>}
|
|
468
564
|
* @private
|
|
@@ -489,7 +585,6 @@ class WMSGroupContentTreeItem extends VcsObjectContentTreeItem {
|
|
|
489
585
|
if (this._showWhenNotSupported) {
|
|
490
586
|
this.disabled = !isSupported;
|
|
491
587
|
}
|
|
492
|
-
this.state = StateActionState.LOADING;
|
|
493
588
|
this.setPropertiesFromObject(this._layer);
|
|
494
589
|
|
|
495
590
|
this._listeners.push(
|
|
@@ -517,67 +612,18 @@ class WMSGroupContentTreeItem extends VcsObjectContentTreeItem {
|
|
|
517
612
|
}
|
|
518
613
|
}),
|
|
519
614
|
);
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
this._layer.url,
|
|
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
|
-
);
|
|
615
|
+
if (this._loadOnStartup) {
|
|
616
|
+
await this._loadWMSChildren();
|
|
575
617
|
}
|
|
576
618
|
}
|
|
577
619
|
}
|
|
578
620
|
|
|
579
621
|
async clicked() {
|
|
580
622
|
await super.clicked();
|
|
623
|
+
if (!this._childrenLoaded) {
|
|
624
|
+
await this._loadWMSChildren();
|
|
625
|
+
return;
|
|
626
|
+
}
|
|
581
627
|
if (this.state === StateActionState.NONE || this._setWMSLayersExclusive) {
|
|
582
628
|
return;
|
|
583
629
|
}
|
|
@@ -591,12 +637,28 @@ class WMSGroupContentTreeItem extends VcsObjectContentTreeItem {
|
|
|
591
637
|
await this._setStateToLayer();
|
|
592
638
|
}
|
|
593
639
|
|
|
640
|
+
/**
|
|
641
|
+
* Returns a readonly TreeViewItem used for rendering the current item.
|
|
642
|
+
* @returns {import('./contentTreeItem.js').TreeViewItem}
|
|
643
|
+
*/
|
|
644
|
+
getTreeViewItem() {
|
|
645
|
+
const item = super.getTreeViewItem();
|
|
646
|
+
item.forceNodeDisplay = !this._loadOnStartup;
|
|
647
|
+
return item;
|
|
648
|
+
}
|
|
594
649
|
/**
|
|
595
650
|
* @returns {WMSGroupContentTreeItemOptions}
|
|
596
651
|
*/
|
|
597
652
|
toJSON() {
|
|
598
653
|
const config = super.toJSON();
|
|
599
654
|
config.layerName = this._layerName;
|
|
655
|
+
const defaultInitOpen = !this._loadOnStartup;
|
|
656
|
+
if (this.initOpen !== defaultInitOpen) {
|
|
657
|
+
config.initOpen = this.initOpen;
|
|
658
|
+
}
|
|
659
|
+
if (this._loadOnStartup) {
|
|
660
|
+
config.loadOnStartup = this._loadOnStartup;
|
|
661
|
+
}
|
|
600
662
|
if (this._showWhenNotSupported) {
|
|
601
663
|
config.showWhenNotSupported = this._showWhenNotSupported;
|
|
602
664
|
}
|
|
@@ -15,9 +15,23 @@ export type BalloonFeatureInfoViewProps = import("./abstractFeatureInfoView.js")
|
|
|
15
15
|
balloonTitle: string;
|
|
16
16
|
balloonSubtitle: string;
|
|
17
17
|
position: import("ol/coordinate.js").Coordinate;
|
|
18
|
-
heightReference: HeightReference;
|
|
18
|
+
heightReference: import("@vcmap-cesium/engine").HeightReference;
|
|
19
19
|
heightOffset: number;
|
|
20
20
|
};
|
|
21
|
+
/**
|
|
22
|
+
* @typedef {import("./abstractFeatureInfoView.js").FeatureInfoViewOptions & { balloonTitle?: string, balloonSubtitle?: string }} BalloonFeatureInfoViewOptions
|
|
23
|
+
* @property {string} [balloonTitle] - optional title to overwrite default (layerName). Can be attribute key (nested key using '.'), i18n key or text
|
|
24
|
+
* @property {string} [balloonSubtitle] - optional window title to overwrite default (featureId). Can be attribute key (nested key using '.'), i18n key or text
|
|
25
|
+
*/
|
|
26
|
+
/**
|
|
27
|
+
* @typedef {import("./abstractFeatureInfoView.js").FeatureInfoProps & {
|
|
28
|
+
* balloonTitle: string,
|
|
29
|
+
* balloonSubtitle: string,
|
|
30
|
+
* position: import("ol/coordinate.js").Coordinate
|
|
31
|
+
* heightReference: import("@vcmap-cesium/engine").HeightReference,
|
|
32
|
+
* heightOffset: number
|
|
33
|
+
* }} BalloonFeatureInfoViewProps
|
|
34
|
+
*/
|
|
21
35
|
/**
|
|
22
36
|
* @class
|
|
23
37
|
* @description An balloon view.
|
|
@@ -48,5 +62,4 @@ declare class BalloonFeatureInfoView extends AbstractFeatureInfoView {
|
|
|
48
62
|
*/
|
|
49
63
|
toJSON(): BalloonFeatureInfoViewOptions;
|
|
50
64
|
}
|
|
51
|
-
import { HeightReference } from '@vcmap-cesium/engine';
|
|
52
65
|
import AbstractFeatureInfoView from './abstractFeatureInfoView.js';
|
|
@@ -1,24 +1,8 @@
|
|
|
1
|
-
import { Feature } from 'ol';
|
|
2
|
-
import { getCenter } from 'ol/extent.js';
|
|
3
|
-
import Point from 'ol/geom/Point.js';
|
|
4
|
-
import {
|
|
5
|
-
Cartographic,
|
|
6
|
-
Entity,
|
|
7
|
-
HeightReference,
|
|
8
|
-
Math as CesiumMath,
|
|
9
|
-
} from '@vcmap-cesium/engine';
|
|
10
|
-
import {
|
|
11
|
-
getGeometryHeight,
|
|
12
|
-
getHeightInfo,
|
|
13
|
-
isAbsoluteHeightReference,
|
|
14
|
-
isRelativeHeightReference,
|
|
15
|
-
Projection,
|
|
16
|
-
VectorProperties,
|
|
17
|
-
} from '@vcmap/core';
|
|
18
1
|
import { check } from '@vcsuite/check';
|
|
19
2
|
import AbstractFeatureInfoView from './abstractFeatureInfoView.js';
|
|
20
3
|
import { WindowSlot } from '../manager/window/windowManager.js';
|
|
21
4
|
import BalloonComponent from './BalloonComponent.vue';
|
|
5
|
+
import { getBalloonPositionFromFeature } from './balloonHelper.js';
|
|
22
6
|
|
|
23
7
|
/**
|
|
24
8
|
* derive value from attributes
|
|
@@ -47,91 +31,11 @@ export function extractNestedKey(key, attrs, defaultValue = null) {
|
|
|
47
31
|
* balloonTitle: string,
|
|
48
32
|
* balloonSubtitle: string,
|
|
49
33
|
* position: import("ol/coordinate.js").Coordinate
|
|
50
|
-
* heightReference: HeightReference,
|
|
34
|
+
* heightReference: import("@vcmap-cesium/engine").HeightReference,
|
|
51
35
|
* heightOffset: number
|
|
52
36
|
* }} BalloonFeatureInfoViewProps
|
|
53
37
|
*/
|
|
54
38
|
|
|
55
|
-
/**
|
|
56
|
-
* @param {import("@vcmap/core").Cartesian3} cartesian
|
|
57
|
-
* @returns {import("ol/coordinate.js").Coordinate}
|
|
58
|
-
*/
|
|
59
|
-
function cartesian3ToCoordinate(cartesian) {
|
|
60
|
-
const cartographic = Cartographic.fromCartesian(cartesian);
|
|
61
|
-
const wgs84position = [
|
|
62
|
-
CesiumMath.toDegrees(cartographic.longitude),
|
|
63
|
-
CesiumMath.toDegrees(cartographic.latitude),
|
|
64
|
-
cartographic.height,
|
|
65
|
-
];
|
|
66
|
-
return Projection.wgs84ToMercator(wgs84position);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* @param {FeatureType} feature
|
|
71
|
-
* @param {import("@vcmap/core").Layer} layer
|
|
72
|
-
* @param {import("ol/coordinate.js").Coordinate|undefinded} clickedPosition
|
|
73
|
-
* @returns {{position?: import("ol/coordinate.js").Coordinate, heightReference: HeightReference, heightOffset: number}}
|
|
74
|
-
*/
|
|
75
|
-
function getPositionFromFeature(feature, layer, clickedPosition) {
|
|
76
|
-
let heightReference = HeightReference.NONE;
|
|
77
|
-
let heightOffset = 0;
|
|
78
|
-
let position = null;
|
|
79
|
-
if (feature instanceof Feature && feature.getGeometry() instanceof Point) {
|
|
80
|
-
const point = feature.getGeometry();
|
|
81
|
-
const vectorProperties =
|
|
82
|
-
layer.vectorProperties ??
|
|
83
|
-
layer.featureProvider?.vectorProperties ??
|
|
84
|
-
new VectorProperties();
|
|
85
|
-
const renderAs = vectorProperties.renderAs(feature);
|
|
86
|
-
if (renderAs === 'geometry') {
|
|
87
|
-
// special case where we do not want to use the clickedPosition but the exact Position of the Point
|
|
88
|
-
const heightInfo = getHeightInfo(feature, point, vectorProperties);
|
|
89
|
-
({ heightReference } = heightInfo);
|
|
90
|
-
let height = clickedPosition?.[2] ?? 0;
|
|
91
|
-
position = point.getCoordinates();
|
|
92
|
-
// if clamped, do nothing
|
|
93
|
-
if (isRelativeHeightReference(heightReference)) {
|
|
94
|
-
height = getGeometryHeight(point, heightInfo);
|
|
95
|
-
if (heightInfo.groundLevel != null) {
|
|
96
|
-
// we have a groundLevel, so no need to clamp the point
|
|
97
|
-
heightReference = HeightReference.NONE;
|
|
98
|
-
}
|
|
99
|
-
if (heightInfo.heightAboveGround != null) {
|
|
100
|
-
heightOffset += heightInfo.heightAboveGround;
|
|
101
|
-
}
|
|
102
|
-
const extrudedHeight = heightInfo.storeyHeightsAboveGround.reduce(
|
|
103
|
-
(acc, storeyHeight) => acc + storeyHeight,
|
|
104
|
-
0,
|
|
105
|
-
);
|
|
106
|
-
heightOffset += extrudedHeight;
|
|
107
|
-
height += extrudedHeight;
|
|
108
|
-
position = [position[0], position[1], height];
|
|
109
|
-
} else if (isAbsoluteHeightReference(heightReference)) {
|
|
110
|
-
const extrudedHeight = heightInfo.storeyHeightsAboveGround.reduce(
|
|
111
|
-
(acc, storeyHeight) => acc + storeyHeight,
|
|
112
|
-
0,
|
|
113
|
-
);
|
|
114
|
-
position = [
|
|
115
|
-
position[0],
|
|
116
|
-
position[1],
|
|
117
|
-
heightInfo.groundLevelOrMinHeight + extrudedHeight,
|
|
118
|
-
];
|
|
119
|
-
}
|
|
120
|
-
return { position, heightOffset, heightReference };
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
if (clickedPosition) {
|
|
124
|
-
position = clickedPosition.slice();
|
|
125
|
-
} else if (feature instanceof Feature && feature.getGeometry()) {
|
|
126
|
-
position = getCenter(feature.getGeometry().getExtent());
|
|
127
|
-
} else if (feature instanceof Entity) {
|
|
128
|
-
position = cartesian3ToCoordinate(feature.position);
|
|
129
|
-
} else if (feature?.primitive?.boundingSphere?.center) {
|
|
130
|
-
position = cartesian3ToCoordinate(feature.primitive.boundingSphere.center);
|
|
131
|
-
}
|
|
132
|
-
return { position, heightReference, heightOffset };
|
|
133
|
-
}
|
|
134
|
-
|
|
135
39
|
/**
|
|
136
40
|
* @class
|
|
137
41
|
* @description An balloon view.
|
|
@@ -170,11 +74,12 @@ class BalloonFeatureInfoView extends AbstractFeatureInfoView {
|
|
|
170
74
|
*/
|
|
171
75
|
getProperties(featureInfo, layer) {
|
|
172
76
|
const properties = super.getProperties(featureInfo, layer);
|
|
173
|
-
const { position, heightReference, heightOffset } =
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
77
|
+
const { position, heightReference, heightOffset } =
|
|
78
|
+
getBalloonPositionFromFeature(
|
|
79
|
+
featureInfo.feature,
|
|
80
|
+
layer,
|
|
81
|
+
featureInfo.position,
|
|
82
|
+
);
|
|
178
83
|
return {
|
|
179
84
|
...properties,
|
|
180
85
|
position,
|
|
@@ -20,6 +20,17 @@ export function setBalloonPosition(windowManager: import("../manager/window/wind
|
|
|
20
20
|
* @returns {Promise<(() => void)>}
|
|
21
21
|
*/
|
|
22
22
|
export function setupBalloonPositionListener(vcsApp: import("@vcmap/core").VcsApp, windowId: string, clickedPosition: import("ol/coordinate.js").Coordinate): Promise<(() => void)>;
|
|
23
|
+
/**
|
|
24
|
+
* @param {Feature} feature
|
|
25
|
+
* @param {import("@vcmap/core").Layer} layer
|
|
26
|
+
* @param {import("ol/coordinate.js").Coordinate|undefined} clickedPosition
|
|
27
|
+
* @returns {{position?: import("ol/coordinate.js").Coordinate, heightReference: HeightReference, heightOffset: number}}
|
|
28
|
+
*/
|
|
29
|
+
export function getBalloonPositionFromFeature(feature: Feature, layer: import("@vcmap/core").Layer, clickedPosition: import("ol/coordinate.js").Coordinate | undefined): {
|
|
30
|
+
position?: import("ol/coordinate.js").Coordinate;
|
|
31
|
+
heightReference: HeightReference;
|
|
32
|
+
heightOffset: number;
|
|
33
|
+
};
|
|
23
34
|
/**
|
|
24
35
|
* balloon offset from location or click position in pixel
|
|
25
36
|
* @type {{x: number, y: number}}
|
|
@@ -29,3 +40,5 @@ export const balloonOffset: {
|
|
|
29
40
|
y: number;
|
|
30
41
|
};
|
|
31
42
|
import { Cartesian2 } from '@vcmap-cesium/engine';
|
|
43
|
+
import Feature from 'ol/Feature.js';
|
|
44
|
+
import { HeightReference } from '@vcmap-cesium/engine';
|
|
@@ -2,15 +2,26 @@ import {
|
|
|
2
2
|
Cartesian2,
|
|
3
3
|
Cartographic,
|
|
4
4
|
SceneTransforms,
|
|
5
|
+
HeightReference,
|
|
6
|
+
Entity,
|
|
5
7
|
} from '@vcmap-cesium/engine';
|
|
6
8
|
import {
|
|
9
|
+
cartesianToMercator,
|
|
7
10
|
CesiumMap,
|
|
11
|
+
getGeometryHeight,
|
|
12
|
+
getHeightInfo,
|
|
13
|
+
isAbsoluteHeightReference,
|
|
14
|
+
isRelativeHeightReference,
|
|
8
15
|
ObliqueMap,
|
|
9
16
|
OpenlayersMap,
|
|
10
17
|
Projection,
|
|
11
18
|
transformToImage,
|
|
19
|
+
VectorProperties,
|
|
12
20
|
} from '@vcmap/core';
|
|
13
21
|
import { unByKey } from 'ol/Observable.js';
|
|
22
|
+
import Feature from 'ol/Feature.js';
|
|
23
|
+
import { Point } from 'ol/geom.js';
|
|
24
|
+
import { getCenter } from 'ol/extent.js';
|
|
14
25
|
import {
|
|
15
26
|
getWindowPositionOptionsFromMapEvent,
|
|
16
27
|
WindowAlignment,
|
|
@@ -173,3 +184,69 @@ export async function setupBalloonPositionListener(
|
|
|
173
184
|
|
|
174
185
|
return destroy;
|
|
175
186
|
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* @param {Feature} feature
|
|
190
|
+
* @param {import("@vcmap/core").Layer} layer
|
|
191
|
+
* @param {import("ol/coordinate.js").Coordinate|undefined} clickedPosition
|
|
192
|
+
* @returns {{position?: import("ol/coordinate.js").Coordinate, heightReference: HeightReference, heightOffset: number}}
|
|
193
|
+
*/
|
|
194
|
+
export function getBalloonPositionFromFeature(feature, layer, clickedPosition) {
|
|
195
|
+
let heightReference = HeightReference.NONE;
|
|
196
|
+
let heightOffset = 0;
|
|
197
|
+
let position = null;
|
|
198
|
+
if (feature instanceof Feature && feature.getGeometry() instanceof Point) {
|
|
199
|
+
const point = feature.getGeometry();
|
|
200
|
+
const vectorProperties =
|
|
201
|
+
layer.vectorProperties ??
|
|
202
|
+
layer.featureProvider?.vectorProperties ??
|
|
203
|
+
new VectorProperties();
|
|
204
|
+
const renderAs = vectorProperties.renderAs(feature);
|
|
205
|
+
if (renderAs === 'geometry') {
|
|
206
|
+
// special case where we do not want to use the clickedPosition but the exact Position of the Point
|
|
207
|
+
const heightInfo = getHeightInfo(feature, point, vectorProperties);
|
|
208
|
+
({ heightReference } = heightInfo);
|
|
209
|
+
let height = clickedPosition?.[2] ?? 0;
|
|
210
|
+
position = point.getCoordinates();
|
|
211
|
+
// if clamped, do nothing
|
|
212
|
+
if (isRelativeHeightReference(heightReference)) {
|
|
213
|
+
height = getGeometryHeight(point, heightInfo);
|
|
214
|
+
if (heightInfo.groundLevel != null) {
|
|
215
|
+
// we have a groundLevel, so no need to clamp the point
|
|
216
|
+
heightReference = HeightReference.NONE;
|
|
217
|
+
}
|
|
218
|
+
if (heightInfo.heightAboveGround != null) {
|
|
219
|
+
heightOffset += heightInfo.heightAboveGround;
|
|
220
|
+
}
|
|
221
|
+
const extrudedHeight = heightInfo.storeyHeightsAboveGround.reduce(
|
|
222
|
+
(acc, storeyHeight) => acc + storeyHeight,
|
|
223
|
+
0,
|
|
224
|
+
);
|
|
225
|
+
heightOffset += extrudedHeight;
|
|
226
|
+
height += extrudedHeight;
|
|
227
|
+
position = [position[0], position[1], height];
|
|
228
|
+
} else if (isAbsoluteHeightReference(heightReference)) {
|
|
229
|
+
const extrudedHeight = heightInfo.storeyHeightsAboveGround.reduce(
|
|
230
|
+
(acc, storeyHeight) => acc + storeyHeight,
|
|
231
|
+
0,
|
|
232
|
+
);
|
|
233
|
+
position = [
|
|
234
|
+
position[0],
|
|
235
|
+
position[1],
|
|
236
|
+
heightInfo.groundLevelOrMinHeight + extrudedHeight,
|
|
237
|
+
];
|
|
238
|
+
}
|
|
239
|
+
return { position, heightOffset, heightReference };
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
if (clickedPosition) {
|
|
243
|
+
position = clickedPosition.slice();
|
|
244
|
+
} else if (feature instanceof Feature && feature.getGeometry()) {
|
|
245
|
+
position = getCenter(feature.getGeometry().getExtent());
|
|
246
|
+
} else if (feature instanceof Entity) {
|
|
247
|
+
position = cartesianToMercator(feature.position);
|
|
248
|
+
} else if (feature?.primitive?.boundingSphere?.center) {
|
|
249
|
+
position = cartesianToMercator(feature.primitive.boundingSphere.center);
|
|
250
|
+
}
|
|
251
|
+
return { position, heightReference, heightOffset };
|
|
252
|
+
}
|
|
@@ -225,9 +225,10 @@ declare class FeatureInfo extends Collection<AbstractFeatureInfoView> {
|
|
|
225
225
|
* The cluster feature will be cloned, highlighted and added on an internal scratch layer to ensure availability until deselection.
|
|
226
226
|
* The original cluster feature will be hidden until deselection.
|
|
227
227
|
* @param {import("ol").Feature} clusterFeature
|
|
228
|
+
* @param {import("ol/coordinate.js").Coordinate} position
|
|
228
229
|
* @returns {Promise<void>}
|
|
229
230
|
*/
|
|
230
|
-
selectClusterFeature(clusterFeature: import("ol").Feature): Promise<void>;
|
|
231
|
+
selectClusterFeature(clusterFeature: import("ol").Feature, position: import("ol/coordinate.js").Coordinate): Promise<void>;
|
|
231
232
|
/**
|
|
232
233
|
* Clears the current feature. remove window, highlighting and provided feature.
|
|
233
234
|
* @private
|
|
@@ -296,7 +296,10 @@ function setupFeatureInfoTool(app) {
|
|
|
296
296
|
});
|
|
297
297
|
|
|
298
298
|
function addFeatureInfoButton() {
|
|
299
|
-
if (
|
|
299
|
+
if (
|
|
300
|
+
app.uiConfig.getByKey('startingFeatureInfo')?.value !== false &&
|
|
301
|
+
!action.active
|
|
302
|
+
) {
|
|
300
303
|
action.callback();
|
|
301
304
|
}
|
|
302
305
|
if (!app.toolboxManager.has('featureInfo')) {
|
|
@@ -754,9 +757,10 @@ class FeatureInfo extends Collection {
|
|
|
754
757
|
* The cluster feature will be cloned, highlighted and added on an internal scratch layer to ensure availability until deselection.
|
|
755
758
|
* The original cluster feature will be hidden until deselection.
|
|
756
759
|
* @param {import("ol").Feature} clusterFeature
|
|
760
|
+
* @param {import("ol/coordinate.js").Coordinate} position
|
|
757
761
|
* @returns {Promise<void>}
|
|
758
762
|
*/
|
|
759
|
-
async selectClusterFeature(clusterFeature) {
|
|
763
|
+
async selectClusterFeature(clusterFeature, position) {
|
|
760
764
|
this.clearFeature();
|
|
761
765
|
this._clearClusterInternal();
|
|
762
766
|
const id = `cluster-at-${clusterFeature.getGeometry().getCoordinates().join('-')}`;
|
|
@@ -800,7 +804,11 @@ class FeatureInfo extends Collection {
|
|
|
800
804
|
this._scratchLayer.addFeatures([clonedFeature]);
|
|
801
805
|
|
|
802
806
|
const features = clusterFeature.get('features');
|
|
803
|
-
const { items, groups } = getGroupedFeatureList(
|
|
807
|
+
const { items, groups } = getGroupedFeatureList(
|
|
808
|
+
this._app,
|
|
809
|
+
features,
|
|
810
|
+
position,
|
|
811
|
+
);
|
|
804
812
|
|
|
805
813
|
this._clusterWindowId = id;
|
|
806
814
|
this._app.windowManager.add(
|