@vcmap/core 5.1.5 → 5.2.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 (66) hide show
  1. package/dist/src/featureProvider/wmsFeatureProvider.d.ts +2 -2
  2. package/dist/src/featureProvider/wmsFeatureProvider.js +3 -2
  3. package/dist/src/featureProvider/wmsFeatureProvider.js.map +1 -1
  4. package/dist/src/interaction/abstractInteraction.d.ts +5 -0
  5. package/dist/src/interaction/abstractInteraction.js.map +1 -1
  6. package/dist/src/interaction/eventHandler.d.ts +5 -1
  7. package/dist/src/interaction/eventHandler.js +29 -12
  8. package/dist/src/interaction/eventHandler.js.map +1 -1
  9. package/dist/src/map/baseOLMap.d.ts +2 -1
  10. package/dist/src/map/baseOLMap.js +1 -1
  11. package/dist/src/map/baseOLMap.js.map +1 -1
  12. package/dist/src/map/cesiumMap.d.ts +2 -1
  13. package/dist/src/map/cesiumMap.js +7 -4
  14. package/dist/src/map/cesiumMap.js.map +1 -1
  15. package/dist/src/map/obliqueMap.js +3 -3
  16. package/dist/src/map/obliqueMap.js.map +1 -1
  17. package/dist/src/map/openlayersMap.js +1 -1
  18. package/dist/src/map/openlayersMap.js.map +1 -1
  19. package/dist/src/map/vcsMap.d.ts +17 -6
  20. package/dist/src/map/vcsMap.js +46 -8
  21. package/dist/src/map/vcsMap.js.map +1 -1
  22. package/dist/src/util/clipping/clippingObject.js +10 -1
  23. package/dist/src/util/clipping/clippingObject.js.map +1 -1
  24. package/dist/src/util/clipping/clippingObjectManager.js +6 -0
  25. package/dist/src/util/clipping/clippingObjectManager.js.map +1 -1
  26. package/dist/src/util/clipping/clippingPlaneHelper.d.ts +3 -2
  27. package/dist/src/util/clipping/clippingPlaneHelper.js +14 -7
  28. package/dist/src/util/clipping/clippingPlaneHelper.js.map +1 -1
  29. package/dist/src/util/editor/editFeaturesSession.js +56 -4
  30. package/dist/src/util/editor/editFeaturesSession.js.map +1 -1
  31. package/dist/src/util/editor/editGeometrySession.d.ts +6 -1
  32. package/dist/src/util/editor/editGeometrySession.js +51 -44
  33. package/dist/src/util/editor/editGeometrySession.js.map +1 -1
  34. package/dist/src/util/editor/interactions/editGeometryMouseOverInteraction.d.ts +1 -1
  35. package/dist/src/util/editor/interactions/editGeometryMouseOverInteraction.js +4 -2
  36. package/dist/src/util/editor/interactions/editGeometryMouseOverInteraction.js.map +1 -1
  37. package/dist/src/util/editor/interactions/rightClickInteraction.d.ts +9 -0
  38. package/dist/src/util/editor/interactions/rightClickInteraction.js +31 -0
  39. package/dist/src/util/editor/interactions/rightClickInteraction.js.map +1 -0
  40. package/dist/src/util/flight/flightInstance.d.ts +1 -1
  41. package/dist/src/util/flight/flightPlayer.js +16 -13
  42. package/dist/src/util/flight/flightPlayer.js.map +1 -1
  43. package/dist/src/util/mapCollection.d.ts +14 -0
  44. package/dist/src/util/mapCollection.js +33 -0
  45. package/dist/src/util/mapCollection.js.map +1 -1
  46. package/dist/src/vcsModule.js +1 -1
  47. package/dist/src/vcsModule.js.map +1 -1
  48. package/package.json +3 -2
  49. package/src/featureProvider/wmsFeatureProvider.ts +6 -8
  50. package/src/interaction/abstractInteraction.ts +5 -0
  51. package/src/interaction/eventHandler.ts +30 -13
  52. package/src/map/baseOLMap.ts +3 -2
  53. package/src/map/cesiumMap.ts +11 -4
  54. package/src/map/obliqueMap.ts +3 -3
  55. package/src/map/openlayersMap.ts +1 -1
  56. package/src/map/vcsMap.ts +63 -10
  57. package/src/util/clipping/clippingObject.ts +10 -1
  58. package/src/util/clipping/clippingObjectManager.ts +6 -0
  59. package/src/util/clipping/clippingPlaneHelper.ts +14 -6
  60. package/src/util/editor/editFeaturesSession.ts +72 -10
  61. package/src/util/editor/editGeometrySession.ts +61 -39
  62. package/src/util/editor/interactions/editGeometryMouseOverInteraction.ts +7 -2
  63. package/src/util/editor/interactions/rightClickInteraction.ts +42 -0
  64. package/src/util/flight/flightPlayer.ts +21 -15
  65. package/src/util/mapCollection.ts +47 -0
  66. package/src/vcsModule.ts +1 -1
