@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,435 @@
1
+ import { Color, Cesium3DTileFeature, Cesium3DTilePointFeature, Entity as CesiumEntity } from '@vcmap/cesium';
2
+ import Feature from 'ol/Feature.js';
3
+ import Style from 'ol/style/Style.js';
4
+
5
+ import VectorStyleItem, { fromCesiumColor } from '../util/style/vectorStyleItem.js';
6
+ import { emptyStyle } from '../util/style/styleHelpers.js';
7
+ import VcsEvent from '../event/vcsEvent.js';
8
+
9
+ /**
10
+ * Set on an ol.Feature or Cesium.Cesium3DTileFeature to indicate its style before it was hidden or highlighted.
11
+ * Can be undefined or ol.style.Style for ol.Features and Cesium.Color for Cesium.Cesium3DTileFeatures.
12
+ * @type {symbol}
13
+ */
14
+ export const originalStyle = Symbol('originalStyle');
15
+
16
+ /**
17
+ * Set on an ol.Feature or Cesium.Cesium3DTileFeature to indicate that this features is highlighted.
18
+ * Its value is a {@link VectorStyleItem}.
19
+ * @type {symbol}
20
+ */
21
+ export const highlighted = Symbol('highlighted');
22
+
23
+ /**
24
+ * Is a boolean value set on ol.Feature or Cesium.Cesium3DTileFeature to indicate it is hidden
25
+ * by the layers {@link FeatureVisibility}.
26
+ * @type {symbol}
27
+ */
28
+ export const hidden = Symbol('hidden');
29
+
30
+ /**
31
+ * Is a boolean value set on ol.Feature or Cesium.Cesium3DTileFeature to indicate it is hidden
32
+ * by the {@link GlobalHider}
33
+ * @type {symbol}
34
+ */
35
+ export const globalHidden = Symbol('globalHidden');
36
+
37
+ /**
38
+ * @typedef {Object} HighlightedObject
39
+ * @property {VectorStyleItem} style
40
+ * @property {Set<import("ol").Feature<import("ol/geom/Geometry").default>|import("@vcmap/cesium").Cesium3DTileFeature|import("@vcmap/cesium").Cesium3DTilePointFeature>} features
41
+ */
42
+
43
+ /**
44
+ * @typedef {Object} FeatureVisibilityEvent
45
+ * @property {FeatureVisibilityAction} action
46
+ * @property {Array<string>} ids
47
+ * @api
48
+ */
49
+
50
+ /**
51
+ * @param {import("@vcmap/cesium").Cesium3DTileFeature|import("@vcmap/cesium").Cesium3DTilePointFeature} feature
52
+ * @returns {boolean}
53
+ */
54
+ export function featureExists(feature) {
55
+ return feature &&
56
+ feature.content &&
57
+ !feature.content.isDestroyed() &&
58
+ !feature.content.batchTable.isDestroyed();
59
+ }
60
+
61
+ /**
62
+ * @param {import("@vcmap/cesium").Cesium3DTileFeature|import("@vcmap/cesium").Cesium3DTilePointFeature|import("ol").Feature<import("ol/geom/Geometry").default>|import("@vcmap/cesium").Entity} feature
63
+ * @private
64
+ */
65
+ export function hideFeature(feature) {
66
+ if (
67
+ (
68
+ (feature instanceof Cesium3DTileFeature || feature instanceof Cesium3DTilePointFeature) &&
69
+ featureExists(feature)
70
+ ) || feature instanceof CesiumEntity
71
+ ) {
72
+ feature.show = false;
73
+ } else if (feature instanceof Feature) {
74
+ feature.setStyle(emptyStyle.clone());
75
+ }
76
+ }
77
+
78
+ /**
79
+ * Caches the original style on the feature using the originalStyle symbol
80
+ * @param {import("@vcmap/cesium").Cesium3DTileFeature|import("@vcmap/cesium").Cesium3DTilePointFeature|import("ol").Feature<import("ol/geom/Geometry").default>|import("@vcmap/cesium").Entity} feature
81
+ * @private
82
+ */
83
+ export function cacheOriginalStyle(feature) {
84
+ if (!Reflect.has(feature, originalStyle)) {
85
+ if (
86
+ (feature instanceof Cesium3DTileFeature || feature instanceof Cesium3DTilePointFeature) &&
87
+ featureExists(feature)
88
+ ) {
89
+ feature[originalStyle] = feature.color.clone();
90
+ } else if (feature instanceof Feature) {
91
+ feature[originalStyle] = feature.getStyle();
92
+ }
93
+ }
94
+ }
95
+
96
+ /**
97
+ * @param {import("@vcmap/cesium").Cesium3DTileFeature|import("@vcmap/cesium").Cesium3DTilePointFeature|import("ol").Feature<import("ol/geom/Geometry").default>|import("@vcmap/cesium").Entity} feature
98
+ * @private
99
+ */
100
+ export function resetOriginalStyle(feature) {
101
+ if (!(feature[globalHidden] || feature[hidden] || feature[highlighted])) {
102
+ const style = feature[originalStyle];
103
+ if (
104
+ (feature instanceof Cesium3DTileFeature || feature instanceof Cesium3DTilePointFeature) &&
105
+ featureExists(feature)
106
+ ) {
107
+ feature.color = style;
108
+ } else if (feature instanceof Feature) {
109
+ feature.setStyle(style);
110
+ }
111
+ delete feature[originalStyle];
112
+ }
113
+ }
114
+
115
+ /**
116
+ * @param {import("@vcmap/cesium").Cesium3DTileFeature|import("@vcmap/cesium").Cesium3DTilePointFeature|import("ol").Feature<import("ol/geom/Geometry").default>|import("@vcmap/cesium").Entity} feature
117
+ * @private
118
+ */
119
+ export function highlightFeature(feature) {
120
+ if (!(feature[globalHidden] || feature[hidden])) {
121
+ const style = feature[highlighted];
122
+ if (
123
+ (feature instanceof Cesium3DTileFeature || feature instanceof Cesium3DTilePointFeature) &&
124
+ featureExists(feature)
125
+ ) {
126
+ feature.color = style.cesiumFillColor;
127
+ } else if (feature instanceof Feature) {
128
+ feature.setStyle(/** @type {import("ol/style/Style").default} */ (style.style));
129
+ }
130
+ }
131
+ }
132
+
133
+ /**
134
+ * Updates the cached original style
135
+ * @param {import("@vcmap/cesium").Cesium3DTileFeature|import("@vcmap/cesium").Cesium3DTilePointFeature|import("ol").Feature<import("ol/geom/Geometry").default>} feature
136
+ * @private
137
+ */
138
+ export function updateOriginalStyle(feature) {
139
+ delete feature[originalStyle];
140
+ cacheOriginalStyle(feature);
141
+ if (feature[hidden] || feature[globalHidden]) {
142
+ hideFeature(feature);
143
+ } else if (feature[highlighted]) {
144
+ highlightFeature(feature);
145
+ }
146
+ }
147
+
148
+ /**
149
+ * @param {import("@vcmap/cesium").Cesium3DTileFeature|import("@vcmap/cesium").Cesium3DTilePointFeature|import("ol").Feature<import("ol/geom/Geometry").default>} feature
150
+ */
151
+ function unhighlightFeature(feature) {
152
+ delete feature[highlighted];
153
+ resetOriginalStyle(feature);
154
+ }
155
+
156
+ /**
157
+ * @param {import("@vcmap/cesium").Cesium3DTileFeature|import("@vcmap/cesium").Cesium3DTilePointFeature|import("ol").Feature<import("ol/geom/Geometry").default>|import("@vcmap/cesium").Entity} feature
158
+ * @param {symbol} symbol
159
+ * @private
160
+ */
161
+ export function showFeature(feature, symbol) {
162
+ delete feature[symbol];
163
+
164
+ if (!(feature[hidden] || feature[globalHidden])) {
165
+ if (
166
+ (
167
+ (feature instanceof Cesium3DTileFeature || feature instanceof Cesium3DTilePointFeature) &&
168
+ featureExists(feature)
169
+ ) || feature instanceof CesiumEntity
170
+ ) {
171
+ feature.show = true;
172
+ }
173
+ if (feature[highlighted]) {
174
+ highlightFeature(feature);
175
+ } else {
176
+ resetOriginalStyle(feature);
177
+ }
178
+ }
179
+ }
180
+
181
+ /**
182
+ * Enumeration of feature visibility actions.
183
+ * @enum {number}
184
+ * @export
185
+ * @api
186
+ * @property {number} HIGHLIGHT
187
+ * @property {number} UNHIGHLIGHT
188
+ * @property {number} HIDE
189
+ * @property {number} SHOW
190
+ */
191
+ export const FeatureVisibilityAction = {
192
+ HIGHLIGHT: 1,
193
+ UNHIGHLIGHT: 2,
194
+ HIDE: 3,
195
+ SHOW: 4,
196
+ };
197
+
198
+ /**
199
+ * @param {FeatureVisibility} source
200
+ * @param {FeatureVisibility} destination
201
+ * @returns {Function}
202
+ */
203
+ export function synchronizeFeatureVisibility(source, destination) {
204
+ function handler({ action, ids }) {
205
+ if (action === FeatureVisibilityAction.HIGHLIGHT) {
206
+ /** @type {Object<string, VectorStyleItem>} */
207
+ const toHighlight = {};
208
+ ids.forEach((id) => {
209
+ toHighlight[id] = source.highlightedObjects[id].style;
210
+ });
211
+ destination.highlight(toHighlight);
212
+ } else if (action === FeatureVisibilityAction.UNHIGHLIGHT) {
213
+ destination.unHighlight(ids);
214
+ } else if (action === FeatureVisibilityAction.HIDE) {
215
+ destination.hideObjects(ids);
216
+ } else if (action === FeatureVisibilityAction.SHOW) {
217
+ destination.showObjects(ids);
218
+ }
219
+ }
220
+
221
+ const toHighlight = Object.keys(source.highlightedObjects);
222
+ if (toHighlight.length > 0) {
223
+ handler({ action: FeatureVisibilityAction.HIGHLIGHT, ids: toHighlight });
224
+ }
225
+
226
+ const toHide = Object.keys(source.hiddenObjects);
227
+ if (toHide.length > 0) {
228
+ handler({ action: FeatureVisibilityAction.HIDE, ids: toHide });
229
+ }
230
+
231
+ return source.changed.addEventListener(handler);
232
+ }
233
+
234
+ /**
235
+ * @class
236
+ */
237
+ class FeatureVisibility {
238
+ constructor() {
239
+ /** @type {Object<string, Set<(import("@vcmap/cesium").Cesium3DTileFeature|import("ol").Feature<import("ol/geom/Geometry").default>|import("@vcmap/cesium").Entity)>>} */
240
+ this.hiddenObjects = {};
241
+ /** @type {Object<string, HighlightedObject>} */
242
+ this.highlightedObjects = {};
243
+ /** @type {number} */
244
+ this.lastUpdated = Date.now();
245
+ /**
246
+ * An event raised when the hidden or highlighted ids change. Is called with
247
+ * {@link FeatureVisibilityEvent} as its only argument
248
+ * @type {VcsEvent<FeatureVisibilityEvent>}
249
+ */
250
+ this.changed = new VcsEvent();
251
+ }
252
+
253
+ /**
254
+ * highlights a number of features by ID (import("@vcmap/cesium").Cesium3DTileFeature|ol/Feature) with the given color.
255
+ * @param {Object<string, (VectorStyleItem|import("@vcmap/cesium").Color|import("ol/style/Style").default)>} toHighlight
256
+ * @api stable
257
+ */
258
+ highlight(toHighlight) {
259
+ const updatedIds = [];
260
+ Object.entries(toHighlight)
261
+ .forEach(([id, style]) => {
262
+ let usedStyle = style;
263
+ if (style instanceof Color) {
264
+ usedStyle = fromCesiumColor(style);
265
+ } else if (style instanceof Style) {
266
+ usedStyle = new VectorStyleItem({});
267
+ if (style.getText() && style.getText().getText()) {
268
+ usedStyle.label = style.getText().getText();
269
+ }
270
+ usedStyle.style = style;
271
+ }
272
+ // eslint-disable-next-line no-self-assign
273
+ usedStyle = /** @type {VectorStyleItem} */ (usedStyle);
274
+
275
+ if (!this.highlightedObjects[id]) {
276
+ this.highlightedObjects[id] = {
277
+ style: usedStyle,
278
+ features: new Set(),
279
+ };
280
+ updatedIds.push(id);
281
+ // @ts-ignore
282
+ } else if (this.highlightedObjects[id].style !== usedStyle) {
283
+ this.highlightedObjects[id].style = usedStyle;
284
+ this.highlightedObjects[id].features.forEach((s, feature) => {
285
+ feature[highlighted] = usedStyle;
286
+ highlightFeature(feature);
287
+ });
288
+ }
289
+ });
290
+
291
+ if (updatedIds.length > 0) {
292
+ this.lastUpdated = Date.now();
293
+ this.changed.raiseEvent({ action: FeatureVisibilityAction.HIGHLIGHT, ids: updatedIds });
294
+ }
295
+ }
296
+
297
+ /**
298
+ * unhighlights a number of features given by the ID (import("@vcmap/cesium").Cesium3DTileFeature|import("ol").Feature<import("ol/geom/Geometry").default>)
299
+ * @param {Array<string>} toUnHighlight Array with IDS to unhighlight
300
+ * @api stable
301
+ */
302
+ unHighlight(toUnHighlight) {
303
+ const updatedIds = [];
304
+ toUnHighlight.forEach((id) => {
305
+ if (this.highlightedObjects[id]) {
306
+ this.highlightedObjects[id].features
307
+ .forEach((f) => {
308
+ unhighlightFeature(f);
309
+ });
310
+ delete this.highlightedObjects[id];
311
+ updatedIds.push(id);
312
+ }
313
+ });
314
+
315
+ if (updatedIds.length > 0) {
316
+ this.changed.raiseEvent({ action: FeatureVisibilityAction.UNHIGHLIGHT, ids: updatedIds });
317
+ }
318
+ }
319
+
320
+ /**
321
+ * clears all highlighted objects
322
+ * @api stable
323
+ */
324
+ clearHighlighting() {
325
+ this.unHighlight(Object.keys(this.highlightedObjects));
326
+ }
327
+
328
+ /**
329
+ * @param {string|number} id
330
+ * @param {import("ol").Feature<import("ol/geom/Geometry").default>|import("@vcmap/cesium").Cesium3DTileFeature} feature
331
+ * @returns {boolean}
332
+ */
333
+ hasHighlightFeature(id, feature) {
334
+ return this.highlightedObjects[id] && this.highlightedObjects[id].features.has(feature);
335
+ }
336
+
337
+ /**
338
+ * @param {string|number} id
339
+ * @param {import("ol").Feature<import("ol/geom/Geometry").default>|import("@vcmap/cesium").Cesium3DTileFeature} feature
340
+ */
341
+ addHighlightFeature(id, feature) {
342
+ if (this.highlightedObjects[id]) {
343
+ cacheOriginalStyle(feature);
344
+ this.highlightedObjects[id].features.add(feature);
345
+ feature[highlighted] = this.highlightedObjects[id].style;
346
+ highlightFeature(feature);
347
+ }
348
+ }
349
+
350
+ /**
351
+ * hides a number of objects
352
+ * @param {Array<string|number>} toHide A list of Object Ids which will be hidden
353
+ * @api stable
354
+ */
355
+ hideObjects(toHide) {
356
+ const updatedIds = [];
357
+ toHide.forEach((id) => {
358
+ if (!this.hiddenObjects[id]) {
359
+ this.hiddenObjects[id] = new Set();
360
+ updatedIds.push(id);
361
+ }
362
+ });
363
+
364
+ if (updatedIds.length > 0) {
365
+ this.lastUpdated = Date.now();
366
+ this.changed.raiseEvent({ action: FeatureVisibilityAction.HIDE, ids: updatedIds });
367
+ }
368
+ }
369
+
370
+ /**
371
+ * unHides a number of objects
372
+ * @param {Array<string|number>} unHide A list of Object Ids which will be unHidden
373
+ * @api stable
374
+ */
375
+ showObjects(unHide) {
376
+ const updatedIds = [];
377
+ unHide.forEach((id) => {
378
+ if (this.hiddenObjects[id]) {
379
+ this.hiddenObjects[id]
380
+ .forEach((f) => {
381
+ showFeature(f, hidden);
382
+ });
383
+ delete this.hiddenObjects[id];
384
+ updatedIds.push(id);
385
+ }
386
+ });
387
+
388
+ if (updatedIds.length > 0) {
389
+ this.changed.raiseEvent({ action: FeatureVisibilityAction.SHOW, ids: updatedIds });
390
+ }
391
+ }
392
+
393
+ /**
394
+ * clears all the hidden objects
395
+ * @api stable
396
+ */
397
+ clearHiddenObjects() {
398
+ this.showObjects(Object.keys(this.hiddenObjects));
399
+ }
400
+
401
+ /**
402
+ * @param {string|number} id
403
+ * @param {import("ol").Feature<import("ol/geom/Geometry").default>|import("@vcmap/cesium").Cesium3DTileFeature|import("@vcmap/cesium").Entity} feature
404
+ * @returns {boolean}
405
+ */
406
+ hasHiddenFeature(id, feature) {
407
+ return this.hiddenObjects[id] && this.hiddenObjects[id].has(feature);
408
+ }
409
+
410
+ /**
411
+ * @param {string|number} id
412
+ * @param {import("ol").Feature<import("ol/geom/Geometry").default>|import("@vcmap/cesium").Cesium3DTileFeature|import("@vcmap/cesium").Entity} feature
413
+ */
414
+ addHiddenFeature(id, feature) {
415
+ if (this.hiddenObjects[id]) {
416
+ cacheOriginalStyle(feature);
417
+ this.hiddenObjects[id].add(feature);
418
+ feature[hidden] = true;
419
+ hideFeature(feature);
420
+ }
421
+ }
422
+
423
+ /**
424
+ * Clears all caches and removes cesium events.
425
+ */
426
+ destroy() {
427
+ Object.values(this.hiddenObjects).forEach((s) => { s.clear(); });
428
+ this.hiddenObjects = {};
429
+ Object.values(this.highlightedObjects).forEach(({ features }) => { features.clear(); });
430
+ this.highlightedObjects = {};
431
+ this.changed.destroy();
432
+ }
433
+ }
434
+
435
+ export default FeatureVisibility;
@@ -0,0 +1,185 @@
1
+ import axios from 'axios';
2
+ import Vector from './vector.js';
3
+ import { parseGeoJSON, writeGeoJSONFeature } from './geojsonHelpers.js';
4
+ import Projection, { wgs84Projection } from '../util/projection.js';
5
+ import { VcsClassRegistry } from '../classRegistry.js';
6
+
7
+ /**
8
+ * @typedef {VectorOptions} GeoJSONOptions
9
+ * @property {Array<Object>|undefined} features - an array of GeoJSON features to parse
10
+ * @api
11
+ */
12
+
13
+ /**
14
+ * indicates, that this feature is part of the options
15
+ * @type {symbol}
16
+ */
17
+ export const featureFromOptions = Symbol('featureFromOptions');
18
+
19
+
20
+ /**
21
+ * GeoJSON layer for Cesium, Openlayers and Oblique
22
+ * @class
23
+ * @export
24
+ * @extends {Vector}
25
+ * @api stable
26
+ */
27
+ class GeoJSON extends Vector {
28
+ static get className() { return 'vcs.vcm.layer.GeoJSON'; }
29
+
30
+ /**
31
+ * @returns {GeoJSONOptions}
32
+ */
33
+ static getDefaultOptions() {
34
+ return {
35
+ ...Vector.getDefaultOptions(),
36
+ projection: wgs84Projection.getConfigObject(),
37
+ features: undefined,
38
+ };
39
+ }
40
+
41
+ /**
42
+ * @param {GeoJSONOptions} options
43
+ */
44
+ constructor(options) {
45
+ const defaultOptions = GeoJSON.getDefaultOptions();
46
+ options.projection = options.projection || defaultOptions.projection;
47
+
48
+ super(options);
49
+
50
+ /**
51
+ * @type {Promise<void>|null}
52
+ * @private
53
+ */
54
+ this._dataFetchedPromise = null;
55
+ /**
56
+ * @type {Array<Object>}
57
+ * @private
58
+ */
59
+ this._featuresToLoad = options.features || defaultOptions.features;
60
+ }
61
+
62
+ /**
63
+ * @inheritDoc
64
+ * @returns {Promise<void>}
65
+ */
66
+ async initialize() {
67
+ if (!this.initialized) {
68
+ await this.fetchData();
69
+ }
70
+ return super.initialize();
71
+ }
72
+
73
+ /**
74
+ * @inheritDoc
75
+ * @returns {Promise<void>}
76
+ */
77
+ async reload() {
78
+ if (this._dataFetchedPromise) {
79
+ const configFeatures = this.getFeatures().filter(f => f[featureFromOptions]);
80
+ this.removeAllFeatures();
81
+ this.source.addFeatures(configFeatures);
82
+ this._dataFetchedPromise = null;
83
+ await this.fetchData();
84
+ }
85
+ return super.reload();
86
+ }
87
+
88
+ /**
89
+ * Fetches the data for the layer. If data is already fetched returns a resolved Promise
90
+ * @returns {Promise<void>}
91
+ * @api
92
+ */
93
+ fetchData() {
94
+ if (this._dataFetchedPromise) {
95
+ return this._dataFetchedPromise;
96
+ }
97
+
98
+ if (Array.isArray(this._featuresToLoad)) {
99
+ this._parseGeojsonData({
100
+ type: 'FeatureCollection',
101
+ features: this._featuresToLoad,
102
+ });
103
+
104
+ this.getFeatures()
105
+ .forEach((f) => {
106
+ f[featureFromOptions] = true;
107
+ });
108
+
109
+ this._featuresToLoad.splice(0);
110
+ this._featuresToLoad = undefined;
111
+ }
112
+
113
+ if (this.url) {
114
+ this._dataFetchedPromise = axios.get(this.url)
115
+ .then((response) => {
116
+ this._parseGeojsonData(response.data);
117
+ })
118
+ .catch((err) => {
119
+ this.getLogger().warning(`Could not send request for loading layer content (${err.message})`);
120
+ return Promise.reject(err);
121
+ });
122
+ } else {
123
+ this._dataFetchedPromise = Promise.resolve();
124
+ }
125
+ return this._dataFetchedPromise;
126
+ }
127
+
128
+ /**
129
+ * @param {Object} obj
130
+ * @private
131
+ */
132
+ _parseGeojsonData(obj) {
133
+ const data = parseGeoJSON(obj, {
134
+ dataProjection: this.projection,
135
+ dynamicStyle: true,
136
+ });
137
+ this.addFeatures(data.features);
138
+ if (data.style) {
139
+ this.setStyle(data.style);
140
+ }
141
+ if (data.vcsMeta) {
142
+ // configured layer vectorProperties trumps vectorProperties from geojson file;
143
+ const meta = { ...data.vcsMeta, ...this.vectorProperties.getVcsMeta() };
144
+ this.setVcsMeta(meta);
145
+ }
146
+ }
147
+
148
+ /**
149
+ * @inheritDoc
150
+ * @returns {GeoJSONOptions}
151
+ */
152
+ getConfigObject() {
153
+ const config = /** @type {GeoJSONOptions} */ (super.getConfigObject());
154
+ const defaultOptions = GeoJSON.getDefaultOptions();
155
+
156
+ const defaultProjection = new Projection(defaultOptions.projection);
157
+ if (!this.projection.equals(defaultProjection)) {
158
+ config.projection = this.projection.getConfigObject();
159
+ } else {
160
+ delete config.projection;
161
+ }
162
+
163
+ if (Array.isArray(this._featuresToLoad)) {
164
+ config.features = this._featuresToLoad.slice();
165
+ } else {
166
+ const features = this.getFeatures().filter(f => f[featureFromOptions]);
167
+ if (features.length > 0) {
168
+ config.features = features.map(f => writeGeoJSONFeature(f, { writeStyle: true, writeId: true }));
169
+ }
170
+ }
171
+
172
+ return config;
173
+ }
174
+
175
+ /**
176
+ * @inheritDoc
177
+ */
178
+ destroy() {
179
+ super.destroy();
180
+ this._featuresToLoad = undefined;
181
+ }
182
+ }
183
+
184
+ VcsClassRegistry.registerClass(GeoJSON.className, GeoJSON);
185
+ export default GeoJSON;