@vcmap/ui 6.1.0-rc.1 → 6.1.0-rc.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.
Files changed (128) hide show
  1. package/config/base.config.json +6 -0
  2. package/config/clipping.config.json +384 -0
  3. package/config/cluster.config.json +106 -0
  4. package/config/concepts-show-case.config.json +4 -0
  5. package/config/projects.config.json +5 -2
  6. package/dist/assets/{cesium-11e5bbc6.js → cesium-87d5e72d.js} +438 -432
  7. package/dist/assets/cesium.js +1 -1
  8. package/dist/assets/{core-9d0cfec3.js → core-72f9f393.js} +4907 -4514
  9. package/dist/assets/core.js +1 -1
  10. package/dist/assets/{ol-0d0ebb27.js → ol-e468ba43.js} +23518 -22404
  11. package/dist/assets/ol.js +1 -1
  12. package/dist/assets/ui-73257b15.css +1 -0
  13. package/dist/assets/{ui-08446666.js → ui-73257b15.js} +13703 -12977
  14. package/dist/assets/ui.js +1 -1
  15. package/dist/assets/vue.js +1 -1
  16. package/dist/assets/{vuetify-67025c41.css → vuetify-2437380c.css} +2 -2
  17. package/dist/assets/{vuetify-67025c41.js → vuetify-2437380c.js} +8024 -7634
  18. package/dist/assets/vuetify.js +1 -1
  19. package/index.d.ts +40 -19
  20. package/index.js +36 -6
  21. package/lib/olLib.js +25 -3
  22. package/package.json +6 -6
  23. package/plugins/@vcmap-show-case/callback-tester/README.md +3 -0
  24. package/plugins/@vcmap-show-case/callback-tester/package.json +5 -0
  25. package/plugins/@vcmap-show-case/callback-tester/src/CallbackTester.vue +62 -0
  26. package/plugins/@vcmap-show-case/callback-tester/src/index.js +48 -0
  27. package/plugins/@vcmap-show-case/form-inputs-example/src/FormInputsExample.vue +1 -0
  28. package/src/actions/actionHelper.d.ts +1 -0
  29. package/src/actions/actionHelper.js +70 -19
  30. package/src/application/VcsApp.vue +83 -50
  31. package/src/application/VcsApp.vue.d.ts +28 -2
  32. package/src/application/VcsContainer.vue +5 -3
  33. package/src/application/VcsContainer.vue.d.ts +14 -0
  34. package/src/application/VcsNavbar.vue +10 -6
  35. package/src/application/VcsNavbar.vue.d.ts +2 -0
  36. package/src/application/VcsObliqueFooter.vue +9 -3
  37. package/src/application/VcsSplashScreen.vue +37 -0
  38. package/src/application/VcsSplashScreen.vue.d.ts +6 -0
  39. package/src/application/positionDisplayInteraction.js +1 -1
  40. package/src/callback/activateClippingPolygonCallback.d.ts +29 -0
  41. package/src/callback/activateClippingPolygonCallback.js +54 -0
  42. package/src/callback/closeSplashScreenCallback.d.ts +8 -0
  43. package/src/callback/closeSplashScreenCallback.js +33 -0
  44. package/src/callback/deactivateClippingPolygonCallback.d.ts +29 -0
  45. package/src/callback/deactivateClippingPolygonCallback.js +54 -0
  46. package/src/callback/openSplashScreenCallback.d.ts +8 -0
  47. package/src/callback/openSplashScreenCallback.js +35 -0
  48. package/src/callback/toggleNavbarButtonCallback.d.ts +36 -0
  49. package/src/callback/toggleNavbarButtonCallback.js +62 -0
  50. package/src/components/buttons/VcsActionButtonList.vue +6 -4
  51. package/src/components/buttons/VcsToolButton.vue +0 -1
  52. package/src/components/form-inputs-controls/VcsDatePicker.vue +7 -1
  53. package/src/components/form-inputs-controls/VcsDatePicker.vue.d.ts +9 -0
  54. package/src/components/form-inputs-controls/VcsSelect.vue +1 -1
  55. package/src/components/form-inputs-controls/VcsTextArea.vue +13 -8
  56. package/src/components/form-output/markdownHelper.d.ts +0 -25
  57. package/src/components/form-output/markdownHelper.js +1 -386
  58. package/src/components/import/VcsImportComponent.vue +2 -0
  59. package/src/components/lists/VcsGroupedList.vue +178 -0
  60. package/src/components/lists/VcsGroupedList.vue.d.ts +17 -0
  61. package/src/components/lists/VcsList.vue +144 -394
  62. package/src/components/lists/VcsList.vue.d.ts +38 -159
  63. package/src/components/lists/VcsTreeNode.vue +18 -11
  64. package/src/components/lists/VcsTreeview.vue +27 -20
  65. package/src/components/lists/VcsTreeview.vue.d.ts +18 -1
  66. package/src/components/lists/listHelper.d.ts +87 -0
  67. package/src/components/lists/listHelper.js +348 -0
  68. package/src/components/section/VcsFormSection.vue +7 -2
  69. package/src/components/section/VcsFormSection.vue.d.ts +9 -0
  70. package/src/components/tables/VcsDataTable.vue +14 -3
  71. package/src/components/tables/VcsDataTable.vue.d.ts +9 -0
  72. package/src/components/vector-properties/VcsVectorPropertiesComponent.vue.d.ts +1 -1
  73. package/src/contentTree/LayerTree.vue +2 -1
  74. package/src/contentTree/LayerTree.vue.d.ts +2 -0
  75. package/src/contentTree/contentTreeCollection.d.ts +1 -0
  76. package/src/contentTree/contentTreeCollection.js +7 -3
  77. package/src/contentTree/contentTreeItem.js +4 -2
  78. package/src/contentTree/groupContentTreeItem.js +5 -3
  79. package/src/featureInfo/ClusterFeatureComponent.vue +58 -0
  80. package/src/featureInfo/ClusterFeatureComponent.vue.d.ts +6 -0
  81. package/src/featureInfo/abstractFeatureInfoView.js +1 -2
  82. package/src/featureInfo/featureInfo.d.ts +87 -1
  83. package/src/featureInfo/featureInfo.js +342 -34
  84. package/src/featureInfo/featureInfoInteraction.js +18 -3
  85. package/src/featureInfo/iframeFeatureInfoView.js +1 -1
  86. package/src/featureInfo/markdownBalloonFeatureInfoView.js +2 -4
  87. package/src/featureInfo/markdownFeatureInfoView.js +1 -1
  88. package/src/i18n/de.d.ts +17 -4
  89. package/src/i18n/de.js +7 -0
  90. package/src/i18n/en.d.ts +17 -4
  91. package/src/i18n/en.js +7 -0
  92. package/src/legend/VcsLegend.vue +1 -1
  93. package/src/legend/legendHelper.d.ts +1 -1
  94. package/src/legend/legendHelper.js +52 -9
  95. package/src/localStorage.d.ts +21 -0
  96. package/src/localStorage.js +51 -0
  97. package/src/manager/collectionManager/CollectionComponent.vue +1 -1
  98. package/src/manager/collectionManager/CollectionComponentContent.vue +2 -3
  99. package/src/manager/collectionManager/CollectionComponentList.vue +2 -3
  100. package/src/manager/collectionManager/CollectionComponentStandalone.vue +1 -1
  101. package/src/manager/navbarManager.js +9 -4
  102. package/src/manager/toolbox/ToolboxManagerComponent.vue +14 -12
  103. package/src/manager/toolbox/ToolboxManagerComponent.vue.d.ts +13 -2
  104. package/src/manager/toolbox/toolboxManager.d.ts +5 -0
  105. package/src/manager/toolbox/toolboxManager.js +7 -1
  106. package/src/manager/window/WindowComponent.vue +10 -0
  107. package/src/manager/window/WindowComponent.vue.d.ts +1 -0
  108. package/src/manager/window/WindowManager.vue +14 -4
  109. package/src/manager/window/WindowManager.vue.d.ts +1 -0
  110. package/src/manager/window/windowHelper.d.ts +7 -3
  111. package/src/manager/window/windowHelper.js +30 -10
  112. package/src/navigation/MapNavigation.vue +5 -5
  113. package/src/navigation/MapNavigation.vue.d.ts +1 -1
  114. package/src/navigation/overviewMap.d.ts +7 -0
  115. package/src/navigation/overviewMap.js +18 -4
  116. package/src/pluginHelper.d.ts +7 -0
  117. package/src/pluginHelper.js +18 -4
  118. package/src/search/ResultItem.vue.d.ts +1 -1
  119. package/src/search/markText.d.ts +1 -1
  120. package/src/search/markText.js +4 -4
  121. package/src/search/search.js +1 -1
  122. package/src/state.d.ts +4 -2
  123. package/src/state.js +54 -31
  124. package/src/uiConfig.d.ts +36 -0
  125. package/src/uiConfig.js +17 -1
  126. package/src/vcsUiApp.js +7 -11
  127. package/dist/assets/ui-08446666.css +0 -1
  128. /package/dist/assets/{vue-2f81c7f8.js → vue-ff37ea23.js} +0 -0
