@vcmap/ui 6.0.0-rc.9 → 6.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (160) hide show
  1. package/README.md +2 -0
  2. package/build/commonViteConfig.js +7 -0
  3. package/config/aerowest.config.json +12 -2
  4. package/config/analysis.config.json +17 -0
  5. package/config/base.config.json +16 -4
  6. package/config/components-show-case.config.json +53 -0
  7. package/config/concepts-show-case.config.json +39 -0
  8. package/config/dev.config.json +165 -104
  9. package/config/dynamic-layer.config.json +32 -0
  10. package/config/hello-world.config.json +11 -0
  11. package/config/projects.config.json +9 -1
  12. package/config/solar.config.json +65 -0
  13. package/config/vectorTile.config.json +70 -0
  14. package/config/www.config.json +33 -10
  15. package/dist/assets/cesium.js +1 -1
  16. package/dist/assets/{core-ccecb5f4.js → core-a599e8b6.js} +7302 -6838
  17. package/dist/assets/core.js +1 -1
  18. package/dist/assets/{ol-3c6b9b5b.js → ol-21bbc740.js} +5057 -5178
  19. package/dist/assets/ol.js +1 -1
  20. package/dist/assets/ui-adeddc7d.css +1 -0
  21. package/dist/assets/{ui-8a8aef2a.js → ui-adeddc7d.js} +9687 -8940
  22. package/dist/assets/ui.js +1 -1
  23. package/dist/assets/vue.js +1 -1
  24. package/dist/assets/{vuetify-ac50bfc8.js → vuetify-c0e02f11.js} +2507 -2504
  25. package/dist/assets/vuetify.js +1 -1
  26. package/index.d.ts +2 -0
  27. package/index.js +1 -0
  28. package/package.json +12 -12
  29. package/plugins/@vcmap-show-case/README.md +15 -6
  30. package/plugins/@vcmap-show-case/category-tester/package.json +1 -1
  31. package/plugins/@vcmap-show-case/category-tester/src/CollectionComponentOptions.vue +23 -23
  32. package/plugins/@vcmap-show-case/category-tester/src/FoobarEditor.vue +2 -8
  33. package/plugins/@vcmap-show-case/collection-manager-example/package.json +1 -1
  34. package/plugins/@vcmap-show-case/collection-manager-example/src/CollectionManagerExample.vue +10 -8
  35. package/plugins/@vcmap-show-case/context-menu-tester/package.json +1 -1
  36. package/plugins/@vcmap-show-case/extent-example/package.json +1 -1
  37. package/plugins/@vcmap-show-case/flight-component-example/package.json +1 -1
  38. package/plugins/@vcmap-show-case/form-inputs-example/package.json +1 -1
  39. package/plugins/@vcmap-show-case/hello-world/package.json +1 -1
  40. package/plugins/@vcmap-show-case/icons-example/package.json +1 -1
  41. package/plugins/@vcmap-show-case/notifier-tester/package.json +1 -1
  42. package/plugins/@vcmap-show-case/panel-tester/package.json +1 -1
  43. package/plugins/@vcmap-show-case/plugin-editors/package.json +1 -1
  44. package/plugins/@vcmap-show-case/plugin-editors/src/index.js +17 -6
  45. package/plugins/@vcmap-show-case/project-selector/package.json +1 -9
  46. package/plugins/@vcmap-show-case/project-selector/src/ModulesListComponent.vue +22 -31
  47. package/plugins/@vcmap-show-case/project-selector/src/ProjectSelectorComponent.vue +15 -23
  48. package/plugins/@vcmap-show-case/projection-example/README.md +3 -0
  49. package/plugins/@vcmap-show-case/projection-example/package.json +5 -0
  50. package/plugins/@vcmap-show-case/projection-example/src/ProjectionExample.vue +73 -0
  51. package/plugins/@vcmap-show-case/{table-example → projection-example}/src/index.js +22 -11
  52. package/plugins/@vcmap-show-case/search-example/package.json +1 -1
  53. package/plugins/@vcmap-show-case/simple-graph/package.json +1 -4
  54. package/plugins/@vcmap-show-case/style-input-example/package.json +1 -1
  55. package/plugins/@vcmap-show-case/switch-map-callback-example/README.md +2 -2
  56. package/plugins/@vcmap-show-case/switch-map-callback-example/package.json +2 -1
  57. package/plugins/@vcmap-show-case/switch-map-callback-example/src/index.js +4 -1
  58. package/plugins/@vcmap-show-case/theming-example/package.json +1 -1
  59. package/plugins/@vcmap-show-case/toolbox-example/package.json +1 -1
  60. package/plugins/@vcmap-show-case/vector-properties-example/package.json +1 -1
  61. package/plugins/@vcmap-show-case/viewpoint-component-example/package.json +1 -1
  62. package/plugins/@vcmap-show-case/window-tester/package.json +1 -1
  63. package/plugins/@vcmap-show-case/window-tester/src/WindowExample.vue +1 -1
  64. package/plugins/@vcmap-show-case/window-tester/src/WindowExampleToggleChild.vue +5 -1
  65. package/plugins/@vcmap-show-case/wizard-example/package.json +1 -1
  66. package/plugins/package.json +7 -3
  67. package/src/actions/flightActions.js +40 -20
  68. package/src/actions/listActions.d.ts +1 -1
  69. package/src/actions/listActions.js +1 -1
  70. package/src/application/VcsApp.vue +3 -0
  71. package/src/application/VcsApp.vue.d.ts +12 -0
  72. package/src/application/VcsAttributions.vue +1 -1
  73. package/src/application/VcsAttributionsFooter.vue +1 -1
  74. package/src/application/VcsContainer.vue +0 -1
  75. package/src/application/VcsContainer.vue.d.ts +12 -0
  76. package/src/application/VcsObliqueFooter.vue +110 -0
  77. package/src/application/VcsObliqueFooter.vue.d.ts +4 -0
  78. package/src/application/VcsTextPageFooter.vue +1 -0
  79. package/src/application/attributionsHelper.js +10 -6
  80. package/src/components/flight/VcsFlightPlayer.vue +26 -20
  81. package/src/components/form-inputs-controls/VcsDatePicker.vue +23 -3
  82. package/src/components/form-inputs-controls/VcsDatePicker.vue.d.ts +1 -1
  83. package/src/components/form-inputs-controls/VcsFileInput.vue +1 -1
  84. package/src/components/form-inputs-controls/VcsLabel.vue +10 -1
  85. package/src/components/form-inputs-controls/VcsLabel.vue.d.ts +9 -0
  86. package/src/components/form-inputs-controls/VcsRadio.vue +4 -0
  87. package/src/components/form-inputs-controls/VcsSelect.vue.d.ts +2 -2
  88. package/src/components/form-inputs-controls/VcsTextField.vue +1 -1
  89. package/src/components/form-inputs-controls/VcsWizardStep.vue.d.ts +2 -2
  90. package/src/components/import/VcsImportComponent.vue +3 -3
  91. package/src/components/lists/VcsActionList.vue +1 -1
  92. package/src/components/lists/VcsList.vue +42 -29
  93. package/src/components/lists/VcsListItemComponent.vue +1 -1
  94. package/src/components/lists/VcsListItemComponent.vue.d.ts +5 -32
  95. package/src/components/lists/VcsTreeview.vue +2 -0
  96. package/src/components/notification/VcsHelp.vue +0 -1
  97. package/src/components/notification/VcsHelpTooltip.vue +48 -0
  98. package/src/components/notification/VcsHelpTooltip.vue.d.ts +25 -0
  99. package/src/components/projection/VcsProjection.vue +329 -0
  100. package/src/components/projection/VcsProjection.vue.d.ts +7 -0
  101. package/src/components/section/VcsFormSection.vue +0 -1
  102. package/src/components/section/VcsFormSection.vue.d.ts +1 -1
  103. package/src/components/tables/VcsDataTable.vue +13 -2
  104. package/src/components/tables/VcsDataTable.vue.d.ts +12 -1
  105. package/src/components/vector-properties/VcsFeatureEditingWindow.vue +17 -1
  106. package/src/components/vector-properties/VcsFeatureEditingWindow.vue.d.ts +10 -1
  107. package/src/components/vector-properties/VcsFeatureTransforms.vue +39 -5
  108. package/src/components/vector-properties/VcsFeatureTransforms.vue.d.ts +2 -1
  109. package/src/components/vector-properties/VcsVectorPropertiesComponent.vue +44 -24
  110. package/src/components/vector-properties/VcsVectorPropertiesComponent.vue.d.ts +27 -2
  111. package/src/components/viewpoint/VcsViewpointComponent.vue +6 -6
  112. package/src/contentTree/contentTreeCollection.js +12 -1
  113. package/src/featureInfo/abstractFeatureInfoView.d.ts +9 -0
  114. package/src/featureInfo/abstractFeatureInfoView.js +17 -1
  115. package/src/i18n/de.d.ts +90 -41
  116. package/src/i18n/de.js +63 -22
  117. package/src/i18n/en.d.ts +90 -41
  118. package/src/i18n/en.js +59 -18
  119. package/src/legend/StyleLegendItem.vue +1 -5
  120. package/src/legend/VcsLegend.vue +9 -10
  121. package/src/legend/VcsLegend.vue.d.ts +1 -1
  122. package/src/legend/legendHelper.js +6 -1
  123. package/src/manager/collectionManager/collectionComponentClass.js +4 -4
  124. package/src/manager/collectionManager/editorCollectionComponentClass.js +5 -3
  125. package/src/manager/toolbox/GroupToolboxComponent.vue +6 -1
  126. package/src/manager/toolbox/SelectToolboxComponent.vue +6 -2
  127. package/src/manager/toolbox/ToolboxManagerComponent.vue +7 -2
  128. package/src/manager/window/WindowComponentHeader.vue +1 -1
  129. package/src/navigation/MapNavCompass.vue +166 -140
  130. package/src/navigation/MapNavCompass.vue.d.ts +3 -1
  131. package/src/navigation/MapNavigation.vue +22 -5
  132. package/src/navigation/VcsCompass.vue +2 -1
  133. package/src/navigation/overviewMap.js +4 -1
  134. package/src/styles/main.scss +2 -2
  135. package/src/uiConfig.d.ts +27 -0
  136. package/src/uiConfig.js +3 -0
  137. package/src/vuePlugins/vuetify.js +2 -0
  138. package/dist/assets/ui-8a8aef2a.css +0 -1
  139. package/plugins/@vcmap-show-case/buttons-example/README.md +0 -4
  140. package/plugins/@vcmap-show-case/buttons-example/package.json +0 -5
  141. package/plugins/@vcmap-show-case/buttons-example/src/ButtonsExample.vue +0 -281
  142. package/plugins/@vcmap-show-case/buttons-example/src/index.js +0 -51
  143. package/plugins/@vcmap-show-case/config-editor/README.md +0 -3
  144. package/plugins/@vcmap-show-case/config-editor/package.json +0 -5
  145. package/plugins/@vcmap-show-case/config-editor/src/ConfigEditor.vue +0 -62
  146. package/plugins/@vcmap-show-case/config-editor/src/index.js +0 -49
  147. package/plugins/@vcmap-show-case/list-example/README.md +0 -3
  148. package/plugins/@vcmap-show-case/list-example/package.json +0 -5
  149. package/plugins/@vcmap-show-case/list-example/src/ListExample.vue +0 -406
  150. package/plugins/@vcmap-show-case/list-example/src/index.js +0 -46
  151. package/plugins/@vcmap-show-case/table-example/README.md +0 -3
  152. package/plugins/@vcmap-show-case/table-example/package.json +0 -5
  153. package/plugins/@vcmap-show-case/table-example/src/DataTableExample.vue +0 -203
  154. package/plugins/@vcmap-show-case/textfields-example/README.md +0 -3
  155. package/plugins/@vcmap-show-case/textfields-example/package.json +0 -5
  156. package/plugins/@vcmap-show-case/textfields-example/src/TextfieldsExample.vue +0 -115
  157. package/plugins/@vcmap-show-case/textfields-example/src/index.js +0 -64
  158. /package/dist/assets/{cesium-a21a380a.js → cesium-00deba88.js} +0 -0
  159. /package/dist/assets/{vue-bcc58dd1.js → vue-8269279d.js} +0 -0
  160. /package/dist/assets/{vuetify-ac50bfc8.css → vuetify-c0e02f11.css} +0 -0
