@vcmap/viewshed 2.0.3 → 2.0.5

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.3",
3
+ "version": "2.0.5",
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",
@@ -1,7 +1,12 @@
1
1
  <template>
2
2
  <div>
3
3
  <div v-if="viewshedMode === ViewshedPluginModes.CREATE" class="px-2 py-1">
4
- {{ $t('viewshed.createDescription') }}
4
+ <template v-if="viewshedType === ViewshedTypes.CONE">
5
+ {{ $t('viewshed.createDescription') }}
6
+ </template>
7
+ <template v-else-if="viewshedType === ViewshedTypes.THREESIXTY">
8
+ {{ $t('viewshed.createThreeSixtyDescription') }}
9
+ </template>
5
10
  </div>
6
11
  <VcsFormSection
7
12
  v-else-if="
package/src/index.js CHANGED
@@ -68,25 +68,40 @@ export default function plugin(config) {
68
68
  vcsUiApp,
69
69
  viewshedCategoryHelper.collectionComponent,
70
70
  );
71
+
72
+ const { activeMap } = vcsUiApp.maps;
73
+ 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) {
77
+ viewshedManager.viewViewshed(activeViewshed);
78
+ } else {
79
+ viewshedManager.editViewshed(activeViewshed);
80
+ }
81
+ }
82
+ }
83
+ let appliedCachedViewshed = false;
84
+ if (activeMap) {
85
+ appliedCachedViewshed = true;
86
+ activateCachedViewshed(activeMap);
87
+ }
88
+ const mapActivatedListener = vcsUiApp.maps.mapActivated.addEventListener(
89
+ (map) => {
90
+ viewshedManager.stop();
91
+ if (!appliedCachedViewshed) {
92
+ activateCachedViewshed(map);
93
+ appliedCachedViewshed = true;
94
+ }
95
+ },
96
+ );
97
+
71
98
  destroy = () => {
99
+ mapActivatedListener();
72
100
  destroyButtons();
73
101
  destroyViewshedWindow();
74
102
  viewshedCategoryHelper.destroy();
103
+ viewshedManager.destroy();
75
104
  };
76
-
77
- const { activeMap } = vcsUiApp.maps;
78
- if (
79
- state?.mode &&
80
- state.currentViewshed &&
81
- activeMap instanceof CesiumMap
82
- ) {
83
- const activeViewshed = new Viewshed(state.currentViewshed, activeMap);
84
- if (state.mode === ViewshedPluginModes.VIEW) {
85
- viewshedManager.viewViewshed(activeViewshed);
86
- } else {
87
- viewshedManager.editViewshed(activeViewshed);
88
- }
89
- }
90
105
  },
91
106
  /**
92
107
  * should return all default values of the configuration
@@ -163,9 +178,11 @@ export default function plugin(config) {
163
178
  move: 'Move viewpoint',
164
179
  createDescription:
165
180
  'Click the map twice. First click places the origin, second defines the distance and direction of the viewshed.',
181
+ createThreeSixtyDescription:
182
+ 'Click the map twice. First click places the origin, second defines the distance of the viewshed.',
166
183
  remove: 'Remove',
167
184
  editor: {
168
- general: 'General',
185
+ general: 'General Settings',
169
186
  visibleColor: 'Visible color',
170
187
  shadowColor: 'Shadow color',
171
188
  tools: 'Tools',
@@ -197,11 +214,13 @@ export default function plugin(config) {
197
214
  move: 'Viewpoint verschieben',
198
215
  createDescription:
199
216
  'Klicke zweimal in die Karte. Der erste Klick platziert den Ursprung, der zweite die Distanz und die Richtung des Viewsheds.',
217
+ createThreeSixtyDescription:
218
+ 'Klicke zweimal in die Karte. Der erste Klick platziert den Ursprung, der zweite die Distanz des Viewsheds.',
200
219
  remove: 'Entfernen',
201
220
  editor: {
202
- general: 'Generelles',
221
+ general: 'Allgemeine Einstellungen',
203
222
  visibleColor: 'Sichtbarer Bereich',
204
- shadowColor: 'Schatten Bereich',
223
+ shadowColor: 'Nicht sichtbarer Bereich',
205
224
  tools: 'Werkzeuge',
206
225
  },
207
226
  },
@@ -97,7 +97,6 @@ function createViewshedToolbox(app, manager, name, tools) {
97
97
  toolbox.action.disabled = false;
98
98
  } else {
99
99
  toolbox.action.disabled = true;
100
- manager.stop();
101
100
  }
102
101
  });
103
102
 
package/src/viewshed.js CHANGED
@@ -102,9 +102,8 @@ export default class Viewshed extends VcsObject {
102
102
 
103
103
  /**
104
104
  * @param {ViewshedOptions} options The options for the viewshed.
105
- * @param {import("@vcmap/core").CesiumMap} [cesiumMap] The cesiumMap the viewshed should be applied to. If this parameter is passed, the viewshed is activated and all other viewsheds are deactivated.
106
105
  */