@@ -16,6 +16,7 @@ declare const _default: import("vue").DefineComponent<{
16
16
  isDynamic: import("vue").ComputedRef<boolean>;
17
17
  isChild: import("vue").ComputedRef<boolean>;
18
18
  isDocked: import("vue").ComputedRef<boolean>;
19
+ isTabletWithOpenToolbar: import("vue").ComputedRef<any>;
19
20
  isDynamicLeft: import("vue").ComputedRef<boolean>;
20
21
  isDynamicRight: import("vue").ComputedRef<boolean>;
21
22
  isDraggable: import("vue").Ref<boolean>;
@@ -1,6 +1,8 @@
1
1
  <template>
2
2
  <div
3
- :class="{ 'win-container-mobile': addMobileClass }"
3
+ :class="{
4
+ 'win-container-mobile': addMobileClass,
5
+ }"
4
6
  class="window-manager"
5
7
  >
6
8
  <WindowComponent
@@ -126,13 +128,14 @@
126
128
  // do not clip balloons to target
127
129
  return windowComponent?.position;
128
130
  }
129
-
130
131
  return getPositionAppliedOnTarget(
131
132
  windowComponent?.position,
132
133
  targetSize.value,
133
134
  getPosition(parentComponent),
134
135
  );
135
136
  };
