@vcmap/core 5.0.0-rc.1 → 5.0.0-rc.12

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 (185) hide show
  1. package/LICENSE.md +1 -1
  2. package/README.md +3 -2
  3. package/index.d.ts +2085 -1969
  4. package/index.js +137 -131
  5. package/package.json +14 -22
  6. package/src/category/appBackedCategory.js +76 -0
  7. package/src/category/category.js +417 -0
  8. package/src/category/categoryCollection.js +145 -0
  9. package/src/cesium/cesium3DTileFeature.js +1 -1
  10. package/src/classRegistry.js +162 -0
  11. package/src/context.js +72 -0
  12. package/src/{vcs/vcm/util/featureProvider → featureProvider}/abstractFeatureProvider.js +8 -9
  13. package/src/{vcs/vcm/util/featureProvider → featureProvider}/featureProviderHelpers.js +4 -5
  14. package/src/{vcs/vcm/util/featureProvider → featureProvider}/featureProviderSymbols.js +0 -0
  15. package/src/{vcs/vcm/util/featureProvider → featureProvider}/tileProviderFeatureProvider.js +4 -2
  16. package/src/{vcs/vcm/util/featureProvider → featureProvider}/wmsFeatureProvider.js +25 -18
  17. package/src/{vcs/vcm/interaction → interaction}/abstractInteraction.js +19 -18
  18. package/src/{vcs/vcm/interaction → interaction}/coordinateAtPixel.js +6 -9
  19. package/src/{vcs/vcm/interaction → interaction}/eventHandler.js +3 -3
  20. package/src/{vcs/vcm/interaction → interaction}/featureAtPixelInteraction.js +6 -19
  21. package/src/{vcs/vcm/interaction → interaction}/featureProviderInteraction.js +2 -13
  22. package/src/{vcs/vcm/interaction → interaction}/interactionChain.js +11 -32
  23. package/src/{vcs/vcm/interaction → interaction}/interactionType.js +1 -5
  24. package/src/{vcs/vcm/layer/cesium/cesiumTilesetCesium.js → layer/cesium/cesiumTilesetCesiumImpl.js} +10 -13
  25. package/src/{vcs/vcm/layer → layer}/cesium/clusterContext.js +0 -0
  26. package/src/{vcs/vcm/layer/cesium/dataSourceCesium.js → layer/cesium/dataSourceCesiumImpl.js} +5 -3
  27. package/src/{vcs/vcm/layer/cesium/openStreetMapCesium.js → layer/cesium/openStreetMapCesiumImpl.js} +6 -7
  28. package/src/{vcs/vcm/layer/cesium/rasterLayerCesium.js → layer/cesium/rasterLayerCesiumImpl.js} +5 -6
  29. package/src/{vcs/vcm/layer/cesium/singleImageCesium.js → layer/cesium/singleImageCesiumImpl.js} +5 -6
  30. package/src/{vcs/vcm/layer/cesium/terrainCesium.js → layer/cesium/terrainCesiumImpl.js} +4 -5
  31. package/src/{vcs/vcm/layer/cesium/tmsCesium.js → layer/cesium/tmsCesiumImpl.js} +6 -7
  32. package/src/{vcs/vcm/layer/cesium/vectorCesium.js → layer/cesium/vectorCesiumImpl.js} +6 -7
  33. package/src/{vcs/vcm/layer → layer}/cesium/vectorContext.js +0 -0
  34. package/src/{vcs/vcm/layer/cesium/vectorRasterTileCesium.js → layer/cesium/vectorRasterTileCesiumImpl.js} +5 -6
  35. package/src/{vcs/vcm/layer → layer}/cesium/vectorTileImageryProvider.js +1 -2
  36. package/src/{vcs/vcm/layer/cesium/wmsCesium.js → layer/cesium/wmsCesiumImpl.js} +6 -7
  37. package/src/{vcs/vcm/layer/cesium/wmtsCesium.js → layer/cesium/wmtsCesiumImpl.js} +6 -7
  38. package/src/{vcs/vcm/layer → layer}/cesium/x3dmHelper.js +0 -0
  39. package/src/{vcs/vcm/layer/cesiumTileset.js → layer/cesiumTilesetLayer.js} +38 -37
  40. package/src/{vcs/vcm/layer/czml.js → layer/czmlLayer.js} +14 -17
  41. package/src/{vcs/vcm/layer/dataSource.js → layer/dataSourceLayer.js} +38 -29
  42. package/src/{vcs/vcm/layer → layer}/featureLayer.js +27 -31
  43. package/src/{vcs/vcm/layer/featureStore.js → layer/featureStoreLayer.js} +54 -54
  44. package/src/{vcs/vcm/layer/featureStoreChanges.js → layer/featureStoreLayerChanges.js} +98 -82
  45. package/src/{vcs/vcm/layer/featureStoreState.js → layer/featureStoreLayerState.js} +1 -2
  46. package/src/{vcs/vcm/layer → layer}/featureVisibility.js +9 -6
  47. package/src/{vcs/vcm/layer → layer}/geojsonHelpers.js +15 -41
  48. package/src/{vcs/vcm/layer/geojson.js → layer/geojsonLayer.js} +19 -22
  49. package/src/{vcs/vcm/layer → layer}/globalHider.js +8 -32
  50. package/src/{vcs/vcm/layer → layer}/layer.js +63 -20
  51. package/src/{vcs/vcm/layer → layer}/layerImplementation.js +2 -3
  52. package/src/{vcs/vcm/layer → layer}/layerState.js +0 -1
  53. package/src/{vcs/vcm/layer → layer}/layerSymbols.js +0 -0
  54. package/src/{vcs/vcm/layer/oblique/layerOblique.js → layer/oblique/layerObliqueImpl.js} +4 -4
  55. package/src/{vcs/vcm/layer → layer}/oblique/obliqueHelpers.js +2 -2
  56. package/src/{vcs/vcm/layer/oblique/vectorOblique.js → layer/oblique/vectorObliqueImpl.js} +7 -9
  57. package/src/{vcs/vcm/layer/openStreetMap.js → layer/openStreetMapLayer.js} +32 -33
  58. package/src/{vcs/vcm/layer/openlayers/layerOpenlayers.js → layer/openlayers/layerOpenlayersImpl.js} +5 -6
  59. package/src/layer/openlayers/openStreetMapOpenlayersImpl.js +26 -0
  60. package/src/{vcs/vcm/layer/openlayers/rasterLayerOpenlayers.js → layer/openlayers/rasterLayerOpenlayersImpl.js} +15 -14
  61. package/src/{vcs/vcm/layer/openlayers/singleImageOpenlayers.js → layer/openlayers/singleImageOpenlayersImpl.js} +6 -7
  62. package/src/{vcs/vcm/layer/openlayers/tileDebugOpenlayers.js → layer/openlayers/tileDebugOpenlayersImpl.js} +5 -6
  63. package/src/{vcs/vcm/layer/openlayers/tmsOpenlayers.js → layer/openlayers/tmsOpenlayersImpl.js} +7 -8
  64. package/src/{vcs/vcm/layer/openlayers/vectorOpenlayers.js → layer/openlayers/vectorOpenlayersImpl.js} +8 -9
  65. package/src/{vcs/vcm/layer/openlayers/vectorTileOpenlayers.js → layer/openlayers/vectorTileOpenlayersImpl.js} +6 -7
  66. package/src/{vcs/vcm/layer/openlayers/wmsOpenlayers.js → layer/openlayers/wmsOpenlayersImpl.js} +7 -8
  67. package/src/{vcs/vcm/layer/openlayers/wmtsOpenlayers.js → layer/openlayers/wmtsOpenlayersImpl.js} +7 -8
  68. package/src/{vcs/vcm/layer/pointCloud.js → layer/pointCloudLayer.js} +26 -34
  69. package/src/{vcs/vcm/layer → layer}/rasterLayer.js +18 -20
  70. package/src/{vcs/vcm/layer/singleImage.js → layer/singleImageLayer.js} +20 -20
  71. package/src/{vcs/vcm/layer → layer}/terrainHelpers.js +13 -49
  72. package/src/{vcs/vcm/layer/terrain.js → layer/terrainLayer.js} +13 -14
  73. package/src/{vcs/vcm/layer → layer}/tileLoadedHelper.js +5 -5
  74. package/src/{vcs/vcm/layer → layer}/tileProvider/mvtTileProvider.js +22 -5
  75. package/src/layer/tileProvider/staticGeojsonTileProvider.js +81 -0
  76. package/src/{vcs/vcm/layer → layer}/tileProvider/tileProvider.js +16 -8
  77. package/src/{vcs/vcm/layer → layer}/tileProvider/urlTemplateTileProvider.js +20 -6
  78. package/src/{vcs/vcm/layer/tms.js → layer/tmsLayer.js} +19 -20
  79. package/src/{vcs/vcm/layer → layer}/vectorHelpers.js +5 -5
  80. package/src/{vcs/vcm/layer/vector.js → layer/vectorLayer.js} +38 -48
  81. package/src/{vcs/vcm/layer → layer}/vectorProperties.js +3 -4
  82. package/src/{vcs/vcm/layer → layer}/vectorSymbols.js +0 -0
  83. package/src/{vcs/vcm/layer/vectorTile.js → layer/vectorTileLayer.js} +55 -54
  84. package/src/{vcs/vcm/layer/wfs.js → layer/wfsLayer.js} +19 -20
  85. package/src/{vcs/vcm/layer → layer}/wmsHelpers.js +1 -1
  86. package/src/{vcs/vcm/layer/wms.js → layer/wmsLayer.js} +22 -23
  87. package/src/{vcs/vcm/layer/wmts.js → layer/wmtsLayer.js} +20 -21
  88. package/src/{vcs/vcm/maps → map}/baseOLMap.js +5 -6
  89. package/src/{vcs/vcm/maps → map}/cameraLimiter.js +11 -17
  90. package/src/{vcs/vcm/maps/cesium.js → map/cesiumMap.js} +21 -34
  91. package/src/{vcs/vcm/maps → map}/mapState.js +0 -1
  92. package/src/{vcs/vcm/maps/oblique.js → map/obliqueMap.js} +42 -57
  93. package/src/{vcs/vcm/maps/openlayers.js → map/openlayersMap.js} +17 -15
  94. package/src/{vcs/vcm/maps/map.js → map/vcsMap.js} +41 -22
  95. package/src/oblique/defaultObliqueCollection.js +62 -0
  96. package/src/{vcs/vcm/oblique → oblique}/helpers.js +13 -44
  97. package/src/{vcs/vcm/oblique/ObliqueCollection.js → oblique/obliqueCollection.js} +117 -37
  98. package/src/{vcs/vcm/oblique/ObliqueDataSet.js → oblique/obliqueDataSet.js} +67 -26
  99. package/src/{vcs/vcm/oblique/ObliqueImage.js → oblique/obliqueImage.js} +1 -2
  100. package/src/{vcs/vcm/oblique/ObliqueImageMeta.js → oblique/obliqueImageMeta.js} +4 -5
  101. package/src/{vcs/vcm/oblique/ObliqueProvider.js → oblique/obliqueProvider.js} +17 -12
  102. package/src/{vcs/vcm/oblique/ObliqueView.js → oblique/obliqueView.js} +31 -2
  103. package/src/{vcs/vcm/oblique/ObliqueViewDirection.js → oblique/obliqueViewDirection.js} +0 -3
  104. package/src/{vcs/vcm/oblique → oblique}/parseImageJson.js +20 -12
  105. package/src/ol/geom/circle.js +1 -1
  106. package/src/ol/render/canvas/canvasTileRenderer.js +0 -1
  107. package/src/overrideClassRegistry.js +204 -0
  108. package/src/{vcs/vcm/util/style → style}/declarativeStyleItem.js +43 -20
  109. package/src/{vcs/vcm/util/style → style}/shapesCategory.js +0 -2
  110. package/src/style/styleFactory.js +29 -0
  111. package/src/{vcs/vcm/util/style → style}/styleHelpers.js +3 -14
  112. package/src/{vcs/vcm/util/style → style}/styleItem.js +23 -86
  113. package/src/{vcs/vcm/util/style → style}/vectorStyleItem.js +73 -85
  114. package/src/{vcs/vcm/util/style → style}/writeStyle.js +4 -7
  115. package/src/{vcs/vcm/util → util}/clipping/clippingObject.js +10 -12
  116. package/src/{vcs/vcm/util → util}/clipping/clippingObjectManager.js +2 -3
  117. package/src/{vcs/vcm/util → util}/clipping/clippingPlaneHelper.js +4 -8
  118. package/src/{vcs/vcm/util → util}/collection.js +16 -4
  119. package/src/{vcs/vcm/util → util}/dateTime.js +0 -0
  120. package/src/{vcs/vcm/util → util}/exclusiveManager.js +0 -0
  121. package/src/{vcs/vcm/util → util}/extent.js +18 -12
  122. package/src/{vcs/vcm/util → util}/featureconverter/circleToCesium.js +0 -0
  123. package/src/{vcs/vcm/util → util}/featureconverter/convert.js +0 -0
  124. package/src/util/featureconverter/extent3D.js +181 -0
  125. package/src/{vcs/vcm/util → util}/featureconverter/featureconverterHelper.js +1 -1
  126. package/src/{vcs/vcm/util → util}/featureconverter/lineStringToCesium.js +0 -0
  127. package/src/{vcs/vcm/util → util}/featureconverter/pointToCesium.js +3 -3
  128. package/src/{vcs/vcm/util → util}/featureconverter/polygonToCesium.js +1 -1
  129. package/src/util/fetch.js +32 -0
  130. package/src/{vcs/vcm/util → util}/geometryHelpers.js +0 -0
  131. package/src/{vcs/vcm/util → util}/indexedCollection.js +24 -2
  132. package/src/{vcs/vcm/util → util}/isMobile.js +0 -0
  133. package/src/{vcs/vcm/util → util}/layerCollection.js +49 -12
  134. package/src/{vcs/vcm/util → util}/locale.js +1 -1
  135. package/src/{vcs/vcm/util → util}/mapCollection.js +91 -34
  136. package/src/{vcs/vcm/util → util}/math.js +0 -0
  137. package/src/util/overrideCollection.js +223 -0
  138. package/src/{vcs/vcm/util → util}/projection.js +39 -29
  139. package/src/{vcs/vcm/util → util}/splitScreen.js +10 -10
  140. package/src/{vcs/vcm/util → util}/urlHelpers.js +0 -0
  141. package/src/{vcs/vcm/util → util}/viewpoint.js +5 -9
  142. package/src/vcsApp.js +471 -0
  143. package/src/vcsAppContextHelpers.js +121 -0
  144. package/src/{vcs/vcm/event/vcsEvent.js → vcsEvent.js} +2 -3
  145. package/src/{vcs/vcm/object.js → vcsObject.js} +2 -10
  146. package/tests/data/buildings/tileset.json +428 -0
  147. package/tests/data/dynamicPointCzml.json +64 -0
  148. package/tests/data/oblique/imageData/imagev34.json +352 -0
  149. package/tests/data/oblique/imageData/imagev35.json +54 -0
  150. package/tests/data/oblique/imageData/imagev35PerImageSize.json +53 -0
  151. package/tests/data/oblique/tiledImageData/12/2199/1342.json +1 -0
  152. package/tests/data/oblique/tiledImageData/12/2199/1343.json +1 -0
  153. package/tests/data/oblique/tiledImageData/12/2199/1344.json +1 -0
  154. package/tests/data/oblique/tiledImageData/12/2200/1342.json +1 -0
  155. package/tests/data/oblique/tiledImageData/12/2200/1343.json +1 -0
  156. package/tests/data/oblique/tiledImageData/12/2200/1344.json +1 -0
  157. package/tests/data/oblique/tiledImageData/12/2201/1342.json +1 -0
  158. package/tests/data/oblique/tiledImageData/12/2201/1343.json +1 -0
  159. package/tests/data/oblique/tiledImageData/12/2201/1344.json +1 -0
  160. package/tests/data/oblique/tiledImageData/image.json +1 -0
  161. package/tests/data/terrain/13/8800/6485.terrain +0 -0
  162. package/tests/data/terrain/13/8800/6486.terrain +0 -0
  163. package/tests/data/terrain/13/8801/6485.terrain +0 -0
  164. package/tests/data/terrain/13/8801/6486.terrain +0 -0
  165. package/tests/data/terrain/layer.json +136 -0
  166. package/tests/data/testGeoJSON.json +161 -0
  167. package/tests/data/tile.pbf +0 -0
  168. package/tests/unit/helpers/cesiumHelpers.js +272 -0
  169. package/tests/unit/helpers/getFileNameFromUrl.js +12 -0
  170. package/tests/unit/helpers/helpers.js +11 -0
  171. package/tests/unit/helpers/imageHelpers.js +20 -0
  172. package/tests/unit/helpers/importJSON.js +15 -0
  173. package/tests/unit/helpers/obliqueData.js +76 -0
  174. package/tests/unit/helpers/obliqueHelpers.js +112 -0
  175. package/tests/unit/helpers/openlayersHelpers.js +22 -0
  176. package/tests/unit/helpers/terrain/terrainData.js +46 -0
  177. package/src/vcs/vcm/classRegistry.js +0 -106
  178. package/src/vcs/vcm/globalCollections.js +0 -11
  179. package/src/vcs/vcm/layer/buildings.js +0 -17
  180. package/src/vcs/vcm/layer/cesium/pointCloudCesium.js +0 -58
  181. package/src/vcs/vcm/layer/openlayers/openStreetMapOpenlayers.js +0 -27
  182. package/src/vcs/vcm/layer/tileProvider/staticGeojsonTileProvider.js +0 -67
  183. package/src/vcs/vcm/layer/tileProvider/tileProviderFactory.js +0 -28
  184. package/src/vcs/vcm/util/featureconverter/extent3d.js +0 -154
  185. package/src/vcs/vcm/util/style/styleFactory.js +0 -48
