@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,359 @@
1
+ import {
2
+ Composite3DTileContent,
3
+ Cesium3DTileset,
4
+ Cesium3DTileColorBlendMode,
5
+ Matrix4,
6
+ Cartesian3,
7
+ Cartographic,
8
+ Rectangle,
9
+ Math as CesiumMath,
10
+ } from '@vcmap/cesium';
11
+ import { createEmpty } from 'ol/extent.js';
12
+ import LayerImplementation from '../layerImplementation.js';
13
+ import { vcsLayerName } from '../layerSymbols.js';
14
+ import { getGlobalHider } from '../globalHider.js';
15
+ import { originalStyle, updateOriginalStyle } from '../featureVisibility.js';
16
+ import Projection from '../../util/projection.js';
17
+ import { circleFromCenterRadius } from '../../util/geometryHelpers.js';
18
+
19
+ /**
20
+ * @type {symbol}
21
+ */
22
+ export const cesiumTilesetLastUpdated = Symbol('cesiumTilesetLastUpdated');
23
+
24
+ /**
25
+ * @param {import("@vcmap/cesium").Cesium3DTileset} cesium3DTileset
26
+ * @returns {import("ol/extent").Extent} in mercator
27
+ */
28
+ export function getExtentFromTileset(cesium3DTileset) {
29
+ if (!cesium3DTileset.ready) {
30
+ return createEmpty();
31
+ }
32
+ const { rectangle } = cesium3DTileset.root.boundingVolume;
33
+ if (rectangle) {
34
+ const scratchSW = Rectangle.southwest(rectangle);
35
+ const scratchNE = Rectangle.northeast(rectangle);
36
+ const mercatorSW = Projection.wgs84ToMercator([
37
+ CesiumMath.toDegrees(scratchSW.longitude),
38
+ CesiumMath.toDegrees(scratchSW.latitude),
39
+ ]);
40
+
41
+ const mercatorNE = Projection.wgs84ToMercator([
42
+ CesiumMath.toDegrees(scratchNE.longitude),
43
+ CesiumMath.toDegrees(scratchNE.latitude),
44
+ ]);
45
+ return /** @type {import("ol/extent").Extent} */ ([mercatorSW[0], mercatorSW[1], mercatorNE[0], mercatorNE[1]]);
46
+ }
47
+
48
+ const { center, radius } = cesium3DTileset.boundingSphere;
49
+ const cart = Cartographic.fromCartesian(center);
50
+ const mercatorCenter = Projection.wgs84ToMercator([
51
+ CesiumMath.toDegrees(cart.longitude),
52
+ CesiumMath.toDegrees(cart.latitude),
53
+ cart.height,
54
+ ]);
55
+ const circle = circleFromCenterRadius(mercatorCenter, radius);
56
+ return circle.getExtent();
57
+ }
58
+
59
+ /**
60
+ * represents the cesium implementation for a {@link CesiumTileset} layer.
61
+ * @class
62
+ * @export
63
+ * @extends {LayerImplementation<import("@vcmap/core").CesiumMap>}}
64
+ * @implements {FeatureLayerImplementation}
65
+ * @api stable
66
+ */
67
+ class CesiumTilesetCesium extends LayerImplementation {
68
+ /** @type {string} */
69
+ static get className() { return 'vcs.vcm.layer.cesium.CesiumTilesetCesium'; }
70
+
71
+ /**
72
+ * @param {import("@vcmap/core").CesiumMap} map
73
+ * @param {CesiumTilesetImplementationOptions} options
74
+ */
75
+ constructor(map, options) {
76
+ super(map, options);
77
+
78
+ /** @type {import("@vcmap/cesium").Cesium3DTileset} */
79
+ this.cesium3DTileset = null;
80
+ /** @type {Object} */
81
+ this.tilesetOptions = options.tilesetOptions;
82
+ /** @type {import("@vcmap/cesium").ImagerySplitDirection} */
83
+ this.splitDirection = options.splitDirection;
84
+ /** @type {import("@vcmap/core").StyleItem} */
85
+ this.style = options.style;
86
+ /** @type {import("@vcmap/core").FeatureVisibility} */
87
+ this.featureVisibility = options.featureVisibility;
88
+ /** @type {Array<CesiumTilesetTilesetProperties>} */
89
+ this.tilesetProperties = options.tilesetProperties;
90
+ /** @type {import("@vcmap/cesium").Matrix4} */
91
+ this.modelMatrix = options.modelMatrix;
92
+ /** @type {import("ol/coordinate").Coordinate} */
93
+ this.offset = options.offset;
94
+ /**
95
+ * @type {Promise<void>}
96
+ * @private
97
+ */
98
+ this._initializedPromise = null;
99
+ /**
100
+ * @type {import("@vcmap/cesium").Cartesian3}
101
+ * @private
102
+ */
103
+ this._originalOrigin = null;
104
+ /**
105
+ * @type {number}
106
+ * @private
107
+ */
108
+ this._styleLastUpdated = Date.now();
109
+ this.globalHider = getGlobalHider();
110
+ }
111
+
112
+ /**
113
+ * @inheritDoc
114
+ * @returns {Promise<void>}
115
+ */
116
+ async initialize() {
117
+ if (!this._initializedPromise) {
118
+ /** @type {import("@vcmap/cesium").Cesium3DTileset} */
119
+ this.cesium3DTileset = new Cesium3DTileset(this.tilesetOptions);
120
+ if (this.tilesetProperties) {
121
+ this.tilesetProperties.forEach(({ key, value }) => {
122
+ this.cesium3DTileset[key] = value;
123
+ });
124
+ }
125
+ this.cesium3DTileset[vcsLayerName] = this.name;
126
+ this.cesium3DTileset.tileVisible.addEventListener(this.applyStyle.bind(this));
127
+ this.cesium3DTileset.tileUnload.addEventListener((tile) => {
128
+ delete tile[cesiumTilesetLastUpdated];
129
+ });
130
+
131
+ this._initializedPromise = new Promise((resolve, reject) => {
132
+ this.cesium3DTileset.readyPromise.then(() => { resolve(); }, reject);
133
+ });
134
+
135
+ await this._initializedPromise;
136
+ this._originalOrigin = Cartesian3.clone(this.cesium3DTileset.boundingSphere.center);
137
+
138
+ if (this.modelMatrix) {
139
+ this.cesium3DTileset.modelMatrix = this.modelMatrix;
140
+ } else if (this.offset) {
141
+ this._calculateOffset();
142
+ }
143
+ this.map.addPrimitiveCollection(this.cesium3DTileset);
144
+ await super.initialize();
145
+ if (this.splitDirection) {
146
+ this.updateSplitDirection(this.splitDirection);
147
+ }
148
+ this.updateStyle(this.style);
149
+ }
150
+ return this._initializedPromise;
151
+ }
152
+
153
+ /**
154
+ * @private
155
+ */
156
+ _calculateOffset() {
157
+ if (this.cesium3DTileset && !this.modelMatrix) {
158
+ if (!this.offset) {
159
+ this.cesium3DTileset.modelMatrix = Matrix4.IDENTITY;
160
+ } else {
161
+ const cartographicCenter = Cartographic.fromCartesian(this._originalOrigin);
162
+ cartographicCenter.longitude += CesiumMath.toRadians(this.offset[0]);
163
+ cartographicCenter.latitude += CesiumMath.toRadians(this.offset[1]);
164
+ cartographicCenter.height += this.offset[2];
165
+ const offset = Cartographic.toCartesian(cartographicCenter);
166
+ const translation = Cartesian3.subtract(offset, this._originalOrigin, offset);
167
+ this.cesium3DTileset.modelMatrix = Matrix4.fromTranslation(translation);
168
+ }
169
+ }
170
+ }
171
+
172
+ /**
173
+ * @param {import("@vcmap/cesium").Matrix4=} modelMatrix
174
+ */
175
+ updateModelMatrix(modelMatrix) {
176
+ this.modelMatrix = modelMatrix;
177
+ if (this.cesium3DTileset) {
178
+ if (!this.modelMatrix) {
179
+ if (this.offset) {
180
+ this._calculateOffset();
181
+ } else {
182
+ this.cesium3DTileset.modelMatrix = Matrix4.IDENTITY;
183
+ }
184
+ } else {
185
+ this.cesium3DTileset.modelMatrix = modelMatrix;
186
+ }
187
+ }
188
+ }
189
+
190
+ /**
191
+ * @param {import("ol/coordinate").Coordinate=} offset
192
+ */
193
+ updateOffset(offset) {
194
+ this.offset = offset;
195
+ this._calculateOffset();
196
+ }
197
+
198
+ /**
199
+ * @inheritDoc
200
+ * @returns {Promise<void>}
201
+ */
202
+ async activate() {
203
+ await super.activate();
204
+ if (this.active) {
205
+ this.cesium3DTileset.show = true;
206
+ }
207
+ }
208
+
209
+ /**
210
+ * @inheritDoc
211
+ */
212
+ deactivate() {
213
+ super.deactivate();
214
+ if (this.cesium3DTileset) {
215
+ this.cesium3DTileset.show = false;
216
+ }
217
+ }
218
+
219
+ /**
220
+ * @param {import("@vcmap/core").StyleItem} style
221
+ * @param {boolean=} silent
222
+ */
223
+ // eslint-disable-next-line no-unused-vars
224
+ updateStyle(style, silent) {
225
+ this.style = style;
226
+ if (this.initialized) {
227
+ this.cesium3DTileset.style = this.style.cesiumStyle;
228
+ if (this._onStyleChangeRemover) {
229
+ this._onStyleChangeRemover();
230
+ }
231
+ this._onStyleChangeRemover = this.style.styleChanged.addEventListener(() => {
232
+ this.cesium3DTileset.makeStyleDirty();
233
+ this._styleLastUpdated = Date.now();
234
+ });
235
+ this._styleLastUpdated = Date.now();
236
+ this.cesium3DTileset.readyPromise.then(() => {
237
+ if (this.cesium3DTileset.colorBlendMode !== this.style.colorBlendMode) {
238
+ // we only support replace and mix mode if the _3DTILESDIFFUSE Flag is set in the tileset
239
+ if (this.style.colorBlendMode !== Cesium3DTileColorBlendMode.HIGHLIGHT) {
240
+ // eslint-disable-next-line no-underscore-dangle
241
+ if (this.cesium3DTileset.extras && this.cesium3DTileset.extras._3DTILESDIFFUSE) {
242
+ this.cesium3DTileset.colorBlendMode = this.style.colorBlendMode;
243
+ }
244
+ } else {
245
+ this.cesium3DTileset.colorBlendMode = this.style.colorBlendMode;
246
+ }
247
+ }
248
+ });
249
+ }
250
+ }
251
+
252
+ /**
253
+ * @param {import("@vcmap/cesium").ImagerySplitDirection} splitDirection
254
+ */
255
+ updateSplitDirection(splitDirection) {
256
+ const { splitScreen } = this.map;
257
+ if (splitScreen) { // XXX edge case: what if the map get splitScreen added later?
258
+ const previousClippingObject = splitScreen.getClippingObjectForDirection(this.splitDirection);
259
+ if (previousClippingObject) {
260
+ previousClippingObject.removeLayer(this.name);
261
+ }
262
+ this.splitDirection = splitDirection;
263
+ const currentClippingObject = splitScreen.getClippingObjectForDirection(this.splitDirection);
264
+ if (currentClippingObject) {
265
+ currentClippingObject.addLayer(this.name);
266
+ }
267
+ }
268
+ }
269
+
270
+ /**
271
+ * @param {import("@vcmap/cesium").Cesium3DTile} tile
272
+ */
273
+ applyStyle(tile) {
274
+ if (tile.content instanceof Composite3DTileContent) {
275
+ for (let i = 0; i < tile.content.innerContents.length; i++) {
276
+ this.styleContent(tile.content.innerContents[i]);
277
+ }
278
+ } else {
279
+ this.styleContent(tile.content);
280
+ }
281
+ }
282
+
283
+ /**
284
+ * @param {import("@vcmap/cesium").Cesium3DTileContent} content
285
+ */
286
+ styleContent(content) {
287
+ if (
288
+ !content[cesiumTilesetLastUpdated] ||
289
+ content[cesiumTilesetLastUpdated] < this.featureVisibility.lastUpdated ||
290
+ content[cesiumTilesetLastUpdated] < this.globalHider.lastUpdated ||
291
+ content[cesiumTilesetLastUpdated] < this._styleLastUpdated
292
+ ) {
293
+ const batchSize = content.featuresLength;
294
+ for (let batchId = 0; batchId < batchSize; batchId++) {
295
+ const feature = content.getFeature(batchId);
296
+ if (feature) {
297
+ let id = feature.getProperty('id');
298
+ if (!id) {
299
+ id = `${content.url}${batchId}`;
300
+ }
301
+
302
+ if (
303
+ this.featureVisibility.highlightedObjects[id] &&
304
+ !this.featureVisibility.hasHighlightFeature(id, feature)
305
+ ) {
306
+ this.featureVisibility.addHighlightFeature(id, feature);
307
+ }
308
+
309
+ if (this.featureVisibility.hiddenObjects[id] && !this.featureVisibility.hasHiddenFeature(id, feature)) {
310
+ this.featureVisibility.addHiddenFeature(id, feature);
311
+ }
312
+
313
+ if (this.globalHider.hiddenObjects[id] && !this.globalHider.hasFeature(id, feature)) {
314
+ this.globalHider.addFeature(id, feature);
315
+ }
316
+
317
+ if (
318
+ this._styleLastUpdated > content[cesiumTilesetLastUpdated] &&
319
+ feature[originalStyle] // can only be a color for cesium, so no check for undefined required
320
+ ) {
321
+ updateOriginalStyle(feature);
322
+ }
323
+ }
324
+ }
325
+ content[cesiumTilesetLastUpdated] = Date.now();
326
+ }
327
+ }
328
+
329
+ /**
330
+ * @inheritDoc
331
+ */
332
+ destroy() {
333
+ if (this.cesium3DTileset) {
334
+ if (this.map.initialized) {
335
+ const toRemove = this.cesium3DTileset;
336
+ this.map.removePrimitiveCollection(/** @type {undefined} */ (toRemove)); // cast to undefined do to missing inheritance
337
+ } else {
338
+ this.cesium3DTileset.destroy();
339
+ }
340
+
341
+ this.cesium3DTileset = null;
342
+ }
343
+
344
+ if (this._onStyleChangeRemover) {
345
+ this._onStyleChangeRemover();
346
+ }
347
+
348
+ if (this.splitDirection && this.map.splitScreen) {
349
+ const previousClippingObject = this.map.splitScreen.getClippingObjectForDirection(this.splitDirection);
350
+ if (previousClippingObject) {
351
+ previousClippingObject.removeLayer(this.name);
352
+ }
353
+ }
354
+
355
+ super.destroy();
356
+ }
357
+ }
358
+
359
+ export default CesiumTilesetCesium;
@@ -0,0 +1,95 @@
1
+ import { removeFeatureFromMap, addPrimitiveToContext, removeArrayFromCollection } from './vectorContext.js';
2
+
3
+ /**
4
+ * @class
5
+ */
6
+ class ClusterContext {
7
+ /**
8
+ * @param {import("@vcmap/cesium").CustomDataSource} dataSource
9
+ */
10
+ constructor(dataSource) {
11
+ /** @type {import("@vcmap/cesium").EntityCollection} */
12
+ this.entities = dataSource.entities;
13
+ /** @type {Map<import("ol").Feature<import("ol/geom/Geometry").default>, Array<import("@vcmap/cesium").Entity>>} */
14
+ this.featureToBillboardMap = new Map();
15
+ /** @type {Map<import("ol").Feature<import("ol/geom/Geometry").default>, Array<import("@vcmap/cesium").Entity>>} */
16
+ this.featureToLabelMap = new Map();
17
+ }
18
+
19
+ /**
20
+ * @param {Array<import("@vcmap/cesium").Primitive|import("@vcmap/cesium").GroundPrimitive|import("@vcmap/cesium").GroundPolylinePrimitive|import("@vcmap/cesium").ClassificationPrimitive|import("@vcmap/cesium").Model>} primitives
21
+ * @param {import("ol").Feature<import("ol/geom/Geometry").default>} feature
22
+ * @param {boolean=} allowPicking
23
+ */
24
+ // eslint-disable-next-line class-methods-use-this,no-unused-vars
25
+ addPrimitives(primitives, feature, allowPicking) {}
26
+
27
+ /**
28
+ * @param {Array<Object>} billboardOptions
29
+ * @param {import("ol").Feature<import("ol/geom/Geometry").default>} feature
30
+ * @param {boolean=} allowPicking
31
+ */
32
+ addBillboards(billboardOptions, feature, allowPicking) {
33
+ addPrimitiveToContext(
34
+ billboardOptions.map(billboard => ({ billboard, position: billboard.position })),
35
+ feature,
36
+ allowPicking,
37
+ this.entities,
38
+ this.featureToBillboardMap,
39
+ );
40
+ }
41
+
42
+ /**
43
+ * @param {Array<Object>} labelOptions
44
+ * @param {import("ol").Feature<import("ol/geom/Geometry").default>} feature
45
+ * @param {boolean=} allowPicking
46
+ */
47
+ addLabels(labelOptions, feature, allowPicking) {
48
+ addPrimitiveToContext(
49
+ labelOptions.map(label => ({ label, position: label.position })),
50
+ feature,
51
+ allowPicking,
52
+ this.entities,
53
+ this.featureToLabelMap,
54
+ );
55
+ }
56
+
57
+ /**
58
+ * @param {import("ol").Feature<import("ol/geom/Geometry").default>} feature
59
+ */
60
+ removeFeature(feature) {
61
+ removeFeatureFromMap(feature, this.featureToBillboardMap, this.entities);
62
+ removeFeatureFromMap(feature, this.featureToLabelMap, this.entities);
63
+ }
64
+
65
+ /**
66
+ * Caches the current cesium resources for a feature, removing them from the feature map
67
+ * @param {import("ol").Feature<import("ol/geom/Geometry").default>}feature
68
+ * @returns {VectorContextFeatureCache}
69
+ */
70
+ createFeatureCache(feature) {
71
+ /** @type {VectorContextFeatureCache} */
72
+ const cache = {};
73
+ cache.billboards = this.featureToBillboardMap.get(feature);
74
+ this.featureToBillboardMap.delete(feature);
75
+ cache.labels = this.featureToLabelMap.get(feature);
76
+ this.featureToLabelMap.delete(feature);
77
+ return cache;
78
+ }
79
+
80
+ /**
81
+ * @param {VectorContextFeatureCache} cache
82
+ */
83
+ clearFeatureCache(cache) {
84
+ removeArrayFromCollection(this.entities, cache.billboards);
85
+ removeArrayFromCollection(this.entities, cache.labels);
86
+ }
87
+
88
+ clear() {
89
+ this.entities.removeAll();
90
+ this.featureToBillboardMap.clear();
91
+ this.featureToLabelMap.clear();
92
+ }
93
+ }
94
+
95
+ export default ClusterContext;
@@ -0,0 +1,171 @@
1
+ import {
2
+ CustomDataSource,
3
+ BoundingSphereState,
4
+ BoundingSphere,
5
+ HeadingPitchRange,
6
+ Math as CesiumMath,
7
+ } from '@vcmap/cesium';
8
+ import LayerImplementation from '../layerImplementation.js';
9
+ import { vcsLayerName } from '../layerSymbols.js';
10
+
11
+ /**
12
+ * @param {import("@vcmap/cesium").EntityCollection} source
13
+ * @param {import("@vcmap/cesium").EntityCollection} destination
14
+ * @returns {Function}
15
+ */
16
+ function synchronizeEntityCollections(source, destination) {
17
+ source.values.forEach((entity) => {
18
+ destination.add(entity);
19
+ });
20
+ return source.collectionChanged.addEventListener((c, added, removed) => {
21
+ added.forEach((e) => { destination.add(e); });
22
+ removed.forEach((e) => { destination.remove(e); });
23
+ });
24
+ }
25
+
26
+ /**
27
+ * @class
28
+ * @export
29
+ * @extends {LayerImplementation<import("@vcmap/core").CesiumMap>}}
30
+ */
31
+ class DataSourceCesium extends LayerImplementation {
32
+ /**
33
+ * @param {import("@vcmap/core").CesiumMap} map
34
+ * @param {DataSourceImplementationOptions} options
35
+ */
36
+ constructor(map, options) {
37
+ super(map, options);
38
+
39
+ /**
40
+ * @type {import("@vcmap/cesium").CustomDataSource|import("@vcmap/cesium").CzmlDataSource}
41
+ */
42
+ this.dataSource = new CustomDataSource(this.name);
43
+ this.dataSource[vcsLayerName] = this.name;
44
+ /**
45
+ * @type {import("@vcmap/cesium").EntityCollection}
46
+ */
47
+ this.entities = options.entities;
48
+ /**
49
+ * @type {import("@vcmap/cesium").DataSourceClock|undefined}
50
+ */
51
+ this.clock = options.clock;
52
+ /**
53
+ * @type {Function}
54
+ * @private
55
+ */
56
+ this._collectionListener = () => {};
57
+ }
58
+
59
+ /**
60
+ * @inheritDoc
61
+ * @returns {Promise<void>}
62
+ */
63
+ async initialize() {
64
+ if (!this.initialized) {
65
+ this._collectionListener = synchronizeEntityCollections(this.entities, this.dataSource.entities);
66
+ await this.map.addDataSource(this.dataSource);
67
+ }
68
+ await super.initialize();
69
+ }
70
+
71
+ /**
72
+ * @inheritDoc
73
+ * @returns {Promise<void>}
74
+ */
75
+ async activate() {
76
+ await super.activate();
77
+ if (this.active) {
78
+ this.dataSource.show = true;
79
+ }
80
+ if (this.clock) {
81
+ this.map.setDataSourceDisplayClock(this.clock);
82
+ }
83
+ }
84
+
85
+ /**
86
+ * @inheritDoc
87
+ */
88
+ deactivate() {
89
+ super.deactivate();
90
+ this.dataSource.show = false;
91
+ if (this.clock) {
92
+ this.map.unsetDataSourceDisplayClock(this.clock);
93
+ }
94
+ }
95
+
96
+ /**
97
+ * @param {string} id
98
+ */
99
+ flyToEntity(id) {
100
+ if (this.active) {
101
+ const entity = this.dataSource.entities.getById(id);
102
+ if (!entity) {
103
+ this.getLogger().warning('could not find entity on this layer');
104
+ return;
105
+ }
106
+ const dataSource = this.map.getDataSourceDisplay();
107
+ const scene = this.map.getScene();
108
+ const { camera } = scene;
109
+
110
+ const bSphere = new BoundingSphere();
111
+
112
+ const viewpoint = this.map.getViewPointSync();
113
+ const { heading, pitch } = viewpoint;
114
+ const offset = new HeadingPitchRange(
115
+ CesiumMath.toRadians(heading),
116
+ CesiumMath.toRadians(pitch < -45 ? pitch : -45),
117
+ undefined,
118
+ );
119
+ let listener;
120
+ let count = 0;
121
+
122
+ const onRender = () => {
123
+ const state = dataSource.getBoundingSphere(entity, true, bSphere);
124
+ if (state === BoundingSphereState.PENDING) {
125
+ return;
126
+ }
127
+
128
+ if (state === BoundingSphereState.FAILED) {
129
+ count += 1;
130
+ if (count > 3) {
131
+ listener();
132
+ }
133
+ return;
134
+ }
135
+
136
+ camera.flyToBoundingSphere(bSphere, {
137
+ duration: 1,
138
+ offset,
139
+ });
140
+ listener();
141
+ };
142
+
143
+ const datas = dataSource.defaultDataSource;
144
+ if (datas.isLoading) {
145
+ const loadedListener = datas.loadingEvent.addEventListener(() => {
146
+ listener = scene.postRender.addEventListener(onRender);
147
+ loadedListener();
148
+ });
149
+ } else {
150
+ listener = scene.postRender.addEventListener(onRender);
151
+ }
152
+ }
153
+ }
154
+
155
+ /**
156
+ * @inheritDoc
157
+ */
158
+ destroy() {
159
+ if (this.map.initialized && !this.isDestroyed) {
160
+ this.map.removeDataSource(this.dataSource);
161
+ }
162
+ this._collectionListener();
163
+ this.dataSource.entities.removeAll();
164
+ if (this.clock) {
165
+ this.map.unsetDataSourceDisplayClock(this.clock);
166
+ }
167
+ super.destroy();
168
+ }
169
+ }
170
+
171
+ export default DataSourceCesium;
@@ -0,0 +1,29 @@
1
+ import { OpenStreetMapImageryProvider, ImageryLayer as CesiumImageryLayer } from '@vcmap/cesium';
2
+ import RasterLayerCesium from './rasterLayerCesium.js';
3
+
4
+ /**
5
+ * represents a specific OpenStreetMap layer for cesium.
6
+ * @class
7
+ * @export
8
+ * @extends {RasterLayerCesium}
9
+ */
10
+ class OpenStreetMapCesium extends RasterLayerCesium {
11
+ static get className() { return 'vcs.vcm.layer.cesium.OpenStreetMapCesium'; }
12
+
13
+ /**
14
+ * @inheritDoc
15
+ * @returns {import("@vcmap/cesium").ImageryLayer}
16
+ */
17
+ getCesiumLayer() {
18
+ return new CesiumImageryLayer(
19
+ new OpenStreetMapImageryProvider({ maximumLevel: this.maxLevel }),
20
+ {
21
+ alpha: this.opacity,
22
+ splitDirection: this.splitDirection,
23
+ },
24
+ );
25
+ }
26
+ }
27
+
28
+
29
+ export default OpenStreetMapCesium;
@@ -0,0 +1,58 @@
1
+ import { Cesium3DTileStyle } from '@vcmap/cesium';
2
+ import CesiumTilesetCesium from './cesiumTilesetCesium.js';
3
+
4
+ /**
5
+ * represents a specific PointCloud layer for cesium.
6
+ * <h3>Config Parameter</h3>
7
+ * <ul>
8
+ * <li>url: string: url to the p3dm dataset
9
+ * <li>pointSize: number: size of the points to display
10
+ * </ul>
11
+ *
12
+ * @class
13
+ * @export
14
+ * @extends {CesiumTilesetCesium}
15
+ * @api stable
16
+ */
17
+ class PointCloudCesium extends CesiumTilesetCesium {
18
+ static get className() { return 'vcs.vcm.layer.cesium.PointCloud'; }
19
+
20
+ /**
21
+ * @param {import("@vcmap/core").CesiumMap} map
22
+ * @param {PointCloudImplementationOptions} options
23
+ */
24
+ constructor(map, options) {
25
+ super(map, options);
26
+ /** @type {string|number} */
27
+ this.pointSize = options.pointSize;
28
+ }
29
+
30
+ /**
31
+ * @inheritDoc
32
+ * @returns {Promise<void>}
33
+ */
34
+ async initialize() {
35
+ await super.initialize();
36
+ this.updatePointSize(this.pointSize);
37
+ }
38
+
39
+ /**
40
+ * @param {string|number} size
41
+ */
42
+ updatePointSize(size) {
43
+ this.pointSize = size;
44
+ if (this.initialized) {
45
+ if (this.cesium3DTileset.style) {
46
+ // @ts-ignore
47
+ this.cesium3DTileset.style.pointSize = this.pointSize;
48
+ this.cesium3DTileset.makeStyleDirty();
49
+ } else if (this.pointSize != null) {
50
+ this.cesium3DTileset.style = new Cesium3DTileStyle({
51
+ pointSize: this.pointSize.toString(),
52
+ });
53
+ }
54
+ }
55
+ }
56
+ }
57
+
58
+ export default PointCloudCesium;