@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
@@ -1,26 +1,6 @@
1
1
  import VectorSource from 'ol/source/Vector.js';
2
2
  import OLVectorLayer from 'ol/layer/Vector.js';
3
- import { unByKey } from 'ol/Observable.js';
4
- import Feature from 'ol/Feature.js';
5
- import type { EventsKey } from 'ol/events.js';
6
- import type { Extent } from 'ol/extent.js';
7
3
  import type { SplitDirection } from '@vcmap-cesium/engine';
8
- import type { Geometry } from 'ol/geom.js';
9
-
10
- import { mercatorProjection } from '../../util/projection.js';
11
- import {
12
- mercatorGeometryToImageGeometry,
13
- imageGeometryToMercatorGeometry,
14
- getPolygonizedGeometry,
15
- setNewGeometry,
16
- } from './obliqueHelpers.js';
17
- import {
18
- actuallyIsCircle,
19
- alreadyTransformedToImage,
20
- doNotTransform,
21
- obliqueGeometry,
22
- originalFeatureSymbol,
23
- } from '../vectorSymbols.js';
24
4
  import LayerObliqueImpl from './layerObliqueImpl.js';
25
5
  import { synchronizeFeatureVisibilityWithSource } from '../vectorHelpers.js';
26
6
  import { FeatureLayerImplementation } from '../featureLayer.js';
@@ -29,7 +9,10 @@ import type ObliqueMap from '../../map/obliqueMap.js';
29
9
  import type GlobalHider from '../globalHider.js';
30
10
  import type StyleItem from '../../style/styleItem.js';
31
11
  import type FeatureVisibility from '../featureVisibility.js';
32
- import type ObliqueImage from '../../oblique/obliqueImage.js';
12
+ import {
13
+ createSourceObliqueSync,
14
+ SourceObliqueSync,
15
+ } from './sourceObliqueSync.js';
33
16
 
34
17
  /**
35
18
  * represents a specific vector layer for oblique.
@@ -42,31 +25,7 @@ class VectorObliqueImpl
42
25
  return 'VectorObliqueImpl';
43
26
  }
44
27
 
45
- obliqueSource = new VectorSource({});
46
-
47
- private _featureListeners: Record<string, Record<string, EventsKey>> = {};
48
-
49
- private _sourceListener: EventsKey[] = [];
50
-
51
- /**
52
- * The extent of the current image for which features where fetched
53
- */
54
- currentExtent: Extent | null = null;
55
-
56
- /**
57
- * The image name for which the current features where fetched
58
- */
59
- fetchedFeaturesForImageName: string | null = null;
60
-
61
- private _updatingMercator: Record<
62
- string,
63
- number | boolean | null | NodeJS.Timeout
64
- > = {};
65
-
66
- private _updatingOblique: Record<
67
- string,
68
- number | boolean | null | NodeJS.Timeout
69
- > = {};
28
+ obliqueSource: VectorSource;
70
29
 
71
30
  private _featureVisibilityListeners: (() => void)[] = [];
72
31
 
@@ -80,11 +39,13 @@ class VectorObliqueImpl
80
39
 
81
40
  olLayer: OLVectorLayer | null = null;
82
41
 
83
- private _imageChangedListener: (() => void) | null | undefined = null;
42
+ private _sourceObliqueSync: SourceObliqueSync;
84
43
 