@@ -1,6 +1,6 @@
1
- import { checkMaybe } from '@vcsuite/check';
1
+ import { check, checkMaybe } from '@vcsuite/check';
2
2
  import { getLogger } from '@vcsuite/logger';
3
- import VcsEvent from '../event/vcsEvent.js';
3
+ import VcsEvent from '../vcsEvent.js';
4
4
  import Collection from './collection.js';
5
5
  import EventHandler from '../interaction/eventHandler.js';
6
6
  import LayerCollection from './layerCollection.js';
@@ -15,7 +15,7 @@ import SplitScreen from './splitScreen.js';
15
15
 
16
16
  /**
17
17
  * @param {import("@vcmap/core").CesiumMap} cesiumMap
18
- * @param {import("@vcmap/core").Openlayers} olMap
18
+ * @param {import("@vcmap/core").OpenlayersMap} olMap
19
19
  * @returns {Promise<void>}
20
20
  */
21
21
  async function setCesiumToOLViewpoint(cesiumMap, olMap) {
@@ -42,7 +42,6 @@ async function setCesiumToOLViewpoint(cesiumMap, olMap) {
42
42
 
43
43
  /**
44
44
  * @class
45
- * @export
46
45
  * @extends {Collection<import("@vcmap/core").VcsMap>}}
47
46
  */
48
47
  // ignored do to static issues, see https://github.com/microsoft/TypeScript/issues/4628
@@ -83,6 +82,13 @@ class MapCollection extends Collection {
83
82
  */
84
83
  this._target = null;
85
84
 
85
+ /**
86
+ * if the active map is removed the last viewpoint is cached for the next mapActivation.
87
+ * @type {import("@vcmap/core").ViewPoint}
88
+ * @private
89
+ */
90
+ this._cachedViewpoint = null;
91
+
86
92
  /**
87
93
  * The map pointer event handler. The EventHandler is shared amongst all maps within the collection.
88
94
  * @type {EventHandler}
@@ -94,9 +100,8 @@ class MapCollection extends Collection {
94
100
  * Collection of layers shared amongst the maps within this collection,
95
101
  * layers will be rendered if supported on the currently active map.
96
102
  * @type {LayerCollection}
97
- * @api
98
103
  */
99
- this.layerCollection = new LayerCollection();
104
+ this._layerCollection = new LayerCollection();
100
105
 
101
106
  /**
102
107
  * Called, if a map fails to initialize. The map causing the error will be removed from the collection.
@@ -125,12 +130,13 @@ class MapCollection extends Collection {
125
130
  * @type {ClippingObjectManager}
126
131
  * @api
127
132
  */
128
- this.clippingObjectManager = new ClippingObjectManager(this.layerCollection);
133
+ this.clippingObjectManager = new ClippingObjectManager(this._layerCollection);
129
134
 
130
135
  /**
131
136
  * @type {SplitScreen}
137
+ * @private
132
138
  */
133
- this.splitScreen = new SplitScreen(this.clippingObjectManager);
139
+ this._splitScreen = new SplitScreen(this.clippingObjectManager);
134
140
 
135
141
  /**
136
142
  * @type {Array<Function>}
@@ -157,6 +163,48 @@ class MapCollection extends Collection {
157
163
  return this._target;
158
164
  }
159
165
 
166
+ /**
167
+ * The current layer collection
168
+ * @type {LayerCollection}
169
+ */
170
+ get layerCollection() {
171
+ return this._layerCollection;
172
+ }
173
+
174
+ /**
175
+ * Set the layer collection for these maps.
176
+ * @param {LayerCollection} layerCollection
177
+ */
178
+ set layerCollection(layerCollection) {
179
+ check(layerCollection, LayerCollection);
180
+
181
+ this._layerCollection = layerCollection;
182
+ this._array.forEach((map) => {
183
+ map.layerCollection = this._layerCollection;
184
+ });
185
+ }
186
+
187
+ /**
188
+ * The current split screen
189
+ * @type {SplitScreen}
190
+ */
191
+ get splitScreen() {
192
+ return this._splitScreen;
193
+ }
194
+
195
+ /**
196
+ * Set split screen for these maps.
197
+ * @param {SplitScreen} splitScreen
198
+ */
199
+ set splitScreen(splitScreen) {
200
+ check(splitScreen, SplitScreen);
201
+
202
+ this._splitScreen = splitScreen;
203
+ this._array.forEach((map) => {
204
+ map.splitScreen = this._splitScreen;
205
+ });
206
+ }
207
+
160
208
  /**
161
209
  * Adds a map to the collection. This will set the collections target, {@link SplitScreen}
162
210
  * and the collections {@link LayerCollection} on the map.
@@ -169,28 +217,33 @@ class MapCollection extends Collection {
169
217
  if (added !== null) {
170
218
  this._mapPointerListeners
171
219
  .push(map.pointerInteractionEvent.addEventListener(this.eventHandler.handleMapEvent.bind(this.eventHandler)));
172
- map.layerCollection = this.layerCollection;
173
- map.splitScreen = this.splitScreen;
220
+ map.layerCollection = this._layerCollection;
221
+ map.splitScreen = this._splitScreen;
174
222
  map.setTarget(this._target);
175
223
  }
176
224
  return added;
177
225
  }
178
226
 
179
227
  /**
180
- * Removes the map from the collection. Will also set splitScreen & target to null and an empty layerCollection on the map,
181
- * if the map is currently part of the collection.
182
228
  * @param {import("@vcmap/core").VcsMap} map
229
+ * @returns {number}
230
+ * @protected
183
231
  */
184
- remove(map) {
232
+ _remove(map) {
233
+ if (this._activeMap === map) {
234
+ this._cachedViewpoint = map.getViewPointSync();
235
+ if (this._target) {
236
+ const mapClassName = this._activeMap.className.split('.').pop();
237
+ this._target.classList.remove(mapClassName);
238
+ }
239
+ this._activeMap = null;
240
+ }
185
241
  if (this.has(map)) {
186
242
  map.setTarget(null);
187
243
  map.splitScreen = null;
188
244
  map.layerCollection = new LayerCollection();
189
245
  }
190
- super.remove(map);
191
- if (this._activeMap === map) {
192
- this._activeMap = null;
193
- }
246
+ return super._remove(map);
194
247
  }
195
248
 
196
249
  /**
@@ -245,7 +298,7 @@ class MapCollection extends Collection {
245
298
  _getFallbackMapOrDefault(map) {
246
299
  const fallbackMap = this._getFallbackMap(map);
247
300
  return fallbackMap ||
248
- this.getByType('vcs.vcm.maps.Openlayers')[0] ||
301
+ this.getByType('OpenlayersMap')[0] ||
249
302
  this._array[0];
250
303
  }
251
304
 
@@ -259,25 +312,25 @@ class MapCollection extends Collection {
259
312
  async setActiveMap(mapName) {
260
313
  const map = this.getByKey(mapName);
261
314
  if (!map) {
262
- getLogger('vcs.vcm.util.MapCollection').warning(`could not find map with name ${mapName}`);
315
+ getLogger('MapCollection').warning(`could not find map with name ${mapName}`);
263
316
  return Promise.resolve();
264
317
  }
265
318
 
266
319
  if (
267
320
  this._activeMap &&
268
- this._activeMap.className === 'vcs.vcm.maps.Cesium' &&
269
- map.className === 'vcs.vcm.maps.Openlayers'
321
+ this._activeMap.className === 'CesiumMap' &&
322
+ map.className === 'OpenlayersMap'
270
323
  ) {
271
324
  await setCesiumToOLViewpoint(
272
325
  /** @type {import("@vcmap/core").CesiumMap} */ (this._activeMap),
273
- /** @type {import("@vcmap/core").Openlayers} */ (map),
326
+ /** @type {import("@vcmap/core").OpenlayersMap} */ (map),
274
327
  );
275
328
  }
276
329
 
277
330
  try {
278
331
  await map.initialize();
279
332
  } catch (error) { // typically unsupported webGL and cesium map
280
- getLogger('vcs.vcm.util.MapCollection').error(error);
333
+ getLogger('MapCollection').error(error);
281
334
  this.remove(map);
282
335
  const fallbackMap = this._getFallbackMapOrDefault(map);
283
336
  this.initializeError.raiseEvent({
@@ -292,12 +345,13 @@ class MapCollection extends Collection {
292
345
  }
293
346
 
294
347
  let viewpoint;
295
- if (this._activeMap) {
348
+ if (this._activeMap || this._cachedViewpoint) {
296
349
  if (this._activeMap === map) {
297
350
  return map.activate();
298
351
  }
299
352
 
300
- viewpoint = await this._activeMap.getViewPoint();
353
+ viewpoint = this._activeMap ? await this._activeMap.getViewPoint() : this._cachedViewpoint;
354
+
301
355
  const canShow = await map.canShowViewpoint(viewpoint);
302
356
  if (!canShow) {
303
357
  const fallbackMap = this._getFallbackMap(map);
@@ -306,10 +360,13 @@ class MapCollection extends Collection {
306
360
  return this.setActiveMap(fallbackMap.name);
307
361
  }
308
362
  }
309
- this._activeMap.deactivate();
310
- if (this._target) {
311
- const mapClassName = this._activeMap.className.split('.').pop();
312
- this._target.classList.remove(mapClassName);
363
+ this._cachedViewpoint = null;
364
+ if (this._activeMap) {
365
+ this._activeMap.deactivate();
366
+ if (this._target) {
367
+ const mapClassName = this._activeMap.className.split('.').pop();
368
+ this._target.classList.remove(mapClassName);
369
+ }
313
370
  }
314
371
  }
315
372
 
@@ -322,7 +379,7 @@ class MapCollection extends Collection {
322
379
  }
323
380
 
324
381
  this.clippingObjectManager.mapActivated(map);
325
- this.splitScreen.mapActivated(map);
382
+ this._splitScreen.mapActivated(map);
326
383
  this.mapActivated.raiseEvent(map);
327
384
  return Promise.resolve();
328
385
  }
@@ -342,14 +399,14 @@ class MapCollection extends Collection {
342
399
  */
343
400
  destroy() {
344
401
  super.destroy();
345
- [...this.layerCollection].forEach((l) => { l.destroy(); });
346
- this.layerCollection.destroy();
402
+ [...this._layerCollection].forEach((l) => { l.destroy(); });
403
+ this._layerCollection.destroy();
347
404
  this.eventHandler.destroy();
348
405
  this.mapActivated.destroy();
349
406
  this.clippingObjectManager.destroy();
350
407
  this.clippingObjectManager = null;
351
- this.splitScreen.destroy();
352
- this.splitScreen = null;
408
+ this._splitScreen.destroy();
409
+ this._splitScreen = null;
353
410
  this.fallbackMapActivated.destroy();
354
411
  this.initializeError.destroy();
355
412
 
File without changes
@@ -0,0 +1,223 @@
1
+ /* eslint no-underscore-dangle: ["error", { "allow": ["_array"] }] */
2
+ // eslint-disable-next-line max-classes-per-file
3
+ import { check } from '@vcsuite/check';
4
+ import { getLogger as getLoggerByName } from '@vcsuite/logger';
5
+ import { contextIdSymbol } from '../vcsAppContextHelpers.js';
6
+ import Collection from './collection.js';
7
+ import VcsEvent from '../vcsEvent.js';
8
+
9
+ /**
10
+ * @returns {import("@vcsuite/logger").Logger}
11
+ */
12
+ function getLogger() {
13
+ return getLoggerByName('OverrideCollection');
14
+ }
15
+
16
+ /**
17
+ * The override collection adds the ability to override a unique item and re-creating it, should the override
18
+ * be removed. This does change some flow of called events. 1) if you override an item, removed is not called for the
19
+ * removed current item. 2) added can be called more the once for the same unique id. 3) replaced is called for items
20
+ * which where replaced. replaced is called after added has been called for the item.
21
+ * @interface OverrideCollectionInterface
22
+ * @property {import("@vcmap/core").VcsEvent<T>} replaced - replaced is called after added
23
+ * @property {function(T):T|null} override - returns the overriden item or null if the item could not be inserted (this would be the result of a race condition)
24
+ * @property {Map<string, Array<Object>>} shadowMap
25
+ * @property {function(Array<Object>, string):Promise<void>} parseItems
26
+ * @property {function(string):Promise<void>} removeContext
27
+ * @property {function(string):Array<Object>} serializeContext
28
+ * @template {*} T
29
+ */
30
+
31
+ /**
32
+ * A symbol added to override collections.
33
+ * @type {symbol}
34
+ */
35
+ export const isOverrideCollection = Symbol('OverrideCollection');
36
+
37
+ /**
38
+ * @param {Collection<T>} collection
39
+ * @param {function():string} getDynamicContextId - function to get the current dynamic context id
40
+ * @param {(function(T):Object)=} serializeItem - optional function to serialize an item, defaults to returning item.toJSON or item: i => (i.toJSON || i)
41
+ * @param {(function(Object):(T|Promise<T>))=} deserializeItem - optional deserialization function. defaults to returning the passed object: i => i
42
+ * @param {*=} ctor - optional constructor to validate deserialized items against. if passed, deserializeItem must be an instance of ctor.
43
+ * @param {(function(T, (T|null|undefined), (number|undefined)):number|null)=} determineShadowIndex - return the index where a shadow should be inserted. only has relevance, if the collection is indexed. previous and current index may be null.
44
+ * @template {*} T
45
+ * @returns {OverrideCollection<T>}
46
+ */
47
+ function makeOverrideCollection(
48
+ collection,
49
+ getDynamicContextId,
50
+ serializeItem,
51
+ deserializeItem,
52
+ ctor,
53
+ determineShadowIndex,
54
+ ) {
55
+ check(collection, Collection);
56
+
57
+ const overrideCollection = /** @type {OverrideCollection<T>} */ (collection);
58
+ if (overrideCollection[isOverrideCollection]) {
59
+ throw new Error('Cannot transform collection, collection already is an OverrideCollection');
60
+ }
61
+ overrideCollection[isOverrideCollection] = true;
62
+
63
+ const deserialize = deserializeItem || (i => i);
64
+ // @ts-ignore
65
+ const serialize = serializeItem || (i => (i.toJSON ? i.toJSON() : i));
66
+ const getShadowIndex = determineShadowIndex || ((item, shadow, currentIndex) => currentIndex);
67
+
68
+ /**
69
+ * @type {Map<string, Array<Object>>}
70
+ */
71
+ overrideCollection.shadowMap = new Map();
72
+
73
+ /**
74
+ * @param {T} item
75
+ * @returns {T|null}
76
+ */
77
+ overrideCollection.override = function override(item) {
78
+ let shadow;
79
+ let index;
80
+ const itemId = item[overrideCollection.uniqueKey];
81
+
82
+ if (overrideCollection.hasKey(itemId)) {
83
+ shadow = overrideCollection.getByKey(itemId);
84
+
85
+ // @ts-ignore
86
+ // eslint-disable-next-line no-underscore-dangle
87
+ index = overrideCollection._remove(shadow);
88
+
89
+ if (!overrideCollection.shadowMap.has(itemId)) {
90
+ overrideCollection.shadowMap.set(itemId, []);
91
+ }
92
+ const shadowsArray = overrideCollection.shadowMap.get(itemId);
93
+ const serializedShadow = serialize(shadow);
94
+ // @ts-ignore
95
+ if (shadow.destroy) {
96
+ // @ts-ignore
97
+ shadow.destroy();
98
+ }
99
+ serializedShadow[contextIdSymbol] = shadow[contextIdSymbol];
100
+ shadowsArray.push(serializedShadow);
101
+ }
102
+
103
+ const usedIndex = shadow ? getShadowIndex(shadow, item, index) : null;
104
+ if (shadow) {
105
+ overrideCollection.replaced.raiseEvent(item);
106
+ }
107
+ // @ts-ignore
108
+ if (overrideCollection.add(item, usedIndex) >= 0) {
109
+ return item;
110
+ }
111
+ return null;
112
+ };
113
+
114
+ /**
115
+ * @param {Array<Object>} configArray
116
+ * @param {string} contextId
117
+ * @returns {Promise<void>}
118
+ */
119
+ overrideCollection.parseItems = async function parseItems(configArray, contextId) {
120
+ if (Array.isArray(configArray)) {
121
+ const instanceArray = await Promise.all(configArray.map(async (config) => {
122
+ const item = await deserialize(config);
123
+ if (!item || (ctor && !(item instanceof ctor))) {
124
+ getLogger().warning(`Could not load item ${config[overrideCollection.uniqueKey]} of type ${config.type}`);
125
+ return null;
126
+ }
127
+ item[contextIdSymbol] = contextId;
128
+ return item;
129
+ }));
130
+ instanceArray
131
+ .filter(i => i)
132
+ .forEach((i) => { overrideCollection.override(i); });
133
+ }
134
+ };
135
+
136
+ overrideCollection.removed.addEventListener(async (item) => {
137
+ const itemId = item[overrideCollection.uniqueKey];
138
+
139
+ if (overrideCollection.shadowMap.has(itemId)) {
140
+ const serializedShadow = overrideCollection.shadowMap.get(itemId).pop();
141
+ if (serializedShadow) {
142
+ const reincarnation = await deserialize(serializedShadow);
143
+ reincarnation[contextIdSymbol] = serializedShadow[contextIdSymbol];
144
+ // @ts-ignore
145
+ const index = getShadowIndex(reincarnation, item, item[overrideCollection.previousIndexSymbol]);
146
+ // @ts-ignore
147
+ overrideCollection.add(reincarnation, index);
148
+ }
149
+
150
+ if (overrideCollection.shadowMap.get(itemId).length === 0) {
151
+ overrideCollection.shadowMap.delete(itemId);
152
+ }
153
+ }
154
+ });
155
+
156
+ overrideCollection.added.addEventListener((item) => {
157
+ if (!item[contextIdSymbol]) {
158
+ item[contextIdSymbol] = getDynamicContextId();
159
+ }
160
+ });
161
+
162
+ /**
163
+ * @param {string} contextId
164
+ * @returns {Promise<void>}
165
+ */
166
+ overrideCollection.removeContext = async function removeContext(contextId) {
167
+ overrideCollection.shadowMap.forEach((shadowsArray, name) => {
168
+ const newShadowsArray = shadowsArray.filter(c => c[contextIdSymbol] !== contextId);
169
+ if (newShadowsArray.length === 0) {
170
+ overrideCollection.shadowMap.delete(name);
171
+ } else if (newShadowsArray.length !== shadowsArray.length) {
172
+ overrideCollection.shadowMap.set(name, newShadowsArray);
173
+ }
174
+ });
175
+
176
+ await Promise.all([...overrideCollection]
177
+ .filter(item => item[contextIdSymbol] === contextId)
178
+ .map(async (item) => {
179
+ overrideCollection.remove(item);
180
+ // @ts-ignore
181
+ if (item.destroy) {
182
+ // @ts-ignore
183
+ item.destroy();
184
+ }
185
+ }));
186
+ };
187
+
188
+ /**
189
+ * @type {VcsEvent<T>}
190
+ */
191
+ overrideCollection.replaced = new VcsEvent();
192
+
193
+ /**
194
+ * @param {string} contextId
195
+ * @returns {Array<Object>}
196
+ */
197
+ overrideCollection.serializeContext = function serializeContext(contextId) {
198
+ return [...overrideCollection]
199
+ .map((item) => {
200
+ if (item[contextIdSymbol] === contextId) {
201
+ return serialize(item);
202
+ }
203
+ if (overrideCollection.shadowMap.has(item[overrideCollection.uniqueKey])) {
204
+ return overrideCollection.shadowMap.get(item[overrideCollection.uniqueKey])
205
+ .find(i => i[contextIdSymbol] === contextId);
206
+ }
207
+ return null;
208
+ })
209
+ .filter(i => i);
210
+ };
211
+
212
+ const originalDestroy = overrideCollection.destroy.bind(overrideCollection);
213
+
214
+ overrideCollection.destroy = function destroy() {
215
+ originalDestroy();
216
+ overrideCollection.shadowMap.clear();
217
+ overrideCollection.replaced.destroy();
218
+ };
219
+
220
+ return overrideCollection;
221
+ }
222
+
223
+ export default makeOverrideCollection;
@@ -1,27 +1,23 @@
1
1
  import { getTransform, get as getProjection, equivalent } from 'ol/proj.js';
2
2
  import { register } from 'ol/proj/proj4.js';
3
3
  import proj4 from 'proj4';
4
- import { getLogger as getLoggerByName } from '@vcsuite/logger';
5
4
  import { check } from '@vcsuite/check';
6
5
 
7
6
  /**
8
7
  * @typedef {Object} ProjectionOptions
8
+ * @property {string} [type]
9
9
  * @property {string|number} [epsg] - EPSG of the projection, for example: "EPSG:4326" if not specified, uses the framework projection
10
10
  * @property {string|undefined|null} [proj4] - definition of the projection. See for example: {@link http://spatialreference.org/ref/epsg/4326/proj4/} proj4
11
11
  * @property {Array<string>|undefined|null} [alias] - aliases to define
12
+ * @property {string|undefined} [prefix='EPSG:'] - an alternate prefix to use for custom projection
12
13
  * @api stable
13
14
  */
14
-
15
- export const wgs84ToMercatorTransformer = getTransform('EPSG:4326', 'EPSG:3857');
16
- export const mercatorToWgs84Transformer = getTransform('EPSG:3857', 'EPSG:4326');
17
-
18
-
19
15
  /**
20
- * @returns {import("@vcsuite/logger").Logger}
16
+ * @typedef {function(Array<number>, Array<number>=, number=): Array<number>} CorrectTransformFunction
21
17
  */
22
- function getLogger() {
23
- return getLoggerByName('vcs.vcm.util.Projection');
24
- }
18
+
19
+ export const wgs84ToMercatorTransformer = /** @type {CorrectTransformFunction} */ (getTransform('EPSG:4326', 'EPSG:3857'));
20
+ export const mercatorToWgs84Transformer = /** @type {CorrectTransformFunction} */ (getTransform('EPSG:3857', 'EPSG:4326'));
25
21
 
26
22
  /**
27
23
  * @type {ProjectionOptions}
@@ -36,7 +32,8 @@ let defaultProjectionOption = {
36
32
  * @returns {string}
37
33
  */
38
34
  function parseEPSGCode(value, prefix = 'EPSG:') {
39
- const matches = `${value}`.match(/^(?:epsg:)?(\d+)/i);
35
+ const regex = new RegExp(`^(?:${prefix})?(\\d+)`, 'i');
36
+ const matches = `${value}`.match(regex);
40
37
  if (matches && matches[1]) {
41
38
  return `${prefix}${matches[1]}`;
42
39
  }
@@ -73,9 +70,11 @@ function validateProjectionOptions(options) {
73
70
  * @returns {ProjectionOptions} valid options
74
71
  */
75
72
  function registerProjection(options) {
76
- const saneOptions = {};
73
+ const saneOptions = {
74
+ prefix: options.prefix,
75
+ };
77
76
  if (options.epsg) {
78
- saneOptions.epsg = parseEPSGCode(options.epsg);
77
+ saneOptions.epsg = parseEPSGCode(options.epsg, options.prefix);
79
78
  if (saneOptions.epsg) {
80
79
  if (options.proj4) {
81
80
  saneOptions.proj4 = options.proj4;
@@ -99,7 +98,6 @@ function registerProjection(options) {
99
98
  * projection created prior to this functions call.
100
99
  * @param {ProjectionOptions} options
101
100
  * @api
102
- * @export
103
101
  */
104
102
  export function setDefaultProjectionOptions(options) {
105
103
  check(options, { epsg: [String, Number], proj4: [String, undefined, null] });
@@ -112,7 +110,6 @@ export function setDefaultProjectionOptions(options) {
112
110
  /**
113
111
  * Projection Class, if no valid options are given, the Projection will initialize with the Framework default Projection
114
112
  * @class
115
- * @export
116
113
  * For example:
117
114
  * <pre><code>
118
115
  * {
@@ -123,6 +120,11 @@ export function setDefaultProjectionOptions(options) {
123
120
  * @api stable
124
121
  */
125
122
  class Projection {
123
+ /**
124
+ * @returns {string}
125
+ */
126
+ static get className() { return 'Projection'; }
127
+
126
128
  /**
127
129
  * @param {ProjectionOptions} options
128
130
  */
@@ -143,6 +145,20 @@ class Projection {
143
145
  if (!this.proj) {
144
146
  this._epsg = Projection.parseEPSGCode(defaultProjectionOption.epsg);
145
147
  }
148
+
149
+ /**
150
+ * Cached for toJSON
151
+ * @type {Array<string>}
152
+ * @private
153
+ */
154
+ this._alias = saneOptions.alias;
155
+
156
+ /**
157
+ * Cached for toJSON
158
+ * @type {string}
159
+ * @private
160
+ */
161
+ this._prefix = saneOptions.prefix;
146
162
  }
147
163
 
148
164
  /**
@@ -174,16 +190,6 @@ class Projection {
174
190
  return getProjection(this.epsg);
175
191
  }
176
192
 
177
- /**
178
- * @returns {import("ol/proj/Projection").default}
179
- * @api
180
- * @deprecated 3.7
181
- */
182
- getProjection() {
183
- getLogger().deprecate('getProjection', 'Access the property proj directly');
184
- return this.proj;
185
- }
186
-
187
193
  /**
188
194
  * @param {Projection} projection
189
195
  * @returns {boolean}
@@ -262,13 +268,20 @@ class Projection {
262
268
  * @returns {ProjectionOptions}
263
269
  * @api stable
264
270
  */
265
- getConfigObject() {
271
+ toJSON() {
266
272
  const configObject = {
273
+ type: Projection.className,
267
274
  epsg: this.epsg,
268
275
  };
269
276
  if (this.proj4) {
270
277
  configObject.proj4 = this.proj4;
271
278
  }
279
+ if (Array.isArray(this._alias) && this._alias.length > 0) {
280
+ configObject.alias = this._alias.slice();
281
+ }
282
+ if (this._prefix) {
283
+ configObject.prefix = this._prefix;
284
+ }
272
285
  return configObject;
273
286
  }
274
287
 
@@ -326,7 +339,6 @@ export default Projection;
326
339
  * Returns the default Projection.
327
340
  * @api stable
328
341
  * @returns {Projection}
329
- * @export
330
342
  */
331
343
  export function getDefaultProjection() {
332
344
  return new Projection(defaultProjectionOption);
@@ -336,13 +348,11 @@ export function getDefaultProjection() {
336
348
  * wgs84 Projection EPSG Code: 4326
337
349
  * @api stable
338
350
  * @type {Projection}
339
- * @export
340
351
  */
341
352
  export const wgs84Projection = new Projection({ epsg: 4326 });
342
353
  /**
343
354
  * mercator Projection EPSG Code: 3857
344
355
  * @api stable
345
356
  * @type {Projection}
346
- * @export
347
357
  */
348
358
  export const mercatorProjection = new Projection({ epsg: 3857 });
@@ -4,13 +4,13 @@ import {
4
4
  Plane,
5
5
  ClippingPlane,
6
6
  ClippingPlaneCollection,
7
- ImagerySplitDirection,
7
+ SplitDirection,
8
8
  } from '@vcmap/cesium';
9
9
 
10
10
  import { check } from '@vcsuite/check';
11
- import CesiumMap from '../maps/cesium.js';
11
+ import CesiumMap from '../map/cesiumMap.js';
12
12
  import ClippingObject from './clipping/clippingObject.js';
13
- import Openlayers from '../maps/openlayers.js';
13
+ import OpenlayersMap from '../map/openlayersMap.js';
14
14
 
15
15
  /**
16
16
  * @class
@@ -136,7 +136,7 @@ class SplitScreen {
136
136
  this.scene = map.getScene();
137
137
  this.olMap = null;
138
138
  this._targetsChanged();
139
- } else if (map instanceof Openlayers) {
139
+ } else if (map instanceof OpenlayersMap) {
140
140
  this.scene = null;
141
141
  this.olMap = map.olMap;
142
142
  }
@@ -194,21 +194,21 @@ class SplitScreen {
194
194
 
195
195
  /**
196
196
  * Gets the clipping object for a split direction
197
- * @param {import("@vcmap/cesium").ImagerySplitDirection} splitDirection
197
+ * @param {import("@vcmap/cesium").SplitDirection} splitDirection
198
198
  * @returns {ClippingObject|null}
199
199
  * @api
200
200
  */
201
201
  getClippingObjectForDirection(splitDirection) {
202
202
  check(splitDirection, [
203
- ImagerySplitDirection.LEFT,
204
- ImagerySplitDirection.RIGHT,
205
- ImagerySplitDirection.NONE,
203
+ SplitDirection.LEFT,
204
+ SplitDirection.RIGHT,
205
+ SplitDirection.NONE,
206
206
  ]);
207
207
 
208
- if (splitDirection === ImagerySplitDirection.LEFT) {
208
+ if (splitDirection === SplitDirection.LEFT) {
209
209
  return this.leftScreenClippingObject;
210
210
  }
211
- if (splitDirection === ImagerySplitDirection.RIGHT) {
211
+ if (splitDirection === SplitDirection.RIGHT) {
212
212
  return this.rightScreenClippingObject;
213
213
  }
214
214