@vcmap/core 6.0.7 → 6.1.0-rc.2

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 (146) hide show
  1. package/dist/cesium.d.ts +3 -0
  2. package/dist/index.d.ts +16 -1
  3. package/dist/index.js +16 -1
  4. package/dist/index.js.map +1 -1
  5. package/dist/ol.d.ts +8 -1
  6. package/dist/src/featureProvider/featureProviderSymbols.d.ts +5 -0
  7. package/dist/src/featureProvider/featureProviderSymbols.js +5 -1
  8. package/dist/src/featureProvider/featureProviderSymbols.js.map +1 -1
  9. package/dist/src/interaction/featureAtPixelInteraction.js +58 -62
  10. package/dist/src/interaction/featureAtPixelInteraction.js.map +1 -1
  11. package/dist/src/interaction/featureProviderInteraction.js +25 -13
  12. package/dist/src/interaction/featureProviderInteraction.js.map +1 -1
  13. package/dist/src/layer/cesium/sourceVectorContextSync.d.ts +27 -0
  14. package/dist/src/layer/cesium/sourceVectorContextSync.js +94 -0
  15. package/dist/src/layer/cesium/sourceVectorContextSync.js.map +1 -0
  16. package/dist/src/layer/cesium/vectorCesiumImpl.d.ts +4 -27
  17. package/dist/src/layer/cesium/vectorCesiumImpl.js +15 -107
  18. package/dist/src/layer/cesium/vectorCesiumImpl.js.map +1 -1
  19. package/dist/src/layer/cesium/vectorContext.d.ts +12 -1
  20. package/dist/src/layer/cesium/vectorContext.js +6 -0
  21. package/dist/src/layer/cesium/vectorContext.js.map +1 -1
  22. package/dist/src/layer/layerSymbols.js +1 -1
  23. package/dist/src/layer/layerSymbols.js.map +1 -1
  24. package/dist/src/layer/oblique/sourceObliqueSync.d.ts +18 -0
  25. package/dist/src/layer/oblique/sourceObliqueSync.js +319 -0
  26. package/dist/src/layer/oblique/sourceObliqueSync.js.map +1 -0
  27. package/dist/src/layer/oblique/vectorObliqueImpl.d.ts +2 -40
  28. package/dist/src/layer/oblique/vectorObliqueImpl.js +8 -283
  29. package/dist/src/layer/oblique/vectorObliqueImpl.js.map +1 -1
  30. package/dist/src/layer/vectorLayer.d.ts +10 -1
  31. package/dist/src/layer/vectorLayer.js +23 -1
  32. package/dist/src/layer/vectorLayer.js.map +1 -1
  33. package/dist/src/map/baseOLMap.js +8 -1
  34. package/dist/src/map/baseOLMap.js.map +1 -1
  35. package/dist/src/map/cesiumMap.d.ts +2 -0
  36. package/dist/src/map/cesiumMap.js +26 -1
  37. package/dist/src/map/cesiumMap.js.map +1 -1
  38. package/dist/src/map/vcsMap.d.ts +24 -12
  39. package/dist/src/map/vcsMap.js +92 -38
  40. package/dist/src/map/vcsMap.js.map +1 -1
  41. package/dist/src/ol/source/ClusterEnhancedVectorSource.d.ts +6 -4
  42. package/dist/src/ol/source/ClusterEnhancedVectorSource.js +4 -9
  43. package/dist/src/ol/source/ClusterEnhancedVectorSource.js.map +1 -1
  44. package/dist/src/ol/source/VcsCluster.d.ts +10 -10
  45. package/dist/src/ol/source/VcsCluster.js +23 -7
  46. package/dist/src/ol/source/VcsCluster.js.map +1 -1
  47. package/dist/src/util/clipping/clippingPolygonHelper.d.ts +7 -0
  48. package/dist/src/util/clipping/clippingPolygonHelper.js +53 -0
  49. package/dist/src/util/clipping/clippingPolygonHelper.js.map +1 -0
  50. package/dist/src/util/clipping/clippingPolygonObject.d.ts +59 -0
  51. package/dist/src/util/clipping/clippingPolygonObject.js +158 -0
  52. package/dist/src/util/clipping/clippingPolygonObject.js.map +1 -0
  53. package/dist/src/util/clipping/clippingPolygonObjectCollection.d.ts +18 -0
  54. package/dist/src/util/clipping/clippingPolygonObjectCollection.js +167 -0
  55. package/dist/src/util/clipping/clippingPolygonObjectCollection.js.map +1 -0
  56. package/dist/src/util/layerCollection.d.ts +11 -1
  57. package/dist/src/util/layerCollection.js +67 -12
  58. package/dist/src/util/layerCollection.js.map +1 -1
  59. package/dist/src/util/mapCollection.d.ts +16 -1
  60. package/dist/src/util/mapCollection.js +37 -3
  61. package/dist/src/util/mapCollection.js.map +1 -1
  62. package/dist/src/util/renderScreenshot.d.ts +9 -0
  63. package/dist/src/util/renderScreenshot.js +162 -0
  64. package/dist/src/util/renderScreenshot.js.map +1 -0
  65. package/dist/src/util/rotation.d.ts +30 -0
  66. package/dist/src/util/rotation.js +145 -0
  67. package/dist/src/util/rotation.js.map +1 -0
  68. package/dist/src/util/vcsTemplate.d.ts +7 -0
  69. package/dist/src/util/vcsTemplate.js +248 -0
  70. package/dist/src/util/vcsTemplate.js.map +1 -0
  71. package/dist/src/vcsApp.d.ts +7 -0
  72. package/dist/src/vcsApp.js +29 -0
  73. package/dist/src/vcsApp.js.map +1 -1
  74. package/dist/src/vcsModule.d.ts +6 -2
  75. package/dist/src/vcsModule.js.map +1 -1
  76. package/dist/src/vectorCluster/vectorClusterCesiumContext.d.ts +18 -0
  77. package/dist/src/{layer/cesium/clusterContext.js → vectorCluster/vectorClusterCesiumContext.js} +28 -42
  78. package/dist/src/vectorCluster/vectorClusterCesiumContext.js.map +1 -0
  79. package/dist/src/vectorCluster/vectorClusterGroup.d.ts +96 -0
  80. package/dist/src/vectorCluster/vectorClusterGroup.js +320 -0
  81. package/dist/src/vectorCluster/vectorClusterGroup.js.map +1 -0
  82. package/dist/src/vectorCluster/vectorClusterGroupCesiumImpl.d.ts +20 -0
  83. package/dist/src/vectorCluster/vectorClusterGroupCesiumImpl.js +115 -0
  84. package/dist/src/vectorCluster/vectorClusterGroupCesiumImpl.js.map +1 -0
  85. package/dist/src/vectorCluster/vectorClusterGroupCollection.d.ts +19 -0
  86. package/dist/src/vectorCluster/vectorClusterGroupCollection.js +37 -0
  87. package/dist/src/vectorCluster/vectorClusterGroupCollection.js.map +1 -0
  88. package/dist/src/vectorCluster/vectorClusterGroupImpl.d.ts +31 -0
  89. package/dist/src/vectorCluster/vectorClusterGroupImpl.js +76 -0
  90. package/dist/src/vectorCluster/vectorClusterGroupImpl.js.map +1 -0
  91. package/dist/src/vectorCluster/vectorClusterGroupObliqueImpl.d.ts +17 -0
  92. package/dist/src/vectorCluster/vectorClusterGroupObliqueImpl.js +62 -0
  93. package/dist/src/vectorCluster/vectorClusterGroupObliqueImpl.js.map +1 -0
  94. package/dist/src/vectorCluster/vectorClusterGroupOpenlayersImpl.d.ts +17 -0
  95. package/dist/src/vectorCluster/vectorClusterGroupOpenlayersImpl.js +62 -0
  96. package/dist/src/vectorCluster/vectorClusterGroupOpenlayersImpl.js.map +1 -0
  97. package/dist/src/vectorCluster/vectorClusterStyleItem.d.ts +110 -0
  98. package/dist/src/vectorCluster/vectorClusterStyleItem.js +374 -0
  99. package/dist/src/vectorCluster/vectorClusterStyleItem.js.map +1 -0
  100. package/dist/src/vectorCluster/vectorClusterSymbols.d.ts +1 -0
  101. package/dist/src/vectorCluster/vectorClusterSymbols.js +3 -0
  102. package/dist/src/vectorCluster/vectorClusterSymbols.js.map +1 -0
  103. package/index.ts +42 -1
  104. package/package.json +3 -1
  105. package/src/cesium/cesium.d.ts +3 -0
  106. package/src/featureProvider/featureProviderSymbols.ts +6 -1
  107. package/src/interaction/featureAtPixelInteraction.ts +109 -84
  108. package/src/interaction/featureProviderInteraction.ts +42 -28
  109. package/src/layer/cesium/sourceVectorContextSync.ts +134 -0
  110. package/src/layer/cesium/vcsTile/vcsDebugTile.ts +1 -1
  111. package/src/layer/cesium/vcsTile/vcsVectorTile.ts +1 -1
  112. package/src/layer/cesium/vectorCesiumImpl.ts +30 -144
  113. package/src/layer/cesium/vectorContext.ts +17 -1
  114. package/src/layer/layerSymbols.ts +1 -1
  115. package/src/layer/oblique/sourceObliqueSync.ts +436 -0
  116. package/src/layer/oblique/vectorObliqueImpl.ts +11 -397
  117. package/src/layer/vectorLayer.ts +35 -2
  118. package/src/map/baseOLMap.ts +8 -1
  119. package/src/map/cesiumMap.ts +36 -3
  120. package/src/map/vcsMap.ts +121 -47
  121. package/src/ol/ol.d.ts +8 -1
  122. package/src/ol/source/{ClusterEnhancedVectorSource.js → ClusterEnhancedVectorSource.ts} +7 -10
  123. package/src/ol/source/VcsCluster.ts +58 -0
  124. package/src/util/clipping/clippingPolygonHelper.ts +86 -0
  125. package/src/util/clipping/clippingPolygonObject.ts +223 -0
  126. package/src/util/clipping/clippingPolygonObjectCollection.ts +249 -0
  127. package/src/util/layerCollection.ts +90 -12
  128. package/src/util/mapCollection.ts +53 -2
  129. package/src/util/renderScreenshot.ts +193 -0
  130. package/src/util/rotation.ts +215 -0
  131. package/src/util/vcsTemplate.ts +373 -0
  132. package/src/vcsApp.ts +65 -0
  133. package/src/vcsModule.ts +6 -2
  134. package/src/vectorCluster/vectorClusterCesiumContext.ts +123 -0
  135. package/src/vectorCluster/vectorClusterGroup.ts +463 -0
  136. package/src/vectorCluster/vectorClusterGroupCesiumImpl.ts +176 -0
  137. package/src/vectorCluster/vectorClusterGroupCollection.ts +43 -0
  138. package/src/vectorCluster/vectorClusterGroupImpl.ts +107 -0
  139. package/src/vectorCluster/vectorClusterGroupObliqueImpl.ts +84 -0
  140. package/src/vectorCluster/vectorClusterGroupOpenlayersImpl.ts +81 -0
  141. package/src/vectorCluster/vectorClusterStyleItem.ts +490 -0
  142. package/src/vectorCluster/vectorClusterSymbols.ts +2 -0
  143. package/dist/src/layer/cesium/clusterContext.d.ts +0 -20
  144. package/dist/src/layer/cesium/clusterContext.js.map +0 -1
  145. package/src/layer/cesium/clusterContext.ts +0 -140
  146. package/src/ol/source/VcsCluster.js +0 -37