85
44
  constructor(map: ObliqueMap, options: VectorImplementationOptions) {
86
45
  super(map, options);
87
46
 
47
+ this._sourceObliqueSync = createSourceObliqueSync(options.source, map);
48
+ this.obliqueSource = this._sourceObliqueSync.obliqueSource;
88
49
  this.globalHider = options.globalHider as GlobalHider;
89
50
  this.source = options.source;
90
51
  this.style = options.style;
@@ -110,56 +71,6 @@ class VectorObliqueImpl
110
71
  // eslint-disable-next-line class-methods-use-this,no-unused-vars
111
72
  updateSplitDirection(_splitDirection: SplitDirection): void {}
112
73
 
113
- /**
114
- * clears the current image and fetches features for the next
115
- */
116
- private _onObliqueImageChanged(): void {
117
- this._clearCurrentImage();
118
- this._fetchFeaturesInView();
119
- }
120
-
121
- private _featureInExtent(feature: Feature): boolean {
122
- if (this.currentExtent) {
123
- const geometry = feature.getGeometry();
124
- if (geometry) {
125
- return (
126
- geometry[alreadyTransformedToImage] ||
127
- geometry.intersectsExtent(this.currentExtent)
128
- );
129
- }
130
- }
131
- return false;
132
- }
133
-
134
- protected _addSourceListeners(): void {
135
- this._sourceListener.push(
136
- this.source.on('addfeature', (event) => {
137
- const f = event.feature as Feature;
138
- if (this._featureInExtent(f)) {
139
- // eslint-disable-next-line no-void
140
- void this.addFeature(f);
141
- }
142
- }),
143
- );
144
-
145
- this._sourceListener.push(
146
- this.source.on('removefeature', (event) => {
147
- this.removeFeature(event.feature as Feature);
148
- }),
149
- );
150
-
151
- this._sourceListener.push(
152
- this.source.on('changefeature', (event) => {
153
- const f = event.feature as Feature;
154
- const newFeatureId = f.getId() as string | number;
155
- if (!this._featureListeners[newFeatureId] && this._featureInExtent(f)) {
156
- // eslint-disable-next-line no-void
157
- void this.addFeature(f);
158
- }
159
- }),
160
- );
161
- }
162
-
163
74
  async activate(): Promise<void> {
164
75
  if (!this.active) {
165
76
  await super.activate();
@@ -173,282 +84,11 @@ class VectorObliqueImpl
173
84
  this.globalHider,
174
85
  );
175
86
  }
176
- this._addSourceListeners();
177
- this._imageChangedListener = this.map.imageChanged?.addEventListener(
178
- this._onObliqueImageChanged.bind(this),
179
- );
180
- this._fetchFeaturesInView();
87
+ this._sourceObliqueSync.activate();
181
88
  }
182
89
  }
183
90
  }
184
91
 
