@vcmap/core 6.0.7 → 6.1.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (130) hide show
  1. package/dist/cesium.d.ts +3 -0
  2. package/dist/index.d.ts +13 -1
  3. package/dist/index.js +13 -1
  4. package/dist/index.js.map +1 -1
  5. package/dist/ol.d.ts +3 -0
  6. package/dist/src/interaction/abstractInteraction.d.ts +4 -0
  7. package/dist/src/interaction/abstractInteraction.js.map +1 -1
  8. package/dist/src/interaction/featureAtPixelInteraction.d.ts +3 -0
  9. package/dist/src/interaction/featureAtPixelInteraction.js +98 -62
  10. package/dist/src/interaction/featureAtPixelInteraction.js.map +1 -1
  11. package/dist/src/interaction/featureProviderInteraction.js +16 -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 +16 -12
  39. package/dist/src/map/vcsMap.js +78 -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/layerCollection.d.ts +11 -1
  48. package/dist/src/util/layerCollection.js +67 -12
  49. package/dist/src/util/layerCollection.js.map +1 -1
  50. package/dist/src/util/mapCollection.d.ts +16 -1
  51. package/dist/src/util/mapCollection.js +37 -3
  52. package/dist/src/util/mapCollection.js.map +1 -1
  53. package/dist/src/util/rotation.d.ts +30 -0
  54. package/dist/src/util/rotation.js +145 -0
  55. package/dist/src/util/rotation.js.map +1 -0
  56. package/dist/src/util/vcsTemplate.d.ts +7 -0
  57. package/dist/src/util/vcsTemplate.js +248 -0
  58. package/dist/src/util/vcsTemplate.js.map +1 -0
  59. package/dist/src/vcsApp.d.ts +4 -0
  60. package/dist/src/vcsApp.js +10 -0
  61. package/dist/src/vcsApp.js.map +1 -1
  62. package/dist/src/vcsModule.d.ts +4 -2
  63. package/dist/src/vcsModule.js.map +1 -1
  64. package/dist/src/vectorCluster/vectorClusterCesiumContext.d.ts +18 -0
  65. package/dist/src/{layer/cesium/clusterContext.js → vectorCluster/vectorClusterCesiumContext.js} +28 -42
  66. package/dist/src/vectorCluster/vectorClusterCesiumContext.js.map +1 -0
  67. package/dist/src/vectorCluster/vectorClusterGroup.d.ts +96 -0
  68. package/dist/src/vectorCluster/vectorClusterGroup.js +320 -0
  69. package/dist/src/vectorCluster/vectorClusterGroup.js.map +1 -0
  70. package/dist/src/vectorCluster/vectorClusterGroupCesiumImpl.d.ts +20 -0
  71. package/dist/src/vectorCluster/vectorClusterGroupCesiumImpl.js +115 -0
  72. package/dist/src/vectorCluster/vectorClusterGroupCesiumImpl.js.map +1 -0
  73. package/dist/src/vectorCluster/vectorClusterGroupCollection.d.ts +19 -0
  74. package/dist/src/vectorCluster/vectorClusterGroupCollection.js +37 -0
  75. package/dist/src/vectorCluster/vectorClusterGroupCollection.js.map +1 -0
  76. package/dist/src/vectorCluster/vectorClusterGroupImpl.d.ts +31 -0
  77. package/dist/src/vectorCluster/vectorClusterGroupImpl.js +76 -0
  78. package/dist/src/vectorCluster/vectorClusterGroupImpl.js.map +1 -0
  79. package/dist/src/vectorCluster/vectorClusterGroupObliqueImpl.d.ts +17 -0
  80. package/dist/src/vectorCluster/vectorClusterGroupObliqueImpl.js +62 -0
  81. package/dist/src/vectorCluster/vectorClusterGroupObliqueImpl.js.map +1 -0
  82. package/dist/src/vectorCluster/vectorClusterGroupOpenlayersImpl.d.ts +17 -0
  83. package/dist/src/vectorCluster/vectorClusterGroupOpenlayersImpl.js +62 -0
  84. package/dist/src/vectorCluster/vectorClusterGroupOpenlayersImpl.js.map +1 -0
  85. package/dist/src/vectorCluster/vectorClusterStyleItem.d.ts +110 -0
  86. package/dist/src/vectorCluster/vectorClusterStyleItem.js +374 -0
  87. package/dist/src/vectorCluster/vectorClusterStyleItem.js.map +1 -0
  88. package/dist/src/vectorCluster/vectorClusterSymbols.d.ts +1 -0
  89. package/dist/src/vectorCluster/vectorClusterSymbols.js +3 -0
  90. package/dist/src/vectorCluster/vectorClusterSymbols.js.map +1 -0
  91. package/index.ts +35 -1
  92. package/package.json +3 -1
  93. package/src/cesium/cesium.d.ts +3 -0
  94. package/src/interaction/abstractInteraction.ts +4 -0
  95. package/src/interaction/featureAtPixelInteraction.ts +158 -84
  96. package/src/interaction/featureProviderInteraction.ts +31 -28
  97. package/src/layer/cesium/sourceVectorContextSync.ts +134 -0
  98. package/src/layer/cesium/vcsTile/vcsDebugTile.ts +1 -1
  99. package/src/layer/cesium/vcsTile/vcsVectorTile.ts +1 -1
  100. package/src/layer/cesium/vectorCesiumImpl.ts +30 -144
  101. package/src/layer/cesium/vectorContext.ts +17 -1
  102. package/src/layer/layerSymbols.ts +1 -1
  103. package/src/layer/oblique/sourceObliqueSync.ts +436 -0
  104. package/src/layer/oblique/vectorObliqueImpl.ts +11 -397
  105. package/src/layer/vectorLayer.ts +35 -2
  106. package/src/map/baseOLMap.ts +8 -1
  107. package/src/map/cesiumMap.ts +36 -3
  108. package/src/map/vcsMap.ts +102 -47
  109. package/src/ol/ol.d.ts +3 -0
  110. package/src/ol/source/{ClusterEnhancedVectorSource.js → ClusterEnhancedVectorSource.ts} +7 -10
  111. package/src/ol/source/VcsCluster.ts +58 -0
  112. package/src/util/layerCollection.ts +90 -12
  113. package/src/util/mapCollection.ts +53 -2
  114. package/src/util/rotation.ts +215 -0
  115. package/src/util/vcsTemplate.ts +373 -0
  116. package/src/vcsApp.ts +29 -0
  117. package/src/vcsModule.ts +4 -2
  118. package/src/vectorCluster/vectorClusterCesiumContext.ts +123 -0
  119. package/src/vectorCluster/vectorClusterGroup.ts +463 -0
  120. package/src/vectorCluster/vectorClusterGroupCesiumImpl.ts +176 -0
  121. package/src/vectorCluster/vectorClusterGroupCollection.ts +43 -0
  122. package/src/vectorCluster/vectorClusterGroupImpl.ts +107 -0
  123. package/src/vectorCluster/vectorClusterGroupObliqueImpl.ts +84 -0
  124. package/src/vectorCluster/vectorClusterGroupOpenlayersImpl.ts +81 -0
  125. package/src/vectorCluster/vectorClusterStyleItem.ts +490 -0
  126. package/src/vectorCluster/vectorClusterSymbols.ts +2 -0
  127. package/dist/src/layer/cesium/clusterContext.d.ts +0 -20
  128. package/dist/src/layer/cesium/clusterContext.js.map +0 -1
  129. package/src/layer/cesium/clusterContext.ts +0 -140
  130. 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
 
