@vcmap/core 5.0.0-rc.0

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/LICENSE.md +21 -0
  2. package/README.md +44 -0
  3. package/build/postinstall.js +44 -0
  4. package/index.js +139 -0
  5. package/package.json +92 -0
  6. package/src/cesium/cesium3DTileFeature.js +9 -0
  7. package/src/cesium/cesium3DTilePointFeature.js +9 -0
  8. package/src/cesium/cesiumVcsCameraPrimitive.js +146 -0
  9. package/src/cesium/wallpaperMaterial.js +64 -0
  10. package/src/ol/feature.js +47 -0
  11. package/src/ol/geom/circle.js +24 -0
  12. package/src/ol/geom/geometryCollection.js +33 -0
  13. package/src/ol/render/canvas/canvasTileRenderer.js +179 -0
  14. package/src/ol/source/ClusterEnhancedVectorSource.js +39 -0
  15. package/src/ol/source/VcsCluster.js +37 -0
  16. package/src/vcs/vcm/classRegistry.js +106 -0
  17. package/src/vcs/vcm/event/vcsEvent.js +89 -0
  18. package/src/vcs/vcm/globalCollections.js +11 -0
  19. package/src/vcs/vcm/interaction/abstractInteraction.js +149 -0
  20. package/src/vcs/vcm/interaction/coordinateAtPixel.js +102 -0
  21. package/src/vcs/vcm/interaction/eventHandler.js +425 -0
  22. package/src/vcs/vcm/interaction/featureAtPixelInteraction.js +286 -0
  23. package/src/vcs/vcm/interaction/featureProviderInteraction.js +54 -0
  24. package/src/vcs/vcm/interaction/interactionChain.js +124 -0
  25. package/src/vcs/vcm/interaction/interactionType.js +114 -0
  26. package/src/vcs/vcm/layer/buildings.js +17 -0
  27. package/src/vcs/vcm/layer/cesium/cesiumTilesetCesium.js +359 -0
  28. package/src/vcs/vcm/layer/cesium/clusterContext.js +95 -0
  29. package/src/vcs/vcm/layer/cesium/dataSourceCesium.js +171 -0
  30. package/src/vcs/vcm/layer/cesium/openStreetMapCesium.js +29 -0
  31. package/src/vcs/vcm/layer/cesium/pointCloudCesium.js +58 -0
  32. package/src/vcs/vcm/layer/cesium/rasterLayerCesium.js +110 -0
  33. package/src/vcs/vcm/layer/cesium/singleImageCesium.js +49 -0
  34. package/src/vcs/vcm/layer/cesium/terrainCesium.js +80 -0
  35. package/src/vcs/vcm/layer/cesium/tmsCesium.js +54 -0
  36. package/src/vcs/vcm/layer/cesium/vectorCesium.js +255 -0
  37. package/src/vcs/vcm/layer/cesium/vectorContext.js +167 -0
  38. package/src/vcs/vcm/layer/cesium/vectorRasterTileCesium.js +116 -0
  39. package/src/vcs/vcm/layer/cesium/vectorTileImageryProvider.js +246 -0
  40. package/src/vcs/vcm/layer/cesium/wmsCesium.js +71 -0
  41. package/src/vcs/vcm/layer/cesium/wmtsCesium.js +101 -0
  42. package/src/vcs/vcm/layer/cesium/x3dmHelper.js +22 -0
  43. package/src/vcs/vcm/layer/cesiumTileset.js +376 -0
  44. package/src/vcs/vcm/layer/czml.js +141 -0
  45. package/src/vcs/vcm/layer/dataSource.js +259 -0
  46. package/src/vcs/vcm/layer/featureLayer.js +261 -0
  47. package/src/vcs/vcm/layer/featureStore.js +647 -0
  48. package/src/vcs/vcm/layer/featureStoreChanges.js +360 -0
  49. package/src/vcs/vcm/layer/featureStoreState.js +19 -0
  50. package/src/vcs/vcm/layer/featureVisibility.js +435 -0
  51. package/src/vcs/vcm/layer/geojson.js +185 -0
  52. package/src/vcs/vcm/layer/geojsonHelpers.js +450 -0
  53. package/src/vcs/vcm/layer/globalHider.js +157 -0
  54. package/src/vcs/vcm/layer/layer.js +752 -0
  55. package/src/vcs/vcm/layer/layerImplementation.js +102 -0
  56. package/src/vcs/vcm/layer/layerState.js +17 -0
  57. package/src/vcs/vcm/layer/layerSymbols.js +6 -0
  58. package/src/vcs/vcm/layer/oblique/layerOblique.js +76 -0
  59. package/src/vcs/vcm/layer/oblique/obliqueHelpers.js +175 -0
  60. package/src/vcs/vcm/layer/oblique/vectorOblique.js +469 -0
  61. package/src/vcs/vcm/layer/openStreetMap.js +194 -0
  62. package/src/vcs/vcm/layer/openlayers/layerOpenlayers.js +79 -0
  63. package/src/vcs/vcm/layer/openlayers/openStreetMapOpenlayers.js +27 -0
  64. package/src/vcs/vcm/layer/openlayers/rasterLayerOpenlayers.js +121 -0
  65. package/src/vcs/vcm/layer/openlayers/singleImageOpenlayers.js +49 -0
  66. package/src/vcs/vcm/layer/openlayers/tileDebugOpenlayers.js +39 -0
  67. package/src/vcs/vcm/layer/openlayers/tmsOpenlayers.js +62 -0
  68. package/src/vcs/vcm/layer/openlayers/vectorOpenlayers.js +118 -0
  69. package/src/vcs/vcm/layer/openlayers/vectorTileOpenlayers.js +177 -0
  70. package/src/vcs/vcm/layer/openlayers/wmsOpenlayers.js +55 -0
  71. package/src/vcs/vcm/layer/openlayers/wmtsOpenlayers.js +141 -0
  72. package/src/vcs/vcm/layer/pointCloud.js +162 -0
  73. package/src/vcs/vcm/layer/rasterLayer.js +294 -0
  74. package/src/vcs/vcm/layer/singleImage.js +119 -0
  75. package/src/vcs/vcm/layer/terrain.js +122 -0
  76. package/src/vcs/vcm/layer/terrainHelpers.js +123 -0
  77. package/src/vcs/vcm/layer/tileLoadedHelper.js +72 -0
  78. package/src/vcs/vcm/layer/tileProvider/mvtTileProvider.js +104 -0
  79. package/src/vcs/vcm/layer/tileProvider/staticGeojsonTileProvider.js +67 -0
  80. package/src/vcs/vcm/layer/tileProvider/tileProvider.js +584 -0
  81. package/src/vcs/vcm/layer/tileProvider/tileProviderFactory.js +28 -0
  82. package/src/vcs/vcm/layer/tileProvider/urlTemplateTileProvider.js +106 -0
  83. package/src/vcs/vcm/layer/tms.js +121 -0
  84. package/src/vcs/vcm/layer/vector.js +632 -0
  85. package/src/vcs/vcm/layer/vectorHelpers.js +206 -0
  86. package/src/vcs/vcm/layer/vectorProperties.js +1391 -0
  87. package/src/vcs/vcm/layer/vectorSymbols.js +40 -0
  88. package/src/vcs/vcm/layer/vectorTile.js +480 -0
  89. package/src/vcs/vcm/layer/wfs.js +165 -0
  90. package/src/vcs/vcm/layer/wms.js +270 -0
  91. package/src/vcs/vcm/layer/wmsHelpers.js +65 -0
  92. package/src/vcs/vcm/layer/wmts.js +235 -0
  93. package/src/vcs/vcm/maps/baseOLMap.js +257 -0
  94. package/src/vcs/vcm/maps/cameraLimiter.js +219 -0
  95. package/src/vcs/vcm/maps/cesium.js +1192 -0
  96. package/src/vcs/vcm/maps/map.js +511 -0
  97. package/src/vcs/vcm/maps/mapState.js +17 -0
  98. package/src/vcs/vcm/maps/oblique.js +536 -0
  99. package/src/vcs/vcm/maps/openlayers.js +205 -0
  100. package/src/vcs/vcm/object.js +92 -0
  101. package/src/vcs/vcm/oblique/ObliqueCollection.js +572 -0
  102. package/src/vcs/vcm/oblique/ObliqueDataSet.js +357 -0
  103. package/src/vcs/vcm/oblique/ObliqueImage.js +247 -0
  104. package/src/vcs/vcm/oblique/ObliqueImageMeta.js +126 -0
  105. package/src/vcs/vcm/oblique/ObliqueProvider.js +433 -0
  106. package/src/vcs/vcm/oblique/ObliqueView.js +130 -0
  107. package/src/vcs/vcm/oblique/ObliqueViewDirection.js +40 -0
  108. package/src/vcs/vcm/oblique/helpers.js +483 -0
  109. package/src/vcs/vcm/oblique/parseImageJson.js +248 -0
  110. package/src/vcs/vcm/util/clipping/clippingObject.js +386 -0
  111. package/src/vcs/vcm/util/clipping/clippingObjectManager.js +312 -0
  112. package/src/vcs/vcm/util/clipping/clippingPlaneHelper.js +413 -0
  113. package/src/vcs/vcm/util/collection.js +193 -0
  114. package/src/vcs/vcm/util/dateTime.js +60 -0
  115. package/src/vcs/vcm/util/exclusiveManager.js +135 -0
  116. package/src/vcs/vcm/util/extent.js +124 -0
  117. package/src/vcs/vcm/util/featureProvider/abstractFeatureProvider.js +196 -0
  118. package/src/vcs/vcm/util/featureProvider/featureProviderHelpers.js +51 -0
  119. package/src/vcs/vcm/util/featureProvider/featureProviderSymbols.js +11 -0
  120. package/src/vcs/vcm/util/featureProvider/tileProviderFeatureProvider.js +62 -0
  121. package/src/vcs/vcm/util/featureProvider/wmsFeatureProvider.js +280 -0
  122. package/src/vcs/vcm/util/featureconverter/circleToCesium.js +215 -0
  123. package/src/vcs/vcm/util/featureconverter/convert.js +83 -0
  124. package/src/vcs/vcm/util/featureconverter/extent3d.js +154 -0
  125. package/src/vcs/vcm/util/featureconverter/featureconverterHelper.js +591 -0
  126. package/src/vcs/vcm/util/featureconverter/lineStringToCesium.js +171 -0
  127. package/src/vcs/vcm/util/featureconverter/pointToCesium.js +359 -0
  128. package/src/vcs/vcm/util/featureconverter/polygonToCesium.js +229 -0
  129. package/src/vcs/vcm/util/geometryHelpers.js +172 -0
  130. package/src/vcs/vcm/util/indexedCollection.js +158 -0
  131. package/src/vcs/vcm/util/isMobile.js +12 -0
  132. package/src/vcs/vcm/util/layerCollection.js +216 -0
  133. package/src/vcs/vcm/util/locale.js +53 -0
  134. package/src/vcs/vcm/util/mapCollection.js +363 -0
  135. package/src/vcs/vcm/util/math.js +71 -0
  136. package/src/vcs/vcm/util/projection.js +348 -0
  137. package/src/vcs/vcm/util/splitScreen.js +233 -0
  138. package/src/vcs/vcm/util/style/declarativeStyleItem.js +631 -0
  139. package/src/vcs/vcm/util/style/shapesCategory.js +67 -0
  140. package/src/vcs/vcm/util/style/styleFactory.js +48 -0
  141. package/src/vcs/vcm/util/style/styleHelpers.js +555 -0
  142. package/src/vcs/vcm/util/style/styleItem.js +226 -0
  143. package/src/vcs/vcm/util/style/vectorStyleItem.js +927 -0
  144. package/src/vcs/vcm/util/style/writeStyle.js +48 -0
  145. package/src/vcs/vcm/util/urlHelpers.js +16 -0
  146. package/src/vcs/vcm/util/viewpoint.js +333 -0