185
- private async addFeature(originalFeature: Feature): Promise<void> {
186
- if (!this.active) {
187
- this.fetchedFeaturesForImageName = null;
188
- }
189
- if (this.active && this.currentExtent) {
190
- const id = originalFeature.getId() as string | number;
191
- const originalGeometry = originalFeature.getGeometry();
192
- if (originalFeature[doNotTransform]) {
193
- if (originalGeometry && !this.obliqueSource.getFeatureById(id)) {
194
- this.obliqueSource.addFeature(originalFeature);
195
- }
196
- return Promise.resolve();
197
- }
198
-
199
- if (this.obliqueSource.getFeatureById(id) || this._updatingOblique[id]) {
200
- return Promise.resolve();
201
- }
202
- const obliqueFeature = new Feature({});
203
- obliqueFeature.setId(id);
204
- obliqueFeature[originalFeatureSymbol] = originalFeature;
205
- setNewGeometry(originalFeature, obliqueFeature);
206
- obliqueFeature.setStyle(originalFeature.getStyle());
207
-
208
- this._setFeatureListeners(originalFeature, obliqueFeature);
209
-
210
- await this._convertToOblique(originalFeature, obliqueFeature);
211
- if (this.source.hasFeature(originalFeature)) {
212
- // if not in source, feature has been removed in between.
213
- this.obliqueSource.addFeature(obliqueFeature);
214
- }
215
- }
216
- return Promise.resolve();
217
- }
218
-
219
- private _originalGeometryChanged(
220
- listeners: Record<string, EventsKey>,
221
- originalFeature: Feature,
222
- obliqueFeature: Feature,
223
- ): void {
224
- unByKey(listeners.originalGeometryChanged);
225
- unByKey(listeners.obliqueGeometryChanged);
226
- setNewGeometry(originalFeature, obliqueFeature);
227
- this.updateObliqueGeometry(originalFeature, obliqueFeature);
228
- listeners.originalGeometryChanged = originalFeature
229
- .getGeometry()!
230
- .on(
231
- 'change',
232
- this.updateObliqueGeometry.bind(this, originalFeature, obliqueFeature),
233
- );
234
- listeners.obliqueGeometryChanged = obliqueFeature
235
- .getGeometry()!
236
- .on(
237
- 'change',
238
- this.updateMercatorGeometry.bind(this, originalFeature, obliqueFeature),
239
- );
240
- }
241
-
242
- private _setFeatureListeners(
243
- originalFeature: Feature,
244
- obliqueFeature: Feature,
245
- ): void {
246
- const featureId = obliqueFeature.getId() as string | number;
247
- const listeners = {
248
- originalFeatureGeometryChanged: originalFeature.on(
249
- 'change:geometry',
250
- () => {
251
- const originalGeometry = originalFeature.getGeometry() as Geometry;
252
- if (originalGeometry[actuallyIsCircle]) {
253
- unByKey(listeners.originalGeometryChanged);
254
- listeners.originalGeometryChanged = originalFeature
255
- .getGeometry()!
256
- .on('change', () => {
257
- if (this._updatingMercator[featureId]) {
258
- return;
259
- }
260
- delete originalGeometry[actuallyIsCircle];
261
- this._originalGeometryChanged(
262
- listeners,
263
- originalFeature,
264
- obliqueFeature,
265
- );
266
- });
267
- return;
268
- }
269
- this._originalGeometryChanged(
270
- listeners,
271
- originalFeature,
272
- obliqueFeature,
273
- );
274
- },
275
- ),
276
- originalFeatureChanged: originalFeature.on('change', () => {
277
- obliqueFeature.setStyle(originalFeature.getStyle());
278
- }),
279
- originalGeometryChanged: originalFeature
280
- .getGeometry()!
281
- .on(
282
- 'change',
283
- this.updateObliqueGeometry.bind(
284
- this,
285
- originalFeature,
286
- obliqueFeature,
287
- ),
288
- ),
289
- obliqueGeometryChanged: obliqueFeature
290
- .getGeometry()!
291
- .on(
292
- 'change',
293
- this.updateMercatorGeometry.bind(
294
- this,
295
- originalFeature,
296
- obliqueFeature,
297
- ),
298
- ),
299
- };
300
- this._featureListeners[featureId] = listeners;
301
- }
302
-
303
- private async _convertToOblique(
304
- originalFeature: Feature,
305
- obliqueFeature: Feature,
306
- ): Promise<void> {
307
- const id = originalFeature.getId() as string | number;
308
- const vectorGeometry = originalFeature.getGeometry() as Geometry;
309
- const imageGeometry = obliqueFeature.getGeometry() as Geometry;
310
- this._updatingOblique[id] = true;
311
- let promise: Promise<unknown>;
312
- if (!vectorGeometry[alreadyTransformedToImage]) {
313
- promise = mercatorGeometryToImageGeometry(
314
- vectorGeometry,
315
- imageGeometry,
316
- this.map.currentImage as ObliqueImage,
317
- );
318
- } else {
319
- obliqueFeature
320
- .getGeometry()!
321
- .setCoordinates(vectorGeometry.getCoordinates());
322
- // we MUST wait for a promise, otherwise this is sync and you can add a feature twice
323
- promise = Promise.resolve();
324
- }
325
- await promise;
326
- this._updatingOblique[id] = null;
327
- }
328
-
329
- updateObliqueGeometry(
330
- originalFeature: Feature,
331
- obliqueFeature: Feature,
332
- ): void {
333
- const id = originalFeature.getId() as string | number;
334
- if (this._updatingMercator[id]) {
335
- return;
336
- }
337
- if (this._updatingOblique[id] != null) {
338
- clearTimeout(this._updatingOblique[id] as number);
339
- }
340
- if (originalFeature.getGeometry()?.[alreadyTransformedToImage]) {
341
- // eslint-disable-next-line no-void
342
- void this._convertToOblique(originalFeature, obliqueFeature);
343
- } else {
344
- this._updatingOblique[id] = setTimeout(() => {
345
- // eslint-disable-next-line no-void
346
- void this._convertToOblique(originalFeature, obliqueFeature);
347
- }, 200);
348
- }
349
- }
350
-
351
- updateMercatorGeometry(
352
- originalFeature: Feature,
353
- obliqueFeature: Feature,
354
- ): void {
355
- const id = originalFeature.getId() as string | number;
356
- if (this._updatingOblique[id]) {
357
- return;
358
- }
359
- if (this._updatingMercator[id] != null) {
360
- clearTimeout(this._updatingMercator[id] as number);
361
- }
362
- const imageName = this.fetchedFeaturesForImageName;
363
- // eslint-disable-next-line @typescript-eslint/no-misused-promises
364
- this._updatingMercator[id] = setTimeout(async () => {
365
- const originalGeometry = getPolygonizedGeometry(originalFeature, false);
366
- if (originalGeometry[actuallyIsCircle]) {
367
- originalFeature.setGeometry(originalGeometry);
368
- }
369
- const imageGeometry = getPolygonizedGeometry(obliqueFeature, true);
370
- this._updatingMercator[id] = true;
371
- await imageGeometryToMercatorGeometry(
372
- imageGeometry,
373
- originalGeometry,
374
- this.map.collection!.getImageByName(
375
- imageName as string,
376
- ) as ObliqueImage,
377
- );
378
- this._updatingMercator[id] = null;
379
- }, 200);
380
- }
381
-
382
- /**
383
- * Synchronizes image Features if the geometry has been changed.
384
- * also clears source and featureListeners
385
- */
386
- private _clearCurrentImage(): void {
387
- Object.values(this._featureListeners).forEach((listeners) => {
388
- unByKey(Object.values(listeners));
389
- });
390
- this._featureListeners = {};
391
- this._updatingOblique = {};
392
- this._updatingMercator = {};
393
- this.obliqueSource.getFeatures().forEach((f) => {
394
- const original = f[originalFeatureSymbol];
395
- if (original) {
396
- delete original[obliqueGeometry];
397
- const originalGeometry = original.getGeometry();
398
- if (originalGeometry?.[alreadyTransformedToImage]) {
399
- this.updateMercatorGeometry(original, f);
400
- }
401
- delete originalGeometry?.[alreadyTransformedToImage];
402
- }
403
- });
404
- this.obliqueSource.clear(true);
405
- this.fetchedFeaturesForImageName = null;
406
- }
407
-
408
- /**
409
- * Fetches the features within the extent of the current image
410
- * @private
411
- */
412
- private _fetchFeaturesInView(): void {
413
- if (
414
- this.active &&
415
- this.map.currentImage &&
416
- this.fetchedFeaturesForImageName !== this.map.currentImage.name
417
- ) {
418
- this.currentExtent = this.map
419
- .getExtentOfCurrentImage()
420
- .getCoordinatesInProjection(mercatorProjection);
421
- this.source.forEachFeatureInExtent(this.currentExtent, (feature) => {
422
- // eslint-disable-next-line no-void
423
- void this.addFeature(feature);
424
- });
425
- this.source.forEachFeature((feature) => {
426
- if (feature.getGeometry()?.[alreadyTransformedToImage]) {
427
- // eslint-disable-next-line no-void
428
- void this.addFeature(feature);
429
- }
430
- });
431
- this.fetchedFeaturesForImageName = this.map.currentImage.name;
432
- }
433
- }
434
-
435
- private removeFeature(feature: Feature): void {
436
- const id = feature.getId() as number | string;
437
- const feat = this.obliqueSource.getFeatureById(id);
438
- if (this._updatingOblique[id] != null) {
439
- clearTimeout(this._updatingOblique[id] as number);
440
- this._updatingOblique[id] = null;
441
- }
442
- if (feat) {
443
- const listeners = this._featureListeners[id];
444
- if (listeners) {
445
- unByKey(Object.values(listeners));
446
- delete this._featureListeners[id];
447
- }
448
- this.obliqueSource.removeFeature(feat);
449
- }
450
- }
451
-
452
92
  deactivate(): void {
453
93
  super.deactivate();
454
94
  if (this.olLayer) {
@@ -460,15 +100,7 @@ class VectorObliqueImpl
460
100
  });