package/src/map/vcsMap.ts CHANGED
@@ -18,6 +18,8 @@ import type Viewpoint from '../util/viewpoint.js';
18
18
  import type Layer from '../layer/layer.js';
19
19
  import type { MapEvent } from '../interaction/abstractInteraction.js';
20
20
  import type { DisableMapControlOptions } from '../util/mapCollection.js';
21
+ import type VectorClusterGroup from '../vectorCluster/vectorClusterGroup.js';
22
+ import { vectorClusterGroupName } from '../vectorCluster/vectorClusterSymbols.js';
21
23
 
22
24
  function getLogger(): Logger {
23
25
  return getLoggerByName('vcMap');
@@ -106,7 +108,9 @@ class VcsMap<
106
108
  */
107
109
  fallbackToCurrentMap: boolean;
108
110
 
109
- private _visualizations: Map<string, Set<V>>;
111
+ private _visualizations = new Map<string, Set<V>>();
112
+
113
+ private _clusterVisualizations = new Map<string, Set<V>>();
110
114
 
111
115
  private _state: MapState;
112
116
 
@@ -115,6 +119,16 @@ class VcsMap<
115
119
  */
116
120
  stateChanged: VcsEvent<MapState>;
117
121
 
122
+ /**
123
+ * Event raised when a visualization is added to the map
124
+ */
125
+ visualizationAdded: VcsEvent<VisualisationType>;
126
+
127
+ /**
128
+ * Event raised when a visualization is removed from the map
129
+ */
130
+ visualizationRemoved: VcsEvent<VisualisationType>;
131
+
118
132
  /**
119
133
  * Event raised then the map has a pointer interaction. Raises {@link MapEvent}.
120
134
  */
@@ -125,7 +139,7 @@ class VcsMap<
125
139
  */
126
140
  private _splitPosition: number;
127
141
 
128
- private _postRender: VcsEvent<VcsMapRenderEvent<V>>;
142
+ private _postRender = new VcsEvent<VcsMapRenderEvent<V>>();
129
143
 
130
144
  /**
131
145
  * @param options
@@ -162,17 +176,17 @@ class VcsMap<
162
176
  defaultOptions.fallbackToCurrentMap,
163
177
  );
164
178
 
165
- this._visualizations = new Map();
166
-
167
179
  this._state = MapState.INACTIVE;
168
180
 
169
181
  this.stateChanged = new VcsEvent();
170
182
 
183
+ this.visualizationAdded = new VcsEvent();
184
+
185
+ this.visualizationRemoved = new VcsEvent();
186
+
171
187
  this.pointerInteractionEvent = new VcsEvent();
172
188
 
173
189
  this._splitPosition = 0.5;
174
-
175
- this._postRender = new VcsEvent();
176
190
  }
177
191
 
178
192
  /**
@@ -253,12 +267,24 @@ class VcsMap<
253
267
  [...this._layerCollection].forEach((l) => {
254
268
  l.removedFromMap(this);
255
269
  });
270
+ [...this._layerCollection.vectorClusterGroups].forEach((g) => {
271
+ g.removedFromMap(this);
272
+ });
273
+
256
274
  this._layerCollection = layerCollection;
257
275
 
258
276
  if (this.active) {
259
277
  [...this._layerCollection].forEach((l) => {
260
- // eslint-disable-next-line no-void
261
- void l.mapActivated(this);
278
+ l.mapActivated(this).catch((_e) => {
279
+ this.getLogger().error(`Failed to activate map on layer: ${l.name}`);
280
+ });
281
+ });
282
+ [...this._layerCollection.vectorClusterGroups].forEach((g) => {
283
+ g.mapActivated(this).catch((_e) => {
284
+ this.getLogger().error(
285
+ `Failed to activate map on vector cluster group: ${g.name}`,
286
+ );
287
+ });
262
288
  });
263
289
  }
264
290
 
@@ -293,16 +319,28 @@ class VcsMap<
293
319
  cb();
294
320
  });
295
321
 
322
+ const added = (i: Layer | VectorClusterGroup): void => {
323
+ if (this.active) {
324
+ i.mapActivated(this).catch((_e) => {
325
+ this.getLogger().error(`Failed to activate map on layer: ${i.name}`);
326
+ });
327
+ }
328
+ };
329
+
330
+ const removed = (i: Layer | VectorClusterGroup): void => {
331
+ i.removedFromMap(this);
332
+ };
333
+
296
334
  this._collectionListeners = [
297
335
  this.layerCollection.moved.addEventListener((layer) => {
298
336
  this.indexChanged(layer);
299
337
  }),
300
- this.layerCollection.added.addEventListener((layer) => {
301
- this._layerAdded(layer);
302
- }),
303
- this.layerCollection.removed.addEventListener((layer) => {
304
- this._layerRemoved(layer);
305
- }),
338
+ this.layerCollection.added.addEventListener(added),
339
+ this.layerCollection.removed.addEventListener(removed),
340
+ this.layerCollection.vectorClusterGroups.added.addEventListener(added),
341
+ this.layerCollection.vectorClusterGroups.removed.addEventListener(
342
+ removed,
343
+ ),
306
344
  ];
307
345
  }
308
346
 
@@ -342,28 +380,20 @@ class VcsMap<
342
380
  // eslint-disable-next-line no-unused-vars,class-methods-use-this
343
381
  indexChanged(_layer: Layer): void {}
344
382
 
345
- /**
346
- * is called if a layer is added to the layerCollection.
347
- */
348
- private _layerAdded(layer: Layer): void {
349
- if (this.active) {
350
- // eslint-disable-next-line no-void
351
- void layer.mapActivated(this);
352
- }
353
- }
354
-
355
- /**
356
- * is called if a layer is added to the layerCollection.
357
- */
358
- private _layerRemoved(layer: Layer): void {
359
- layer.removedFromMap(this);
360
- }
361
-
362
383
  /**
363
384
  * Validates a visualization. A visualization must have the vcsLayeName symbol set and a layer with said name must be
364
385
  * part of the maps layerCollection.
365
386
  */
366
- validateVisualization(item: V): item is V & { [vcsLayerName]: string } {
387
+ validateVisualization(item: V): item is V & {
388
+ [vcsLayerName]?: string;
389
+ [vectorClusterGroupName]?: string;
390
+ } {
391
+ const vectorCluster = (item as OLLayer)[vectorClusterGroupName];
392
+ if (vectorCluster) {
393
+ return this.layerCollection.vectorClusterGroups.hasKey(
394
+ vectorCluster,
395
+ ) as boolean;
396
+ }
367
397
  const layerName = item[vcsLayerName];
368
398
  if (layerName == null) {
369
399
  this.getLogger().warning('item is missing vcsLayerName symbol');
@@ -376,45 +406,77 @@ class VcsMap<
376
406
  /**
377
407
  * Adds a visualization to the visualizations map for its layer. The visualization must be valid, use validateVisualization first
378
408
  */
379
- addVisualization(item: V): void {
409
+ addVisualization(item: V & { [vectorClusterGroupName]?: string }): void {
380
410
  if (!this.validateVisualization(item)) {
381
411
  throw new Error(
382
412
  'Visualization item is not valid, validate before adding',
383
413
  );
384
414
  }
385
- const layerName = item[vcsLayerName];
386
- if (!this._visualizations.has(layerName)) {
387
- this._visualizations.set(layerName, new Set());
415
+ let name: string;
416
+ let setMap;
417
+ if (item[vectorClusterGroupName]) {
418
+ name = item[vectorClusterGroupName];
419
+ setMap = this._clusterVisualizations;
420
+ } else {
421
+ name = item[vcsLayerName]!;
422
+ setMap = this._visualizations;
423
+ }
424
+
425
+ if (!setMap.has(name)) {
426
+ setMap.set(name, new Set());
388
427
  }
389
- (this._visualizations.get(layerName) as Set<V>).add(item);
428
+ (setMap.get(name) as Set<V>).add(item);
429
+ this.visualizationAdded.raiseEvent(item);
390
430
  }
391
431
 
392
432
  /**
393
433
  * Removes a visualization
394
434
  */
395
- removeVisualization(item: V): void {
396
- const layerName = item[vcsLayerName];
397
- const viz = layerName ? this._visualizations.get(layerName) : undefined;
398
- if (viz && layerName) {
435
+ removeVisualization(item: V & { [vectorClusterGroupName]?: string }): void {
436
+ let name: string | undefined;
437
+ let setMap;
438
+ if (item[vectorClusterGroupName]) {
439
+ name = item[vectorClusterGroupName];
440
+ setMap = this._clusterVisualizations;
441
+ } else {
442
+ name = item[vcsLayerName];
443
+ setMap = this._visualizations;
444
+ }
445
+
446
+ const viz = name ? setMap.get(name) : undefined;
447
+ if (viz && name) {
399
448
  viz.delete(item);
400
449
  if (viz.size === 0) {
401
- this._visualizations.delete(layerName);
450
+ setMap.delete(name);
402
451
  }
452
+ this.visualizationRemoved.raiseEvent(item);
403
453
  }
404
454
  }
405
455
 
406
456
  /**
407
- * Gets the visualizations for a specific layer.
457
+ * Gets the visualizations for a specific layer
408
458
  */
409
459
  getVisualizationsForLayer(layer: Layer): Set<V> | undefined {
410
460
  return this._visualizations.get(layer.name);
411
461
  }
412
462
 
463
+ /**
464
+ * Gets the visualizations of a vector cluster group
465
+ */
466
+ getVisualizationsForVectorClusterGroup(
467
+ group: VectorClusterGroup,
468
+ ): Set<V> | undefined {
469
+ return this._clusterVisualizations.get(group.name);
470
+ }
471
+
413
472
  /**
414
473
  * Get all visualizations added to this map.
415
474
  */
416
475
  getVisualizations(): V[] {
417
- return [...this._visualizations.values()]
476
+ return [
477
+ ...this._visualizations.values(),
478
+ ...this._clusterVisualizations.values(),
479
+ ]
418
480
  .map((layerVisualizations) => [...layerVisualizations])
419
481
  .flat();
420
482
  }
@@ -433,9 +495,12 @@ class VcsMap<
433
495
  return;
434
496
  }
435
497
  this._state = MapState.ACTIVE;
436
- await Promise.all(
437
- [...this.layerCollection].map((layer) => layer.mapActivated(this)),
438
- );
498
+ await Promise.all([
499
+ ...[...this.layerCollection].map((layer) => layer.mapActivated(this)),
500
+ ...[...this.layerCollection.vectorClusterGroups].map((clusterGroup) =>
501
+ clusterGroup.mapActivated(this),
502
+ ),
503
+ ]);
439
504
  if (this._state !== MapState.ACTIVE) {
440
505
  return;
441
506
  }
@@ -453,6 +518,9 @@ class VcsMap<
453
518
  [...this.layerCollection].forEach((layer) => {
454
519
  layer.mapDeactivated(this);
455
520
  });
521
+ [...this.layerCollection.vectorClusterGroups].forEach((clusterGroup) =>
522
+ clusterGroup.mapDeactivated(this),
523
+ );
456
524
  this.stateChanged.raiseEvent(this._state);
457
525
  }
458
526
  }
@@ -559,11 +627,17 @@ class VcsMap<
559
627
  [...this.layerCollection].forEach((l) => {
560
628
  l.removedFromMap(this);
561
629
  });
630
+ [...this.layerCollection.vectorClusterGroups].forEach((g) => {
631
+ g.removedFromMap(this);
632
+ });
562
633
  }
563
634
  if (this.stateChanged) {
564
635
  this.stateChanged.destroy();
565
636
  }
566
637
 
638
+ this.visualizationAdded.destroy();
639
+ this.visualizationRemoved.destroy();
640
+
567
641
  if (this.destroyLayerCollection && this.layerCollection) {
568
642
  this.layerCollection.destroy();
569
643
  }
package/src/ol/ol.d.ts CHANGED
@@ -22,7 +22,10 @@ import {
22
22
  originalFeatureSymbol,
23
23
  } from '../layer/vectorSymbols.js';
24
24
  import { vcsLayerName } from '../layer/layerSymbols.js';
25
- import { isProvidedFeature } from '../featureProvider/featureProviderSymbols.js';
25
+ import {
26
+ isProvidedFeature,
27
+ isProvidedClusterFeature,
28
+ } from '../featureProvider/featureProviderSymbols.js';
26
29
  import {
27
30
  globalHidden,
28
31
  hidden,
@@ -42,6 +45,7 @@ import {
42
45
  globalHiderLastUpdated,
43
46
  } from '../layer/vectorHelpers.js';
44
47
  import { validityPlaceholder } from '../util/editor/interactions/createPolygonInteraction.js';
48
+ import { vectorClusterGroupName } from '../vectorCluster/vectorClusterSymbols.js';
45
49
 
46
50
  declare module 'ol/geom.js' {
47
51
  interface Geometry {
@@ -101,6 +105,7 @@ declare module 'ol/index.js' {
101
105
  [vectorStyleSymbol]?: VectorStyleItem;
102
106
  [featureArcStruct]?: ArcStruct;
103
107
  [isProvidedFeature]?: boolean;
108
+ [isProvidedClusterFeature]?: boolean;
104
109
  [globalHidden]?: boolean;
105
110
  [hidden]?: boolean;
106
111
  [highlighted]?: VectorStyleItem;
@@ -113,6 +118,7 @@ declare module 'ol/index.js' {
113
118
  [handlerSymbol]?: AxisAndPlanes;
114
119
  [vertexSymbol]?: boolean;
115
120
  [createSync]?: boolean;
121
+ [vectorClusterGroupName]?: string;
116
122
  }
117
123
 
118
124
  class CanvasTileRenderer extends CanvasImmediateRenderer {
@@ -141,6 +147,7 @@ declare module 'ol/style.js' {
141
147
  declare module 'ol/layer.js' {
142
148
  interface Layer {
143
149
  [vcsLayerName]: string;
150
+ [vectorClusterGroupName]?: string;
144
151
  }
145
152
  }
146
153
 
@@ -1,5 +1,5 @@
1
- import { getUid } from 'ol/util.js';
2
1
  import VectorSource from 'ol/source/Vector.js';
2
+ import Feature from 'ol/Feature.js';
3
3
 
4
4
  /**
5
5
  * @class
@@ -11,15 +11,12 @@ class ClusterEnhancedVectorSource extends VectorSource {
11
11
  * @param {import("ol").Feature<import("ol/geom/Geometry").default>} feature
12
12
  * @param {boolean=} silent
13
13
  */
14
- removeFeature(feature, silent) {
15
- const featureKey = getUid(feature);
16
- if (featureKey in this.nullGeometryFeatures_) {
17
- delete this.nullGeometryFeatures_[featureKey];
18
- } else if (this.featuresRtree_) {
19
- this.featuresRtree_.remove(feature);
14
+ removeFeature(feature: Feature, silent?: boolean): void {
15
+ if (!feature) {
16
+ return;
20
17
  }
21
- this.removeFeatureInternal(feature);
22
- if (!silent) {
18
+ const removed = this.removeFeatureInternal(feature);
19
+ if (removed && !silent) {
23
20
  this.changed();
24
21
  }
25
22
  }
@@ -28,7 +25,7 @@ class ClusterEnhancedVectorSource extends VectorSource {
28
25
  * @param {import("ol").Feature<import("ol/geom/Geometry").default>} feature
29
26
  * @param {boolean=} silent
30
27
  */
31
- addFeature(feature, silent) {
28
+ addFeature(feature: Feature, silent?: boolean): void {
32
29
  this.addFeatureInternal(feature);
33
30
  if (!silent) {
34
31
  this.changed();
@@ -0,0 +1,58 @@
1
+ import Cluster, { type Options } from 'ol/source/Cluster.js';
2
+ import Feature from 'ol/Feature.js';
3
+ import { Point } from 'ol/geom.js';
4
+ import { vectorClusterGroupName } from '../../vectorCluster/vectorClusterSymbols.js';
5
+ import { hidden } from '../../layer/featureVisibility.js';
6
+
7
+ /**
8
+ * @class
9
+ * @extends {import("ol/source/Cluster").default}
10
+ * @memberOf ol
11
+ */
12
+ class VcsCluster extends Cluster<Feature> {
13
+ private _paused = false;
14
+
15
+ constructor(
16
+ props: Options<Feature>,
17
+ private _name: string,
18
+ ) {
19
+ props.geometryFunction =
20
+ props.geometryFunction ??
21
+ ((feature: Feature): Point | null => {
22
+ if (feature[hidden]) {
23
+ return null;
24
+ }
25
+ return feature.getGeometry() as Point;
26
+ });
27
+
28
+ super(props);
29
+ /**
30
+ * @type {boolean}
31
+ */
32
+ this._paused = false;
33
+ }
34
+
35
+ addFeatures(features: Feature[]): void {
36
+ features.forEach((f) => {
37
+ f[vectorClusterGroupName] = this._name;
38
+ });
39
+ super.addFeatures(features);
40
+ }
41
+
42
+ get paused(): boolean {
43
+ return this._paused;
44
+ }
45
+
46
+ set paused(pause: boolean) {
47
+ this._paused = pause;
48
+ }
49
+
50
+ refresh(): void {
51
+ if (this._paused) {
52
+ return;
53
+ }
54
+ super.refresh();
55
+ }
56
+ }
57
+
58
+ export default VcsCluster;
@@ -0,0 +1,86 @@
1
+ import {
2
+ Cesium3DTileset,
3
+ ClippingPolygon,
4
+ ClippingPolygonCollection,
5
+ Globe,
6
+ } from '@vcmap-cesium/engine';
7
+ import type CesiumMap from '../../map/cesiumMap.js';
8
+ import { vcsLayerName } from '../../layer/layerSymbols.js';
9
+
10
+ export function getTargetTilesets(
11
+ map: CesiumMap,
12
+ layerNames: string[] | 'all' = 'all',
13
+ ): Cesium3DTileset[] {
14
+ const tilesets = map
15
+ .getVisualizations()
16
+ .filter((v) => v instanceof Cesium3DTileset);
17
+ if (Array.isArray(layerNames)) {
18
+ return tilesets.filter((v) => layerNames.includes(v[vcsLayerName]));
19
+ }
20
+ return tilesets;
21
+ }
22
+
23
+ export function addClippingPolygon(
24
+ clippee: Globe | Cesium3DTileset,
25
+ polygon: ClippingPolygon | undefined,
26
+ ): void {
27
+ if (polygon) {
28
+ if (clippee.clippingPolygons === undefined) {
29
+ clippee.clippingPolygons = new ClippingPolygonCollection();
30
+ }
31
+ if (!clippee.clippingPolygons.contains(polygon)) {
32
+ clippee.clippingPolygons.add(polygon);
33
+ }
34
+ }
35
+ }
36
+
37
+ export function removeClippingPolygon(
38
+ clippee: Globe | Cesium3DTileset,
39
+ polygon: ClippingPolygon | undefined,
40
+ ): void {
41
+ if (
42
+ polygon &&
43
+ clippee.clippingPolygons &&
44
+ clippee.clippingPolygons.contains(polygon)
45
+ ) {
46
+ clippee.clippingPolygons.remove(polygon);
47
+ }
48
+ }
49
+
50
+ export function addClippingPolygonObjectToMap(
51
+ map: CesiumMap,
52
+ polygon: ClippingPolygon | undefined,
53
+ terrain: boolean,
54
+ layerNames: string[] | 'all',
55
+ ): void {
56
+ if (terrain) {
57
+ const globe = map.getScene()?.globe;
58
+ if (globe) {
59
+ addClippingPolygon(globe, polygon);
60
+ }
61
+ }
62
+
63
+ const tilesets = getTargetTilesets(map, layerNames);
64
+ tilesets.forEach((tileset) => {
65
+ addClippingPolygon(tileset, polygon);
66
+ });
67
+ }
68
+
69
+ export function removeClippingPolygonFromMap(
70
+ map: CesiumMap,
71
+ polygon: ClippingPolygon | undefined,
72
+ terrain: boolean,
73
+ layerNames: string[] | 'all',
74
+ ): void {
75
+ if (terrain) {
76
+ const globe = map.getScene()?.globe;
77
+ if (globe) {
78
+ removeClippingPolygon(globe, polygon);
79
+ }
80
+ }
81
+
82
+ const tilesets = getTargetTilesets(map, layerNames);
83
+ tilesets.forEach((tileset) => {
84
+ removeClippingPolygon(tileset, polygon);
85
+ });
86
+ }