@@ -1,10 +1,7 @@
1
1
  import GML2 from 'ol/format/GML2.js';
2
2
  import type { Options as GMLOptions } from 'ol/format/GMLBase.js';
3
3
  import WFS from 'ol/format/WFS.js';
4
- import GeoJSON, {
5
- type GeoJSONObject,
6
- type Options as GeoJSONOptions,
7
- } from 'ol/format/GeoJSON.js';
4
+ import GeoJSON, { type Options as GeoJSONOptions } from 'ol/format/GeoJSON.js';
8
5
  import GML3 from 'ol/format/GML3.js';
9
6
  import Point from 'ol/geom/Point.js';
10
7
  import { getTransform, type Projection as OLProjection } from 'ol/proj.js';
@@ -24,7 +21,7 @@ import Projection, {
24
21
  import type { WMSSourceOptions } from '../layer/wmsHelpers.js';
25
22
  import { getWMSSource } from '../layer/wmsHelpers.js';
26
23
  import Extent, { ExtentOptions } from '../util/extent.js';
27
- import { getInitForUrl, requestJson } from '../util/fetch.js';
24
+ import { getInitForUrl, requestUrl } from '../util/fetch.js';
28
25
  import { featureProviderClassRegistry } from '../classRegistry.js';
29
26
  import { TilingScheme } from '../layer/rasterLayer.js';
30
27
 
@@ -206,7 +203,7 @@ class WMSFeatureProvider extends AbstractFeatureProvider {
206
203
  }
207
204
 
208
205
  featureResponseCallback(
209
- data: GeoJSONObject,
206
+ data: Document | Element | ArrayBuffer | any | string,
210
207
  coordinate: Coordinate,
211
208
  ): Feature[] {
212
209
  let features: Feature[];
@@ -259,9 +256,10 @@ class WMSFeatureProvider extends AbstractFeatureProvider {
259
256
 
260
257
  if (url) {
261
258
  const init = getInitForUrl(url, headers);
262
- let data: GeoJSONObject;
259
+ let data: string;
263
260
  try {
264
- data = await requestJson<GeoJSONObject>(url, init);
261
+ const response = await requestUrl(url, init);
262
+ data = await response.text();
265
263
  } catch (ex) {
266
264
  this.getLogger().error(`Failed fetching WMS FeatureInfo ${url}`);
267
265
  return [];
@@ -15,6 +15,7 @@ import {
15
15
  PointerKeyType,
16
16
  } from './interactionType.js';
17
17
  import type VcsMap from '../map/vcsMap.js';
18
+ import VcsEvent from '../vcsEvent.js';
18
19
 
19
20
  export type MapEvent = {
20
21
  pointerEvent: PointerEventType;
@@ -70,6 +71,10 @@ export type InteractionEvent = MapEvent & {
70
71
  * whether the position is exact, eg with translucentDepthPicking on
71
72
  */
72
73
  exactPosition?: boolean;
74
+ /**
75
+ * called when the event chain has ended in which this event was fired.
76
+ */
77
+ chainEnded?: VcsEvent<void>;
73
78
  };
74
79
 
75
80
  export type EventAfterEventHandler = Omit<
@@ -146,6 +146,14 @@ class EventHandler {
146
146
  return this._modifierChanged;
147
147
  }
148
148
 
149
+ /**
150
+ * if an exclusive Interaction is set, this will return the id of the exclusive Interaction
151
+ * This can be used to add another Interaction to the same Id
152
+ */
153
+ get exclusiveInteractionId(): string | undefined {
154
+ return this._exclusiveInteraction?.id;
155
+ }
156
+
149
157
  /**
150
158
  * Add a dynamic interaction to the interaction chain. This is the default methodology for
151
159
  * user map interactions, such as drawing or measuring. If another exclusive interaction is added,
@@ -296,7 +304,10 @@ class EventHandler {
296
304
  return;
297
305
  }
298
306
 
299
- const actualEvent: Partial<InteractionEvent> & MapEvent = event;
307
+ const actualEvent: Partial<InteractionEvent> & MapEvent = {
308
+ ...event,
309
+ chainEnded: new VcsEvent(),
310
+ };
300
311
  if (this._dragging) {
301
312
  actualEvent.type = EventType.DRAGEND;
302
313
  actualEvent.key = this._dragging.key;
@@ -328,7 +339,10 @@ class EventHandler {
328
339
  }
329
340
 
330
341
  private _mouseMove(event: MapEvent): void {
331
- let actualEvent: Partial<InteractionEvent> & MapEvent = event;
342
+ let actualEvent: Partial<InteractionEvent> & MapEvent = {
343
+ ...event,
344
+ chainEnded: new VcsEvent(),
345
+ };
332
346
  if (this._lastDown) {
333
347
  if (this._dragging) {
334
348
  actualEvent.type = EventType.DRAG;
@@ -339,7 +353,11 @@ class EventHandler {
339
353
  !this._dragging &&
340
354
  Date.now() - (this._lastDown.time as number) > this.dragDuration
341
355
  ) {
342
- actualEvent = { type: EventType.DRAGSTART, ...this._lastDown };
356
+ actualEvent = {
357
+ type: EventType.DRAGSTART,
358
+ ...this._lastDown,
359
+ chainEnded: new VcsEvent(),
360
+ };
343
361
  this._dragging = actualEvent;
344
362
  this._startChain(actualEvent as InteractionEvent, true);
345
363
  }
@@ -399,22 +417,21 @@ class EventHandler {
399
417
  this._running = true;
400
418
  this._interactionChain
401
419
  .pipe(event)
402
- .then(this._endChain.bind(this))
403
420
  .catch((error) => {
404
421
  getLogger().error((error as Error).message);
405
- this._endChain();
422
+ })
423
+ .finally(() => {
424
+ event.chainEnded?.raiseEvent();
425
+ event.chainEnded?.destroy();
426
+ this._running = false;
427
+ const nextEvent = this._eventQueue.shift();
428
+ if (nextEvent) {
429
+ this._startChain(nextEvent);
430
+ }
406
431
  });
407
432
  }
408
433
  }
409
434
 
410
- private _endChain(): void {
411
- this._running = false;
412
- const nextEvent = this._eventQueue.shift();
413
- if (nextEvent) {
414
- this._startChain(nextEvent);
415
- }
416
- }
417
-
418
435
  /**
419
436
  * Destroys the event handler and its interaction chain.
420
437
  */
@@ -17,6 +17,7 @@ import {
17
17
  import { mapClassRegistry } from '../classRegistry.js';
18
18
  import type LayerCollection from '../util/layerCollection.js';
19
19
  import type Layer from '../layer/layer.js';
20
+ import { DisableMapControlOptions } from '../util/mapCollection.js';
20
21
 
21
22
  export function ensureLayerInCollection(
22
23
  layers: OLCollection<OLLayer>,
@@ -204,11 +205,11 @@ class BaseOLMap extends VcsMap<OLLayer> {
204
205
  }
205
206
  }
206
207
 
207
- disableMovement(prevent: boolean): void {
208
+ disableMovement(prevent: boolean | DisableMapControlOptions): void {
208
209
  super.disableMovement(prevent);
209
210
  if (this._olMap) {
210
211
  this._olMap.getInteractions().forEach((i) => {
211
- i.setActive(!prevent);
212
+ i.setActive(!this.movementPointerEventsDisabled);
212
213
  });
213
214
  }
214
215
  }
@@ -57,6 +57,7 @@ import { mapClassRegistry } from '../classRegistry.js';
57
57
  import type LayerCollection from '../util/layerCollection.js';
58
58
  import type Layer from '../layer/layer.js';
59
59
  import VcsEvent from '../vcsEvent.js';
60
+ import { DisableMapControlOptions } from '../util/mapCollection.js';
60
61
 
61
62
  export type CesiumMapOptions = VcsMapOptions & {
62
63
  /**
@@ -850,7 +851,11 @@ class CesiumMap extends VcsMap<CesiumVisualisationType> {
850
851
  viewpoint: Viewpoint,
851
852
  optMaximumHeight?: number,
852
853
  ): Promise<void> {
853
- if (this.movementDisabled || !viewpoint.isValid() || !this._cesiumWidget) {
854
+ if (
855
+ this.movementApiCallsDisabled ||
856
+ !viewpoint.isValid() ||
857
+ !this._cesiumWidget
858
+ ) {
854
859
  return;
855
860
  }
856
861
 
@@ -980,10 +985,12 @@ class CesiumMap extends VcsMap<CesiumVisualisationType> {
980
985
  );
981
986
  }
982
987
 
983
- disableMovement(bool: boolean): void {
984
- super.disableMovement(bool);
988
+ disableMovement(prevent: boolean | DisableMapControlOptions): void {
989
+ super.disableMovement(prevent);
990
+
985
991
  if (this._cesiumWidget) {
986
- this._cesiumWidget.scene.screenSpaceCameraController.enableInputs = !bool;
992
+ this._cesiumWidget.scene.screenSpaceCameraController.enableInputs =
993
+ !this.movementPointerEventsDisabled;
987
994
  }
988
995
  }
989
996
 
@@ -280,7 +280,7 @@ class ObliqueMap extends BaseOLMap {
280
280
  ): Promise<void> {
281
281
  check(obliqueCollection, ObliqueCollection);
282
282
 
283
- if (this.movementDisabled) {
283
+ if (this.movementApiCallsDisabled) {
284
284
  return;
285
285
  }
286
286
 
@@ -329,7 +329,7 @@ class ObliqueMap extends BaseOLMap {
329
329
  imageName: string,
330
330
  optCenter?: Coordinate,
331
331
  ): Promise<void> {
332
- if (this.movementDisabled || !this.initializedPromise) {
332
+ if (this.movementApiCallsDisabled || !this.initializedPromise) {
333
333
  return;
334
334
  }
335
335
  await this.initializedPromise;
@@ -414,7 +414,7 @@ class ObliqueMap extends BaseOLMap {
414
414
 
415
415
  async gotoViewpoint(viewpoint: Viewpoint): Promise<void> {
416
416
  if (
417
- this.movementDisabled ||
417
+ this.movementApiCallsDisabled ||
418
418
  !this.olMap ||
419
419
  !this._obliqueProvider ||
420
420
  !viewpoint.isValid()
@@ -106,7 +106,7 @@ class OpenlayersMap extends BaseOLMap {
106
106
  }
107
107
 
108
108
  gotoViewpoint(viewpoint: Viewpoint): Promise<void> {
109
- if (this.movementDisabled || !viewpoint.isValid() || !this.olMap) {
109
+ if (this.movementApiCallsDisabled || !viewpoint.isValid() || !this.olMap) {
110
110
  return Promise.resolve();
111
111
  }
112
112
  let { heading } = viewpoint;
package/src/map/vcsMap.ts CHANGED
@@ -1,9 +1,10 @@
1
+ import { getLogger as getLoggerByName, Logger } from '@vcsuite/logger';
1
2
  import { v4 as uuidv4 } from 'uuid';
2
3
  import type { MapEvent as OLMapEvent } from 'ol';
3
4
  import type { Layer as OLLayer } from 'ol/layer.js';
4
5
  import type { Coordinate } from 'ol/coordinate.js';
5
6
 
6
- import { check, maybe, oneOf } from '@vcsuite/check';
7
+ import { check, is, maybe, oneOf } from '@vcsuite/check';
7
8
  import VcsObject, { VcsObjectOptions } from '../vcsObject.js';
8
9
  import LayerCollection from '../util/layerCollection.js';
9
10
  import MapState from './mapState.js';
@@ -15,6 +16,11 @@ import { CesiumVisualisationType } from './cesiumMap.js';
15
16
  import type Viewpoint from '../util/viewpoint.js';
16
17
  import type Layer from '../layer/layer.js';
17
18
  import type { MapEvent } from '../interaction/abstractInteraction.js';
19
+ import type { DisableMapControlOptions } from '../util/mapCollection.js';
20
+
21
+ function getLogger(): Logger {
22
+ return getLoggerByName('vcMap');
23
+ }
18
24
 
19
25
  export type VcsMapOptions = VcsObjectOptions & {
20
26
  /**
@@ -76,10 +82,11 @@ class VcsMap<
76
82
 
77
83
  initialized: boolean;
78
84
 
79
- /**
80
- * if true, no movements should occur
81
- */
82
- movementDisabled: boolean;
85
+ private _movementApiCallsDisabled = false;
86
+
87
+ private _movementKeyEventsDisabled = false;
88
+
89
+ private _movementPointerEventsDisabled = false;
83
90
 
84
91
  /**
85
92
  * The name of a map to fall back on, if this map cant show a viewpoint
@@ -134,8 +141,6 @@ class VcsMap<
134
141
 
135
142
  this.initialized = false;
136
143
 
137
- this.movementDisabled = false;
138
-
139
144
  this.fallbackMap = options.fallbackMap || null;
140
145
 
141
146
  this._visualizations = new Map();
@@ -172,6 +177,44 @@ class VcsMap<
172
177
  return this._target;
173
178
  }
174
179
 
180
+ set movementDisabled(prevent: boolean) {
181
+ this._movementApiCallsDisabled = prevent;
182
+ this._movementKeyEventsDisabled = prevent;
183
+ this._movementPointerEventsDisabled = prevent;
184
+
185
+ getLogger().deprecate('movementDisabled', 'disableMovement');
186
+ }
187
+
188
+ /**
189
+ * @deprecated use disableMovement() for setting and movementApiCallsDisabled, movementKeyEventsDisabled and movementPointerEventsDisabled getter
190
+ */
191
+ get movementDisabled(): boolean {
192
+ getLogger().deprecate(
193
+ 'movementDisabled',
194
+ 'use the following getters: "movementApiCallsDisabled", "movementKeyEventsDisabled", "movementPointerEventsDisabled"',
195
+ );
196
+ return (
197
+ this._movementApiCallsDisabled &&
198
+ this._movementKeyEventsDisabled &&
199
+ this._movementPointerEventsDisabled
200
+ );
201
+ }
202
+
203
+ /** Whether api calls like gotoViewpoint & setting of oblique images are disabled */
204
+ get movementApiCallsDisabled(): boolean {
205
+ return this._movementApiCallsDisabled;
206
+ }
207
+
208
+ /** Whether movement related key events like the arrow keys for navigating in map are disabled. */
209
+ get movementKeyEventsDisabled(): boolean {
210
+ return this._movementKeyEventsDisabled;
211
+ }
212
+
213
+ /** Whether movement related pointer events for navigating in map are disabled. */
214
+ get movementPointerEventsDisabled(): boolean {
215
+ return this._movementPointerEventsDisabled;
216
+ }
217
+
175
218
  /**
176
219
  * The layer collection of this map. LayerCollections can be shared among maps.
177
220
  * When adding the map to a , the layer collection of the will be set.
@@ -396,10 +439,20 @@ class VcsMap<
396
439
  }
397
440
 
398
441
  /**
399
- * prevent all movement, including navigation controls, gotoViewpoint & setting of oblique images
442
+ * prevent all movement, including api calls (gotoViewpoint, setting oblique images), key and pointer events.
400
443
  */
401
- disableMovement(prevent: boolean): void {
402
- this.movementDisabled = prevent;
444
+ disableMovement(prevent: boolean | DisableMapControlOptions): void {
445
+ const disable: DisableMapControlOptions = is(prevent, Boolean)
446
+ ? {
447
+ apiCalls: prevent,
448
+ pointerEvents: prevent,
449
+ keyEvents: prevent,
450
+ }
451
+ : prevent;
452
+
453
+ this._movementApiCallsDisabled = disable.apiCalls;
454
+ this._movementKeyEventsDisabled = disable.keyEvents;
455
+ this._movementPointerEventsDisabled = disable.pointerEvents;
403
456
  }
404
457
 
405
458
  /**
@@ -245,10 +245,19 @@ class ClippingObject {
245
245
  }
246
246
 
247
247
  handleMapChanged(map: VcsMap | null): void {
248
+ // clear old destroyed targets
249
+ this.targets.forEach((target, key) => {
250
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
251
+ // @ts-ignore
252
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-call
253
+ if (target.isDestroyed && target.isDestroyed()) {
254
+ this.targets.delete(key);
255
+ }
256
+ });
248
257
  if (map instanceof CesiumMap) {
249
258
  const { globe } = map.getScene() as Scene;
250
259
  let raise = false;
251
- if (this._terrain && !this.targets.has(globeSymbol)) {
260
+ if (this._terrain && !(this.targets.get(globeSymbol) === globe)) {
252
261
  this.targets.set(globeSymbol, globe);
253
262
  raise = true;
254
263
  } else if (!this._terrain && this.targets.has(globeSymbol)) {
@@ -233,6 +233,12 @@ class ClippingObjectManager {
233
233
 
234
234
  const setTargets = (clippingObject: ClippingObject): void => {
235
235
  clippingObject.targets.forEach((target) => {
236
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
237
+ // @ts-ignore
238
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-call
239
+ if (target.isDestroyed && target.isDestroyed()) {
240
+ return;
241
+ }
236
242
  this._targetsMap.set(target, clippingObject);
237
243
  currentTargets.delete(target);
238
244
  });
@@ -266,6 +266,12 @@ export function copyClippingPlanesToCollection(
266
266
  export function clearClippingPlanes(
267
267
  target: Globe | Cesium3DTileset | Entity,
268
268
  ): void {
269
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
270
+ // @ts-ignore
271
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-call
272
+ if (target.isDestroyed && target.isDestroyed()) {
273
+ return;
274
+ }
269
275
  if (target instanceof Entity) {
270
276
  if (target.model) {
271
277
  if (target.model.clippingPlanes) {
@@ -399,11 +405,12 @@ export function setClippingPlanes(
399
405
  }
400
406
 
401
407
  /**
402
- * Creates a new feature at the given coordinate, which can be set on a .
408
+ * Creates a new feature at the given coordinate, which can then be used to create a clippingPlaneCollection.
403
409
  * @param coordinate - in WGS84
404
410
  * @param camera
405
411
  * @param [vertical=false]
406
412
  * @param [offsetDistance=25] - the offset from the coordinate to use for the size of the geometry
413
+ * @param [rotate=0] - rotation of clipping plane in radians. 0 means vertical plane is parallel to camera.heading and horizontal feature is aligned with axes.
407
414
  * @returns - the features geometry is in web mercator
408
415
  */
409
416
  export function createClippingFeature(
@@ -411,6 +418,7 @@ export function createClippingFeature(
411
418
  camera: Camera,
412
419
  vertical = false,
413
420
  offsetDistance = 25,
421
+ rotate = 0,
414
422
  ): Feature {
415
423
  check(coordinate, [Number]);
416
424
  check(vertical, Boolean);
@@ -418,18 +426,18 @@ export function createClippingFeature(
418
426
 
419
427
  let geometry;
420
428
  if (vertical) {
421
- const p1 = offset(coordinate, -offsetDistance, camera.heading);
422
- const p2 = offset(coordinate, offsetDistance, camera.heading);
429
+ const p1 = offset(coordinate, -offsetDistance, camera.heading + rotate);
430
+ const p2 = offset(coordinate, offsetDistance, camera.heading + rotate);
423
431
  geometry = new LineString(
424
432
  [
425
- [p1[0], p1[1], coordinate[2]],
426
- [p2[0], p2[1], coordinate[2]],
433
+ [p1[0], p1[1], coordinate[2] - offsetDistance],
434
+ [p2[0], p2[1], coordinate[2] - offsetDistance],
427
435
  ],
428
436
  'XYZ',
429
437
  );
430
438
  } else {
431
439
  geometry = new Polygon([[]], 'XYZ');
432
- let bearing = 2 * Math.PI - Math.PI / 4; // Bearing NW
440
+ let bearing = 2 * Math.PI - Math.PI / 4 + rotate; // Bearing NW
433
441
  const coordinates = [...(new Array(4) as undefined[])].map(() => {
434
442
  const newPoint = offset(coordinate, offsetDistance, bearing);
435
443
  bearing -= Math.PI / 2;
@@ -25,7 +25,7 @@ import MapInteractionController from './interactions/mapInteractionController.js
25
25
  import TranslateInteraction from './transformation/translateInteraction.js';
26
26
  import RotateInteraction from './transformation/rotateInteraction.js';
27
27
  import ScaleInteraction from './transformation/scaleInteraction.js';
28
- import { obliqueGeometry } from '../../layer/vectorSymbols.js';
28
+ import { createSync, obliqueGeometry } from '../../layer/vectorSymbols.js';
29
29
  import ExtrudeInteraction from './transformation/extrudeInteraction.js';
30
30
  import ObliqueMap from '../../map/obliqueMap.js';
31
31
  import { ensureFeatureAbsolute, geometryChangeKeys } from './editorHelpers.js';
@@ -36,6 +36,7 @@ import { ModificationKeyType } from '../../interaction/interactionType.js';
36
36
  import type VcsApp from '../../vcsApp.js';
37
37
  import type VectorLayer from '../../layer/vectorLayer.js';
38
38
  import type VcsMap from '../../map/vcsMap.js';
39
+ import RightClickInteraction from './interactions/rightClickInteraction.js';
39
40
 
40
41
  /**
41
42
  * Saves the original allowPicking settings and sets them to false if CTRL is not pressed.
@@ -77,6 +78,37 @@ function clearAllowPicking(
77
78
  }
78
79
  }
79
80
 
81
+ /**
82
+ * Saves the original createSync State of the feature, and sets createSync to true.
83
+ * @param feature
84
+ * @param originalCreateSyncMap
85
+ */
86
+ function setCreateSync(
87
+ feature: Feature,
88
+ originalCreateSyncMap: Map<string | number, boolean>,
89
+ ): void {
90
+ const id = feature.getId() as string | number;
91
+ const hasCreateSync = !!feature[createSync];
92
+ originalCreateSyncMap.set(id, hasCreateSync);
93
+ feature[createSync] = true;
94
+ }
95
+
96
+ /**
97
+ * Restores the original createSync State of the feature, and removes createSync if it was not set.
98
+ * @param feature
99
+ * @param originalCreateSyncMap
100
+ */
101
+ function clearCreateSync(
102
+ feature: Feature,
103
+ originalCreateSyncMap: Map<string | number, boolean>,
104
+ ): void {
105
+ const id = feature.getId() as string | number;
106
+ if (!originalCreateSyncMap.get(id)) {
107
+ delete feature[createSync];
108
+ }
109
+ originalCreateSyncMap.delete(id);
110
+ }
111
+
80
112
  export type EditFeaturesSession = EditorSession<SessionType.EDIT_FEATURES> & {
81
113
  readonly mode: TransformationMode;
82
114
  /**
@@ -127,6 +159,21 @@ function startEditFeaturesSession(
127
159
  });
128
160
  });
129
161
 
162
+ const rightClickStart = new RightClickInteraction();
163
+ rightClickStart.rightClicked.addEventListener(() => {
164
+ // we allow picking the Feature on rightClick, for this we add the RightClickInteraction
165
+ currentFeatures.forEach((feature) => {
166
+ feature.set('olcs_allowPicking', true);
167
+ });
168
+ });
169
+ rightClickStart.eventChainFinished.addEventListener(() => {
170
+ // reset olcs_allowPicking after rightClick
171
+ const allowPicking = modificationKey === ModificationKeyType.CTRL;
172
+ currentFeatures.forEach((feature) => {
173
+ feature.set('olcs_allowPicking', allowPicking);
174
+ });
175
+ });
176
+
130
177
  const scratchLayer = setupScratchLayer(app.layers);
131
178
 
132
179
  const {
@@ -135,6 +182,14 @@ function startEditFeaturesSession(
135
182
  destroy: destroyInteractionChain,
136
183
  } = setupInteractionChain(app.maps.eventHandler, interactionId);
137
184
 
185
+ const { exclusiveInteractionId } = app.maps.eventHandler;
186
+ const removeRightClickStart = app.maps.eventHandler.addExclusiveInteraction(
187
+ rightClickStart,
188
+ () => interactionRemoved.raiseEvent(),
189
+ 0,
190
+ exclusiveInteractionId,
191
+ );
192
+
138
193
  const mouseOverInteraction = new EditFeaturesMouseOverInteraction();
139
194
  interactionChain.addInteraction(mouseOverInteraction);
140
195
 
@@ -308,6 +363,8 @@ function startEditFeaturesSession(
308
363
  );
309
364
  };
310
365
 
366
+ const originalCreateSyncMap = new Map<string | number, boolean>();
367
+
311
368
  const stop = (): void => {
312
369
  destroyTransformation();
313
370
  destroyInteractionChain();
@@ -315,12 +372,15 @@ function startEditFeaturesSession(
315
372
  mapChangedListener();
316
373
  modifierChangedListener();
317
374
  unByKey(featureListeners);
318
- currentFeatures.forEach((feature) =>
319
- clearAllowPicking(feature, allowPickingMap),
320
- );
375
+ currentFeatures.forEach((feature) => {
376
+ clearAllowPicking(feature, allowPickingMap);
377
+ clearCreateSync(feature, originalCreateSyncMap);
378
+ });
321
379
  allowPickingMap.clear();
322
380
  app.layers.remove(scratchLayer);
323
381
  modeChanged.destroy();
382
+ removeRightClickStart();
383
+ rightClickStart.destroy();
324
384
  stopped.raiseEvent();
325
385
  stopped.destroy();
326
386
  };
@@ -340,14 +400,16 @@ function startEditFeaturesSession(
340
400
  translate,
341
401
  scale,
342
402
  setFeatures(features: Feature[]): void {
343
- currentFeatures.forEach((feature) =>
344
- clearAllowPicking(feature, allowPickingMap),
345
- );
403
+ currentFeatures.forEach((feature) => {
404
+ clearAllowPicking(feature, allowPickingMap);
405
+ clearCreateSync(feature, originalCreateSyncMap);
406
+ });
346
407
  currentFeatures.length = 0;
347
408
  currentFeatures.push(...features);
348
- currentFeatures.forEach((feature) =>
349
- setAllowPicking(feature, allowPickingMap, modificationKey),
350
- );
409
+ currentFeatures.forEach((feature) => {
410
+ setAllowPicking(feature, allowPickingMap, modificationKey);
411
+ setCreateSync(feature, originalCreateSyncMap);
412
+ });
351
413
  setFeatureListeners();
352
414
  transformationHandler?.setFeatures(features);
353
415
  },