@@ -0,0 +1,329 @@
1
+ <script setup>
2
+ import { computed, inject, ref, toRaw, useAttrs, watch } from 'vue';
3
+ import { VRow, VCol, VContainer } from 'vuetify/components';
4
+ import { Projection } from '@vcmap/core';
5
+ import deepEqual from 'fast-deep-equal';
6
+ import { getLogger } from '@vcsuite/logger';
7
+ import VcsCheckbox from '../form-inputs-controls/VcsCheckbox.vue';
8
+ import VcsButton from '../buttons/VcsButton.vue';
9
+ import VcsTextField from '../form-inputs-controls/VcsTextField.vue';
10
+ import VcsChipArrayInput from '../form-inputs-controls/VcsChipArrayInput.vue';
11
+ import VcsLabel from '../form-inputs-controls/VcsLabel.vue';
12
+ import { NotificationType } from '../../notifier/notifier.js';
13
+ import { useComponentId, usePadding } from '../composables.js';
14
+
15
+ const epsgRegex = /^([a-zA-Z]+:)*(\d{4,6})$/i;
16
+
17
+ function parseEPSGCode(epsg) {
18
+ if (!epsg) {
19
+ return {};
20
+ }
21
+
22
+ const match = epsg.match(epsgRegex);
23
+ if (!match) {
24
+ return {};
25
+ }
26
+
27
+ let prefix = match[1] ? match[1].toUpperCase().replace(/:$/, '') : null;
28
+ const code = match[2];
29
+
30
+ if (prefix === 'EPSG') {
31
+ prefix = null;
32
+ }
33
+ return { prefix, code };
34
+ }
35
+
36
+ /**
37
+ * @param {string|number} epsgCode
38
+ * @returns {Promise<string>}
39
+ */
40
+ function getProj4FromEPSGIo(epsgCode) {
41
+ return fetch(`https://epsg.io/${epsgCode}.proj4`)
42
+ .then((response) => {
43
+ if (!response.ok) {
44
+ throw new Error('Could not find EPSG Code');
45
+ }
46
+ return response.text();
47
+ })
48
+ .then((data) => {
49
+ if (data.length > 1000) {
50
+ throw new Error('Could not find EPSG Code');
51
+ }
52
+ return data;
53
+ });
54
+ }
55
+
56
+ const props = defineProps({
57
+ /**
58
+ * @type {import("@vcmap/core").ProjectionOptions}
59
+ */
60
+ modelValue: {
61
+ type: Object,
62
+ default: undefined,
63
+ },
64
+ required: {
65
+ type: Boolean,
66
+ default: false,
67
+ },
68
+ disabled: {
69
+ type: Boolean,
70
+ default: false,
71
+ },
72
+ hideRequestButton: {
73
+ type: Boolean,
74
+ default: false,
75
+ },
76
+ hideAlias: {
77
+ type: Boolean,
78
+ default: false,
79
+ },
80
+ });
81
+
82
+ const emit = defineEmits(['update:modelValue']);
83
+
84
+ const localValue = ref(structuredClone(toRaw(props.modelValue)));
85
+ // Watch for changes in prop (reassignment) and update internal
86
+ watch(
87
+ () => props.modelValue,
88
+ (internalValue) => {
89
+ const newValue = toRaw(internalValue);
90
+ if (!newValue || deepEqual(localValue.value, newValue)) {
91
+ return;
92
+ }
93
+ try {
94
+ localValue.value = structuredClone(newValue);
95
+ } catch (e) {
96
+ getLogger('modelHelper').error(
97
+ 'Failed to update internal value. You may have a provided a deeply nested ref, which caused',
98
+ e,
99
+ );
100
+ }
101
+ },
102
+ {
103
+ deep: true,
104
+ immediate: true,
105
+ },
106
+ );
107
+
108
+ const hasLocalValue = computed({
109
+ get() {
110
+ return Object.keys(localValue?.value ?? {}).length > 0;
111
+ },
112
+ set(value) {
113
+ localValue.value = value ? { epsg: null } : undefined;
114
+ },
115
+ });
116
+
117
+ watch(
118
+ () => localValue.value?.epsg,
119
+ () => {
120
+ const { code, prefix } = parseEPSGCode(localValue.value?.epsg);
121
+ if (code && code !== localValue.value.code) {
122
+ localValue.value.epsg = code;
123
+ }
124
+ if (prefix && prefix !== localValue.value.prefix) {
125
+ localValue.value.prefix = prefix;
126
+ }
127
+ },
128
+ { immediate: true },
129
+ );
130
+
131
+ const app = inject('vcsApp');
132
+
133
+ const requesting = ref(false);
134
+
135
+ async function requestProj4() {
136
+ try {
137
+ requesting.value = true;
138
+ localValue.value.proj4 = await getProj4FromEPSGIo(localValue.value.epsg);
139
+ } catch (err) {
140
+ app.notifier.add({
141
+ type: NotificationType.ERROR,
142
+ title: 'components.projection.epsgIoRequestFailed',
143
+ });
144
+ getLogger('VcsProjection').error(err);
145
+ } finally {
146
+ requesting.value = false;
147
+ }
148
+ }
149
+
150
+ function validateProj4(proj4) {
151
+ return (
152
+ Projection.validateOptions({ ...localValue.value, proj4 }) ||
153
+ 'components.projection.invalidProj4'
154
+ );
155
+ }
156
+
157
+ function validateEpsg(epsg) {
158
+ return /^\d{4,6}$/.test(epsg) || 'components.projection.invalidProj4';
159
+ }
160
+
161
+ watch(
162
+ localValue,
163
+ (internalValue) => {
164
+ const newValue = toRaw(internalValue);
165
+ const value = toRaw(props.modelValue);
166
+ if (
167
+ newValue !== undefined &&
168
+ (deepEqual(value, newValue) ||
169
+ !(
170
+ validateEpsg(newValue?.epsg) === true &&
171
+ Projection.validateOptions(newValue)
172
+ ))
173
+ ) {
174
+ return;
175
+ }
176
+ try {
177
+ emit(`update:modelValue`, structuredClone(newValue));
178
+ } catch (e) {
179
+ getLogger('modelHelper').error(
180
+ 'Failed to emit value. You may have a provided a deeply nested ref, which caused',
181
+ e,
182
+ );
183
+ }
184
+ },
185
+ { deep: true },
186
+ );
187
+
188
+ const cid = useComponentId();
189
+ const paddingProvided = usePadding(useAttrs());
190
+
191
+ const prefix = computed({
192
+ get() {
193
+ return localValue.value?.prefix ?? '';
194
+ },
195
+ set(value) {
196
+ if (localValue.value === undefined) {
197
+ localValue.value = {};
198
+ }
199
+ localValue.value.prefix = value;
200
+ },
201
+ });
202
+
203
+ const epsg = computed({
204
+ get() {
205
+ return localValue.value?.epsg ?? '';
206
+ },
207
+ set(value) {
208
+ if (localValue.value === undefined) {
209
+ localValue.value = {};
210
+ }
211
+ localValue.value.epsg = value;
212
+ },
213
+ });
214
+
215
+ const proj4 = computed({
216
+ get() {
217
+ return localValue.value?.proj4 ?? '';
218
+ },
219
+ set(value) {
220
+ if (localValue.value === undefined) {
221
+ localValue.value = {};
222
+ }
223
+ localValue.value.proj4 = value;
224
+ },
225
+ });
226
+
227
+ const alias = computed({
228
+ get() {
229
+ return localValue.value?.alias ?? [];
230
+ },
231
+ set(value) {
232
+ if (localValue.value === undefined) {
233
+ localValue.value = {};
234
+ }
235
+ if (value.length > 0) {
236
+ localValue.value.alias = value;
237
+ } else {
238
+ localValue.value.alias = undefined;
239
+ }
240
+ },
241
+ });
242
+
243
+ // manual conditional validation
244
+ const errorMessages = ref();
245
+ watch([epsg, proj4], () => {
246
+ const e = validateProj4(localValue.value?.proj4);
247
+ errorMessages.value = e === true ? undefined : e;
248
+ });
249
+ </script>
250
+
251
+ <template>
252
+ <v-container :class="{ 'pa-0': !paddingProvided }">
253
+ <v-row no-gutters v-if="!required">
254
+ <v-col>
255
+ <VcsCheckbox
256
+ v-model="hasLocalValue"
257
+ label="components.projection.title"
258
+ ></VcsCheckbox>
259
+ </v-col>
260
+ </v-row>
261
+ <template v-if="required || hasLocalValue">
262
+ <v-row no-gutters>
263
+ <v-col cols="4">
264
+ <VcsLabel :html-for="`${cid}-epsg`" required>
265
+ {{ $t('components.projection.epsg') }}
266
+ </VcsLabel>
267
+ </v-col>
268
+ <v-col>
269
+ <VcsTextField clearable placeholder="EPSG" v-model.trim="prefix">
270
+ <template #append><p>:</p></template>
271
+ </VcsTextField>
272
+ </v-col>
273
+ <v-col>
274
+ <VcsTextField
275
+ :id="`${cid}-epsg`"
276
+ clearable
277
+ placeholder="code"
278
+ v-model.trim="epsg"
279
+ :rules="[validateEpsg]"
280
+ />
281
+ </v-col>
282
+ </v-row>
283
+ <v-row no-gutters>
284
+ <v-col cols="4">
285
+ <VcsLabel :html-for="`${cid}-proj4`">
286
+ {{ $t('components.projection.proj4') }}
287
+ </VcsLabel>
288
+ </v-col>
289
+ <v-col>
290
+ <VcsTextField
291
+ :id="`${cid}-proj4`"
292
+ clearable
293
+ :rules="[validateProj4]"
294
+ :error-messages="errorMessages"
295
+ v-model="proj4"
296
+ class="w-100"
297
+ >
298
+ <template #append>
299
+ <VcsButton
300
+ v-if="!hideRequestButton"
301
+ icon="mdi-download"
302
+ tooltip="components.projection.proj4Tooltip"
303
+ :loading="requesting"
304
+ :disabled="!/^\d{4,6}$/.test(epsg)"
305
+ @click="requestProj4"
306
+ />
307
+ </template>
308
+ </VcsTextField>
309
+ </v-col>
310
+ </v-row>
311
+ <v-row no-gutters v-if="!hideAlias">
312
+ <v-col cols="4">
313
+ <VcsLabel :html-for="`${cid}-alias`">
314
+ {{ $t('components.projection.alias') }}
315
+ </VcsLabel>
316
+ </v-col>
317
+ <v-col>
318
+ <VcsChipArrayInput :id="`${cid}-alias`" clearable v-model="alias" />
319
+ </v-col>
320
+ </v-row>
321
+ </template>
322
+ </v-container>
323
+ </template>
324
+
325
+ <style scoped lang="scss">
326
+ :deep(.v-input__append) {
327
+ margin: 0;
328
+ }
329
+ </style>
@@ -0,0 +1,7 @@
1
+ declare const _default: import("vue").DefineComponent<{}, {
2
+ $emit: (event: "update:modelValue", ...args: any[]) => void;
3
+ $props: {
4
+ readonly [x: string]: any;
5
+ };
6
+ }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{}>>, {}, {}>;
7
+ export default _default;
@@ -9,7 +9,6 @@
9
9
  <div class="d-flex align-center" :class="{ 'px-2': !expandable }">