461
101
  this._featureVisibilityListeners = [];
462
102
 
463
- unByKey(this._sourceListener);
464
- this._sourceListener = [];
465
-
466
- if (this._imageChangedListener) {
467
- this._imageChangedListener();
468
- this._imageChangedListener = null;
469
- }
470
-
471
- this._clearCurrentImage();
103
+ this._sourceObliqueSync.deactivate();
472
104
  }
473
105
 
474
106
  destroy(): void {
@@ -477,25 +109,7 @@ class VectorObliqueImpl
477
109
  }
478
110
  this.olLayer = null;
479
111
 
480
- unByKey(this._sourceListener);
481
- this._sourceListener = [];
482
-
483
- if (this._imageChangedListener) {
484
- this._imageChangedListener();
485
- this._imageChangedListener = null;
486
- }
487
- this.obliqueSource.clear(true);
488
- Object.values(this._updatingOblique).forEach((timer) => {
489
- if (timer != null) {
490
- clearTimeout(timer as number);
491
- }
492
- });
493
- Object.values(this._updatingMercator).forEach((timer) => {
494
- if (timer != null) {
495
- clearTimeout(timer as number);
496
- }
497
- });
498
- this._clearCurrentImage();
112
+ this._sourceObliqueSync.destroy();
499
113
  super.destroy();
