@vcmap/viewshed 3.0.3 → 4.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.
@@ -1,4 +1,10 @@
1
+ import type { Ref, ShallowRef } from 'vue';
1
2
  import { nextTick, ref, shallowRef } from 'vue';
3
+ import type {
4
+ EditFeaturesSession,
5
+ EditGeometrySession,
6
+ FeatureAtPixelInteraction,
7
+ } from '@vcmap/core';
2
8
  import {
3
9
  CesiumMap,
4
10
  EventType,
@@ -12,73 +18,96 @@ import {
12
18
  wgs84Projection,
13
19
  } from '@vcmap/core';
14
20
  import { HeightReference } from '@vcmap-cesium/engine';
21
+ import { getLogger } from '@vcsuite/logger';
15
22
  import { Feature } from 'ol';
16
23
  import { Point } from 'ol/geom';
17
24
  import { Style } from 'ol/style.js';
18
25
  import { unByKey } from 'ol/Observable.js';
26
+ import type { Coordinate } from 'ol/coordinate.js';
27
+ import type { VcsUiApp } from '@vcmap/ui';
28
+ import { name } from '../package.json';
29
+ import type { ViewshedTypes } from './viewshed.js';
19
30
  import Viewshed from './viewshed.js';
20
31
  import ViewshedInteraction from './viewshedInteraction.js';
32
+ import type { ViewshedPluginOptions } from './index.js';
33
+ import type { ViewshedCategoryHelper } from './viewshedCategory.js';
21
34
 
22
35
  /**
23
- * @typedef {Object} ViewshedManager
24
- * @property {import("vue").ShallowRef<import("./viewshed.js").default | null>} currentViewshed The current viewshed, that is displayed in the map.
25
- * @property {import("vue").Ref<null | boolean>} currentIsPersisted Whether current viewshed is persisted or not.
26
- * @property {import("vue").Ref<import("@vcmap/core").EditFeaturesSession | import("@vcmap/core").EditGeometrySession | null>} currentEditSession The current edit session, when in MOVE mode. Read only.
27
- * @property {import("vue").ShallowRef<import("ol").Feature[]>} currentFeatures The feature that is created for feature/geometry editing in {@link moveCurrentViewshed}. Needed to match the EditorManager API from the UI.
28
- * @property {function(import("./viewshed.js").ViewshedTypes): void} createViewshed Creates a new viewshed and stops a running create process.
29
- * @property {function(import("./viewshed.js").default):void} viewViewshed Changes mode to VIEW for passed Viewshed.
30
- * @property {function(import("./viewshed.js").default):void} editViewshed Changes mode to EDIT for passed Viewshed.
31
- * @property {function(boolean):void} moveCurrentViewshed Changes mode to MOVE. If heightMode is ABSOLUTE a translate EditFeatureSession is started, if RELATIVE a EditGeometrySession is started.
32
- * @property {function():void} setupMultiSelect Changes mode to MULTI_SELECT.
33
- * @property {function():void} persistCurrent Adds current viewshed to the category collection.
34
- * @property {import("vue").Ref<ViewshedPluginModes | null>} mode Viewshed mode. Should only be used to watch and get the mode, not to set the mode.
35
- * @property {import("vue").Ref<HeightModes>} heightMode The height mode the viewshed plugin is currently in. Use changeHeightMode to change height mode when there is a currentViewshed.
36
- * @property {function():void} changeHeightMode Sets heightMode and calculates the Z value according to the input heightMode.
37
- * @property {function():void} placeCurrentFeaturesOnTerrain Places viewshed on terrain. Only available when in 'move' mode and height mode 'absolute'.
38
- * @property {function(boolean=):void} stop Stops the creation and removes current viewshed.
39
- * @property {function():void} destroy Destroys the viewshed manager.
40
- */
41
-
42
- /**
43
- * @enum {string}
44
- * @property {string} ABSOLUTE Absolute
45
- * @property {string} RELATIVE Relative to ground
36
+ * ViewshedManager interface for managing viewsheds
46
37
  */
47
- export const HeightModes = {
48
- ABSOLUTE: 'absolute',
49
- RELATIVE: 'relative',
38
+ export type ViewshedManager = {
39
+ /** The current viewshed, that is displayed in the map. */
40
+ currentViewshed: ShallowRef<Viewshed | null>;
41
+ /** Whether current viewshed is persisted or not. */
42
+ currentIsPersisted: Ref<null | boolean>;
43
+ /** The current edit session, when in MOVE mode. Read only. */
44
+ currentEditSession: Ref<EditFeaturesSession | EditGeometrySession | null>;
45
+ /** The feature that is created for feature/geometry editing in moveCurrentViewshed. Needed to match the EditorManager API from the UI. */
46
+ currentFeatures: ShallowRef<Feature[]>;
47
+ /** Creates a new viewshed and stops a running create process. */
48
+ createViewshed(viewshedType: ViewshedTypes): Promise<void>;
49
+ /** Changes mode to VIEW for passed Viewshed. */
50
+ viewViewshed(viewshed: Viewshed): void;
51
+ /** Changes mode to EDIT for passed Viewshed. */
52
+ editViewshed(viewshed: Viewshed): void;
53
+ /** Changes mode to MOVE. If heightMode is ABSOLUTE a translate EditFeatureSession is started, if RELATIVE a EditGeometrySession is started. */
54
+ moveCurrentViewshed(activate: boolean): void;
55
+ /** Changes mode to MULTI_SELECT. */
56
+ setupMultiSelect(): void;
57
+ /** Adds current viewshed to the category collection. */
58
+ persistCurrent(): void;
59
+ /** Viewshed mode. Should only be used to watch and get the mode, not to set the mode. */
60
+ mode: Ref<ViewshedPluginModes | null>;
61
+ /** The height mode the viewshed plugin is currently in. Use changeHeightMode to change height mode when there is a currentViewshed. */
62
+ heightMode: Ref<HeightModes>;
63
+ /** Sets heightMode and calculates the Z value according to the input heightMode. */
64
+ changeHeightMode(newHeightMode: HeightModes): void;
65
+ /** Places viewshed on terrain. Only available when in 'move' mode and height mode 'absolute'. */
66
+ placeCurrentFeaturesOnTerrain(): Promise<void>;
67
+ /** Stops the creation and removes current viewshed. */
68
+ stop(clear?: boolean): void;
69
+ /** Destroys the viewshed manager. */
70
+ destroy(): void;
50
71
  };
51
72
 
52
- /**
53
- * @enum {string}
54
- * @property {string} CREATE Window with instructions is open, map interaction for setting viewshed is active
55
- * @property {string} VIEW Viewshed is visible in map, window is closed
56
- * @property {string} EDIT Viewshed is visible in map, window is open
57
- * @property {string} MOVE Viewshed is visible in map, window is open, move interaction is active
58
- */
59
- export const ViewshedPluginModes = {
60
- CREATE: 'create',
61
- VIEW: 'view',
62
- EDIT: 'edit',
63
- MOVE: 'move',
64
- MULTI_SELECT: 'multiSelect',
65
- };
73
+ export enum HeightModes {
74
+ ABSOLUTE = 'absolute',
75
+ RELATIVE = 'relative',
76
+ }
77
+
78
+ export enum ViewshedPluginModes {
79
+ /** Window with instructions is open, map interaction for setting viewshed is active */
80
+ CREATE = 'create',
81
+ /** Viewshed is visible in map, window is closed */
82
+ VIEW = 'view',
83
+ /** Viewshed is visible in map, window is open */
84
+ EDIT = 'edit',
85
+ /** Viewshed is visible in map, window is open, move interaction is active */
86
+ MOVE = 'move',
87
+ MULTI_SELECT = 'multiSelect',
88
+ }
66
89
 
67
90
  /** The default height offset of a viewshed. */
68
91
  export const defaultHeightOffset = 1.8;
69
92
 
70
93
  /**
71
94
  * Creates layer with feature at a specified position.
72
- * @param {number[]} position Position for feature.
73
- * @returns {{layer: import("@vcmap/core").VectorLayer, feature: import("ol").Feature, destroy: function():void}} A layer and the added feature at the passed position.
95
+ * @param Position for feature.
96
+ * @returns A layer and the added feature at the passed position.
74
97
  */
75
- function createLayerWithFeature(position) {
98
+ function createLayerWithFeature(position: Coordinate): {
99
+ layer: VectorLayer;
100
+ feature: Feature;
101
+ destroy: () => void;
102
+ } {
76
103
  const layer = new VectorLayer({
77
104
  projection: wgs84Projection.toJSON(),
78
105
  zIndex: maxZIndex - 1,
79
106
  });
80
107
  markVolatile(layer);
81
- layer.activate();
108
+ layer.activate().catch((e: unknown) => {
109
+ getLogger(name).error('Failed to activate layer', String(e));
110
+ });
82
111
 
83
112
  const feature = new Feature(new Point(position));
84
113
  // hide feature
@@ -89,7 +118,7 @@ function createLayerWithFeature(position) {
89
118
  return {
90
119
  layer,
91
120
  feature,
92
- destroy() {
121
+ destroy(): void {
93
122
  feature.dispose();
94
123
  layer.destroy();
95
124
  },
@@ -101,10 +130,13 @@ function createLayerWithFeature(position) {
101
130
  * In case of heightMode ABSOLUTE the eventType is CLICKMOVE, and therefore sets the viewshed on top of terrain AND buildings.
102
131
  * In case of heightMode RELATIVE the eventType is NONE which means viewshed is only set on top of terrain.
103
132
  * Run featureInteraction.setActive() to reset eventType, pickPosition and pullPickedPosition.
104
- * @param {import("@vcmap/core").FeatureAtPixelInteraction} featureInteraction The featureInteraction of the maps eventHandler
105
- * @param {HeightModes} heightMode The current height mode of the viewshed plugin
133
+ * @param featureInteraction The featureInteraction of the maps eventHandler
134
+ * @param heightMode The current height mode of the viewshed plugin
106
135
  */
107
- function updateFeatureInteraction(featureInteraction, heightMode) {
136
+ function updateFeatureInteraction(
137
+ featureInteraction: FeatureAtPixelInteraction,
138
+ heightMode: HeightModes,
139
+ ): void {
108
140
  const eventType =
109
141
  heightMode === HeightModes.ABSOLUTE ? EventType.CLICKMOVE : EventType.NONE;
110
142
  featureInteraction.setActive(eventType);
@@ -112,33 +144,27 @@ function updateFeatureInteraction(featureInteraction, heightMode) {
112
144
  featureInteraction.pullPickedPosition = 1.8;
113
145
  }
114
146
 
115
- /**
116
- *
117
- * @param {import("@vcmap/ui").VcsUiApp} app The VcsUiApp instance
118
- * @param {import("./index.js").ViewshedPluginOptions} config
119
- * @param {import("./viewshedCategory.js").ViewshedCategoryHelper} categoryHelper
120
- * @returns {ViewshedManager} The viewshed manager, which is responsible for managing the creation and editing of viewsheds.
121
- */
122
- export default function createViewshedManager(app, config, categoryHelper) {
123
- /** @type {import("vue").ShallowRef<import("./viewshed.js").default | null>} */
124
- const currentViewshed = shallowRef(null);
125
- /** @type {import("vue").Ref<boolean | null>} */
126
- const currentIsPersisted = ref(null);
127
- /** @type {import("vue").Ref<ViewshedPluginModes | null>} */
128
- const mode = ref(null);
147
+ export default function createViewshedManager(
148
+ app: VcsUiApp,
149
+ config: ViewshedPluginOptions,
150
+ categoryHelper: ViewshedCategoryHelper,
151
+ ): ViewshedManager {
152
+ const currentViewshed = shallowRef<Viewshed | null>(null);
153
+ const currentIsPersisted = ref<boolean | null>(null);
154
+ const mode = ref<ViewshedPluginModes | null>(null);
129
155
  const heightMode = ref(HeightModes.ABSOLUTE);
130
- let removeInteraction = () => {};
131
- /** @type {import("vue").Ref<import("@vcmap/core").EditFeaturesSession | import("@vcmap/core").EditGeometrySession | null>} */
132
- const currentEditSession = shallowRef(null);
156
+ const currentEditSession = shallowRef<
157
+ EditFeaturesSession | EditGeometrySession | null
158
+ >(null);
159
+ let removeInteraction = (): void => {};
133
160
  /**
134
161
  * The feature that is created for feature/geometry editing in {@link moveCurrentViewshed}. Needed to match the EditorManager API from the UI.
135
- * @type {import("vue").ShallowRef<import("ol").Feature[]>}
136
162
  */
137
- const currentFeatures = shallowRef([]);
163
+ const currentFeatures = shallowRef<Feature[]>([]);
138
164
 
139
- let shadowMapChangedListener = () => {};
165
+ let shadowMapChangedListener = (): void => {};
140
166
 
141
- function deactivateCurrentViewshed() {
167
+ function deactivateCurrentViewshed(): void {
142
168
  if (currentIsPersisted.value && currentViewshed.value) {
143
169
  currentViewshed.value.deactivate();
144
170
  categoryHelper.setVisibility(currentViewshed.value.name, false);
@@ -149,9 +175,9 @@ export default function createViewshedManager(app, config, categoryHelper) {
149
175
 
150
176
  /**
151
177
  * Stops the viewshed operation.
152
- * @param {boolean} [clear=true] - Indicates whether to clear the selection.
178
+ * Indicates whether to clear the selection.
153
179
  */
154
- function stop(clear = true) {
180
+ function stop(clear = true): void {
155
181
  shadowMapChangedListener();
156
182
  removeInteraction();
157
183
  deactivateCurrentViewshed();
@@ -165,9 +191,8 @@ export default function createViewshedManager(app, config, categoryHelper) {
165
191
 
166
192
  /**
167
193
  * activates a viewshed, and adds a Listener to the shadowMapChangedEvent to deactivate the viewshed plugin.
168
- * @param {Viewshed} viewshed
169
194
  */
170
- function activateViewshed(viewshed) {
195
+ function activateViewshed(viewshed: Viewshed): void {
171
196
  shadowMapChangedListener();
172
197
  // deactivate existing Viewsheds
173
198
  deactivateCurrentViewshed();
@@ -183,7 +208,7 @@ export default function createViewshedManager(app, config, categoryHelper) {
183
208
  }
184
209
  }
185
210
 
186
- async function createViewshed(viewshedType) {
211
+ async function createViewshed(viewshedType: ViewshedTypes): Promise<void> {
187
212
  stop();
188
213
  await nextTick(); // so the viewshedWindow is closed with mode === null and not CREATE
189
214
 
@@ -202,7 +227,7 @@ export default function createViewshedManager(app, config, categoryHelper) {
202
227
  });
203
228
  activateViewshed(viewshed);
204
229
  // setup viewshed create interaction
205
- const interaction = new ViewshedInteraction(currentViewshed.value);
230
+ const interaction = new ViewshedInteraction(currentViewshed.value!);
206
231
 
207
232
  interaction.finished.addEventListener(() => {
208
233
  removeInteraction();
@@ -226,18 +251,18 @@ export default function createViewshedManager(app, config, categoryHelper) {
226
251
  updateFeatureInteraction(featureInteraction, HeightModes.ABSOLUTE); // always set second click (lookAt) absolute
227
252
  });
228
253
 
229
- removeInteraction = () => {
254
+ removeInteraction = (): void => {
230
255
  removeExclusiveInteraction();
231
256
  interaction.destroy();
232
257
  featureInteraction.setActive(); // resets featureInteractions eventType, pickPosition and pullPickedPosition
233
258
 
234
- removeInteraction = () => {};
259
+ removeInteraction = (): void => {};
235
260
  };
236
261
 
237
262
  mode.value = ViewshedPluginModes.CREATE;
238
263
  }
239
264
 
240
- function moveCurrentViewshed(activate) {
265
+ function moveCurrentViewshed(activate: boolean): void {
241
266
  if (currentViewshed.value && activate) {
242
267
  removeInteraction();
243
268
 
@@ -265,9 +290,7 @@ export default function createViewshedManager(app, config, categoryHelper) {
265
290
  const geometryListenerKey = feature.getGeometry()?.on('change', () => {
266
291
  if (currentViewshed.value) {
267
292
  currentViewshed.value.position = Projection.mercatorToWgs84(
268
- /** @type {import("ol/geom").Point} */ (
269
- feature.getGeometry()
270
- ).getCoordinates(),
293
+ (feature as Feature<Point>).getGeometry()!.getCoordinates(),
271
294
  );
272
295
  } else {
273
296
  stop();
@@ -276,8 +299,8 @@ export default function createViewshedManager(app, config, categoryHelper) {
276
299
 
277
300
  mode.value = ViewshedPluginModes.MOVE;
278
301
 
279
- removeInteraction = () => {
280
- removeInteraction = () => {}; // needs to be before currentEditSession.value.stop(), otherwise recursion
302
+ removeInteraction = (): void => {
303
+ removeInteraction = (): void => {}; // needs to be before currentEditSession.value.stop(), otherwise recursion
281
304
 
282
305
  if (geometryListenerKey) {
283
306
  unByKey(geometryListenerKey);
@@ -296,10 +319,11 @@ export default function createViewshedManager(app, config, categoryHelper) {
296
319
 
297
320
  /**
298
321
  * Changes the mode and the current viewshed. Only works with viewshedMode EDIT and VIEW.
299
- * @param {ViewshedPluginModes} viewshedMode
300
- * @param {import("./viewshed.js").default} viewshed
301
322
  */
302
- function changeMode(viewshedMode, viewshed) {
323
+ function changeMode(
324
+ viewshedMode: ViewshedPluginModes,
325
+ viewshed: Viewshed,
326
+ ): void {
303
327
  removeInteraction();
304
328
  if (currentViewshed.value !== viewshed) {
305
329
  activateViewshed(viewshed);
@@ -331,7 +355,7 @@ export default function createViewshedManager(app, config, categoryHelper) {
331
355
  viewshedWindow.state.headerTitle = title;
332
356
  }
333
357
  }),
334
- categoryHelper.visibilityChanged.addEventListener((item) => {
358
+ categoryHelper.visibilityChanged.addEventListener(({ item }) => {
335
359
  const isCurrentlyVisible = currentViewshed.value?.name === item.name;
336
360
  if (isCurrentlyVisible) {
337
361
  stop();
@@ -343,7 +367,7 @@ export default function createViewshedManager(app, config, categoryHelper) {
343
367
  }),
344
368
  ];
345
369
 
346
- function changeHeightMode(newHeightMode) {
370
+ function changeHeightMode(newHeightMode: HeightModes): void {
347
371
  if (newHeightMode === heightMode.value || !currentViewshed.value) {
348
372
  return;
349
373
  }
@@ -365,7 +389,7 @@ export default function createViewshedManager(app, config, categoryHelper) {
365
389
  const { position: currentPosition, heightOffset: currentHeightOffset } =
366
390
  currentViewshed.value;
367
391
  if (newHeightMode === HeightModes.RELATIVE) {
368
- /** @type {import("@vcmap/core").CesiumMap} */ (app.maps.activeMap)
392
+ (app.maps.activeMap as CesiumMap)
369
393
  .getHeightFromTerrain([Projection.wgs84ToMercator(currentPosition)])
370
394
  .then((value) => {
371
395
  const newPosition = Projection.mercatorToWgs84(value[0]);
@@ -375,6 +399,12 @@ export default function createViewshedManager(app, config, categoryHelper) {
375
399
  currentPosition[2] - newPosition[2];
376
400
  currentViewshed.value.position = newPosition;
377
401
  }
402
+ })
403
+ .catch((e: unknown) => {
404
+ getLogger(name).error(
405
+ 'Failed to get height from terrain',
406
+ String(e),
407
+ );
378
408
  });
379
409
  } else {
380
410
  currentViewshed.value.position = [
@@ -393,18 +423,19 @@ export default function createViewshedManager(app, config, categoryHelper) {
393
423
  currentEditSession,
394
424
  currentFeatures,
395
425
  createViewshed,
396
- viewViewshed(viewshed) {
426
+ viewViewshed(viewshed): void {
397
427
  changeMode(ViewshedPluginModes.VIEW, viewshed);
398
428
  },
399
- editViewshed(viewshed) {
429
+ editViewshed(viewshed): void {
400
430
  changeMode(ViewshedPluginModes.EDIT, viewshed);
401
431
  if (currentIsPersisted.value) {
402
432
  // makes sure the editor window is open, if it is not triggered by a new selection but e.g. the tristate button
403
433
  categoryHelper.setSelection(viewshed.name);
404
- categoryHelper.collectionComponent.openEditorWindow(viewshed);
434
+ // FIXME does not exist
435
+ // categoryHelper.collectionComponent.openEditorWindow(viewshed);
405
436
  }
406
437
  },
407
- persistCurrent() {
438
+ persistCurrent(): void {
408
439
  if (currentViewshed.value) {
409
440
  categoryHelper.add(currentViewshed.value);
410
441
  currentIsPersisted.value = true;
@@ -413,7 +444,7 @@ export default function createViewshedManager(app, config, categoryHelper) {
413
444
  }
414
445
  },
415
446
  moveCurrentViewshed,
416
- setupMultiSelect() {
447
+ setupMultiSelect(): void {
417
448
  removeInteraction();
418
449
  mode.value = ViewshedPluginModes.MULTI_SELECT;
419
450
  deactivateCurrentViewshed();
@@ -422,7 +453,7 @@ export default function createViewshedManager(app, config, categoryHelper) {
422
453
  mode,
423
454
  heightMode,
424
455
  changeHeightMode,
425
- async placeCurrentFeaturesOnTerrain() {
456
+ async placeCurrentFeaturesOnTerrain(): Promise<void> {
426
457
  if (
427
458
  currentViewshed.value &&
428
459
  currentEditSession.value?.type === SessionType.EDIT_FEATURES &&
@@ -438,9 +469,11 @@ export default function createViewshedManager(app, config, categoryHelper) {
438
469
  }
439
470
  },
440
471
  stop,
441
- destroy() {
472
+ destroy(): void {
442
473
  stop();
443
- categoryListener.forEach((l) => l());
474
+ categoryListener.forEach((l) => {
475
+ l();
476
+ });
444
477
  },
445
478
  };
446
479
  }
@@ -1,3 +1,4 @@
1
+ import type { Camera } from '@vcmap-cesium/engine';
1
2
  import {
2
3
  Color,
3
4
  ColorGeometryInstanceAttribute,
@@ -9,33 +10,45 @@ import {
9
10
  SphereOutlineGeometry,
10
11
  Transforms,
11
12
  } from '@vcmap-cesium/engine';
13
+ import type { VcsCameraPrimitiveOptions } from '@vcmap/core';
12
14
  import { VcsCameraPrimitive } from '@vcmap/core';
13
15
 
14
- /**
15
- * @type {import("@vcmap-cesium/engine").Color}
16
- */
17
16
  const scratchColor = new Color();
18
- /**
19
- * @type {import("@vcmap-cesium/engine").Matrix4}
20
- */
21
17
  const scratchMatrix = new Matrix4();
22
18
 
23
- /**
24
- * @class
25
- * @extends VcsCameraPrimitive
26
- */
19
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
20
+ // @ts-ignore
27
21
  class ViewshedCameraPrimitive extends VcsCameraPrimitive {
28
- constructor(options) {
22
+ static get className(): string {
23
+ return 'ViewshedCameraPrimitive';
24
+ }
25
+
26
+ spot: boolean;
27
+
28
+ private _allowPicking: boolean;
29
+
30
+ private _color: Color = Color.WHITE;
31
+
32
+ private _camera: Camera;
33
+
34
+ private _planesPrimitives: Primitive[] = [];
35
+
36
+ private _outlinePrimitives: Primitive[] = [];
37
+
38
+ constructor(
39
+ options: VcsCameraPrimitiveOptions & {
40
+ spot: boolean;
41
+ camera: Camera;
42
+ allowPicking: boolean;
43
+ },
44
+ ) {
29
45
  super(options);
30
- /** @type {boolean} */
31
46
  this.spot = options.spot;
47
+ this._camera = options.camera;
48
+ this._allowPicking = options.allowPicking;
32
49
  }
33
50
 
34
- /**
35
- * Updates the camera primitive.
36
- * @param {unknown} frameState
37
- */
38
- update(frameState) {
51
+ update(frameState: unknown): void {
39
52
  if (!this.show) {
40
53
  return;
41
54
  }
@@ -50,7 +63,7 @@ class ViewshedCameraPrimitive extends VcsCameraPrimitive {
50
63
  scratchMatrix,
51
64
  );
52
65
  planesPrimitives[0] = new Primitive({
53
- allowPicking: this.allowPicking,
66
+ allowPicking: this._allowPicking,
54
67
  geometryInstances: new GeometryInstance({
55
68
  geometry: new SphereGeometry({
56
69
  radius: 2,
@@ -70,7 +83,7 @@ class ViewshedCameraPrimitive extends VcsCameraPrimitive {
70
83
  });
71
84
 
72
85
  outlinePrimitives[0] = new Primitive({
73
- allowPicking: this.allowPicking,
86
+ allowPicking: this._allowPicking,
74
87
  geometryInstances: new GeometryInstance({
75
88
  geometry: new SphereOutlineGeometry({
76
89
  radius: 2,
@@ -89,7 +102,9 @@ class ViewshedCameraPrimitive extends VcsCameraPrimitive {
89
102
  }
90
103
  const { length } = planesPrimitives;
91
104
  for (let i = 0; i < length; ++i) {
105
+ // @ts-expect-error update
92
106
  outlinePrimitives[i].update(frameState);
107
+ // @ts-expect-error update
93
108
  planesPrimitives[i].update(frameState);
94
109
  }
95
110
  } else {
@@ -1,132 +0,0 @@
1
- import { CesiumMap } from '@vcmap/core';
2
- import { ToolboxType } from '@vcmap/ui';
3
- import { check, ofEnum } from '@vcsuite/check';
4
- import { reactive, watch } from 'vue';
5
- import { ViewshedTypes } from '../viewshed.js';
6
- import { ViewshedIcons } from './windowHelper.js';
7
- import { ViewshedPluginModes } from '../viewshedManager.js';
8
-
9
- /**
10
- * @typedef {Object} ViewshedToolbox
11
- * @property {import("@vcmap/ui/src/manager/toolbox/toolboxManager").SelectToolboxComponentOptions} toolbox
12
- * @property {function():void} destroy
13
- */
14
-
15
- /**
16
- *
17
- * @param {import("@vcmap/ui").VcsUiApp} app The VcsUiApp instance
18
- * @param {import("../viewshedManager.js").ViewshedManager} manager The viewshed manager.
19
- * @param {string} name Name of toolbox.
20
- * @param {Array<string>} tools The tools to be available in the toolbox
21
- * @returns {ViewshedToolbox} A select toolbox with buttons to create 360 and cone viewshed.
22
- */
23
- function createViewshedToolbox(app, manager, name, tools) {
24
- const toolbox = {
25
- type: ToolboxType.SELECT,
26
- action: reactive({
27
- name,
28
- currentIndex: 0,
29
- active: false,
30
- background: false,
31
- disabled: !(app.maps.activeMap instanceof CesiumMap),
32
- callback() {
33
- if (this.active) {
34
- if (this.background && manager.currentViewshed.value) {
35
- manager.editViewshed(manager.currentViewshed.value);
36
- } else {
37
- manager.stop();
38
- }
39
- } else {
40
- const toolName = this.tools[this.currentIndex].name;
41
- manager.createViewshed(toolName);
42
- }
43
- },
44
- selected(newIndex) {
45
- if (newIndex !== this.currentIndex) {
46
- this.currentIndex = newIndex;
47
- }
48
- const toolName = this.tools[this.currentIndex].name;
49
- manager.createViewshed(toolName);
50
- },
51
- tools: tools.flatMap((tool) => {
52
- if (tool === ViewshedTypes.CONE) {
53
- return {
54
- name: ViewshedTypes.CONE,
55
- icon: ViewshedIcons[ViewshedTypes.CONE],
56
- title: `viewshed.create.${ViewshedTypes.CONE}`,
57
- };
58
- } else if (tool === ViewshedTypes.THREESIXTY) {
59
- return {
60
- name: ViewshedTypes.THREESIXTY,
61
- icon: ViewshedIcons[ViewshedTypes.THREESIXTY],
62
- title: `viewshed.create.${ViewshedTypes.THREESIXTY}`,
63
- };
64
- } else {
65
- return [];
66
- }
67
- }),
68
- }),
69
- };
70
-
71
- const viewshedModeWatcher = watch(manager.mode, (mode) => {
72
- if (mode === ViewshedPluginModes.VIEW) {
73
- toolbox.action.background = true;
74
- toolbox.action.active = true;
75
- } else if (mode) {
76
- toolbox.action.background = false;
77
- toolbox.action.active = true;
78
- } else {
79
- toolbox.action.background = false;
80
- toolbox.action.active = false;
81
- }
82
- });
83
-
84
- const currentViewshedWatcher = watch(
85
- manager.currentViewshed,
86
- (currentViewshed) => {
87
- if (currentViewshed) {
88
- toolbox.action.currentIndex = toolbox.action.tools.findIndex(
89
- (tool) => tool.name === currentViewshed.type,
90
- );
91
- }
92
- },
93
- );
94
-
95
- const mapChangedListener = app.maps.mapActivated.addEventListener((map) => {
96
- if (map instanceof CesiumMap) {
97
- toolbox.action.disabled = false;
98
- } else {
99
- toolbox.action.disabled = true;
100
- }
101
- });
102
-
103
- return {
104
- destroy() {
105
- viewshedModeWatcher();
106
- currentViewshedWatcher();
107
- mapChangedListener();
108
- },
109
- toolbox,
110
- };
111
- }
112
-
113
- /**
114
- *
115
- * @param {import("@vcmap/ui").VcsUiApp} app The VcsUiApp instance
116
- * @param {import("../viewshedManager.js").ViewshedManager} manager The viewshed manager.
117
- * @param {string} name Name of toolbox action and owner of toolbox component
118
- * @param {Array<string>} tools The tools to be available in the toolbox
119
- * @returns {function():void} Function to remove toolbox component.
120
- */
121
- export default function addToolButtons(app, manager, name, tools) {
122
- check(tools, [ofEnum(ViewshedTypes)]);
123
-
124
- const { toolbox: createToolbox, destroy: destroyCreateToolbox } =
125
- createViewshedToolbox(app, manager, name, tools);
126
- const createId = app.toolboxManager.add(createToolbox, name).id;
127
-
128
- return () => {
129
- app.toolboxManager.remove(createId);
130
- destroyCreateToolbox();
131
- };
132
- }