10
10
  <v-btn
11
11
  :ripple="false"
12
- dense
13
12
  variant="text"
14
13
  icon
15
14
  :size="fontSize * 2"
@@ -69,8 +69,8 @@ declare const _default: import("vue").DefineComponent<{
69
69
  headerActions: unknown[];
70
70
  heading: string;
71
71
  actionButtonListOverflowCount: number;
72
+ helpText: string;
72
73
  expandable: boolean;
73
74
  startOpen: boolean;
74
- helpText: string;
75
75
  }, {}>;
76
76
  export default _default;
@@ -16,10 +16,14 @@
16
16
  <slot name="append" v-bind="scope" />
17
17
  </template>
18
18
  </VcsTreeviewSearchbar>
19
- <v-data-table
19
+ <component
20
+ :is="baseComponent"
20
21
  :headers="translatedHeaders"
21
22
  :items="internalItems"
22
23
  :items-per-page="itemsPerPageRef"
24
+ :items-length="
25
+ baseComponent === 'VDataTableServer' ? serverItemsLength : null
26
+ "
23
27
  :search="search"
24
28
  :custom-filter="handleFilter"
25
29
  :no-data-text="
@@ -117,13 +121,14 @@
117
121
  </tr>
118
122
  </tfoot>
119
123
  </template>