107
- constructor(options, cesiumMap) {
106
+ constructor(options) {
108
107
  super(options);
109
108
  /**
110
109
  * @type {import("@vcmap/core").CesiumMap | null}
@@ -198,26 +197,16 @@ export default class Viewshed extends VcsObject {
198
197
  this._showPrimitive = !!options.showPrimitive;
199
198
 
200
199
  /**
201
- * Makes sure that the viewshed instance is deactivated, if shadow map of another viewshed or plugin is applied to the scene of the CesiumMap.
200
+ * @type {import("@vcmap/core").VcsEvent<number[]>}
202
201
  * @private
203
202
  */
204
- this._shadowMapChangedListener = null;
203
+ this._positionChanged = new VcsEvent();
205
204
 
206
205
  /**
207
- * @type {import("@vcmap/core").VcsEvent<number[]>}
206
+ * @type {boolean}
208
207
  * @private
209
208
  */
210
- this._positionChanged = new VcsEvent();
211
-
212
- if (cesiumMap) {
213
- this.activate(cesiumMap);
214
- } else {
215
- /**
216
- * @type {boolean}
217
- * @private
218
- */
219
- this._active = false;
220
- }
209
+ this._active = false;
221
210
  }
222
211
 
223
212
  /**
@@ -267,7 +256,6 @@ export default class Viewshed extends VcsObject {
267
256
  this.position[1],
268
257
  this.position[2] + value,
269
258
  );
270
- this._updateShadowMap();
271
259
  this._updatePrimitive();
272
260
  }
273
261
  }
@@ -289,7 +277,9 @@ export default class Viewshed extends VcsObject {
289
277
  value > Viewshed.MIN_DISTANCE ? value : Viewshed.MIN_DISTANCE;
290
278
  if (this._shadowCamera) {
291
279
  this._shadowCamera.frustum.far = this._frustumOptions.far;
292
- this._updateShadowMap();
280
+ if (this._viewshedType === ViewshedTypes.THREESIXTY) {
281
+ this._updateShadowMap();
282
+ }
293
283
  if (this._viewshedType === ViewshedTypes.CONE) {
294
284
  this._updatePrimitive();
295
285
  }
@@ -314,7 +304,6 @@ export default class Viewshed extends VcsObject {
314
304
  /** @type {import("@vcmap-cesium/engine").PerspectiveFrustum} */ (
315
305
  this._shadowCamera.frustum
316
306
  ).fov = value * CesiumMath.RADIANS_PER_DEGREE;
317
- this._updateShadowMap();
318
307
  if (this._viewshedType === ViewshedTypes.CONE) {
319
308
  this._updatePrimitive();
320
309
  }
@@ -400,7 +389,7 @@ export default class Viewshed extends VcsObject {
400
389
  }
401
390
 
402
391
  /**
403
- * Retruns the type of the Viewshed.
392
+ * Returns the type of the Viewshed.
404
393
  * @returns {ViewshedTypes}
405
394
  */
406
395
  get type() {
@@ -408,25 +397,30 @@ export default class Viewshed extends VcsObject {
408
397
  }
409
398
 
410
399
  /**
411
- * Deactivates the viewshed by removing primitve and removing shadowMap.
400
+ * @returns {ShadowMap|null}
401
+ */
402
+ get shadowMap() {
403
+ return this._shadowMap;
404
+ }
405
+
406
+ /**
407
+ * Deactivates the viewshed by removing primitive and removing shadowMap.
412
408
  */
413
409
  deactivate() {
414
410
  if (this._active) {
415
411
  this._removePrimitive();
416
- this._shadowMapChangedListener?.();
417
- if (this._cesiumMap?.getScene()?.shadowMap === this._shadowMap) {
418
- this._cesiumMap.setDefaultShadowMap();
419
- }
412
+ this._shadowMap.enabled = false;
420
413
  this._shadowMap?.destroy();
421
414
  this._shadowCamera = null;
422
415
  this._scene = null;
423
416
  this._cesiumMap = null;
417
+ this._shadowMap = null;
424
418
  this._active = false;
425
419
  }
426
420
  }
427
421
 
428
422
  /**
429
- * Activates viewshed. Sets the CesiumMap and adds shadowMapChanged listener to CesiumMap. If viewshed is active but
423
+ * Activates viewshed.
430
424
  * @param {import("@vcmap/core").CesiumMap} cesiumMap The cesium map to which the shadow map of the viewshed is applied to.
431
425
  */
432
426
  activate(cesiumMap) {
@@ -451,10 +445,6 @@ export default class Viewshed extends VcsObject {
451
445
 
452
446
  this._updateShadowMap();
453
447
  this._updatePrimitive();
454
- this._shadowMapChangedListener =
455
- this._cesiumMap.shadowMapChanged.addEventListener(() => {
456
- this.deactivate();
457
- });
458
448
  }
459
449
  }
460
450
 
@@ -471,6 +461,7 @@ export default class Viewshed extends VcsObject {
471
461
  return;
472
462
  }
473
463
 
464
+ this._shadowMap?.destroy();
474
465
  // @ts-ignore
475
466
  this._shadowMap = new ShadowMap({
476
467
  // @ts-ignore
@@ -490,7 +481,7 @@ export default class Viewshed extends VcsObject {
490
481
  }
491
482
 
492
483
  _removePrimitive() {
493
- if (this._primitive) {
484
+ if (this._primitive && !this._primitive.isDestroyed?.()) {
494
485
  this._scene?.primitives.remove(this._primitive);
495
486
  this._primitive.destroy();
496
487
  this._primitive = null;
@@ -572,6 +563,11 @@ export default class Viewshed extends VcsObject {
572
563
  * Destroys the viewshed.
573
564
  */
574
565
  destroy() {
566
+ const cesiumMap = this._cesiumMap;
567
+ const shadowMap = this._shadowMap;
575
568
  this.deactivate();
569
+ if (cesiumMap?.getScene()?.shadowMap === shadowMap) {
570
+ cesiumMap.setDefaultShadowMap();
571
+ }
576
572
  }
577
573
  }
@@ -130,15 +130,15 @@ export default function createViewshedManager(app, config, categoryHelper) {
130
130
  /** @type {import("vue").Ref<import("@vcmap/core").EditFeaturesSession | import("@vcmap/core").EditGeometrySession | null>} */
131
131
  const currentEditSession = shallowRef(null);
132
132
 
133
- function setCurrentViewshed(viewshed) {
133
+ let shadowMapChangedListener = () => {};
134
+
135
+ function deactivateCurrentViewshed() {
134
136
  if (currentIsPersisted.value && currentViewshed.value) {
135
137
  currentViewshed.value.deactivate();
136
138
  categoryHelper.setVisibility(currentViewshed.value.name, false);
137
139
  } else {
138
140
  currentViewshed.value?.destroy();
139
141
  }
140
- currentViewshed.value = viewshed;
141
- currentViewshed.value?.activate(app.maps.activeMap);
142
142
  }
143
143
 
144
144
  /**
@@ -146,8 +146,10 @@ export default function createViewshedManager(app, config, categoryHelper) {
146
146
  * @param {boolean} [clear=true] - Indicates whether to clear the selection.
147
147
  */
148
148
  function stop(clear = true) {
149
+ shadowMapChangedListener();
149
150
  removeInteraction();
150
- setCurrentViewshed(null);
151
+ deactivateCurrentViewshed();
152
+ currentViewshed.value = null;
151
153
  if (clear) {
152
154
  categoryHelper.clearSelection();
153
155
  }
@@ -155,6 +157,26 @@ export default function createViewshedManager(app, config, categoryHelper) {
155
157
  mode.value = null;
156
158
  }
157
159
 
160
+ /**
161
+ * activates a viewshed, and adds a Listener to the shadowMapChangedEvent to deactivate the viewshed plugin.
162
+ * @param {Viewshed} viewshed
163
+ */
164
+ function activateViewshed(viewshed) {
165
+ shadowMapChangedListener();
166
+ // deactivate existing Viewsheds
167
+ deactivateCurrentViewshed();
168
+ if (app.maps.activeMap instanceof CesiumMap) {
169
+ currentViewshed.value = viewshed;
170
+ viewshed.activate(app.maps.activeMap);
171
+ shadowMapChangedListener =
172
+ app.maps.activeMap.shadowMapChanged.addEventListener((newShadowMap) => {
173
+ if (newShadowMap !== currentViewshed.value?.shadowMap) {
174
+ stop(false);
175
+ }
176
+ });
177
+ }
178
+ }
179
+
158
180
  async function createViewshed(viewshedType) {
159
181
  stop();
160
182
  await nextTick(); // so the viewshedWindow is closed with mode === null and not CREATE
@@ -163,19 +185,16 @@ export default function createViewshedManager(app, config, categoryHelper) {
163
185
  const { featureInteraction } = eventHandler;
164
186
 
165
187
  // create new viewshed instance
166
- currentViewshed.value = new Viewshed(
167
- {
168
- viewshedType,
169
- colorOptions: {
170
- visibleColor: config.visibleColor,
171
- shadowColor: config.shadowColor,
172
- },
173
- heightOffset:
174
- heightMode.value === HeightModes.ABSOLUTE ? 0 : defaultHeightOffset,
188
+ const viewshed = new Viewshed({
189
+ viewshedType,
190
+ colorOptions: {
191
+ visibleColor: config.visibleColor,
192
+ shadowColor: config.shadowColor,
175
193
  },
176
- /** @type {import("@vcmap/core").CesiumMap} */ (app.maps.activeMap),
177
- );
178
-
194
+ heightOffset:
195
+ heightMode.value === HeightModes.ABSOLUTE ? 0 : defaultHeightOffset,
196
+ });
197
+ activateViewshed(viewshed);
179
198
  // setup viewshed create interaction
180
199
  const interaction = new ViewshedInteraction(currentViewshed.value);
181
200
 
@@ -274,7 +293,7 @@ export default function createViewshedManager(app, config, categoryHelper) {
274
293
  function changeMode(viewshedMode, viewshed) {
275
294
  removeInteraction();
276
295
  if (currentViewshed.value !== viewshed) {
277
- setCurrentViewshed(viewshed);
296
+ activateViewshed(viewshed);
278
297
  heightMode.value = viewshed.heightOffset
279
298
  ? HeightModes.RELATIVE
280
299
  : HeightModes.ABSOLUTE;
@@ -387,7 +406,8 @@ export default function createViewshedManager(app, config, categoryHelper) {
387
406
  setupMultiSelect() {
388
407
  removeInteraction();
389
408
  mode.value = ViewshedPluginModes.MULTI_SELECT;
390
- setCurrentViewshed(null);
409
+ deactivateCurrentViewshed();
410
+ currentViewshed.value = null;
391
411
  },
392
412
  mode,
393
413
  heightMode,