500
114
  }
501
115
  }
@@ -41,10 +41,11 @@ import { originalStyle, updateOriginalStyle } from './featureVisibility.js';
41
41
  import StyleItem, { StyleItemOptions } from '../style/styleItem.js';
42
42
  import { layerClassRegistry } from '../classRegistry.js';
43
43
 
44
- import VcsMap from '../map/vcsMap.js';
44
+ import type VcsMap from '../map/vcsMap.js';
45
45
  import { GeoJSONwriteOptions } from './geojsonHelpers.js';
46
46
  import { vcsLayerName } from './layerSymbols.js';
47
47
  import CesiumTilesetCesiumImpl from './cesium/cesiumTilesetCesiumImpl.js';
48
+ import VcsEvent from '../vcsEvent.js';
48
49
 
49
50
  export type VectorOptions = FeatureLayerOptions & {
50
51
  /**
@@ -61,6 +62,7 @@ export type VectorOptions = FeatureLayerOptions & {
61
62
  */
62
63
  isDynamic?: boolean;
63
64
  vectorProperties?: VectorPropertiesOptions;
65
+ vectorClusterGroup?: string;
64
66
  };
65
67
 
66
68
  export type VectorImplementationOptions = FeatureLayerImplementationOptions & {
@@ -98,6 +100,7 @@ class VectorLayer
98
100
  highlightStyle: undefined,
99
101
  isDynamic: false,
100
102
  vectorProperties: {}, // XXX or should we return VectorProperties default options?
103
+ vectorClusterGroup: undefined,
101
104
  };
102
105
  }
103
106
 
@@ -138,6 +141,13 @@ class VectorLayer
138
141
 
139
142
  private _initialStyle: StyleItemOptions | undefined;
140
143
 
144
+ private _vectorClusterGroup: string | undefined;
145
+
146
+ vectorClusterGroupChanged = new VcsEvent<{
147
+ newGroup?: string;
148
+ oldGroup?: string;
149
+ }>();
150
+
141
151
  constructor(options: VectorOptions) {
142
152
  super(options);
143
153
 
@@ -179,6 +189,7 @@ class VectorLayer
179
189
  }
180
190
 
181
191
  this._initialStyle = initialStyle;
192
+ this._vectorClusterGroup = options.vectorClusterGroup;
182
193
  }
183
194
 
184
195
  get allowPicking(): boolean {
@@ -202,6 +213,24 @@ class VectorLayer
202
213
  }
203
214
  }
204
215
 