@@ -0,0 +1,632 @@
1
+ import VectorSource from 'ol/source/Vector.js';
2
+ import Style from 'ol/style/Style.js';
3
+ import Feature from 'ol/Feature.js';
4
+ import { v4 as uuidv4 } from 'uuid';
5
+ import { check } from '@vcsuite/check';
6
+ import { parseBoolean } from '@vcsuite/parsers';
7
+ import Projection, { getDefaultProjection, mercatorProjection } from '../util/projection.js';
8
+ import Layer, { vcsMetaVersion } from './layer.js';
9
+ import VectorStyleItem, { defaultVectorStyle, vectorStyleSymbol } from '../util/style/vectorStyleItem.js';
10
+ import DeclarativeStyleItem from '../util/style/declarativeStyleItem.js';
11
+ import writeStyle from '../util/style/writeStyle.js';
12
+ import {
13
+ alreadyTransformedToImage,
14
+ alreadyTransformedToMercator,
15
+ doNotTransform,
16
+ obliqueGeometry,
17
+ originalFeatureSymbol,
18
+ } from './vectorSymbols.js';
19
+ import Extent from '../util/extent.js';
20
+ import VectorProperties from './vectorProperties.js';
21
+ import FeatureLayer from './featureLayer.js';
22
+ import Openlayers from '../maps/openlayers.js';
23
+ import VectorOpenlayers from './openlayers/vectorOpenlayers.js';
24
+ import VectorCesium from './cesium/vectorCesium.js';
25
+ import VectorOblique from './oblique/vectorOblique.js';
26
+ import Oblique from '../maps/oblique.js';
27
+ import CesiumMap from '../maps/cesium.js';
28
+ import { originalStyle, updateOriginalStyle } from './featureVisibility.js';
29
+ import StyleItem, { referenceableStyleSymbol, StyleType } from '../util/style/styleItem.js';
30
+ import { getGenericFeatureFromClickedObject } from './vectorHelpers.js';
31
+ import { VcsClassRegistry } from '../classRegistry.js';
32
+
33
+ /**
34
+ * @typedef {FeatureLayerOptions} VectorOptions
35
+ * @property {ProjectionOptions|undefined} projection - if not specified, the framework projection is taken
36
+ * @property {number|undefined} maxResolution
37
+ * @property {number|undefined} minResolution
38
+ * @property {boolean} [dontUseTerrainForOblique=false]
39
+ * @property {number} [zIndex=10]
40
+ * @property {VectorStyleItemOptions|import("@vcmap/core").VectorStyleItem|undefined} highlightStyle
41
+ * @property {boolean} [isDynamic=false] - if true, the cesium synchronizers are destroyed on map change
42
+ * @property {VectorPropertiesOptions|undefined} vectorProperties
43
+ * @api
44
+ */
45
+
46
+ /**
47
+ * @typedef {Object} VectorGeometryFactoryType
48
+ * @property {function(Array<import("ol/geom/SimpleGeometry").default>):Array<import("ol/coordinate").Coordinate>} getCoordinates
49
+ * @property {function(import("ol/geom/SimpleGeometry").default, number):Object} getGeometryOptions
50
+ * @property {function(Object, number, boolean, number=):Array<import("@vcmap/cesium").PolygonGeometry|import("@vcmap/cesium").CircleGeometry|import("@vcmap/cesium").WallGeometry>} createSolidGeometries
51
+ * @property {function(Object, number, boolean, number=):Array<import("@vcmap/cesium").CircleOutlineGeometry|import("@vcmap/cesium").WallOutlineGeometry|import("@vcmap/cesium").PolygonOutlineGeometry>} createOutlineGeometries
52
+ * @property {function(Object, number, boolean):Array<import("@vcmap/cesium").CircleGeometry|import("@vcmap/cesium").PolygonGeometry>} createFillGeometries
53
+ * @property {function(Object, import("ol/style/Style").default):Array<import("@vcmap/cesium").GroundPolylineGeometry>} createGroundLineGeometries
54
+ * @property {function(Object, import("ol/style/Style").default):Array<import("@vcmap/cesium").PolylineGeometry>} createLineGeometries
55
+ * @api
56
+ */
57
+
58
+ /**
59
+ * @typedef {Object} VectorHeightInfo
60
+ * @property {boolean} extruded - if the object is extruded
61
+ * @property {Array<number>} storeyHeightsAboveGround - storey heights above ground, list has the same length as storeysAboveGround
62
+ * @property {Array<number>} storeyHeightsBelowGround - storey heights below ground, list has the same length as storeysBelowGround
63
+ * @property {number} groundLevel - the level above or below mean sea level (minZ value or ground_level or 0)
64
+ * @property {number} skirt - a negative height to <i>push</i> the geometry visually into the ground
65
+ * @property {boolean} perPositionHeight
66
+ * @property {import("@vcmap/cesium").HeightReference} heightReference heightReference of the feature.
67
+ * @property {number} heightAboveGroundAdjustment
68
+ * @api
69
+ */
70
+
71
+ /**
72
+ * @typedef {FeatureLayerImplementationOptions} VectorImplementationOptions
73
+ * @property {import("ol/source").Vector<import("ol/geom/Geometry").default>} source
74
+ * @property {number} maxResolution
75
+ * @property {number} minResolution
76
+ * @property {VectorProperties} vectorProperties
77
+ */
78
+
79
+ /**
80
+ * @typedef {import("ol").Feature<import("ol/geom/Geometry").default>} VectorClickedObject
81
+ * @property {ClickPosition} clickedPosition
82
+ */
83
+
84
+ /**
85
+ * Vector Layer for Openlayers, Cesium and Oblique
86
+ * @class
87
+ * @export
88
+ * @extends {FeatureLayer}
89
+ * @api stable
90
+ */
91
+ class Vector extends FeatureLayer {
92
+ /**
93
+ * @readonly
94
+ * @returns {string}
95
+ */
96
+ static get className() { return 'vcs.vcm.layer.Vector'; }
97
+
98
+ /**
99
+ * @returns {symbol}
100
+ * @readonly
101
+ */
102
+ static get alreadyTransformedToMercator() { return alreadyTransformedToMercator; }
103
+
104
+ /**
105
+ * @returns {symbol}
106
+ * @readonly
107
+ */
108
+ static get alreadyTransformedToImage() { return alreadyTransformedToImage; }
109
+
110
+ /**
111
+ * @returns {symbol}
112
+ * @readonly
113
+ */
114
+ static get obliqueGeometry() { return obliqueGeometry; }
115
+
116
+ /**
117
+ * @returns {symbol}
118
+ * @readonly
119
+ */
120
+ static get doNotTransform() { return doNotTransform; }
121
+
122
+ /**
123
+ * @returns {symbol}
124
+ * @readonly
125
+ */
126
+ static get originalFeatureSymbol() { return originalFeatureSymbol; }
127
+
128
+ /**
129
+ * @returns {VectorOptions}
130
+ */
131
+ static getDefaultOptions() {
132
+ return {
133
+ ...Layer.getDefaultOptions(),
134
+ projection: undefined,
135
+ maxResolution: undefined,
136
+ minResolution: undefined,
137
+ dontUseTerrainForOblique: false,
138
+ zIndex: 50,
139
+ highlightStyle: undefined,
140
+ isDynamic: false,
141
+ vectorProperties: {}, // XXX or should we return VectorProperties default options?
142
+ };
143
+ }
144
+
145
+ /**
146
+ * @param {VectorOptions} options
147
+ */
148
+ constructor(options) {
149
+ super(options);
150
+
151
+ this._supportedMaps = [
152
+ CesiumMap.className,
153
+ Oblique.className,
154
+ Openlayers.className,
155
+ ];
156
+
157
+ const defaultOptions = Vector.getDefaultOptions();
158
+ /** @type {import("ol/source").Vector<import("ol/geom/Geometry").default>} */
159
+ this.source = new VectorSource({});
160
+
161
+ /** @type {Projection} */
162
+ this.projection = new Projection(options.projection);
163
+
164
+ /** @type {?number} */
165
+ this.maxResolution = options.maxResolution != null ? options.maxResolution : defaultOptions.maxResolution;
166
+
167
+ /** @type {?number} */
168
+ this.minResolution = options.minResolution != null ? options.minResolution : defaultOptions.minResolution;
169
+
170
+ /** @type {boolean} */
171
+ this.dontUseTerrainForOblique =
172
+ parseBoolean(options.dontUseTerrainForOblique, defaultOptions.dontUseTerrainForOblique);
173
+
174
+ /** @type {import("@vcmap/core").VectorStyleItem} */
175
+ this.highlightStyle = /** @type {undefined} */ (defaultOptions.highlightStyle);
176
+ if (options.highlightStyle) {
177
+ this.highlightStyle = options.highlightStyle instanceof VectorStyleItem ?
178
+ options.highlightStyle :
179
+ new VectorStyleItem(options.highlightStyle);
180
+ }
181
+
182
+ /**
183
+ * A flag to indicate, whether the features in the layer have a UUID, allowing certain interactions,
184
+ * e.g. hidding its features in plannings
185
+ * @type {boolean}
186
+ * @api
187
+ */
188
+ this.hasFeatureUUID = false;
189
+ /**
190
+ * @type {boolean}
191
+ * @private
192
+ */
193
+ this._visibility = true;
194
+ /**
195
+ * If true, the cesium synchronizers are destroyed on map change
196
+ * @type {boolean}
197
+ */
198
+ this.isDynamic = parseBoolean(options.isDynamic, defaultOptions.isDynamic);
199
+
200
+ /**
201
+ * @type {Function}
202
+ * @private
203
+ */
204
+ this._onStyleChangeRemover = null;
205
+
206
+ /**
207
+ * @type {VectorProperties}
208
+ * @api
209
+ */
210
+ this.vectorProperties = new VectorProperties({
211
+ allowPicking: this.allowPicking,
212
+ ...options.vectorProperties,
213
+ });
214
+
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();
223
+ }
224
+
225
+ /**
226
+ * @type {Reference|StyleItemOptions|string}
227
+ * @private
228
+ */
229
+ this._initialStyle = initialStyle;
230
+ }
231
+
232
+ /**
233
+ * @api
234
+ * @type {boolean}
235
+ */
236
+ get allowPicking() {
237
+ return super.allowPicking;
238
+ }
239
+
240
+ /**
241
+ * @param {boolean} allowPicking
242
+ */
243
+ set allowPicking(allowPicking) {
244
+ super.allowPicking = allowPicking;
245
+ this.vectorProperties.allowPicking = allowPicking;
246
+ }
247
+
248
+ /**
249
+ * @type {boolean}
250
+ * @api
251
+ */
252
+ get visibility() { return this._visibility; }
253
+
254
+ /**
255
+ * @param {boolean} visible
256
+ */
257
+ set visibility(visible) {
258
+ if (this._visibility !== visible) {
259
+ this._visibility = visible;
260
+ this.forceRedraw();
261
+ }
262
+ }
263
+
264
+ /**
265
+ * @inheritDoc
266
+ * @returns {Promise<void>}
267
+ */
268
+ initialize() {
269
+ return super.initialize()
270
+ .then(() => {
271
+ this._trackStyleChanges();
272
+ });
273
+ }
274
+
275
+ /**
276
+ * Returns the layers vcsMeta object
277
+ * @param {GeoJSONwriteOptions=} options
278
+ * @returns {VcsMeta}
279
+ * @api
280
+ */
281
+ getVcsMeta(options = {}) {
282
+ const vcsMeta = this.vectorProperties.getVcsMeta();
283
+ vcsMeta.version = vcsMetaVersion;
284
+
285
+ if (options.embedIcons) {
286
+ vcsMeta.embeddedIcons = [];
287
+ }
288
+
289
+ if (options.writeStyle) {
290
+ const defaultStyle = this.getStyleOrDefaultStyle(this._initialStyle);
291
+ if (options.writeDefaultStyle || !defaultStyle.equals(this.style)) {
292
+ writeStyle(this.style, vcsMeta);
293
+ }
294
+ // TODO embed icons here by running over all features? this is never used anywhere
295
+ }
296
+
297
+ return vcsMeta;
298
+ }
299
+
300
+ /**
301
+ * Sets the meta values based on a {@link VcsMeta} Object. Does not carry over the style
302
+ * @param {VcsMeta} vcsMeta
303
+ */
304
+ setVcsMeta(vcsMeta) { // XXX what about the style?
305
+ this.vectorProperties.setVcsMeta(vcsMeta);
306
+ }
307
+
308
+ /**
309
+ * @returns {VectorImplementationOptions}
310
+ */
311
+ getImplementationOptions() {
312
+ return {
313
+ ...super.getImplementationOptions(),
314
+ source: this.source,
315
+ maxResolution: this.maxResolution,
316
+ minResolution: this.minResolution,
317
+ vectorProperties: this.vectorProperties,
318
+ };
319
+ }
320
+
321
+ /**
322
+ * @inheritDoc
323
+ * @param {import("@vcmap/core").VcsMap} map
324
+ * @returns {Array<VectorOblique|VectorCesium|VectorOpenlayers>}
325
+ */
326
+ createImplementationsForMap(map) {
327
+ if (!this.visibility) {
328
+ return [];
329
+ }
330
+
331
+ if (map instanceof Openlayers) {
332
+ return [new VectorOpenlayers(map, this.getImplementationOptions())];
333
+ }
334
+
335
+ if (map instanceof CesiumMap) {
336
+ return [new VectorCesium(map, this.getImplementationOptions())];
337
+ }
338
+
339
+ if (map instanceof Oblique) {
340
+ return [new VectorOblique(map, this.getImplementationOptions())];
341
+ }
342
+
343
+ return [];
344
+ }
345
+
346
+ /**
347
+ * @param {(Reference|DeclarativeStyleItemOptions|VectorStyleItemOptions|import("@vcmap/core").StyleItem|string)=} styleOptions
348
+ * @param {import("@vcmap/core").VectorStyleItem=} defaultStyle
349
+ * @returns {import("@vcmap/core").StyleItem}
350
+ */
351
+ getStyleOrDefaultStyle(styleOptions, defaultStyle) {
352
+ return super.getStyleOrDefaultStyle(styleOptions, defaultStyle || defaultVectorStyle.clone());
353
+ }
354
+
355
+ /**
356
+ * sets the style of this layer
357
+ * @param {import("ol/style/Style").default|import("ol/style/Style").StyleFunction|import("@vcmap/core").StyleItem|string} style
358
+ * @param {boolean=} silent
359
+ */
360
+ setStyle(style, silent) {
361
+ super.setStyle(style, silent);
362
+ this._trackStyleChanges();
363
+
364
+ const isDeclarative = this.style instanceof DeclarativeStyleItem;
365
+ this.getFeatures().forEach((f) => {
366
+ if (f[vectorStyleSymbol]) {
367
+ let changed;
368
+ if (isDeclarative) {
369
+ changed = true;
370
+ f.setStyle(undefined);
371
+ } else if (f.getStyle() !== f[vectorStyleSymbol].style) {
372
+ changed = true;
373
+ f.setStyle(f[vectorStyleSymbol].style);
374
+ }
375
+ if (changed && Reflect.has(f, originalStyle)) {
376
+ updateOriginalStyle(f);
377
+ }
378
+ }
379
+ });
380
+ }
381
+
382
+ /**
383
+ * Changes features which use the layers style or if the layers style is a declarative style so they are re-rendered
384
+ * @protected
385
+ */
386
+ _trackStyleChanges() {
387
+ if (this._onStyleChangeRemover) {
388
+ this._onStyleChangeRemover();
389
+ this._onStyleChangeRemover = null;
390
+ }
391
+
392
+ const isDeclarative = this.style instanceof DeclarativeStyleItem;
393
+ this._onStyleChangeRemover = this.style.styleChanged.addEventListener(() => {
394
+ this.getFeatures().forEach((f) => {
395
+ if (isDeclarative || !f[vectorStyleSymbol]) {
396
+ f.changed();
397
+ }
398
+ });
399
+ });
400
+ }
401
+
402
+ /**
403
+ * sets the highlightstyle of this layer
404
+ * @param {import("ol/style/Style").default|import("ol/style/Style").StyleFunction|import("@vcmap/core").VectorStyleItem} style
405
+ * @api experimental
406
+ */
407
+ setHighlightStyle(style) {
408
+ check(style, [Style, VectorStyleItem, Function]);
409
+ if (style instanceof VectorStyleItem) {
410
+ this.highlightStyle = style;
411
+ } else {
412
+ if (!this.highlightStyle) {
413
+ this.highlightStyle = new VectorStyleItem({});
414
+ }
415
+ this.highlightStyle.style = style;
416
+ }
417
+ }
418
+
419
+ /**
420
+ * returns the openlayers vector source
421
+ * @returns {import("ol/source").Vector<import("ol/geom/Geometry").default>}
422
+ * @api
423
+ */
424
+ getSource() {
425
+ return this.source;
426
+ }
427
+
428
+ /**
429
+ * add features to the vector layer and return an array with their ids.
430
+ * The geometry will be mutated and transformed to EPSG 3857 mercator coordinate system
431
+ *
432
+ * @param {Array<import("ol").Feature<import("ol/geom/Geometry").default>>} features
433
+ * @returns {Array<string|number>}
434
+ * @api stable
435
+ * @todo mechanism to enforce XYZ coordinate layout for internal usage
436
+ */
437
+ addFeatures(features) {
438
+ check(features, [Feature]);
439
+ const isDeclarative = this.style instanceof DeclarativeStyleItem;
440
+
441
+ const toAdd = features
442
+ .map((feature) => {
443
+ const featureId = feature.getId();
444
+ if (featureId == null) {
445
+ feature.setId(uuidv4());
446
+ } else {
447
+ this.hasFeatureUUID = true;
448
+ if (featureId && this.getFeatureById(featureId)) {
449
+ return false;
450
+ }
451
+ }
452
+
453
+ if (this.projection.epsg !== mercatorProjection.epsg) {
454
+ const geometry = feature.getGeometry();
455
+ if (geometry) {
456
+ if (!geometry[Vector.alreadyTransformedToMercator]) {
457
+ geometry.transform(this.projection.proj, mercatorProjection.proj);
458
+ geometry[Vector.alreadyTransformedToMercator] = true;
459
+ }
460
+ }
461
+ }
462
+
463
+ feature[Layer.vcsLayerNameSymbol] = this.name;
464
+ if (isDeclarative && feature[vectorStyleSymbol]) {
465
+ feature.setStyle();
466
+ }
467
+
468
+ return feature;
469
+ })
470
+ .filter(f => f);
471
+ this.source.addFeatures(/** @type {Array<import("ol").Feature<import("ol/geom/Geometry").default>>} */ (toAdd));
472
+ return features.map(f => f.getId());
473
+ }
474
+
475
+ /**
476
+ * removes features from the vector layer
477
+ * @param {Array<string|number>} ids
478
+ * @api stable
479
+ */
480
+ removeFeaturesById(ids) {
481
+ const features = this.getFeaturesById(ids);
482
+ for (let i = 0; i < features.length; i++) {
483
+ this.source.removeFeature(features[i]);
484
+ }
485
+ }
486
+
487
+ /**
488
+ * removes all features from the vector layer
489
+ * @api stable
490
+ */
491
+ removeAllFeatures() {
492
+ this.source.clear();
493
+ }
494
+
495
+ /**
496
+ * returns an array with features
497
+ * feature geometries are always in EPSG 3857 mercator coordinate system
498
+ * @param {Array<string|number>} ids
499
+ * @returns {Array<import("ol").Feature<import("ol/geom/Geometry").default>>}
500
+ * @api stable
501
+ */
502
+ getFeaturesById(ids) {
503
+ check(ids, [[String, Number]]);
504
+ return ids.map(id => this.getFeatureById(id))
505
+ .filter(f => f != null);
506
+ }
507
+
508
+ /**
509
+ * returns an feature if found, otherwise null
510
+ * feature geometries are always in EPSG 3857 mercator coordinate system
511
+ * @param {string|number} id
512
+ * @returns {import("ol").Feature<import("ol/geom/Geometry").default>}
513
+ * @api stable
514
+ */
515
+ getFeatureById(id) {
516
+ return this.source.getFeatureById(id);
517
+ }
518
+
519
+ /**
520
+ * returns an array with features
521
+ * Feature geometries are always in EPSG 3857 mercator coordinate system
522
+ * @returns {Array<import("ol").Feature<import("ol/geom/Geometry").default>>}
523
+ * @api stable
524
+ */
525
+ getFeatures() {
526
+ return this.source.getFeatures();
527
+ }
528
+
529
+ /**
530
+ * Returns the configured Extent of this layer or tries to calculate the extent based on the current features.
531
+ * Returns null of no extent was configured and the layer is void of any features with a valid geometry.
532
+ * @returns {Extent|null}
533
+ * @api
534
+ */
535
+ getZoomToExtent() {
536
+ const metaExtent = super.getZoomToExtent(); // XXX not sure if this should be the otherway around?
537
+ if (metaExtent) {
538
+ return metaExtent;
539
+ }
540
+ const extent = new Extent({
541
+ ...mercatorProjection.getConfigObject(),
542
+ coordinates: this.source.getExtent(),
543
+ });
544
+ if (extent.isValid()) {
545
+ return extent;
546
+ }
547
+ return null;
548
+ }
549
+
550
+ /**
551
+ * @param {import("ol").Feature<import("ol/geom/Geometry").default>} olFeature
552
+ * @returns {?Object}
553
+ */
554
+ objectClickedHandler(olFeature) {
555
+ const actualFeature = olFeature[originalFeatureSymbol] || olFeature;
556
+ if (this.vectorProperties.getAllowPicking(actualFeature)) {
557
+ return {
558
+ id: actualFeature.getId(),
559
+ feature: actualFeature,
560
+ };
561
+ }
562
+ return null;
563
+ }
564
+
565
+ /**
566
+ * @param {VectorClickedObject} object
567
+ * @returns {?GenericFeature}
568
+ */
569
+ getGenericFeatureFromClickedObject(object) {
570
+ return getGenericFeatureFromClickedObject(object, this);
571
+ }
572
+
573
+ /**
574
+ * @returns {VectorOptions}
575
+ */
576
+ getConfigObject() {
577
+ const config = /** @type {VectorOptions} */ (super.getConfigObject());
578
+ const defaultOptions = Vector.getDefaultOptions();
579
+
580
+ if (this.projection.epsg !== getDefaultProjection().epsg) {
581
+ config.projection = this.projection.getConfigObject();
582
+ }
583
+
584
+ if (this.maxResolution !== defaultOptions.maxResolution) {
585
+ config.maxResolution = this.maxResolution;
586
+ }
587
+
588
+ if (this.minResolution !== defaultOptions.minResolution) {
589
+ config.minResolution = this.minResolution;
590
+ }
591
+
592
+ if (this.dontUseTerrainForOblique !== defaultOptions.dontUseTerrainForOblique) {
593
+ config.dontUseTerrainForOblique = this.dontUseTerrainForOblique;
594
+ }
595
+
596
+ if (this.highlightStyle) {
597
+ config.highlightStyle = this.highlightStyle[referenceableStyleSymbol] ?
598
+ this.highlightStyle.getReference() :
599
+ this.highlightStyle.getOptions();
600
+ }
601
+
602
+ if (this.isDynamic !== defaultOptions.isDynamic) {
603
+ config.isDynamic = this.isDynamic;
604
+ }
605
+
606
+ const vectorPropertiesConfig = this.vectorProperties.getVcsMeta();
607
+ if (Object.keys(vectorPropertiesConfig).length > 0) {
608
+ config.vectorProperties = vectorPropertiesConfig;
609
+ }
610
+
611
+ // XXX missing style
612
+
613
+ return config;
614
+ }
615
+
616
+ /**
617
+ * @inheritDoc
618
+ */
619
+ destroy() {
620
+ if (this.source) {
621
+ this.source.clear(true);
622
+ }
623
+ if (this._onStyleChangeRemover) {
624
+ this._onStyleChangeRemover();
625
+ }
626
+ this.vectorProperties.destroy();
627
+ super.destroy();
628
+ }
629
+ }
630
+
631
+ VcsClassRegistry.registerClass(Vector.className, Vector);
632
+ export default Vector;