@@ -125,7 +129,7 @@ class VcsMap<
125
129
  */
126
130
  private _splitPosition: number;
127
131
 
128
- private _postRender: VcsEvent<VcsMapRenderEvent<V>>;
132
+ private _postRender = new VcsEvent<VcsMapRenderEvent<V>>();
129
133
 
130
134
  /**
131
135
  * @param options
@@ -162,8 +166,6 @@ class VcsMap<
162
166
  defaultOptions.fallbackToCurrentMap,
163
167
  );
164
168
 
165
- this._visualizations = new Map();
166
-
167
169
  this._state = MapState.INACTIVE;
168
170
 
169
171
  this.stateChanged = new VcsEvent();
@@ -171,8 +173,6 @@ class VcsMap<
171
173
  this.pointerInteractionEvent = new VcsEvent();
172
174
 
173
175
  this._splitPosition = 0.5;
174
-
175
- this._postRender = new VcsEvent();
176
176
  }
177
177
 
178
178
  /**
@@ -253,12 +253,24 @@ class VcsMap<
253
253
  [...this._layerCollection].forEach((l) => {
254
254
  l.removedFromMap(this);
255
255
  });
256
+ [...this._layerCollection.vectorClusterGroups].forEach((g) => {
257
+ g.removedFromMap(this);
258
+ });
259
+
256
260
  this._layerCollection = layerCollection;
257
261
 
258
262
  if (this.active) {
259
263
  [...this._layerCollection].forEach((l) => {
260
- // eslint-disable-next-line no-void
261
- void l.mapActivated(this);
264
+ l.mapActivated(this).catch((_e) => {
265
+ this.getLogger().error(`Failed to activate map on layer: ${l.name}`);
266
+ });
267
+ });
268
+ [...this._layerCollection.vectorClusterGroups].forEach((g) => {
269
+ g.mapActivated(this).catch((_e) => {
270
+ this.getLogger().error(
271
+ `Failed to activate map on vector cluster group: ${g.name}`,
272
+ );
273
+ });
262
274
  });
263
275
  }
264
276
 
@@ -293,16 +305,28 @@ class VcsMap<
293
305
  cb();
294
306
  });
295
307
 
308
+ const added = (i: Layer | VectorClusterGroup): void => {
309
+ if (this.active) {
310
+ i.mapActivated(this).catch((_e) => {
311
+ this.getLogger().error(`Failed to activate map on layer: ${i.name}`);
312
+ });
313
+ }
314
+ };
315
+
316
+ const removed = (i: Layer | VectorClusterGroup): void => {
317
+ i.removedFromMap(this);
318
+ };
319
+
296
320
  this._collectionListeners = [
297
321
  this.layerCollection.moved.addEventListener((layer) => {
298
322
  this.indexChanged(layer);
299
323
  }),
300
- this.layerCollection.added.addEventListener((layer) => {
301
- this._layerAdded(layer);
302
- }),
303
- this.layerCollection.removed.addEventListener((layer) => {
304
- this._layerRemoved(layer);
305
- }),
324
+ this.layerCollection.added.addEventListener(added),
325
+ this.layerCollection.removed.addEventListener(removed),
326
+ this.layerCollection.vectorClusterGroups.added.addEventListener(added),
327
+ this.layerCollection.vectorClusterGroups.removed.addEventListener(
328
+ removed,
329
+ ),
306
330
  ];
307
331
  }
308
332
 
@@ -342,28 +366,20 @@ class VcsMap<
342
366
  // eslint-disable-next-line no-unused-vars,class-methods-use-this
343
367
  indexChanged(_layer: Layer): void {}
344
368
 
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
369
  /**
363
370
  * Validates a visualization. A visualization must have the vcsLayeName symbol set and a layer with said name must be
364
371
  * part of the maps layerCollection.
365
372
  */