120
- </v-data-table>
124
+ </component>
121
125
  </div>
122
126
  </template>
123
127
  <script>
124
128
  import { getCurrentInstance, ref, computed, watch } from 'vue';
125
129
  import {
126
130
  VDataTable,
131
+ VDataTableServer,
127
132
  VList,
128
133
  VListItem,
129
134
  VListItemTitle,
@@ -173,6 +178,7 @@
173
178
  VcsButton,
174
179
  VcsTreeviewSearchbar,
175
180
  VDataTable,
181
+ VDataTableServer,
176
182
  VMenu,
177
183
  VIcon,
178
184
  VList,
@@ -180,6 +186,11 @@
180
186
  VListItemTitle,
181
187
  },
182
188
  props: {
189
+ baseComponent: {
190
+ type: String,
191
+ default: 'VDataTable',
192
+ validator: (type) => ['VDataTable', 'VDataTableServer'].includes(type),
193
+ },
183
194
  headers: {
184
195
  type: Array,
185
196
  default: () => [],
@@ -1,4 +1,9 @@
1
1
  declare const _default: import("vue").DefineComponent<{
2
+ baseComponent: {
3
+ type: StringConstructor;
4
+ default: string;
5
+ validator: (type: unknown) => boolean;
6
+ };
2
7
  headers: {
3
8
  type: ArrayConstructor;
4
9
  default: () => never[];
@@ -56,6 +61,11 @@ declare const _default: import("vue").DefineComponent<{
56
61
  showFooter: import("vue").ComputedRef<boolean>;
57
62
  forwardSlots: string[];
58
63
  }, any, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
64
+ baseComponent: {
65
+ type: StringConstructor;
66
+ default: string;
67
+ validator: (type: unknown) => boolean;
68
+ };
59
69
  headers: {
60
70
  type: ArrayConstructor;
61
71
  default: () => never[];
@@ -94,11 +104,12 @@ declare const _default: import("vue").DefineComponent<{
94
104
  };
95
105
  }>>, {
96
106
  items: unknown[];
97
- headers: unknown[];
98
107
  showSearchbar: boolean;
99
108
  searchbarPlaceholder: string;
109
+ headers: unknown[];
100
110
  itemSelectable: string;
101
111
  itemsPerPage: number;
112
+ baseComponent: string;
102
113
  serverItemsLength: number;
103
114
  serverPagesLength: number;
104
115
  itemsPerPageArray: unknown[];
@@ -23,6 +23,7 @@
23
23
  </VcsFormSection>
24
24
  <VcsVectorPropertiesComponent
25
25
  :show3-d-properties="is3D"
26
+ :is2-d-feature="is2DFeature"
26
27
  :value-default="defaultVectorProperties"
27
28
  :properties="availableVectorProperties"
28
29
  :show-dividers="false"
@@ -30,6 +31,7 @@
30
31
  :start-open="startOpenVectorProperties"
31
32
  :show-reset="showResetVectorProperties"
32
33
  :model-value="featureProperties"
34
+ :altitude-modes="altitudeModes"
33
35
  @update:model-value="updateFeatureProperties"
34
36
  />
35
37
  </v-sheet>
@@ -50,6 +52,7 @@
50
52
  import {
51
53
  CesiumMap,
52
54
  GeometryType,
55
+ is2DLayout,
53
56
  SessionType,
54
57
  TransformationMode,
55
58
  VectorProperties,
@@ -69,7 +72,6 @@
69
72
  * @property {import("vue").ShallowRef<import("ol").Feature[]>} currentFeatures
70
73
  * @property {import("vue").ShallowRef<import("@vcmap/core").EditGeometrySession | import("@vcmap/core").EditFeaturesSession | undefined>} currentEditSession
71
74
  * @property {import("vue").ShallowRef<import("@vcmap/core").SelectFeaturesSession | import("@vcmap/core").CreateFeatureSession<import("@vcmap/core").GeometryType> | undefined>} currentSession
72
- * @property {function():Promise<void>} placeCurrentFeaturesOnTerrain
73
75
  * @property {function():void} stopEditing
74
76
  * @property {function(import("ol").Feature=):Promise<void>|void} startEditSession
75
77
  * @property {function(import("@vcmap/core").TransformationMode, import("ol").Feature[]=):Promise<void>|void} startTransformSession
@@ -157,6 +159,10 @@
157
159
  'classificationType',
158
160
  ],
159
161
  },
162
+ altitudeModes: {
163
+ type: Array,
164
+ default: undefined,
165
+ },
160
166
  expandableVectorProperties: {
161
167
  type: Boolean,
162
168
  default: false,
@@ -214,6 +220,15 @@
214
220
  }
215
221
 
216
222
  const is3D = ref(false);
223
+ const is2DFeature = computed(() =>
224
+ features.value.some((f) => {
225
+ const geometry = f.getGeometry();
226
+ if (geometry && geometry.getFlatCoordinates().length > 0) {
227
+ return is2DLayout(f.getGeometry()?.getLayout());
228
+ }
229
+ return !is3D.value;
230
+ }),
231
+ );
217
232
 
218
233
  function updateIs3D() {
219
234
  is3D.value = vcsApp.maps.activeMap instanceof CesiumMap;
@@ -407,6 +422,7 @@
407
422
  availableModifyActions,
408
423
  availableVectorProperties,
409
424
  is3D,
425
+ is2DFeature,
410
426
  updateFeatureProperties,
411
427
  defaultVectorProperties: VectorProperties.getDefaultOptions(),
412
428
  };
@@ -18,6 +18,10 @@ declare const _default: import("vue").DefineComponent<{
18
18
  type: ArrayConstructor;
19
19
  default: () => string[];
20
20
  };
21
+ altitudeModes: {
22
+ type: ArrayConstructor;
23
+ default: undefined;
24
+ };
21
25
  expandableVectorProperties: {
22
26
  type: BooleanConstructor;
23
27
  default: boolean;
@@ -43,6 +47,7 @@ declare const _default: import("vue").DefineComponent<{
43
47
  availableModifyActions: import("vue").ShallowRef<never[]>;
44
48
  availableVectorProperties: import("vue").ShallowRef<never[]>;
45
49
  is3D: import("vue").Ref<boolean>;
50
+ is2DFeature: import("vue").ComputedRef<boolean>;
46
51
  updateFeatureProperties: (update: import("@vcmap/core").VectorPropertiesOptions) => void;
47
52
  defaultVectorProperties: import("@vcmap/core", { with: { "resolution-mode": "import" } }).VectorPropertiesOptions;
48
53
  }, any, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
@@ -50,6 +55,10 @@ declare const _default: import("vue").DefineComponent<{
50
55
  type: ArrayConstructor;
51
56
  default: () => string[];
52
57
  };
58
+ altitudeModes: {
59
+ type: ArrayConstructor;
60
+ default: undefined;
61
+ };
53
62
  expandableVectorProperties: {
54
63
  type: BooleanConstructor;
55
64
  default: boolean;
@@ -67,6 +76,7 @@ declare const _default: import("vue").DefineComponent<{
67
76
  default: boolean;
68
77
  };
69
78
  }>>, {
79
+ altitudeModes: unknown[];
70
80
  allowedVectorProperties: unknown[];
71
81
  expandableVectorProperties: boolean;
72
82
  startOpenVectorProperties: boolean;
@@ -79,7 +89,6 @@ export type EditorManager = {
79
89
  currentFeatures: import("vue").ShallowRef<import("ol").Feature[]>;
80
90
  currentEditSession: import("vue").ShallowRef<import("@vcmap/core").EditGeometrySession | import("@vcmap/core").EditFeaturesSession | undefined>;
81
91
  currentSession: import("vue").ShallowRef<import("@vcmap/core").SelectFeaturesSession | import("@vcmap/core").CreateFeatureSession<import("@vcmap/core").GeometryType> | undefined>;
82
- placeCurrentFeaturesOnTerrain: () => Promise<void>;
83
92
  stopEditing: () => void;
84
93
  startEditSession: (arg0: import("ol").Feature | undefined) => Promise<void> | void;
85
94
  startTransformSession: (arg0: import("@vcmap/core").TransformationMode, arg1: import("ol").Feature[] | undefined) => Promise<void> | void;
@@ -57,7 +57,8 @@
57
57
  !allowZInput || featureProperties.altitudeMode !== 'absolute'
58
58
  "
59
59
  >
60
- <v-icon>$vcsGround</v-icon>
60
+ <v-icon v-if="placeOnTerrainLoading">$vcsProgress</v-icon>
61
+ <v-icon v-else>$vcsGround</v-icon>
61
62
  </VcsButton>
62
63
  </v-col>
63
64
  </v-row>
@@ -118,8 +119,8 @@
118
119
  </template>
119
120
 
120
121
  <script>
121
- import { Math as CesiumMath } from '@vcmap-cesium/engine';
122
- import { TransformationMode } from '@vcmap/core';
122
+ import { Math as CesiumMath, HeightReference } from '@vcmap-cesium/engine';
123
+ import { TransformationMode, placeGeometryOnSurface } from '@vcmap/core';
123
124
  import { VSheet, VContainer, VRow, VCol, VIcon } from 'vuetify/components';
124
125
  import { inject, ref, watch } from 'vue';
125
126
  import VcsButton from '../buttons/VcsButton.vue';
@@ -159,6 +160,8 @@
159
160
  setup(props) {
160
161
  /** @type {import("./VcsFeatureEditingWindow.vue").EditorManager} */
161
162
  const manager = inject('manager');
163
+ /** @type {import("../../vcsUiApp.js").default} */
164
+ const vcsApp = inject('vcsApp');
162
165
 
163
166
  const showTranslate = ref(false);
164
167
  const showRotate = ref(false);
@@ -180,6 +183,8 @@
180
183
  },
181
184
  );
182
185
 
186
+ const placeOnTerrainLoading = ref(false);
187
+
183
188
  return {
184
189
  showTranslate,
185
190
  showRotate,
@@ -215,8 +220,37 @@
215
220
  );
216
221
  resetInputs();
217
222
  },
218
- placeOnTerrain() {
219
- manager.placeCurrentFeaturesOnTerrain();
223
+ placeOnTerrainLoading,
224
+ async placeOnTerrain() {
225
+ const scene = vcsApp.maps.activeMap?.getScene?.();
226
+ if (!scene) {
227
+ return;
228
+ }
229
+
230
+ placeOnTerrainLoading.value = true;
231
+
232
+ await Promise.allSettled(
233
+ manager.currentFeatures.value.map(async (feature) => {
234
+ const geometry = feature.getGeometry();
235
+ if (geometry) {
236
+ await placeGeometryOnSurface(
237
+ geometry,
238
+ scene,
239
+ HeightReference.CLAMP_TO_TERRAIN,
240
+ );
241
+ }
242
+ }),
243
+ );
244
+
245
+ const currentEditingFeatures =
246
+ manager.currentSession.value?.currentFeatures;
247
+ if (currentEditingFeatures) {
248
+ manager.currentSession.value?.setCurrentFeatures(
249
+ currentEditingFeatures,
250
+ );
251
+ }
252
+
253
+ placeOnTerrainLoading.value = false;
220
254
  },
221
255
  };
222
256
  },
@@ -24,7 +24,8 @@ declare const _default: import("vue").DefineComponent<{
24
24
  cw(): Promise<void>;
25
25
  ccw(): Promise<void>;
26
26
  scale(): Promise<void>;
27
- placeOnTerrain(): void;
27
+ placeOnTerrainLoading: import("vue").Ref<boolean>;
28
+ placeOnTerrain(): Promise<void>;
28
29
  }, any, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
29
30
  transformationMode: {
30
31
  type: StringConstructor;