@vcmap/viewshed 2.0.10 → 3.0.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vcmap/viewshed",
3
- "version": "2.0.10",
3
+ "version": "3.0.1",
4
4
  "description": "Tool to simulate a \"viewer\" and their field of vision from a certain standpoint in the map. It allows the user to see which areas and buildings can or can't be seen from a specific standpoint, regarding different viewing distances, viewers' sizes and orientations.Th",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
@@ -47,25 +47,25 @@
47
47
  },
48
48
  "prettier": "@vcsuite/eslint-config/prettier.js",
49
49
  "peerDependencies": {
50
- "@vcmap-cesium/engine": "^4.0.3",
51
- "@vcmap/core": "^5.1.4",
52
- "@vcmap/ui": "^5.1.5",
53
- "ol": "^7.5.2",
54
- "vue": "~2.7.3",
55
- "vuetify": "~2.6.7"
50
+ "@vcmap-cesium/engine": "^11.0.2",
51
+ "@vcmap/core": "^6.0.0",
52
+ "@vcmap/ui": "^6.0.1",
53
+ "ol": "^10.2.1",
54
+ "vue": "~3.4.38",
55
+ "vuetify": "^3.7.3"
56
56
  },
57
57
  "devDependencies": {
58
- "@vcmap/plugin-cli": "^3.0.0",
59
- "@vcsuite/eslint-config": "^3.0.5",
60
- "@vitest/coverage-v8": "^0.34.6",
58
+ "@vcmap/plugin-cli": "^4.0.1",
59
+ "@vcsuite/eslint-config": "^3.0.8",
60
+ "@vitest/coverage-v8": "^2.1.3",
61
61
  "jest-canvas-mock": "^2.5.2",
62
62
  "jsdom": "^22.1.0",
63
63
  "resize-observer-polyfill": "^1.5.1",
64
- "vitest": "^0.34.6"
64
+ "vitest": "^2.1.3"
65
65
  },
66
66
  "dependencies": {
67
- "@vcsuite/check": "^1.1.2",
67
+ "@vcsuite/check": "^2.1.0",
68
68
  "@vcsuite/parsers": "^1.0.3"
69
69
  },
70
- "mapVersion": "^5.1"
70
+ "mapVersion": "^6.0"
71
71
  }
@@ -44,7 +44,7 @@
44
44
 
45
45
  <script>
46
46
  import { ref } from 'vue';