366
- validateVisualization(item: V): item is V & { [vcsLayerName]: string } {
373
+ validateVisualization(item: V): item is V & {
374
+ [vcsLayerName]?: string;
375
+ [vectorClusterGroupName]?: string;
376
+ } {
377
+ const vectorCluster = (item as OLLayer)[vectorClusterGroupName];
378
+ if (vectorCluster) {
379
+ return this.layerCollection.vectorClusterGroups.hasKey(
380
+ vectorCluster,
381
+ ) as boolean;
382
+ }
367
383
  const layerName = item[vcsLayerName];
368
384
  if (layerName == null) {
369
385
  this.getLogger().warning('item is missing vcsLayerName symbol');
@@ -376,45 +392,75 @@ class VcsMap<
376
392
  /**
377
393
  * Adds a visualization to the visualizations map for its layer. The visualization must be valid, use validateVisualization first
378
394
  */
379
- addVisualization(item: V): void {
395
+ addVisualization(item: V & { [vectorClusterGroupName]?: string }): void {
380
396
  if (!this.validateVisualization(item)) {
381
397
  throw new Error(
382
398
  'Visualization item is not valid, validate before adding',
383
399
  );
384
400
  }
385
- const layerName = item[vcsLayerName];
386
- if (!this._visualizations.has(layerName)) {
387
- this._visualizations.set(layerName, new Set());
401
+ let name: string;
402
+ let setMap;
403
+ if (item[vectorClusterGroupName]) {
404
+ name = item[vectorClusterGroupName];
405
+ setMap = this._clusterVisualizations;
406
+ } else {
407
+ name = item[vcsLayerName]!;
408
+ setMap = this._visualizations;
409
+ }
410
+
411
+ if (!setMap.has(name)) {
412
+ setMap.set(name, new Set());
388
413
  }
389
- (this._visualizations.get(layerName) as Set<V>).add(item);
414
+ (setMap.get(name) as Set<V>).add(item);
390
415
  }
391
416
 
392
417
  /**
393
418
  * Removes a visualization
394
419
  */
395
- removeVisualization(item: V): void {
396
- const layerName = item[vcsLayerName];
397
- const viz = layerName ? this._visualizations.get(layerName) : undefined;
398
- if (viz && layerName) {
420
+ removeVisualization(item: V & { [vectorClusterGroupName]?: string }): void {
421
+ let name: string | undefined;
422
+ let setMap;
423
+ if (item[vectorClusterGroupName]) {
424
+ name = item[vectorClusterGroupName];
425
+ setMap = this._clusterVisualizations;
426
+ } else {
427
+ name = item[vcsLayerName];
428
+ setMap = this._visualizations;
429
+ }
430
+
431
+ const viz = name ? setMap.get(name) : undefined;
432
+ if (viz && name) {
399
433
  viz.delete(item);
400
434
  if (viz.size === 0) {
401
- this._visualizations.delete(layerName);
435
+ setMap.delete(name);
402
436
  }
403
437
  }
404
438
  }
405
439
 
406
440
  /**
407
- * Gets the visualizations for a specific layer.
441
+ * Gets the visualizations for a specific layer
408
442
  */
409
443
  getVisualizationsForLayer(layer: Layer): Set<V> | undefined {
410
444
  return this._visualizations.get(layer.name);
411
445
  }
412
446
 
447
+ /**
448
+ * Gets the visualizations of a vector cluster group
449
+ */
450
+ getVisualizationsForVectorClusterGroup(
451
+ group: VectorClusterGroup,
452
+ ): Set<V> | undefined {
453
+ return this._clusterVisualizations.get(group.name);
454
+ }
455
+
413
456
  /**
414
457
  * Get all visualizations added to this map.
415
458
  */
416
459
  getVisualizations(): V[] {
417
- return [...this._visualizations.values()]
460
+ return [
461
+ ...this._visualizations.values(),
462
+ ...this._clusterVisualizations.values(),
463
+ ]
418
464
  .map((layerVisualizations) => [...layerVisualizations])
419
465
  .flat();
420
466
  }
@@ -433,9 +479,12 @@ class VcsMap<
433
479
  return;
434
480
  }
435
481
  this._state = MapState.ACTIVE;
436
- await Promise.all(
437
- [...this.layerCollection].map((layer) => layer.mapActivated(this)),
438
- );
482
+ await Promise.all([
483
+ ...[...this.layerCollection].map((layer) => layer.mapActivated(this)),
484
+ ...[...this.layerCollection.vectorClusterGroups].map((clusterGroup) =>
485
+ clusterGroup.mapActivated(this),
486
+ ),
487
+ ]);
439
488
  if (this._state !== MapState.ACTIVE) {
440
489
  return;
441
490
  }
@@ -453,6 +502,9 @@ class VcsMap<
453
502
  [...this.layerCollection].forEach((layer) => {
454
503
  layer.mapDeactivated(this);
455
504
  });
505
+ [...this.layerCollection.vectorClusterGroups].forEach((clusterGroup) =>
506
+ clusterGroup.mapDeactivated(this),
507
+ );
456
508
  this.stateChanged.raiseEvent(this._state);
457
509
  }
458
510
  }
@@ -559,6 +611,9 @@ class VcsMap<
559
611
  [...this.layerCollection].forEach((l) => {
560
612
  l.removedFromMap(this);
561
613
  });
614
+ [...this.layerCollection.vectorClusterGroups].forEach((g) => {
615
+ g.removedFromMap(this);
616
+ });
562
617
  }
563
618
  if (this.stateChanged) {
564
619
  this.stateChanged.destroy();
package/src/ol/ol.d.ts CHANGED
@@ -42,6 +42,7 @@ import {
42
42
  globalHiderLastUpdated,
43
43
  } from '../layer/vectorHelpers.js';
44
44
  import { validityPlaceholder } from '../util/editor/interactions/createPolygonInteraction.js';
45
+ import { vectorClusterGroupName } from '../vectorCluster/vectorClusterSymbols.js';
45
46
 
46
47
  declare module 'ol/geom.js' {
47
48
  interface Geometry {
@@ -113,6 +114,7 @@ declare module 'ol/index.js' {
113
114
  [handlerSymbol]?: AxisAndPlanes;
114
115
  [vertexSymbol]?: boolean;
115
116
  [createSync]?: boolean;
117
+ [vectorClusterGroupName]?: string;
116
118
  }
117
119
 
118
120
  class CanvasTileRenderer extends CanvasImmediateRenderer {
@@ -141,6 +143,7 @@ declare module 'ol/style.js' {
141
143
  declare module 'ol/layer.js' {
142
144
  interface Layer {
143
145
  [vcsLayerName]: string;
146
+ [vectorClusterGroupName]?: string;
144
147
  }
145
148
  }
146
149
 
@@ -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;
@@ -1,4 +1,4 @@
1
- /* eslint-disable @typescript-eslint/ban-ts-comment */
1
+ import { parseBoolean } from '@vcsuite/parsers';
2
2
  import { check } from '@vcsuite/check';
3
3
  import IndexedCollection from './indexedCollection.js';
4
4
  import ExclusiveManager from './exclusiveManager.js';
@@ -7,6 +7,9 @@ import VcsEvent from '../vcsEvent.js';
7
7
  import GlobalHider from '../layer/globalHider.js';
8
8
  // eslint-disable-next-line import/no-named-default
9
9
  import type { default as Layer, SplitLayer } from '../layer/layer.js';
10
+ import VectorClusterGroupCollection from '../vectorCluster/vectorClusterGroupCollection.js';
11
+ import type VectorLayer from '../layer/vectorLayer.js';
12
+ import { destroyCollection } from '../vcsModuleHelpers.js';
10
13
 
11
14
  /**
12
15
  * The largest integer zindex which can be safely assigned to a layer (equal to Number.MAX_SAFE_INTEGER)
@@ -14,6 +17,11 @@ import type { default as Layer, SplitLayer } from '../layer/layer.js';
14
17
  */
15
18
  export const maxZIndex = Number.MAX_SAFE_INTEGER;
16
19
 
20
+ export type LayerCollectionOptions = {
21
+ vectorClusterGroupCollection?: VectorClusterGroupCollection;
22
+ destroyVectorClusterGroupCollection?: boolean;
23
+ };
24
+
17
25
  /**
18
26
  * A collection of layers. Manages rendering order and layer exclusivity. Emits state changes for convenience. Passed to
19
27
  * {@link Map} for layers available to said map. Layers must have unique names.
@@ -57,6 +65,8 @@ class LayerCollection extends IndexedCollection<Layer> {
57
65
  */
58
66
  private _globalHider: GlobalHider;
59
67
 
68
+ private _vectorClusterGroups: VectorClusterGroupCollection;
69
+
60
70
  /**
61
71
  * Locale for this layerCollection, will be synchronized by the vcsApp, if part of an vcsApp.
62
72
  * This Locale will be set on all Member Layers. On setting the Locale this will trigger a reload of all locale
@@ -64,7 +74,11 @@ class LayerCollection extends IndexedCollection<Layer> {
64
74
  */
65
75
  private _locale: string;
66
76
 
67
- constructor() {
77
+ private _vectorClusterGroupListeners: (() => void) | undefined;
78
+
79
+ destroyVectorClusterGroupCollection: boolean;
80
+
81
+ constructor(options: LayerCollectionOptions = {}) {
68
82
  super();
69
83
 
70
84
  this._layerEventListeners = {};
@@ -73,6 +87,18 @@ class LayerCollection extends IndexedCollection<Layer> {
73
87
  this.exclusiveManager = new ExclusiveManager();
74
88
  this._globalHider = new GlobalHider();
75
89
  this._locale = 'en';
90
+ if (options.vectorClusterGroupCollection) {
91
+ this._vectorClusterGroups = options.vectorClusterGroupCollection;
92
+ } else {
93
+ this._vectorClusterGroups = new VectorClusterGroupCollection(
94
+ this._globalHider,
95
+ );
96
+ }
97
+ this.destroyVectorClusterGroupCollection = parseBoolean(
98
+ options.destroyVectorClusterGroupCollection,
99
+ !options.vectorClusterGroupCollection,
100
+ );
101
+ this._setupVectorClusterGroupListeners();
76
102
  }
77
103
 
78
104
  /**
@@ -102,6 +128,7 @@ class LayerCollection extends IndexedCollection<Layer> {
102
128
  this._array.forEach((layer) => {
103
129
  layer.setGlobalHider(this._globalHider);
104
130
  });
131
+ this.vectorClusterGroups.globalHider = this._globalHider;
105
132
  }
106
133
 
107
134
  get locale(): string {
@@ -119,6 +146,10 @@ class LayerCollection extends IndexedCollection<Layer> {
119
146
  }
120
147
  }
121
148
 
149
+ get vectorClusterGroups(): VectorClusterGroupCollection {
150
+ return this._vectorClusterGroups;
151
+ }
152
+
122
153
  private _listenToLayerEvents(layer: Layer): void {
123
154
  const stateListener = layer.stateChanged.addEventListener(
124
155
  (state: LayerState) => {
@@ -148,6 +179,25 @@ class LayerCollection extends IndexedCollection<Layer> {
148
179
  ),
149
180
  );
150
181
  }
182
+
183
+ if ((layer as VectorLayer).vectorClusterGroupChanged) {
184
+ listeners.push(
185
+ (layer as VectorLayer).vectorClusterGroupChanged.addEventListener(
186
+ ({ newGroup, oldGroup }) => {
187
+ if (oldGroup) {
188
+ this._vectorClusterGroups
189
+ .getByKey(oldGroup)
190
+ ?.removeLayer(layer as VectorLayer);
191
+ }
192
+ if (newGroup) {
193
+ this._vectorClusterGroups
194
+ .getByKey(newGroup)
195
+ ?.addLayer(layer as VectorLayer);
196
+ }
197
+ },
198
+ ),
199
+ );
200
+ }
151
201
  this._layerEventListeners[layer.name] = listeners;
152
202
  }
153
203
 
@@ -158,7 +208,7 @@ class LayerCollection extends IndexedCollection<Layer> {
158
208
  */
159
209
  private _findZIndexPosition(zIndex: number): number | null {
160
210
  const usedIndex = this._array.findIndex(
161
- // @ts-ignore
211
+ // @ts-expect-error: z index is undefined
162
212
  (l) => l[this._zIndexSymbol] > zIndex,
163
213
  );
164
214
  return usedIndex > -1 ? usedIndex : null;
@@ -173,7 +223,7 @@ class LayerCollection extends IndexedCollection<Layer> {
173
223
  private _zIndexChanged(layer: Layer): void {
174
224
  const currentIndex = this.indexOf(layer);
175
225
  if (currentIndex > -1) {
176
- // @ts-ignore
226
+ // @ts-expect-error: z index is undefined
177
227
  layer[this._zIndexSymbol] = layer.zIndex;
178
228
  let zIndexPosition = this._findZIndexPosition(layer.zIndex);
179
229
  if (
@@ -197,29 +247,43 @@ class LayerCollection extends IndexedCollection<Layer> {
197
247
  */
198
248
  private _ensureLocalZIndex(layer: Layer): void {
199
249
  const currentIndex = this.indexOf(layer);
200
- // @ts-ignore
250
+ // @ts-expect-error: z index is undefined
201
251
  const currentLayerZIndex = layer[this._zIndexSymbol] as number;
202
252
  if (currentIndex > 0) {
203
- // @ts-ignore
253
+ // @ts-expect-error: z index is undefined
204
254
  const below: number = this._array[currentIndex - 1][
205
255
  this._zIndexSymbol
206
256
  ] as number;
207
257
  if (below > currentLayerZIndex) {
208
- // @ts-ignore
258
+ // @ts-expect-error: z index is undefined
209
259
  layer[this._zIndexSymbol] = below;
210
260
  }
211
261
  }
212
262
 
213
263
  if (currentIndex < this._array.length - 1) {
214
- // @ts-ignore
264
+ // @ts-expect-error: z index is undefined
215
265
  const above = this._array[currentIndex + 1][this._zIndexSymbol] as number;
216
266
  if (above < currentLayerZIndex) {
217
- // @ts-ignore
267
+ // @ts-expect-error: z index is undefined
218
268
  layer[this._zIndexSymbol] = above;
219
269
  }
220
270
  }
221
271
  }
222
272
 
273
+ private _setupVectorClusterGroupListeners(): void {
274
+ this._vectorClusterGroupListeners =
275
+ this._vectorClusterGroups.added.addEventListener((collection) => {
276
+ this._array
277
+ .filter(
278
+ (layer) =>
279
+ (layer as VectorLayer).vectorClusterGroup === collection.name,
280
+ )
281
+ .forEach((layer) => {
282
+ collection.addLayer(layer as VectorLayer);
283
+ });
284
+ });
285
+ }
286
+
223
287
  /**
224
288
  * Adds a layer to the collection. Can optionally be passed an index at which to insert the layer.
225
289
  * The layer locale will be set to the same locale of the layerCollection. This will trigger a forceRedraw
@@ -235,13 +299,18 @@ class LayerCollection extends IndexedCollection<Layer> {
235
299
  }
236
300
  const insertedAt = super.add(layer, usedIndex);
237
301
  if (insertedAt != null) {
238
- // @ts-ignore
302
+ // @ts-expect-error: z index is undefined
239
303
  layer[this._zIndexSymbol] = layer.zIndex;
240
304
  layer.setGlobalHider(this._globalHider);
241
305
  layer.locale = this.locale;
242
306
  this._ensureLocalZIndex(layer);
243
307
  this._listenToLayerEvents(layer);
244
308
  this.exclusiveManager.registerLayer(layer);
309
+ if ((layer as VectorLayer).vectorClusterGroup) {
310
+ this._vectorClusterGroups
311
+ .getByKey((layer as VectorLayer).vectorClusterGroup)
312
+ ?.addLayer(layer as VectorLayer);
313
+ }
245
314
  }
246
315
  return insertedAt;
247
316
  }
@@ -253,10 +322,15 @@ class LayerCollection extends IndexedCollection<Layer> {
253
322
  });
254
323
  delete this._layerEventListeners[layer.name];
255
324
  }
256
- // @ts-ignore
325
+ // @ts-expect-error: z index is undefined
257
326
  delete layer[this._zIndexSymbol];
258
327
  layer.setGlobalHider();
259
328
  this.exclusiveManager.unregisterLayer(layer);
329
+ if ((layer as VectorLayer).vectorClusterGroup) {
330
+ this._vectorClusterGroups
331
+ .getByKey((layer as VectorLayer).vectorClusterGroup)
332
+ ?.removeLayer(layer as VectorLayer);
333
+ }
260
334
  return super._remove(layer);
261
335
  }
262
336
 
@@ -267,7 +341,7 @@ class LayerCollection extends IndexedCollection<Layer> {
267
341
  r();
268
342
  });
269
343
  this._array.forEach((l) => {
270
- // @ts-ignore
344
+ // @ts-expect-error: z index is undefined
271
345
  delete l[this._zIndexSymbol];
272
346
  });
273
347
 
@@ -286,6 +360,10 @@ class LayerCollection extends IndexedCollection<Layer> {
286
360
  this._layerEventListeners = {};
287
361
  this.exclusiveManager.destroy();
288
362
  this._globalHider.destroy();
363
+ this._vectorClusterGroupListeners?.();
364
+ if (this.destroyVectorClusterGroupCollection) {
365
+ destroyCollection(this._vectorClusterGroups);
366
+ }
289
367
  super.destroy();
290
368
  }
291
369
  }