@vcmap/core 5.0.0-rc.8 → 5.0.0-rc.9

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 (50) hide show
  1. package/index.d.ts +110 -102
  2. package/index.js +4 -5
  3. package/package.json +2 -2
  4. package/src/category/appBackedCategory.js +38 -3
  5. package/src/category/category.js +37 -10
  6. package/src/category/categoryCollection.js +3 -3
  7. package/src/classRegistry.js +107 -28
  8. package/src/featureProvider/abstractFeatureProvider.js +1 -1
  9. package/src/featureProvider/tileProviderFeatureProvider.js +2 -0
  10. package/src/featureProvider/wmsFeatureProvider.js +2 -0
  11. package/src/layer/cesiumTilesetLayer.js +3 -6
  12. package/src/layer/czmlLayer.js +2 -2
  13. package/src/layer/dataSourceLayer.js +2 -2
  14. package/src/layer/featureLayer.js +10 -23
  15. package/src/layer/featureStoreLayer.js +3 -3
  16. package/src/layer/geojsonHelpers.js +1 -18
  17. package/src/layer/geojsonLayer.js +2 -2
  18. package/src/layer/layer.js +3 -3
  19. package/src/layer/openStreetMapLayer.js +2 -2
  20. package/src/layer/pointCloudLayer.js +4 -4
  21. package/src/layer/rasterLayer.js +2 -2
  22. package/src/layer/singleImageLayer.js +2 -2
  23. package/src/layer/terrainLayer.js +2 -2
  24. package/src/layer/tileProvider/mvtTileProvider.js +18 -0
  25. package/src/layer/tileProvider/staticGeojsonTileProvider.js +19 -4
  26. package/src/layer/tileProvider/tileProvider.js +10 -1
  27. package/src/layer/tileProvider/urlTemplateTileProvider.js +15 -0
  28. package/src/layer/tmsLayer.js +2 -2
  29. package/src/layer/vectorLayer.js +9 -18
  30. package/src/layer/vectorTileLayer.js +12 -21
  31. package/src/layer/wfsLayer.js +2 -2
  32. package/src/layer/wmsLayer.js +2 -2
  33. package/src/layer/wmtsLayer.js +2 -2
  34. package/src/map/baseOLMap.js +2 -2
  35. package/src/map/cesiumMap.js +2 -2
  36. package/src/map/obliqueMap.js +2 -2
  37. package/src/map/openlayersMap.js +2 -2
  38. package/src/map/vcsMap.js +2 -2
  39. package/src/overrideClassRegistry.js +204 -0
  40. package/src/style/declarativeStyleItem.js +17 -18
  41. package/src/style/styleFactory.js +14 -33
  42. package/src/style/styleItem.js +15 -96
  43. package/src/style/vectorStyleItem.js +68 -78
  44. package/src/style/writeStyle.js +4 -7
  45. package/src/util/projection.js +0 -3
  46. package/src/util/viewpoint.js +0 -3
  47. package/src/vcsApp.js +103 -5
  48. package/src/vcsAppContextHelpers.js +51 -38
  49. package/src/globalCollections.js +0 -7
  50. package/src/layer/tileProvider/tileProviderFactory.js +0 -28
@@ -1,10 +1,11 @@
1
1
  import { parseGeoJSON } from '../geojsonHelpers.js';
2
2
  import TileProvider from './tileProvider.js';
3
3
  import { requestJson } from '../../util/fetch.js';
4
+ import { tileProviderClassRegistry } from '../../classRegistry.js';
4
5
 
5
6
  /**
6
- * @typedef {TileProviderOptions} StaticGeojsonTileProviderOptions
7
- * @property {string} url geojson
7
+ * @typedef {TileProviderOptions} StaticGeoJSONTileProviderOptions
8
+ * @property {string} url - url to the geojson
8
9
  * @api
9
10
  */
10
11
 