47
- import { VCol, VColorPicker, VContainer, VRow } from 'vuetify/lib';
47
+ import { VCol, VColorPicker, VContainer, VRow } from 'vuetify/components';
48
48
  import {
49
49
  AbstractConfigEditor,
50
50
  VcsFormSection,
@@ -74,7 +74,6 @@
74
74
 
75
75
  export default {
76
76
  name: 'ViewshedConfigEditor',
77
- title: 'Viewshed Editor',
78
77
  components: {
79
78
  AbstractConfigEditor,
80
79
  VcsFormSection,
@@ -97,14 +96,12 @@
97
96
  },
98
97
  setup(props) {
99
98
  /** @type {import("vue").Ref<import("./index.js").ViewshedPluginOptions>} */
100
- const localConfig = ref({});
99
+ const config = props.getConfig();
101
100
  /** @type {import("vue").Ref<import("./index.js").ViewshedPluginOptions>} */
102
- props.getConfig().then((config) => {
103
- localConfig.value = Object.assign(getDefaultOptions(), config);
104
- });
101
+ const localConfig = ref({ ...getDefaultOptions(), ...config });
105
102
 
106
- async function apply() {
107
- await props.setConfig(localConfig.value);
103
+ function apply() {
104
+ props.setConfig(localConfig.value);
108
105
  }
109
106
 
110
107
  return {
@@ -113,7 +110,7 @@
113
110
  apply,
114
111
  toolItems: Object.values(ViewshedTypes).map((type) => ({
115
112
  value: type,
116
- text: `viewshed.${type}`,
113
+ title: `viewshed.${type}`,
117
114
  })),
118
115
  };
119
116
  },
@@ -1,12 +1,12 @@
1
1
  <template>
2
2
  <div>
3
- <div v-if="viewshedMode === ViewshedPluginModes.CREATE" class="px-2 py-1">
4
- <template v-if="viewshedType === ViewshedTypes.CONE">
3
+ <div v-if="viewshedMode === ViewshedPluginModes.CREATE">
4
+ <VcsHelp v-if="viewshedType === ViewshedTypes.CONE">
5
5
  {{ $t('viewshed.createDescription') }}
6
- </template>
7
- <template v-else-if="viewshedType === ViewshedTypes.THREESIXTY">
6
+ </VcsHelp>
7
+ <VcsHelp v-else-if="viewshedType === ViewshedTypes.THREESIXTY">
8
8
  {{ $t('viewshed.createThreeSixtyDescription') }}
9
- </template>
9
+ </VcsHelp>
10
10
  </div>
11
11
  <VcsFormSection
12
12
  v-else-if="
@@ -32,6 +32,7 @@
32
32
  :transformation-mode="TransformationMode.TRANSLATE"
33
33
  :feature-properties="{ altitudeMode: 'absolute' }"
34
34
  :allow-z-input="true"
35
+ class="w-100"
35
36
  />
36
37
  </v-row>
37
38
  <v-row v-else no-gutters>
@@ -41,11 +42,10 @@
41
42
  class="pb-1"
42
43
  >
43
44
  <VcsTextField
44
- :value="value"
45
- @input="(v) => setPosition(v, key, index)"
45
+ :model-value="value"
46
+ @update:model-value="(v) => setPosition(v, key, index)"
46
47
  type="number"
47
48
  :prefix="key"
48
- :show-spin-buttons="true"
49
49
  :step="key === 'Z' ? 1 : 0.0001"
50
50
  :unit="key === 'Z' ? 'm' : '°'"
51
51
  :decimals="key === 'Z' ? 2 : 8"
@@ -53,6 +53,7 @@
53
53
  viewshedMode === ViewshedPluginModes.MOVE &&
54
54
  !(key === 'Z' && heightMode === HeightModes.RELATIVE)
55
55
  "
56
+ :hide-spin-buttons="true"
56
57
  />
57
58
  </v-col>
58
59
  </v-row>
@@ -62,21 +63,22 @@
62
63
  <v-container class="px-1 py-0">
63
64
  <v-row no-gutters>
64
65
  <v-col>
65
- <VcsLabel>
66
+ <VcsLabel html-for="heightMode">
66
67
  {{ $t('viewshed.heightMode') }}
67
68
  </VcsLabel>
68
69
  </v-col>
69
70
  <v-col>
70
71
  <VcsSelect
72
+ id="heightMode"
71
73
  :items="
72
74
  Object.values(HeightModes).map((item) => ({
73
75
  value: item,
74
- text: `viewshed.${item}`,
76
+ title: `viewshed.${item}`,
75
77
  }))
76
78
  "
77
- :value="heightMode"
78
- @input="changeHeightMode"
79
- ></VcsSelect>
79
+ :model-value="heightMode"
80
+ @update:model-value="changeHeightMode"
81
+ />
80
82
  </v-col>
81
83
  </v-row>
82
84
  </v-container>
@@ -94,28 +96,30 @@
94
96
  (viewshedType === ViewshedTypes.CONE && key !== 'showPrimitive')
95
97
  "
96
98
  >
97
- <v-row no-gutters class="pr-1">
99
+ <v-row no-gutters class="px-1">
98
100
  <v-col>
99
- <VcsLabel :html-for="key">
101
+ <VcsLabel :html-for="key" class="py-0">
100
102
  {{ $t(`viewshed.${key}`) }}
101
103
  </VcsLabel>
102
104
  </v-col>
103
105
  <v-col class="d-flex justify-end align-center">
104
- <span v-if="key === 'distance'">{{ `${value} m` }}</span>
105
- <span v-else>{{ `${value} °` }}</span>
106
+ <span v-if="key === 'distance'">{{
107
+ `${Math.round(value)} m`
108
+ }}</span>
109
+ <span v-else>{{ `${Math.round(value)} °` }}</span>
106
110
  </v-col>
107
111
  </v-row>
108
112
  <v-row no-gutters>
109
113
  <v-col>
110
114
  <VcsSlider
111
115
  :id="key"
112
- :value="value"
113
- @input="(v) => setParameter(key, v)"
116
+ class="pa-0"
117
+ :model-value="value"
118
+ @update:model-value="(v) => setParameter(key, v)"
114
119
  type="number"
115
120
  step="1"
116
121
  :min="parameterRanges[key][0]"
117
122
  :max="parameterRanges[key][1]"
118
- height="15"
119
123
  />
120
124
  </v-col>
121
125
  </v-row>
@@ -144,7 +148,7 @@
144
148
  v-else-if="viewshedMode === ViewshedPluginModes.CREATE"
145
149
  class="d-flex w-full justify-end px-2 pt-2 pb-1"
146
150
  >
147
- <VcsFormButton @click="cancel()" variant="filled">
151
+ <VcsFormButton @click="cancel()" variant="outlined">
148
152
  {{ $t('viewshed.cancel') }}
149
153
  </VcsFormButton>
150
154
  </div>
@@ -163,7 +167,7 @@
163
167
  watch,
164
168
  watchEffect,
165
169
  } from 'vue';
166
- import { VCol, VContainer, VDivider, VRow } from 'vuetify/lib';
170
+ import { VCol, VContainer, VDivider, VRow } from 'vuetify/components';
167
171
  import { TransformationMode, Viewpoint } from '@vcmap/core';
168
172
  import {
169
173
  VcsFormButton,
@@ -173,6 +177,7 @@
173
177
  VcsSlider,
174
178
  VcsTextField,
175
179
  VcsFeatureTransforms,
180
+ VcsHelp,
176
181
  } from '@vcmap/ui';
177
182
  import { ViewshedPluginModes, HeightModes } from './viewshedManager.js';
178
183
  import Viewshed, { ViewshedTypes } from './viewshed.js';
@@ -197,6 +202,7 @@
197
202
  VcsSelect,
198
203
  VcsFormButton,
199
204
  VcsFeatureTransforms,
205
+ VcsHelp,
200
206
  },
201
207
  name: 'ViewshedWindow',
202
208
  props: {
@@ -225,6 +231,12 @@
225
231
  currentIsPersisted,
226
232
  } = viewshedManager;
227
233
 
234
+ /** Whether movement is disabled for the current map */
235
+ const movementDisabled = ref(
236
+ app.maps.activeMap?.movementApiCallsDisabled ?? false,
237
+ );
238
+ let movementDisabledListener = () => {};
239
+
228
240
  const selection = computed(() => props.selection);
229
241
 
230
242
  let removePositionChangedListener = () => {};
@@ -330,11 +342,18 @@
330
342
  // only the case for collection component editor
331
343
  viewshedManager.editViewshed(viewshed);
332
344
  }