216
+ get vectorClusterGroup(): string | undefined {
217
+ return this._vectorClusterGroup;
218
+ }
219
+
220
+ set vectorClusterGroup(newGroup: string | undefined) {
221
+ if (this._vectorClusterGroup !== newGroup) {
222
+ const oldGroup = this._vectorClusterGroup;
223
+ this._vectorClusterGroup = newGroup;
224
+ // this will destroy any current implementations which are potentially active and recreate them if needed
225
+ this.forceRedraw().catch(() => {
226
+ this.getLogger().warning(
227
+ 'Failed to redraw after setting vector cluster group',
228
+ );
229
+ });
230
+ this.vectorClusterGroupChanged.raiseEvent({ newGroup, oldGroup });
231
+ }
232
+ }
233
+
205
234
  initialize(): Promise<void> {
206
235
  return super.initialize().then(() => {
207
236
  this._trackStyleChanges();
@@ -264,7 +293,7 @@ class VectorLayer
264
293
  | VectorCesiumImpl
265
294
  | CesiumTilesetCesiumImpl
266
295
  )[] {
267
- if (!this.visibility) {
296
+ if (!this.visibility || !!this.vectorClusterGroup) {
268
297
  return [];
269
298
  }
270
299
 
@@ -506,6 +535,10 @@ class VectorLayer
506
535
  config.vectorProperties = vectorPropertiesConfig;
507
536
  }
508
537
 
538
+ if (this._vectorClusterGroup !== defaultOptions.vectorClusterGroup) {
539
+ config.vectorClusterGroup = this._vectorClusterGroup;
540
+ }
541
+
509
542
  return config;
510
543
  }
511
544
 
@@ -18,13 +18,20 @@ import { mapClassRegistry } from '../classRegistry.js';
18
18
  import type LayerCollection from '../util/layerCollection.js';
19
19
  import type Layer from '../layer/layer.js';
20
20
  import { DisableMapControlOptions } from '../util/mapCollection.js';
21
+ import { vectorClusterGroupName } from '../vectorCluster/vectorClusterSymbols.js';
21
22
 
22
23
  export function ensureLayerInCollection(
23
24
  layers: OLCollection<OLLayer>,
24
25
  layer: OLLayer,
25
26
  layerCollection: LayerCollection,
26
27
  ): void {
27
- const targetIndex = layerCollection.indexOfKey(layer[vcsLayerName]) as number;
28
+ let targetIndex = -1;
29
+ if (layer[vectorClusterGroupName]) {
30
+ targetIndex = layerCollection.size;
31
+ } else {
32
+ targetIndex = layerCollection.indexOfKey(layer[vcsLayerName]) as number;
33
+ }
34
+
28
35
  if (targetIndex > -1) {
29
36
  const layerArray = layers.getArray();
30
37
 
@@ -59,6 +59,7 @@ import type LayerCollection from '../util/layerCollection.js';
59
59
  import type Layer from '../layer/layer.js';
60
60
  import VcsEvent from '../vcsEvent.js';
61
61
  import { DisableMapControlOptions } from '../util/mapCollection.js';
62
+ import { vectorClusterGroupName } from '../vectorCluster/vectorClusterSymbols.js';
62
63
 
63
64
  export type CesiumMapOptions = VcsMapOptions & {
64
65
  /**
@@ -158,9 +159,15 @@ export async function ensureInDataSourceCollection(
158
159
  dataSource: CustomDataSource,
159
160
  layerCollection: LayerCollection,
160
161
  ): Promise<void> {
161
- const targetIndex = layerCollection.indexOfKey(
162
- dataSource[vcsLayerName],
163
- ) as number;
162
+ let targetIndex = -1;
163
+ if (dataSource[vectorClusterGroupName]) {
164
+ targetIndex = layerCollection.size;
165
+ } else {
166
+ targetIndex = layerCollection.indexOfKey(
167
+ dataSource[vcsLayerName],
168
+ ) as number;
169
+ }
170
+
164
171
  if (targetIndex > -1) {
165
172
  if (!dataSourceCollection.contains(dataSource)) {
166
173
  await dataSourceCollection.add(dataSource);
@@ -1290,6 +1297,32 @@ class CesiumMap extends VcsMap<CesiumVisualisationType> {
1290
1297
  }
1291
1298
  }
1292
1299
 
1300
+ async addClusterDataSource(dataSource: CustomDataSource): Promise<void> {
1301
+ const clusterDataSources = this.getClusterDatasources();
1302
+ if (!clusterDataSources) {
1303
+ throw new Error('Cannot add data source to uninitialized map');
1304
+ }
1305
+ if (this.validateVisualization(dataSource)) {
1306
+ this.addVisualization(dataSource);
1307
+ await ensureInDataSourceCollection(
1308
+ clusterDataSources,
1309
+ dataSource,
1310
+ this.layerCollection,
1311
+ );
1312
+ }
1313
+ }
1314
+
1315
+ removeClusterDataSource(dataSource: CustomDataSource): void {
1316
+ this.removeVisualization(dataSource);
1317
+ if (
1318
+ this._clusterDataSourceDisplay &&
1319
+ !this._clusterDataSourceDisplay.isDestroyed() &&
1320
+ !this._clusterDataSourceDisplay.dataSources.isDestroyed()
1321
+ ) {
1322
+ this._clusterDataSourceDisplay.dataSources.remove(dataSource);
1323
+ }
1324
+ }
1325
+
1293
1326
  /**
1294
1327
  * set the cesium TerrainProvider
1295
1328
  */