@@ -24,7 +25,7 @@ class StaticGeoJSONTileProvider extends TileProvider {
24
25
  static get className() { return 'StaticGeoJSONTileProvider'; }
25
26
 
26
27
  /**
27
- * @returns {StaticGeojsonTileProviderOptions}
28
+ * @returns {StaticGeoJSONTileProviderOptions}
28
29
  */
29
30
  static getDefaultOptions() {
30
31
  return {
@@ -35,7 +36,7 @@ class StaticGeoJSONTileProvider extends TileProvider {
35
36
  }
36
37
 
37
38
  /**
38
- * @param {StaticGeojsonTileProviderOptions} options
39
+ * @param {StaticGeoJSONTileProviderOptions} options
39
40
  */
40
41
  constructor(options) {
41
42
  const defaultOptions = StaticGeoJSONTileProvider.getDefaultOptions();
@@ -62,6 +63,20 @@ class StaticGeoJSONTileProvider extends TileProvider {
62
63
  const { features } = parseGeoJSON(data, { dynamicStyle: true });
63
64
  return features;
64
65
  }
66
+
67
+ /**
68
+ * @returns {StaticGeoJSONTileProviderOptions}
69
+ */
70
+ toJSON() {
71
+ const config = /** @type {StaticGeoJSONTileProviderOptions} */ (super.toJSON());
72
+ delete config.baseLevels;
73
+
74
+ if (this.url) {
75
+ config.url = this.url;
76
+ }
77
+ return config;
78
+ }
65
79
  }
66
80
 
67
81
  export default StaticGeoJSONTileProvider;
82
+ tileProviderClassRegistry.registerClass(StaticGeoJSONTileProvider.className, StaticGeoJSONTileProvider);
@@ -12,6 +12,7 @@ import {
12
12
  } from '../../util/projection.js';
13
13
  import VcsObject from '../../vcsObject.js';
14
14
  import VcsEvent from '../../vcsEvent.js';
15
+ import { tileProviderClassRegistry } from '../../classRegistry.js';
15
16
 
16
17
  /**
17
18
  * @typedef {Object} tileProviderRTreeEntry
@@ -538,13 +539,20 @@ class TileProvider extends VcsObject {
538
539
  config.tileCacheSize = this.tileCacheSize;
539
540
  }
540
541
 
541
- if (defaultOptions.baseLevels !== this.baseLevels) {
542
+ if (!(
543
+ this.baseLevels.length === defaultOptions.baseLevels.length &&
544
+ this.baseLevels.every(level => defaultOptions.baseLevels.includes(level))
545
+ )) {
542
546
  config.baseLevels = this.baseLevels.slice();
543
547
  }
544
548
 
545
549
  if (defaultOptions.trackFeaturesToTiles !== this.trackFeaturesToTiles) {
546
550
  config.trackFeaturesToTiles = this.trackFeaturesToTiles;
547
551
  }
552
+
553
+ if (defaultOptions.allowTileAggregation !== this.allowTileAggregation) {
554
+ config.allowTileAggregation = this.allowTileAggregation;
555
+ }
548
556
  return config;
549
557
  }
550
558
 
@@ -582,3 +590,4 @@ class TileProvider extends VcsObject {
582
590
  }
583
591
 
584
592
  export default TileProvider;
593
+ tileProviderClassRegistry.registerClass(TileProvider.className, TileProvider);
@@ -3,6 +3,7 @@ import { parseGeoJSON } from '../geojsonHelpers.js';
3
3
  import TileProvider from './tileProvider.js';
4
4
  import { getCurrentLocale } from '../../util/locale.js';
5
5
  import { requestJson } from '../../util/fetch.js';
6
+ import { tileProviderClassRegistry } from '../../classRegistry.js';
6
7
 
7
8
  /**
8
9
  * @typedef {TileProviderOptions} URLTemplateTileProviderOptions
@@ -101,6 +102,20 @@ class URLTemplateTileProvider extends TileProvider {
101
102
  const { features } = parseGeoJSON(data, { dynamicStyle: true });
102
103
  return features;
103
104
  }
105
+
106
+ /**
107
+ * @returns {URLTemplateTileProviderOptions}
108
+ */
109
+ toJSON() {
110
+ const config = /** @type {URLTemplateTileProviderOptions} */ (super.toJSON());
111
+
112
+ if (this.url) {
113
+ config.url = this.url;
114
+ }
115
+
116
+ return config;
117
+ }
104
118
  }
105
119
 
106
120
  export default URLTemplateTileProvider;
121
+ tileProviderClassRegistry.registerClass(URLTemplateTileProvider.className, URLTemplateTileProvider);
@@ -3,7 +3,7 @@ import OpenlayersMap from '../map/openlayersMap.js';
3
3
  import CesiumMap from '../map/cesiumMap.js';
4
4
  import TmsOpenlayersImpl from './openlayers/tmsOpenlayersImpl.js';
5
5
  import TmsCesiumImpl from './cesium/tmsCesiumImpl.js';
6
- import { VcsClassRegistry } from '../classRegistry.js';
6
+ import { layerClassRegistry } from '../classRegistry.js';
7
7
 
8
8
  /**
9
9
  * @typedef {RasterLayerOptions} TMSOptions
@@ -117,5 +117,5 @@ class TMSLayer extends RasterLayer {
117
117
  }
118
118
  }
119
119
 
120
- VcsClassRegistry.registerClass(TMSLayer.className, TMSLayer);
120
+ layerClassRegistry.registerClass(TMSLayer.className, TMSLayer);
121
121
  export default TMSLayer;
@@ -26,9 +26,9 @@ import VectorObliqueImpl from './oblique/vectorObliqueImpl.js';
26
26
  import ObliqueMap from '../map/obliqueMap.js';
27
27
  import CesiumMap from '../map/cesiumMap.js';
28
28
  import { originalStyle, updateOriginalStyle } from './featureVisibility.js';
29
- import StyleItem, { referenceableStyleSymbol, StyleType } from '../style/styleItem.js';
29
+ import StyleItem from '../style/styleItem.js';
30
30
  import { getGenericFeatureFromClickedObject } from './vectorHelpers.js';
31
- import { VcsClassRegistry } from '../classRegistry.js';
31
+ import { layerClassRegistry } from '../classRegistry.js';
32
32
 
33
33
  /**
34
34
  * @typedef {FeatureLayerOptions} VectorOptions
@@ -213,17 +213,12 @@ class VectorLayer extends FeatureLayer {
213
213
  });
214
214
 
215
215
  let initialStyle = options.style;
216
- if (options.activeStyleName) {
217
- initialStyle = {
218
- type: StyleType.REFERENCE,
219
- name: options.activeStyleName,
220
- };
221
- } else if (options.style instanceof StyleItem) {
222
- initialStyle = options.style.getOptions();
216
+ if (options.style instanceof StyleItem) {
217
+ initialStyle = options.style.toJSON();
223
218
  }
224
219
 
225
220
  /**
226
- * @type {Reference|StyleItemOptions|string}
221
+ * @type {StyleItemOptions}
227
222
  * @private
228
223
  */
229
224
  this._initialStyle = initialStyle;
@@ -344,7 +339,7 @@ class VectorLayer extends FeatureLayer {
344
339
  }
345
340
 
346
341
  /**
347
- * @param {(Reference|DeclarativeStyleItemOptions|VectorStyleItemOptions|import("@vcmap/core").StyleItem|string)=} styleOptions
342
+ * @param {(DeclarativeStyleItemOptions|VectorStyleItemOptions|import("@vcmap/core").StyleItem)=} styleOptions
348
343
  * @param {import("@vcmap/core").VectorStyleItem=} defaultStyle
349
344
  * @returns {import("@vcmap/core").StyleItem}
350
345
  */
@@ -354,7 +349,7 @@ class VectorLayer extends FeatureLayer {
354
349
 
355
350
  /**
356
351
  * sets the style of this layer
357
- * @param {import("ol/style/Style").default|import("ol/style/Style").StyleFunction|import("@vcmap/core").StyleItem|string} style
352
+ * @param {import("ol/style/Style").default|import("ol/style/Style").StyleFunction|import("@vcmap/core").StyleItem} style
358
353
  * @param {boolean=} silent
359
354
  */
360
355
  setStyle(style, silent) {
@@ -594,9 +589,7 @@ class VectorLayer extends FeatureLayer {
594
589
  }
595
590
 
596
591
  if (this.highlightStyle) {
597
- config.highlightStyle = this.highlightStyle[referenceableStyleSymbol] ?
598
- this.highlightStyle.getReference() :
599
- this.highlightStyle.getOptions();
592
+ config.highlightStyle = this.highlightStyle.toJSON();
600
593
  }
601
594
 
602
595
  if (this.isDynamic !== defaultOptions.isDynamic) {
@@ -608,8 +601,6 @@ class VectorLayer extends FeatureLayer {
608
601
  config.vectorProperties = vectorPropertiesConfig;
609
602
  }
610
603
 
611
- // XXX missing style
612
-
613
604
  return config;
614
605
  }
615
606
 
@@ -628,5 +619,5 @@ class VectorLayer extends FeatureLayer {
628
619
  }
629
620
  }
630
621
 
631
- VcsClassRegistry.registerClass(VectorLayer.className, VectorLayer);
622
+ layerClassRegistry.registerClass(VectorLayer.className, VectorLayer);
632
623
  export default VectorLayer;
@@ -12,10 +12,10 @@ import { FeatureVisibilityAction, globalHidden, hidden, highlighted } from './fe
12
12
  import { getStylesArray } from '../util/featureconverter/convert.js';
13
13
  import { vcsLayerName } from './layerSymbols.js';
14
14
  import TileProviderFeatureProvider from '../featureProvider/tileProviderFeatureProvider.js';
15
- import tileProviderFactory from './tileProvider/tileProviderFactory.js';
16
15
  import { getGenericFeatureFromClickedObject } from './vectorHelpers.js';
17
16
  import { originalFeatureSymbol } from './vectorSymbols.js';
18
- import { VcsClassRegistry } from '../classRegistry.js';
17
+ import { getObjectFromClassRegistry, layerClassRegistry, tileProviderClassRegistry } from '../classRegistry.js';
18
+ import TileProvider from './tileProvider/tileProvider.js';
19
19
 
20
20
  /**
21
21
  * synchronizes featureVisibility Symbols on the feature;
@@ -44,7 +44,7 @@ function synchronizeFeatureVisibility(featureVisibility, globalHider, feature) {
44
44
 
45
45
  /**
46
46
  * @typedef {FeatureLayerOptions} VectorTileOptions
47
- * @property {TileProviderOptions} tileProvider
47
+ * @property {TileProviderOptions|import("@vcmap/core").TileProvider} tileProvider
48
48
  * @property {VectorStyleItemOptions|import("@vcmap/core").VectorStyleItem|undefined} highlightStyle
49
49
  * @property {VectorPropertiesOptions|undefined} vectorProperties
50
50
  * @property {number|undefined} minLevel used to restrict the zoom level visibility (minlevel does not allow rendering above tileProvider baseLevel)
@@ -132,17 +132,13 @@ class VectorTileLayer extends FeatureLayer {
132
132
  ...options.vectorProperties,
133
133
  });
134
134
 
135
- /**
136
- * @type {TileProviderOptions}
137
- * @private
138
- */
139
- this._tileProviderOptions = options.tileProvider;
140
-
141
135
  /**
142
136
  * @type {import("@vcmap/core").TileProvider}
143
137
  * @api
144
138
  */
145
- this.tileProvider = undefined;
139
+ this.tileProvider = options.tileProvider instanceof TileProvider ? // XXX this now throws if not passing in a tileProvider.
140
+ options.tileProvider :
141
+ getObjectFromClassRegistry(tileProviderClassRegistry, options.tileProvider);
146
142
 
147
143
  /**
148
144
  * @type {number|undefined}
@@ -187,21 +183,19 @@ class VectorTileLayer extends FeatureLayer {
187
183
  * @returns {Promise<void>}
188
184
  */
189
185
  async initialize() {
190
- await super.initialize();
191
- if (!this.tileProvider) {
192
- this.tileProvider = await tileProviderFactory(this._tileProviderOptions);
193
- // this.tileProvider = await tileProviderFactory(this._tileProviderOptions);
186
+ if (!this.initialized) {
194
187
  this._tileLoadEventListener =
195
188
  this.tileProvider.tileLoadedEvent.addEventListener(event => this._handleTileLoaded(event));
196
189
  this._vectorPropertiesChangedListener =
197
190
  this.vectorProperties.propertyChanged.addEventListener(() => {
198
191
  this.reload();
199
192
  });
200
- this.featureProvider = new TileProviderFeatureProvider(this.name, {
193
+ this.featureProvider = new TileProviderFeatureProvider(this.name, { // XXX this overwrites
201
194
  tileProvider: this.tileProvider,
202
195
  vectorProperties: this.vectorProperties,
203
196
  });
204
197
  }
198
+ await super.initialize();
205
199
  }
206
200
 
207
201
 
@@ -392,7 +386,7 @@ class VectorTileLayer extends FeatureLayer {
392
386
  }
393
387
 
394
388
  /**
395
- * @param {(Reference|DeclarativeStyleItemOptions|VectorStyleItemOptions|import("@vcmap/core").StyleItem|string)=} styleOptions
389
+ * @param {(DeclarativeStyleItemOptions|VectorStyleItemOptions|import("@vcmap/core").StyleItem)=} styleOptions
396
390
  * @param {VectorStyleItem=} defaultStyle
397
391
  * @returns {import("@vcmap/core").StyleItem}
398
392
  */
@@ -466,15 +460,12 @@ class VectorTileLayer extends FeatureLayer {
466
460
  }
467
461
 
468
462
  if (this.tileProvider) {
469
- const tileProviderConfig = this.tileProvider.toJSON();
470
- config.tileProvider = tileProviderConfig;
471
- } else if (this._tileProviderOptions) {
472
- config.tileProvider = this._tileProviderOptions;
463
+ config.tileProvider = this.tileProvider.toJSON();
473
464
  }
474
465
 
475
466
  return config;
476
467
  }
477
468
  }
478
469
 
479
- VcsClassRegistry.registerClass(VectorTileLayer.className, VectorTileLayer);
470
+ layerClassRegistry.registerClass(VectorTileLayer.className, VectorTileLayer);
480
471
  export default VectorTileLayer;
@@ -1,7 +1,7 @@
1
1
  import WFSFormat from 'ol/format/WFS.js';
2
2
  import VectorLayer from './vectorLayer.js';
3
3
  import Projection from '../util/projection.js';
4
- import { VcsClassRegistry } from '../classRegistry.js';
4
+ import { layerClassRegistry } from '../classRegistry.js';
5
5
  import { requestJson } from '../util/fetch.js';
6
6
 
7
7
  /**
@@ -161,5 +161,5 @@ class WFSLayer extends VectorLayer {
161
161
  }
162
162
  }
163
163
 
164
- VcsClassRegistry.registerClass(WFSLayer.className, WFSLayer);
164
+ layerClassRegistry.registerClass(WFSLayer.className, WFSLayer);
165
165
  export default WFSLayer;
@@ -7,7 +7,7 @@ import WmsCesiumImpl from './cesium/wmsCesiumImpl.js';
7
7
  import OpenlayersMap from '../map/openlayersMap.js';
8
8
  import WmsOpenlayersImpl from './openlayers/wmsOpenlayersImpl.js';
9
9
  import Extent from '../util/extent.js';
10
- import { VcsClassRegistry } from '../classRegistry.js';
10
+ import { layerClassRegistry } from '../classRegistry.js';
11
11
 
12
12
  /**
13
13
  * @typedef {RasterLayerImplementationOptions} WMSImplementationOptions
@@ -266,5 +266,5 @@ class WMSLayer extends RasterLayer {
266
266
  }
267
267
  }
268
268
 
269
- VcsClassRegistry.registerClass(WMSLayer.className, WMSLayer);
269
+ layerClassRegistry.registerClass(WMSLayer.className, WMSLayer);
270
270
  export default WMSLayer;
@@ -5,7 +5,7 @@ import OpenlayersMap from '../map/openlayersMap.js';
5
5
  import CesiumMap from '../map/cesiumMap.js';
6
6
  import WmtsOpenlayersImpl from './openlayers/wmtsOpenlayersImpl.js';
7
7
  import WmtsCesiumImpl from './cesium/wmtsCesiumImpl.js';
8
- import { VcsClassRegistry } from '../classRegistry.js';
8
+ import { layerClassRegistry } from '../classRegistry.js';
9
9
 
10
10
  /**
11
11
  * @typedef {RasterLayerOptions} WMTSOptions
@@ -230,6 +230,6 @@ class WMTSLayer extends RasterLayer {
230
230
  }
231
231
  }
232
232
 
233
- VcsClassRegistry.registerClass(WMTSLayer.className, WMTSLayer);
233
+ layerClassRegistry.registerClass(WMTSLayer.className, WMTSLayer);
234
234
  export default WMTSLayer;
235
235
 
@@ -5,7 +5,7 @@ import { defaults as defaultInteractions } from 'ol/interaction.js';
5
5
  import VcsMap from './vcsMap.js';
6
6
  import { vcsLayerName } from '../layer/layerSymbols.js';
7
7
  import { ModificationKeyType, PointerEventType, PointerKeyType } from '../interaction/interactionType.js';
8
- import { VcsClassRegistry } from '../classRegistry.js';
8
+ import { mapClassRegistry } from '../classRegistry.js';
9
9
 
10
10
  /**
11
11
  * @param {import("ol/Collection").default<import("ol/layer/Layer").default>} layers
@@ -253,5 +253,5 @@ class BaseOLMap extends VcsMap {
253
253
  }
254
254
  }
255
255
 
256
- VcsClassRegistry.registerClass(BaseOLMap.className, BaseOLMap);
256
+ mapClassRegistry.registerClass(BaseOLMap.className, BaseOLMap);
257
257
  export default BaseOLMap;
@@ -38,7 +38,7 @@ import { getHeightFromTerrainProvider } from '../layer/terrainHelpers.js';
38
38
  import { vcsLayerName } from '../layer/layerSymbols.js';
39
39
  import { ModificationKeyType, PointerEventType, PointerKeyType } from '../interaction/interactionType.js';
40
40
  import CameraLimiter from './cameraLimiter.js';
41
- import { VcsClassRegistry } from '../classRegistry.js';
41
+ import { mapClassRegistry } from '../classRegistry.js';
42
42
 
43
43
  /**
44
44
  * @typedef {VcsMapOptions} CesiumMapOptions
@@ -1173,5 +1173,5 @@ class CesiumMap extends VcsMap {
1173
1173
  }
1174
1174
  }
1175
1175
 
1176
- VcsClassRegistry.registerClass(CesiumMap.className, CesiumMap);
1176
+ mapClassRegistry.registerClass(CesiumMap.className, CesiumMap);
1177
1177
  export default CesiumMap;
@@ -13,7 +13,7 @@ import { ObliqueViewDirection as ViewDirection } from '../oblique/obliqueViewDir
13
13
  import ObliqueProvider from '../oblique/obliqueProvider.js';
14
14
  import ObliqueCollection from '../oblique/obliqueCollection.js';
15
15
  import { transformFromImage } from '../oblique/helpers.js';
16
- import { VcsClassRegistry } from '../classRegistry.js';
16
+ import { mapClassRegistry } from '../classRegistry.js';
17
17
  import DefaultObliqueCollection from '../oblique/defaultObliqueCollection.js';
18
18
 
19
19
  /**
@@ -518,5 +518,5 @@ class ObliqueMap extends BaseOLMap {
518
518
  }
519
519
  }
520
520
 
521
- VcsClassRegistry.registerClass(ObliqueMap.className, ObliqueMap);
521
+ mapClassRegistry.registerClass(ObliqueMap.className, ObliqueMap);
522
522
  export default ObliqueMap;
@@ -7,7 +7,7 @@ import { parseBoolean } from '@vcsuite/parsers';
7
7
  import ViewPoint from '../util/viewpoint.js';
8
8
  import BaseOLMap from './baseOLMap.js';
9
9
  import VcsMap from './vcsMap.js';
10
- import { VcsClassRegistry } from '../classRegistry.js';
10
+ import { mapClassRegistry } from '../classRegistry.js';
11
11
 
12
12
  /**
13
13
  * @typedef {VcsMapOptions} OpenlayersOptions
@@ -204,5 +204,5 @@ class OpenlayersMap extends BaseOLMap {
204
204
  }
205
205
  }
206
206
 
207
- VcsClassRegistry.registerClass(OpenlayersMap.className, OpenlayersMap);
207
+ mapClassRegistry.registerClass(OpenlayersMap.className, OpenlayersMap);
208
208
  export default OpenlayersMap;
package/src/map/vcsMap.js CHANGED
@@ -5,7 +5,7 @@ import LayerCollection from '../util/layerCollection.js';
5
5
  import MapState from './mapState.js';
6
6
  import { vcsLayerName } from '../layer/layerSymbols.js';
7
7
  import VcsEvent from '../vcsEvent.js';
8
- import { VcsClassRegistry } from '../classRegistry.js';
8
+ import { mapClassRegistry } from '../classRegistry.js';
9
9
 
10
10
  /**
11
11
  * @namespace maps
@@ -522,5 +522,5 @@ class VcsMap extends VcsObject {
522
522
  }
523
523
  }
524
524
 
525
- VcsClassRegistry.registerClass(VcsMap.className, VcsMap);
525
+ mapClassRegistry.registerClass(VcsMap.className, VcsMap);
526
526
  export default VcsMap;
@@ -0,0 +1,204 @@
1
+ import { check } from '@vcsuite/check';
2
+ import { getLogger } from '@vcsuite/logger';
3
+ import VcsEvent from './vcsEvent.js';
4
+
5
+ /**
6
+ * @returns {import("@vcsuite/logger").Logger}
7
+ */
8
+ function logger() {
9
+ return getLogger('OverrideClassRegistry');
10
+ }
11
+
12
+ /**
13
+ * @class
14
+ * @template {Object|import("@vcmap/core").VcsObject} T
15
+ */
16
+ class OverrideClassRegistry {
17
+ /**
18
+ * @param {import("@vcmap/core").ClassRegistry<T>} coreClassRegistry
19
+ */
20
+ constructor(coreClassRegistry) {
21
+ this._coreClassRegistry = coreClassRegistry;
22
+ /**
23
+ * @type {Map<string, { contextId: string, ctor: function(new: T, ...*) }>}
24
+ * @private
25
+ */
26
+ this._classMap = new Map();
27
+ /**
28
+ * @type {Map<string, Array<{ contextId: string, ctor: function(new: T, ...*) }>>}
29
+ * @private
30
+ */
31
+ this._classShadows = new Map();
32
+ /**
33
+ * Called if a class was replaced. Is passed the className
34
+ * @type {VcsEvent<string>}
35
+ */
36
+ this.replaced = new VcsEvent();
37
+ /**
38
+ * Called if a class was removed. Is passed the className
39
+ * @type {VcsEvent<string>}
40
+ */
41
+ this.removed = new VcsEvent();
42
+ }
43
+
44
+ /**
45
+ * @returns {Array<string>}
46
+ */
47
+ getClassNames() {
48
+ return [...new Set([...this._classMap.keys(), ...this._coreClassRegistry.getClassNames()])];
49
+ }
50
+
51
+ /**
52
+ * Register a class for a given context by name. If the class already exists, it will be replaced and replaced called with the classeName.
53
+ * @param {string} contextId
54
+ * @param {string} className
55
+ * @param {function(new: T, ...*)} ctor
56
+ */
57
+ registerClass(contextId, className, ctor) {
58
+ check(contextId, String);
59
+ check(className, String);
60
+ check(ctor, Function);
61
+
62
+ const entry = {
63
+ contextId,
64
+ ctor,
65
+ };
66
+
67
+ const replaced = this.hasClass(className);
68
+
69
+ if (this._classMap.has(className)) {
70
+ if (!this._classShadows.has(className)) {
71
+ this._classShadows.set(className, []);
72
+ }
73
+ this._classShadows.get(className).push(this._classMap.get(className));
74
+ }
75
+ this._classMap.set(className, entry);
76
+
77
+ if (replaced) {
78
+ this.replaced.raiseEvent(className);
79
+ }
80
+ }
81
+
82
+ /**
83
+ * Unregister a previously registered class. You can only unregister classes added to this registry, not the underlying core registry.
84
+ * If when registering this class you have replaced class, it will be re-instated and replaced called.
85
+ * If there is no previously registered class, it will be removed and removed will be called.
86
+ * @param {string} contextId
87
+ * @param {string} className
88
+ */
89
+ unregisterClass(contextId, className) {
90
+ check(contextId, String);
91
+ check(className, String);
92
+
93
+ if (this._classShadows.has(className)) {
94
+ const shadowsArray = this._classShadows.get(className);
95
+ const newShadowsArray = shadowsArray.filter(e => e.contextId !== contextId);
96
+ if (newShadowsArray.length === 0) {
97
+ this._classShadows.delete(className);
98
+ } else if (newShadowsArray.length !== shadowsArray.length) {
99
+ this._classShadows.set(className, newShadowsArray);
100
+ }
101
+ }
102
+
103
+ if (
104
+ this._classMap.has(className) &&
105
+ this._classMap.get(className).contextId === contextId
106
+ ) {
107
+ this._classMap.delete(className);
108
+ if (this._classShadows.has(className)) {
109
+ this._classMap.set(className, this._classShadows.get(className).pop());
110
+ if (this._classShadows.get(className).length === 0) {
111
+ this._classShadows.delete(className);
112
+ }
113
+ this.replaced.raiseEvent(className);
114
+ } else if (this._coreClassRegistry.hasClass(className)) {
115
+ this.replaced.raiseEvent(className);
116
+ } else {
117
+ this.removed.raiseEvent(className);
118
+ }
119
+ }
120
+ }
121
+
122
+ /**
123
+ * Gets the constructor for a registered class or undefined, if no such class was registerd
124
+ * @param {string} className
125
+ * @returns {function(new: T, ...*)|undefined}
126
+ * @api
127
+ */
128
+ getClass(className) {
129
+ check(className, String);
130
+
131
+ if (this._classMap.has(className)) {
132
+ return this._classMap.get(className).ctor;
133
+ }
134
+ return this._coreClassRegistry.getClass(className);
135
+ }
136
+
137
+ /**
138
+ * @param {string} className
139
+ * @returns {boolean}
140
+ */
141
+ hasClass(className) {
142
+ check(className, String);
143
+
144
+ return this._classMap.has(className) || this._coreClassRegistry.hasClass(className);
145
+ }
146
+
147
+ /**
148
+ * Create an object of the given className. The constructor is passed args.
149
+ * @param {string} className
150
+ * @param {...*} args
151
+ * @returns {T}
152
+ * @api
153
+ */
154
+ create(className, ...args) {
155
+ check(className, String);
156
+
157
+ const Ctor = this.getClass(className);
158
+ if (!Ctor) {
159
+ logger().error(`could not find constructor ${className}`);
160
+ return undefined;
161
+ }
162
+ return new Ctor(...args);
163
+ }
164
+
165
+ /**
166
+ * A convenience API to pass in a serialized VcsObject directly. It calls create using options.type as the className.
167
+ * Will throw an error if options.type is not a string or options is not an Object.
168
+ * Passes options and args to the constructor in that order.
169
+ * @param {Object} options
170
+ * @param {...*} args
171
+ * @returns {T}
172
+ */
173
+ createFromTypeOptions(options, ...args) {
174
+ check(options, { type: String });
175
+
176
+ return this.create(options.type, options, ...args);
177
+ }
178
+
179
+ /**
180
+ * Removes all classes registered from within a certain context. Will re-instate classes overwritten by the context
181
+ * and call the appropriate events, outlined in unregisterClass.
182
+ * @param {string} contextId
183
+ */
184
+ removeContext(contextId) {
185
+ check(contextId, String);
186
+
187
+ this._classMap.forEach((cb, className) => {
188
+ this.unregisterClass(contextId, className);
189
+ });
190
+ }
191
+
192
+ /**
193
+ * Destroys the override class registry
194
+ */
195
+ destroy() {
196
+ this._coreClassRegistry = null;
197
+ this._classMap.clear();
198
+ this._classShadows.clear();
199
+ this.replaced.destroy();
200
+ this.removed.destroy();
201
+ }
202
+ }
203
+
204
+ export default OverrideClassRegistry;