345
+ movementDisabledListener =
346
+ app.maps.activeMap?.movementDisabledChanged.addEventListener(
347
+ (options) => {
348
+ movementDisabled.value = options.apiCalls;
349
+ },
350
+ );
333
351
  });
334
352
 
335
353
  onUnmounted(() => {
336
354
  removePositionChangedListener();
337
355
  deleteCachedViewpoint();
356
+ movementDisabledListener();
338
357
 
339
358
  if (!currentIsPersisted.value) {
340
359
  // in case of temp editor
@@ -384,6 +403,7 @@
384
403
  : 'viewshed.jumpToViewpoint',
385
404
  icon: 'mdi-human-male',
386
405
  active: !!cachedViewpoint.value,
406
+ disabled: movementDisabled.value,
387
407
  async callback() {
388
408
  viewshedManager.moveCurrentViewshed(false);
389
409
  if (currentViewshed.value && !cachedViewpoint.value) {
package/src/index.js CHANGED
@@ -28,6 +28,7 @@ import ViewshedConfigEditor, {
28
28
  */
29
29
  export default function plugin(config) {
30
30
  let viewshedManager;
31
+ let app;
31
32
  let destroy = () => {};
32
33
 
33
34
  return {
@@ -46,6 +47,7 @@ export default function plugin(config) {
46
47
  * @returns {Promise<void>}
47
48
  */
48
49
  async initialize(vcsUiApp, state) {
50
+ app = vcsUiApp;
49
51
  vcsUiApp.categoryClassRegistry.registerClass(
50
52
  this[moduleIdSymbol],
51
53
  ViewshedCategory.className,
@@ -71,9 +73,12 @@ export default function plugin(config) {
71
73
 
72
74
  const { activeMap } = vcsUiApp.maps;
73
75
  function activateCachedViewshed(map) {
74
- if (state?.mode && state.currentViewshed && map instanceof CesiumMap) {
75
- const activeViewshed = new Viewshed(state.currentViewshed, activeMap);
76
- if (state.mode === ViewshedPluginModes.VIEW) {
76
+ if (state?.m && state.cv && map instanceof CesiumMap) {
77
+ if (state.cv.properties.title) {
78
+ delete state.cv.properties.title;
79
+ }
80
+ const activeViewshed = new Viewshed(state.cv);
81
+ if (state.m === ViewshedPluginModes.VIEW) {
77
82
  viewshedManager.viewViewshed(activeViewshed);
78
83
  } else {
79
84
  viewshedManager.editViewshed(activeViewshed);
@@ -139,19 +144,34 @@ export default function plugin(config) {
139
144
  * @returns {ViewshedPluginState}
140
145
  */
141
146
  getState() {
142
- return {
143
- mode: viewshedManager.mode.value,
144
- currentViewshed: viewshedManager.currentViewshed.value?.toJSON(),
145
- };
147
+ const state = {};
148
+ const mode = viewshedManager.mode.value;
149
+ const currentViewshed = viewshedManager.currentViewshed.value?.toJSON();
150
+
151
+ if (mode !== null && mode !== 'create' && currentViewshed) {
152
+ state.m = mode;
153
+ state.cv = currentViewshed;
154
+ }
155
+
156
+ return state;
146
157
  },
147
158
  /**
148
159
  * components for configuring the plugin and/ or custom items defined by the plugin
149
160
  * @returns {Array<import("@vcmap/ui").PluginConfigEditor>}
150
161
  */
151
162
  getConfigEditors() {
152
- return [{ component: ViewshedConfigEditor }];
163
+ return [
164
+ {
165
+ component: ViewshedConfigEditor,
166
+ title: 'viewshed.editor.title',
167
+ infoUrlCallback: app?.getHelpUrlCallback(
168
+ '/components/plugins/viewshedToolConfig.html',
169
+ 'app-configurator',
170
+ ),
171
+ },
172
+ ];
153
173
  },
154
- destroy,
174
+ destroy: () => destroy(),
155
175
  i18n: {
156
176
  en: {
157
177
  viewshed: {
@@ -162,15 +182,18 @@ export default function plugin(config) {
162
182
  position: 'Position',
163
183
  showPrimitive: 'Show viewpoint',
164
184
  viewpoint: 'Viewpoint',
165
- viewshed: 'Viewshed',
185
+ viewshedCategory: 'Viewsheds',
166
186
  heightMode: 'Height mode',
167
- relative: 'Relativ to ground',
187
+ relative: 'Relative to ground',
168
188
  absolute: 'Absolute',
169
189
  new: 'New',
170
190
  cancel: 'Cancel',
171
- [ViewshedTypes.CONE]: 'Cone Viewshed',
172
- [ViewshedTypes.THREESIXTY]: '360° Viewshed',
173
- create: 'Create',
191
+ [ViewshedTypes.CONE]: 'Cone viewshed analysis',
192
+ [ViewshedTypes.THREESIXTY]: '360° viewshed analysis',
193
+ create: {
194
+ [ViewshedTypes.CONE]: 'Create cone viewshed analysis',
195
+ [ViewshedTypes.THREESIXTY]: 'Create 360° viewshed analysis',
196
+ },
174
197
  addToMyWorkspace: 'Add to My Workspace',
175
198
  temporary: 'Temporary',
176
199
  jumpToViewpoint: 'Jump to viewpoint',
@@ -182,6 +205,7 @@ export default function plugin(config) {
182
205
  'Click the map twice. First click places the origin, second defines the distance of the viewshed.',
183
206
  remove: 'Remove',
184
207
  editor: {
208
+ title: 'Viewshed Editor',
185
209
  general: 'General Settings',
186
210
  visibleColor: 'Visible color',
187
211
  shadowColor: 'Shadow color',
@@ -196,28 +220,32 @@ export default function plugin(config) {
196
220
  heading: 'Ausrichtung',
197
221
  pitch: 'Neigung',
198
222
  position: 'Position',
199
- showPrimitive: 'Viewpoint zeigen',
200
- viewpoint: 'Viewpoint',
201
- viewshed: 'Viewshed',
223
+ showPrimitive: 'Standpunkt zeigen',
224
+ viewpoint: 'Standpunkt',
225
+ viewshedCategory: 'Sichtbarkeitsanalysen',
202
226
  heightMode: 'Höhenmodus',
203
227
  relative: 'Relativ zum Gelände',
204
228
  absolute: 'Absolut',
205
229
  new: 'Neu',
206
230
  cancel: 'Abbrechen',
207
- [ViewshedTypes.CONE]: 'Kegel Viewshed',
208
- [ViewshedTypes.THREESIXTY]: '360° Viewshed',
209
- create: 'Erzeuge',
231
+ [ViewshedTypes.CONE]: 'Sichtkegelanalyse',
232
+ [ViewshedTypes.THREESIXTY]: '360° Sichtsanalyse',
233
+ create: {
234
+ [ViewshedTypes.CONE]: 'Sichtkegelanalyse erstellen',
235
+ [ViewshedTypes.THREESIXTY]: '360° Sichtanalyse erstellen',
236
+ },
210
237
  addToMyWorkspace: 'Zu Mein Arbeitsbereich hinzufügen',
211
- temporary: 'Temporärer',
212
- jumpToViewpoint: 'Zu Viewpoint springen',
213
- returnToViewpoint: 'Zu vorherigem Viewpoint zurück springen',
214
- move: 'Viewpoint verschieben',
238
+ temporary: 'Temporäre',
239
+ jumpToViewpoint: 'Zu Standpunkt springen',
240
+ returnToViewpoint: 'Zu vorherigem Standpunkt zurück springen',
241
+ move: 'Standpunkt verschieben',
215
242
  createDescription:
216
- 'Klicke zweimal in die Karte. Der erste Klick platziert den Ursprung, der zweite die Distanz und die Richtung des Viewsheds.',
243
+ 'Klicken Sie zweimal in die Karte. Der erste Klick platziert den Ursprung, der zweite die Distanz und die Richtung des Sichtkegels.',
217
244
  createThreeSixtyDescription:
218
- 'Klicke zweimal in die Karte. Der erste Klick platziert den Ursprung, der zweite die Distanz des Viewsheds.',
245
+ 'Klicken Sie zweimal in die Karte. Der erste Klick platziert den Ursprung, der zweite die Distanz der Sichtbarkeitsanalyse.',
219
246
  remove: 'Entfernen',
220
247
  editor: {
248
+ title: 'Viewshed Editor',
221
249
  general: 'Allgemeine Einstellungen',
222
250
  visibleColor: 'Sichtbarer Bereich',
223
251
  shadowColor: 'Nicht sichtbarer Bereich',
@@ -1,6 +1,6 @@
1
1
  import { CesiumMap } from '@vcmap/core';
2
2
  import { ToolboxType } from '@vcmap/ui';
3
- import { check } from '@vcsuite/check';
3
+ import { check, ofEnum } from '@vcsuite/check';
4
4
  import { reactive, watch } from 'vue';
5
5
  import { ViewshedTypes } from '../viewshed.js';
6
6
  import { ViewshedIcons } from './windowHelper.js';
@@ -44,22 +44,22 @@ function createViewshedToolbox(app, manager, name, tools) {
44
44
  selected(newIndex) {
45
45
  if (newIndex !== this.currentIndex) {
46
46
  this.currentIndex = newIndex;
47
- const toolName = this.tools[this.currentIndex].name;
48
- manager.createViewshed(toolName);
49
47
  }
48
+ const toolName = this.tools[this.currentIndex].name;
49
+ manager.createViewshed(toolName);
50
50
  },
51
51
  tools: tools.flatMap((tool) => {
52
52
  if (tool === ViewshedTypes.CONE) {
53
53
  return {
54
54
  name: ViewshedTypes.CONE,
55
55
  icon: ViewshedIcons[ViewshedTypes.CONE],
56
- title: `viewshed.${ViewshedTypes.CONE}`,
56
+ title: `viewshed.create.${ViewshedTypes.CONE}`,
57
57
  };
58
58
  } else if (tool === ViewshedTypes.THREESIXTY) {
59
59
  return {
60
60
  name: ViewshedTypes.THREESIXTY,
61
61
  icon: ViewshedIcons[ViewshedTypes.THREESIXTY],
62
- title: `viewshed.${ViewshedTypes.THREESIXTY}`,
62
+ title: `viewshed.create.${ViewshedTypes.THREESIXTY}`,
63
63
  };
64
64
  } else {
65
65
  return [];
@@ -119,7 +119,7 @@ function createViewshedToolbox(app, manager, name, tools) {
119
119
  * @returns {function():void} Function to remove toolbox component.
120
120
  */
121
121
  export default function addToolButtons(app, manager, name, tools) {
122
- check(tools, [Object.values(ViewshedTypes)]);
122
+ check(tools, [ofEnum(ViewshedTypes)]);
123
123
 
124
124
  const { toolbox: createToolbox, destroy: destroyCreateToolbox } =
125
125
  createViewshedToolbox(app, manager, name, tools);
@@ -61,10 +61,7 @@ export function setupViewshedWindow(manager, app, collectionComponent) {
61
61
  if (manager.currentIsPersisted.value) {
62
62
  headerTitle.value = manager.currentViewshed.value.properties.title;
63
63
  } else if (manager.mode.value === ViewshedPluginModes.CREATE) {
64
- headerTitle.value = [
65
- 'viewshed.create',
66
- `viewshed.${manager.currentViewshed.value.type}`,
67
- ];
64
+ headerTitle.value = `viewshed.create.${manager.currentViewshed.value.type}`;
68
65
  } else {
69
66
  headerTitle.value = [
70
67
  'viewshed.temporary',
package/src/viewshed.js CHANGED
@@ -305,6 +305,7 @@ export default class Viewshed extends VcsObject {
305
305
  this._shadowCamera.frustum
306
306
  ).fov = value * CesiumMath.RADIANS_PER_DEGREE;
307
307
  if (this._viewshedType === ViewshedTypes.CONE) {
308
+ this._updateShadowMap();
308
309
  this._updatePrimitive();
309
310
  }
310
311
  }
@@ -481,7 +482,7 @@ export default class Viewshed extends VcsObject {
481
482
  }
482
483
 
483
484
  _removePrimitive() {
484
- if (this._primitive && !this._primitive.isDestroyed?.()) {
485
+ if (this._primitive && !this._primitive.isDestroyed()) {
485
486
  this._scene?.primitives.remove(this._primitive);
486
487
  this._primitive.destroy();
487
488
  this._primitive = null;
@@ -34,7 +34,7 @@ class ViewshedCategory extends Category {
34
34
  this._app?.maps.getByType(CesiumMap.className)[0]
35
35
  );
36
36
  if (cesiumMap) {
37
- return new Viewshed(item, cesiumMap);
37
+ return new Viewshed(item);
38
38
  } else {
39
39
  throw new Error('No CesiumMap available');
40
40
  }
@@ -83,7 +83,7 @@ export async function createCategory(app) {
83
83
  {
84
84
  type: ViewshedCategory.className,
85
85
  name: 'Viewsheds',
86
- title: 'Viewsheds',
86
+ title: 'viewshed.viewshedCategory',
87
87
  },
88
88
  name,
89
89
  {