137
+ const display = useDisplay();
138
+
136
139
  /**
137
140
  * @param {string} id
138
141
  * @returns {import("vue").ComputedRef<Object>}
@@ -140,12 +143,14 @@
140
143
  const getStyles = (id) =>
141
144
  computed(() => {
142
145
  const windowComponent = windowManager.get(id);
146
+ const zIndexOffset = Number(display.sm.value); // add z-Index Offset for Tablet View to keep the windows above the detached Icon
143
147
  return {
144
- zIndex: windowComponent.zIndex.value,
148
+ zIndex: windowComponent.zIndex.value + zIndexOffset,
145
149
  ...getPosition(windowComponent),
146
150
  ...(windowComponent?.state?.styles || {}),
147
151
  };
148
152
  });
153
+
149
154
  /**
150
155
  * @param {string} id
151
156
  */
@@ -163,11 +168,15 @@
163
168
  const position = getPosition(windowComponent);
164
169
  moveWindow(id, translation, windowManager, targetSize.value, position);
165
170
  };
166
- const display = useDisplay();
171
+
167
172
  const addMobileClass = computed(() => {
168
173
  return display.xs.value && componentIds.length > 0;
169
174
  });
170
175
 
176
+ const addTabletClass = computed(() => {
177
+ return display.sm.value && componentIds.length > 0;
178
+ });
179
+
171
180
  const setTargetSize = () => {
172
181
  targetSize.value = getTargetSize(app.maps.target);
173
182
  };
@@ -199,6 +208,7 @@
199
208
  bringWindowToTop,
200
209
  move,
201
210
  addMobileClass,
211
+ addTabletClass,
202
212
  };
203
213
  },
204
214
  };
@@ -15,5 +15,6 @@ declare const _default: import("vue").DefineComponent<{}, {
15
15
  dy: number;
16
16
  }) => void;
17
17
  addMobileClass: import("vue").ComputedRef<boolean>;
18
+ addTabletClass: import("vue").ComputedRef<boolean>;
18
19
  }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{}>>, {}, {}>;
19
20
  export default _default;
@@ -10,9 +10,11 @@ export function getTargetSize(target: HTMLElement): DOMRect | null;
10
10
  * @param {number} y - client pixel position
11
11
  * @param {HTMLElement} target - the map's target { @link @import("@vcmap/core").MapCollection }
12
12
  * @param {WindowAlignment} [alignment=WindowAlignment.TOP_LEFT]
13
+ * @param {number} [offsetX=0]
14
+ * @param {number} [offsetY=0]
13
15
  * @returns {import("./windowManager.js").WindowPositionOptions}
14
16
  */
15
- export function getWindowPositionOptions(x: number, y: number, target: HTMLElement, alignment?: number | undefined): import("./windowManager.js").WindowPositionOptions;
17
+ export function getWindowPositionOptions(x: number, y: number, target: HTMLElement, alignment?: number | undefined, offsetX?: number | undefined, offsetY?: number | undefined): import("./windowManager.js").WindowPositionOptions;
16
18
  /**
17
19
  * Get window position options based on a pixel in the map
18
20
  * @param {import("@vcmap-cesium/engine").Cartesian2} windowPosition - the window position, as retrieved from an InteractionEvent
@@ -28,10 +30,12 @@ export function getWindowPositionOptionsFromMapEvent(windowPosition: import("@vc
28
30
  * @param {number} y - client pixel position
29
31
  * @param {number} width - window width to fit
30
32
  * @param {number} height - window height to fit
31
- * @param {HTMLElement} target - the map's target { @link @import("@vcmap/core").MapCollection }
33
+ * @param {HTMLElement} target - the map's target { @link @import("@vcmap/core").MapCollection }
34
+ * @param {number} [offsetX=0]
35
+ * @param {number} [offsetY=0]
32
36
  * @returns {import("./windowManager.js").WindowPositionOptions}
33
37
  */
34
- export function getFittedWindowPositionOptions(x: number, y: number, width: number, height: number, target: HTMLElement): import("./windowManager.js").WindowPositionOptions;
38
+ export function getFittedWindowPositionOptions(x: number, y: number, width: number, height: number, target: HTMLElement, offsetX?: number | undefined, offsetY?: number | undefined): import("./windowManager.js").WindowPositionOptions;
35
39
  /**
36
40
  * Fits a window aligned top left, so it fits into currently active map. This will change the alignment to be bottom or right depending
37
41
  * on if the window would not fit into active map element.
@@ -49,6 +49,8 @@ export function getTargetSize(target) {
49
49
  * @param {number} y - client pixel position
50
50
  * @param {HTMLElement} target - the map's target { @link @import("@vcmap/core").MapCollection }
51
51
  * @param {WindowAlignment} [alignment=WindowAlignment.TOP_LEFT]
52
+ * @param {number} [offsetX=0]
53
+ * @param {number} [offsetY=0]
52
54
  * @returns {import("./windowManager.js").WindowPositionOptions}
53
55
  */
54
56
  export function getWindowPositionOptions(
@@ -56,6 +58,8 @@ export function getWindowPositionOptions(
56
58
  y,
57
59
  target,
58
60
  alignment = WindowAlignment.TOP_LEFT,
61
+ offsetX = 0,
62
+ offsetY = 0,
59
63
  ) {
60
64
  const targetSize = getTargetSize(target);
61
65
  if (!targetSize) {
@@ -64,13 +68,19 @@ export function getWindowPositionOptions(
64
68
 
65
69
  const { left, top, width, height } = targetSize;
66
70
  if (alignment === WindowAlignment.TOP_LEFT) {
67
- return { left: x - left, top: y - top };
71
+ return { left: x - left + offsetX, top: y - top - offsetY };
68
72
  } else if (alignment === WindowAlignment.TOP_RIGHT) {
69
- return { right: left + width - x, top: y - top };
73
+ return { right: left + width - x + offsetX, top: y - top - offsetY };
70
74
  } else if (alignment === WindowAlignment.BOTTOM_LEFT) {
71
- return { left: x - left, bottom: height + top - y };
75
+ return {
76
+ left: x - left + offsetX,
77
+ bottom: height + top - y - offsetY,
78
+ };
72
79
  }
73
- return { right: left + width - x, bottom: height + top - y };
80
+ return {
81
+ right: left + width - x + offsetX,
82
+ bottom: height + top - y - offsetY,
83
+ };
74
84
  }
75
85
 
76
86
  /**
@@ -106,18 +116,28 @@ export function getWindowPositionOptionsFromMapEvent(
106
116
  * @param {number} y - client pixel position
107
117
  * @param {number} width - window width to fit
108
118
  * @param {number} height - window height to fit
109
- * @param {HTMLElement} target - the map's target { @link @import("@vcmap/core").MapCollection }
119
+ * @param {HTMLElement} target - the map's target { @link @import("@vcmap/core").MapCollection }
120
+ * @param {number} [offsetX=0]
121
+ * @param {number} [offsetY=0]
110
122
  * @returns {import("./windowManager.js").WindowPositionOptions}
111
123
  */
112
- export function getFittedWindowPositionOptions(x, y, width, height, target) {
124
+ export function getFittedWindowPositionOptions(
125
+ x,
126
+ y,
127
+ width,
128
+ height,
129
+ target,
130
+ offsetX = 0,
131
+ offsetY = 0,
132
+ ) {
113
133
  const targetSize = getTargetSize(target);
114
134
  if (!targetSize) {
115
135
  return { left: x, top: y };
116
136
  }
117
137
 
118
- const { width: parentWidth, height: parentHeight } = targetSize;
119
- const bottom = y + height > parentHeight;
120
- const right = x + width > parentWidth;
138
+ const { left, top, width: parentWidth, height: parentHeight } = targetSize;
139
+ const bottom = y - top + height > parentHeight && y - top > parentHeight / 2;
140
+ const right = x - left + width > parentWidth && x - left > parentWidth / 2;
121
141
  let alignment = WindowAlignment.TOP_LEFT;
122
142
  if (bottom) {
123
143
  if (right) {
@@ -128,7 +148,7 @@ export function getFittedWindowPositionOptions(x, y, width, height, target) {
128
148
  } else if (right) {
129
149
  alignment = WindowAlignment.TOP_RIGHT;
130
150
  }
131
- return getWindowPositionOptions(x, y, target, alignment);
151
+ return getWindowPositionOptions(x, y, target, alignment, offsetX, offsetY);
132
152
  }
133
153
 
134
154
  /**
@@ -25,7 +25,7 @@
25
25
  ></OrientationToolsButton>
26
26
  </v-row>
27
27
  </template>
28
- <template v-if="mdAndUp">
28
+ <template v-if="smAndUp">
29
29
  <v-row justify="center">
30
30
  <VcsZoomButton
31
31
  @zoom-out="zoomOut()"
@@ -33,7 +33,7 @@
33
33
  :disabled="movementApiCallsDisabled"
34
34
  />
35
35
  </v-row>
36
- <v-row justify="center" v-if="is3D && mdAndUp">
36
+ <v-row justify="center" v-if="is3D && smAndUp">
37
37
  <TiltSlider v-model="tilt" :disabled="movementApiCallsDisabled" />
38
38
  </v-row>
39
39
  <v-row v-if="!hideRotationButton && is3D" justify="center">
@@ -187,7 +187,7 @@
187
187
  return {
188
188
  action,
189
189
  destroy: () => {
190
- stopRotation();
190
+ stopRotation?.();
191
191
  rotationListener();
192
192
  },
193
193
  };
@@ -401,11 +401,11 @@
401
401
  removeMovementDisabledListener();
402
402
  });
403
403
 
404
- const { xs, mdAndUp, mobile } = useDisplay();
404
+ const { xs, mobile, smAndUp } = useDisplay();
405
405
 
406
406
  return {
407
407
  xs,
408
- mdAndUp,
408
+ smAndUp,
409
409
  mobile,
410
410
  viewMode,
411
411
  heading,
@@ -1,6 +1,6 @@
1
1
  declare const _default: import("vue").DefineComponent<{}, {
2
2
  xs: import("vue").Ref<boolean>;
3
- mdAndUp: import("vue").Ref<boolean>;
3
+ smAndUp: import("vue").Ref<boolean>;
4
4
  mobile: import("vue").ComputedRef<boolean>;
5
5
  viewMode: import("vue").Ref<string>;
6
6
  heading: import("vue").WritableComputedRef<number>;
@@ -2,6 +2,7 @@
2
2
  * @returns {import("../manager/window/windowManager.js").WindowComponentOptions}
3
3
  */
4
4
  export function getWindowComponentOptions(): import("../manager/window/windowManager.js").WindowComponentOptions;
5
+ export const overviewMapWindowId: "overview-map-container";
5
6
  export const overviewMapLayerSymbol: unique symbol;
6
7
  export default OverviewMap;
7
8
  /**
@@ -53,6 +54,12 @@ declare class OverviewMap {
53
54
  * @type {VectorStyleItem}
54
55
  */
55
56
  obliqueSelectedStyle: VectorStyleItem;
57
+ /**
58
+ * A factor by which to multiply the distance of the viewpoint of the overviewMap.
59
+ * @type {number}
60
+ * @private
61
+ */
62
+ private _scaleFactor;
56
63
  /**
57
64
  * A factor by witch to multiply the resolution when zooming to a single oblique image.
58
65
  * @type {number}
@@ -30,6 +30,7 @@ import {
30
30
  import { vcsAppSymbol } from '../pluginHelper.js';
31
31
  import VcsMap from '../application/VcsMap.vue';
32
32
 
33
+ export const overviewMapWindowId = 'overview-map-container';
33
34
  export const overviewMapLayerSymbol = Symbol('overviewMapLayerSymbol');
34
35
 
35
36
  /**
@@ -40,7 +41,7 @@ export function getWindowComponentOptions() {
40
41
  component: VcsMap,
41
42
  props: { mapId: 'overview-map-container' },
42
43
  slot: WindowSlot.DETACHED,
43
- id: 'overview-map-container',
44
+ id: overviewMapWindowId,
44
45
  state: {
45
46
  hideHeader: true,
46
47
  classes: ['overview-map'],
@@ -157,6 +158,13 @@ class OverviewMap {
157
158
  },
158
159
  });
159
160
 
161
+ /**
162
+ * A factor by which to multiply the distance of the viewpoint of the overviewMap.
163
+ * @type {number}
164
+ * @private
165
+ */
166
+ this._scaleFactor = 1;
167
+
160
168
  /**
161
169
  * A factor by witch to multiply the resolution when zooming to a single oblique image.
162
170
  * @type {number}
@@ -262,13 +270,17 @@ class OverviewMap {
262
270
  () => [
263
271
  this._app.uiConfig.config.hideMapNavigation,
264
272
  this._app.uiConfig.config.overviewMapActiveOnStartup,
273
+ this._app.uiConfig.config.overviewMapScaleFactor,
265
274
  ],
266
- async ([hide, activeOnStartup]) => {
275
+ async ([hide, activeOnStartup, scaleFactor]) => {
267
276
  if (activeOnStartup && !hide && !this._active) {
268
277
  await this.activate();
269
278
  } else if (hide && this._active) {
270
279
  await this.deactivate();
271
280
  }
281
+ if (scaleFactor) {
282
+ this._scaleFactor = scaleFactor;
283
+ }
272
284
  },
273
285
  );
274
286
  }
@@ -350,7 +362,7 @@ class OverviewMap {
350
362
  * @returns {Promise<void>}
351
363
  */
352
364
  async activate() {
353
- if (!this._app.windowManager.has('overview-map-container')) {
365
+ if (!this._app.windowManager.has(overviewMapWindowId)) {
354
366
  this._app.windowManager.add(getWindowComponentOptions(), vcsAppSymbol);
355
367
  }
356
368
  await this._activate();
@@ -360,7 +372,7 @@ class OverviewMap {
360
372
  * closes window and clears all listeners
361
373
  */
362
374
  deactivate() {
363
- this._app.windowManager.remove('overview-map-container');
375
+ this._app.windowManager.remove(overviewMapWindowId);
364
376
  this._clearListeners();
365
377
  if (this._mapActivatedListener) {
366
378
  this._mapActivatedListener();
@@ -482,6 +494,7 @@ class OverviewMap {
482
494
 
483
495
  const vp = Viewpoint.createViewpointFromExtent(extent);
484
496
  vp.distance /= this._obliqueResolutionFactor;
497
+ vp.distance *= this._scaleFactor;
485
498
  this._map.gotoViewpoint(vp);
486
499
  }
487
500
  }
@@ -632,6 +645,7 @@ class OverviewMap {
632
645
  viewpoint.groundPosition = null;
633
646
  viewpoint.distance = distance * 4;
634
647
  }
648
+ viewpoint.distance *= this._scaleFactor;
635
649
  this._map.gotoViewpoint(viewpoint);
636
650
  }
637
651
 
@@ -15,6 +15,13 @@ export function getPluginAssetUrl(app: import("@src/vcsUiApp.js").default, plugi
15
15
  * @returns {boolean}
16
16
  */
17
17
  export function isValidPackageName(name: string): boolean;
18
+ /**
19
+ * joins pathname and moduleUrl.
20
+ * @param {string} pathname will remove filenames with extension or add a trailing slash if missing
21
+ * @param {string} module relative url to the module
22
+ * @returns {string}
23
+ */
24
+ export function getModuleUrl(pathname: string, module: string): string;
18
25
  /**
19
26
  * @param {string} name
20
27
  * @param {T} config
@@ -82,6 +82,23 @@ export function isValidPackageName(name) {
82
82
  );
83
83
  }
84
84
 
85
+ /**
86
+ * joins pathname and moduleUrl.
87
+ * @param {string} pathname will remove filenames with extension or add a trailing slash if missing
88
+ * @param {string} module relative url to the module
89
+ * @returns {string}
90
+ */
91
+ export function getModuleUrl(pathname, module) {
92
+ const pathNameParts = pathname.split('/');
93
+ if (pathNameParts.at(-1).includes('.')) {
94
+ pathNameParts.pop();
95
+ } else if (pathNameParts.at(-1) === '') {
96
+ pathNameParts.pop();
97
+ }
98
+ const pathName = pathNameParts.join('/');
99
+ return `${pathName}/${module}`;
100
+ }
101
+
85
102
  /**
86
103
  * @param {string} name
87
104
  * @param {T} config
@@ -93,10 +110,7 @@ export async function loadPlugin(name, config) {
93
110
  let module = config.entry;
94
111
 
95
112
  if (!/^(https?:\/\/|\/)/.test(module)) {
96
- module = `${window.location.origin}${window.location.pathname.replace(
97
- /\/?$/,
98
- '/',
99
- )}${module}`;
113
+ module = `${window.location.origin}${getModuleUrl(window.location.pathname, module)}`;
100
114
  } else if (module === '_dev') {
101
115
  module = `/${name}.js`;
102
116
  } else if (module === 'http://localhost/_test') {
@@ -9,7 +9,7 @@ declare const _default: import("vue").DefineComponent<{
9
9
  };
10
10
  }, {
11
11
  hasActions: import("vue").ComputedRef<boolean>;
12
- marked: import("vue").ComputedRef<any>;
12
+ marked: import("vue").ComputedRef<string>;
13
13
  }, any, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
14
14
  query: {
15
15
  type: StringConstructor;
@@ -4,7 +4,7 @@
4
4
  * @returns {string}
5
5
  */
6
6
  export function markText(text: string, query: string): string;
7
- export type Block = {
7
+ export type BlockIndices = {
8
8
  start: number;
9
9
  end: number;
10
10
  };
@@ -1,12 +1,12 @@
1
1
  /**
2
- * @typedef {Object} Block
2
+ * @typedef {Object} BlockIndices
3
3
  * @property {number} start
4
4
  * @property {number} end
5
5
  */
6
6
 
7
7
  /**
8
- * @param {Block[]} blocks
9
- * @param {Block} candidate
8
+ * @param {BlockIndices[]} blocks
9
+ * @param {BlockIndices} candidate
10
10
  * @returns {boolean}
11
11
  */
12
12
  function isBlockWithinBlocks(blocks, candidate) {
@@ -18,7 +18,7 @@ function isBlockWithinBlocks(blocks, candidate) {
18
18
  /**
19
19
  * @param {string} text
20
20
  * @param {RegExp} partial
21
- * @param {Block[]} blocks
21
+ * @param {BlockIndices[]} blocks
22
22
  */
23
23
  function addPartialBlocks(text, partial, blocks) {
24
24
  let match;
@@ -318,7 +318,7 @@ class Search extends IndexedCollection {
318
318
  this._app.featureInfo.selectedFeature?.[vcsLayerName] ===
319
319
  this._resultLayer.name
320
320
  ) {
321
- this._app.featureInfo.clear();
321
+ this._app.featureInfo.clearSelection();
322
322
  }
323
323
  }
324
324
 
package/src/state.d.ts CHANGED
@@ -4,14 +4,16 @@
4
4
  export function createEmptyState(): AppState;
5
5
  /**
6
6
  * @param {UrlViewpointState} state
7
+ * @param {string} moduleId
7
8
  * @returns {import("@vcmap/core").ViewpointOptions|null}
8
9
  */
9
- export function parseUrlProjectedViewpointState(state: UrlViewpointState): import("@vcmap/core").ViewpointOptions | null;
10
+ export function parseUrlProjectedViewpointState(state: UrlViewpointState, moduleId: string): import("@vcmap/core").ViewpointOptions | null;
10
11
  /**
11
12
  * @param {UrlExtentState} state
13
+ * @param {string} moduleId
12
14
  * @returns {import("@vcmap/core").ViewpointOptions|null}
13
15
  */
14
- export function parseUrlExtentState(state: UrlExtentState): import("@vcmap/core").ViewpointOptions | null;
16
+ export function parseUrlExtentState(state: UrlExtentState, moduleId: string): import("@vcmap/core").ViewpointOptions | null;
15
17
  /**
16
18
  * @param {(URL)=} url
17
19
  * @returns {AppState}
package/src/state.js CHANGED
@@ -61,7 +61,7 @@ import {
61
61
 
62
62
  /**
63
63
  * @typedef {AppState} CachedAppState
64
- * @property {() => import("@vcmap/core").Viewpoint?} [getViewpoint]
64
+ * @property {(string) => import("@vcmap/core").Viewpoint?} [getViewpoint]
65
65
  */
66
66
 
67
67
  /**
@@ -104,66 +104,87 @@ function parseUrlViewpointState(state) {
104
104
  roll: state[5],
105
105
  });
106
106
 
107
- return vp.isValid() ? vp.toJSON() : null;
107
+ if (vp.isValid()) {
108
+ return vp.toJSON();
109
+ } else {
110
+ getLogger('StateManagement').warning(
111
+ 'The provided viewpoint options are not valid. Viewpoint will be ignored.',
112
+ );
113
+ return null;
114
+ }
108
115
  }
109
116
 
110
117
  /**
111
118
  * @param {UrlViewpointState} state
119
+ * @param {string} moduleId
112
120
  * @returns {import("@vcmap/core").ViewpointOptions|null}
113
121
  */
114
- export function parseUrlProjectedViewpointState(state) {
122
+ export function parseUrlProjectedViewpointState(state, moduleId) {
115
123
  const projection = getDefaultProjection();
116
124
  const projectionCode = parseInt(projection.epsg.split(':')[1], 10);
117
125
 
118
- let cameraPosition = state[0];
119
- let groundPosition = state[1];
120
- if (state[6] && state[6] === projectionCode) {
121
- if (cameraPosition) {
126
+ if (state[6] === projectionCode) {
127
+ let cameraPosition;
128
+ let groundPosition;
129
+ if (state[0]) {
122
130
  // (cameraPosition instanceof Coordinate)
123
131
  cameraPosition = Projection.transform(
124
132
  wgs84Projection,
125
133
  projection,
126
- cameraPosition,
134
+ state[0],
127
135
  );
128
136
  }
129
- if (groundPosition) {
137
+ if (state[1]) {
130
138
  groundPosition = Projection.transform(
131
139
  wgs84Projection,
132
140
  projection,
133
- groundPosition,
141
+ state[1],
134
142
  );
135
143
  }
144
+ return parseUrlViewpointState([
145
+ cameraPosition,
146
+ groundPosition,
147
+ ...state.slice(2),
148
+ ]);
149
+ } else {
150
+ getLogger('StateManagement').warning(
151
+ `The provided viewpoint epsg code (${state[6]}) does not equal epsg code (${projectionCode}) of module '${moduleId}' and therefore can not be handled. Camera and ground position will be ignored.`,
152
+ );
153
+ return null;
136
154
  }
137
-
138
- const vp = new Viewpoint({
139
- cameraPosition: cameraPosition ?? undefined,
140
- groundPosition: groundPosition ?? undefined,
141
- distance: state[2] > 0 ? state[2] : undefined,
142
- heading: state[3],
143
- pitch: state[4],
144
- roll: state[5],
145
- });
146
- vp.animate = false;
147
- return vp.isValid() ? vp.toJSON() : null;
148
155
  }
149
156
 
150
157
  /**
151
158
  * @param {UrlExtentState} state
159
+ * @param {string} moduleId
152
160
  * @returns {import("@vcmap/core").ViewpointOptions|null}
153
161
  */
154
- export function parseUrlExtentState(state) {
162
+ export function parseUrlExtentState(state, moduleId) {
155
163
  const projection = getDefaultProjection();
156
164
  const projectionCode = parseInt(projection.epsg.split(':')[1], 10);
157
165
  const extentOptions = { coordinates: state[0] };
158
- if (projectionCode === state[1]) {
166
+ if (!state[1]) {
167
+ extentOptions.projection = wgs84Projection;
168
+ } else if (state[1] && state[1] === projectionCode) {
159
169
  extentOptions.projection = projection;
160
170
  } else {
161
- extentOptions.projection = wgs84Projection;
171
+ getLogger('StateManagement').warning(
172
+ `The provided extent epsg code (${state[6]}) does not equal epsg code (${projectionCode}) of module '${moduleId}' and therefore can not be handled. The provided extent will be ignored.`,
173
+ );
174
+ return null;
162
175
  }
163
176
  const extent = new Extent(extentOptions);
164
- const vp = Viewpoint.createViewpointFromExtent(extent);
165
- vp.animate = false;
166
- return vp.isValid() ? vp.toJSON() : null;
177
+
178
+ if (extent.isValid()) {
179
+ const vp = Viewpoint.createViewpointFromExtent(extent);
180
+ vp.animate = false;
181
+ return vp.toJSON();
182
+ } else {
183
+ getLogger('StateManagement').warning(
184
+ 'The provided extent options are not valid. Extent will be ignored.',
185
+ );
186
+ return null;
187
+ }
167
188
  }
168
189
 
169
190
  /**
@@ -215,10 +236,12 @@ function writeUrlPluginState(state) {
215
236
  function parseUrlAppState(urlState) {
216
237
  const state = createEmptyState();
217
238
  if (Array.isArray(urlState[0])) {
218
- if (urlState[0][0].length === 4) {
219
- state.getViewpoint = () => parseUrlExtentState(urlState[0]);
220
- } else if (urlState[0].length === 7) {
221
- state.getViewpoint = () => parseUrlProjectedViewpointState(urlState[0]);
239
+ if (Array.isArray(urlState[0][0]) && urlState[0][0].length === 4) {
240
+ state.getViewpoint = (moduleId) =>
241
+ parseUrlExtentState(urlState[0], moduleId);
242
+ } else if (urlState[0][6]) {
243
+ state.getViewpoint = (moduleId) =>
244
+ parseUrlProjectedViewpointState(urlState[0], moduleId);
222
245
  } else {
223
246
  state.activeViewpoint = parseUrlViewpointState(urlState[0]);
224
247
  }