@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,40 @@
1
+ /**
2
+ * Attached to a geometry to indicate, it is already in mercator and not the layers default projection
3
+ * @type {symbol}
4
+ * @const
5
+ */
6
+ export const alreadyTransformedToMercator = Symbol('alreadyTransformedToMercator');
7
+
8
+ /**
9
+ * Attached to a geometry to indicate, it is already in oblique image coordiantes and not mercator
10
+ * @type {symbol}
11
+ * @const
12
+ */
13
+ export const alreadyTransformedToImage = Symbol('alreadyTransformedToImage');
14
+
15
+ /**
16
+ * Attached to an ol/Feature to reference the underlying oblique geometry
17
+ * @type {symbol}
18
+ * @const
19
+ */
20
+ export const obliqueGeometry = Symbol('obliqueGeometry');
21
+
22
+ /**
23
+ * Attached to an ol/Feature which should only exist in oblqie coordinates and not be transformed to mercator on change
24
+ * @type {symbol}
25
+ * @const
26
+ */
27
+ export const doNotTransform = Symbol('doNotTransform');
28
+
29
+ /**
30
+ * Attached to oblique features to reference the underlying original ol/Feature
31
+ * @type {symbol}
32
+ */
33
+ export const originalFeatureSymbol = Symbol('OriginalFeature');
34
+
35
+ /**
36
+ * Attached to mercator or oblique geometries which are polygons but have a circular counterpart. Used to not
37
+ * mess up circle drawing in oblique
38
+ * @type {symbol}
39
+ */
40
+ export const actuallyIsCircle = Symbol('ActuallyIsCircle');
@@ -0,0 +1,480 @@
1
+ import Style from 'ol/style/Style.js';
2
+ import { parseInteger } from '@vcsuite/parsers';
3
+ import CesiumMap from '../maps/cesium.js';
4
+ import VectorRasterTileCesium from './cesium/vectorRasterTileCesium.js';
5
+ import Openlayers from '../maps/openlayers.js';
6
+ import VectorTileOpenlayers from './openlayers/vectorTileOpenlayers.js';
7
+ import FeatureLayer from './featureLayer.js';
8
+ import VectorStyleItem, { defaultVectorStyle } from '../util/style/vectorStyleItem.js';
9
+ import VectorProperties from './vectorProperties.js';
10
+ import DeclarativeStyleItem from '../util/style/declarativeStyleItem.js';
11
+ import { FeatureVisibilityAction, globalHidden, hidden, highlighted } from './featureVisibility.js';
12
+ import { getStylesArray } from '../util/featureconverter/convert.js';
13
+ import { vcsLayerName } from './layerSymbols.js';
14
+ import TileProviderFeatureProvider from '../util/featureProvider/tileProviderFeatureProvider.js';
15
+ import tileProviderFactory from './tileProvider/tileProviderFactory.js';
16
+ import { getGenericFeatureFromClickedObject } from './vectorHelpers.js';
17
+ import { originalFeatureSymbol } from './vectorSymbols.js';
18
+ import { VcsClassRegistry } from '../classRegistry.js';
19
+
20
+ /**
21
+ * synchronizes featureVisibility Symbols on the feature;
22
+ * @param {import("@vcmap/core").FeatureVisibility} featureVisibility
23
+ * @param {import("@vcmap/core").GlobalHider} globalHider
24
+ * @param {import("ol").Feature<import("ol/geom/Geometry").default>} feature
25
+ */
26
+ function synchronizeFeatureVisibility(featureVisibility, globalHider, feature) {
27
+ const featureId = feature.getId();
28
+ if (featureVisibility.hiddenObjects[featureId]) {
29
+ feature[hidden] = true;
30
+ } else if (feature[hidden]) {
31
+ delete feature[hidden];
32
+ }
33
+ if (featureVisibility.highlightedObjects[featureId]) {
34
+ feature[highlighted] = featureVisibility.highlightedObjects[featureId].style;
35
+ } else if (feature[highlighted]) {
36
+ delete feature[highlighted];
37
+ }
38
+ if (globalHider.hiddenObjects[featureId]) {
39
+ feature[globalHidden] = true;
40
+ } else if (feature[globalHidden]) {
41
+ delete feature[globalHidden];
42
+ }
43
+ }
44
+
45
+ /**
46
+ * @typedef {FeatureLayerOptions} VectorTileOptions
47
+ * @property {TileProviderOptions} tileProvider
48
+ * @property {VectorStyleItemOptions|import("@vcmap/core").VectorStyleItem|undefined} highlightStyle
49
+ * @property {VectorPropertiesOptions|undefined} vectorProperties
50
+ * @property {number|undefined} minLevel used to restrict the zoom level visibility (minlevel does not allow rendering above tileProvider baseLevel)
51
+ * @property {number|undefined} maxLevel used to restrict the zoom level visibility
52
+ * @api
53
+ */
54
+
55
+ /**
56
+ * @typedef {FeatureLayerImplementationOptions} VectorTileImplementationOptions
57
+ * @property {import("@vcmap/core").TileProvider} tileProvider
58
+ * @property {import("ol/size").Size} tileSize
59
+ * @property {number} minLevel
60
+ * @property {number} maxLevel
61
+ * @property {import("@vcmap/core").Extent|undefined} extent
62
+ */
63
+
64
+ /**
65
+ * @typedef {FeatureLayerImplementation} VectorTileImplementation
66
+ * @property {function(Array<string>):void} updateTiles
67
+ */
68
+
69
+ /**
70
+ * VectorTile Layer for tiled vector Data. Can be connected to data with a TileProvider
71
+ * @class
72
+ * @export
73
+ * @extends {FeatureLayer}
74
+ * @api stable
75
+ */
76
+ class VectorTile extends FeatureLayer {
77
+ /**
78
+ * @readonly
79
+ * @returns {string}
80
+ */
81
+ static get className() { return 'vcs.vcm.layer.VectorTile'; }
82
+
83
+ /**
84
+ * @returns {VectorTileOptions}
85
+ */
86
+ static getDefaultOptions() {
87
+ return {
88
+ ...FeatureLayer.getDefaultOptions(),
89
+ tileProvider: undefined,
90
+ highlightStyle: undefined,
91
+ vectorProperties: {},
92
+ minLevel: undefined,
93
+ maxLevel: undefined,
94
+ };
95
+ }
96
+
97
+
98
+ /**
99
+ * @param {VectorTileOptions} options
100
+ */
101
+ constructor(options) {
102
+ super(options);
103
+
104
+ this._supportedMaps = [
105
+ CesiumMap.className,
106
+ Openlayers.className,
107
+ ];
108
+
109
+ const defaultOptions = VectorTile.getDefaultOptions();
110
+
111
+ /** @type {VectorStyleItem} */
112
+ this.highlightStyle = /** @type {undefined} */ (defaultOptions.highlightStyle);
113
+ if (options.highlightStyle) {
114
+ this.highlightStyle = options.highlightStyle instanceof VectorStyleItem ?
115
+ options.highlightStyle :
116
+ new VectorStyleItem(options.highlightStyle);
117
+ }
118
+
119
+ /**
120
+ * @type {import("ol/size").Size}
121
+ * @private
122
+ */
123
+ this._tileSize = [256, 256];
124
+
125
+ /**
126
+ * at the moment only used for allowPicking, triggers a reload on change
127
+ * @type {VectorProperties}
128
+ * @api
129
+ */
130
+ this.vectorProperties = new VectorProperties({
131
+ allowPicking: this.allowPicking,
132
+ ...options.vectorProperties,
133
+ });
134
+
135
+ /**
136
+ * @type {TileProviderOptions}
137
+ * @private
138
+ */
139
+ this._tileProviderOptions = options.tileProvider;
140
+
141
+ /**
142
+ * @type {import("@vcmap/core").TileProvider}
143
+ * @api
144
+ */
145
+ this.tileProvider = undefined;
146
+
147
+ /**
148
+ * @type {number|undefined}
149
+ * @private
150
+ */
151
+ this._maxLevel = parseInteger(options.maxLevel, defaultOptions.maxLevel);
152
+
153
+ /**
154
+ * @type {number|undefined}
155
+ * @private
156
+ */
157
+ this._minLevel = parseInteger(options.minLevel, defaultOptions.minLevel);
158
+
159
+ /**
160
+ * @type {Array<Function>}
161
+ * @private
162
+ */
163
+ this._featureVisibilityListener = [];
164
+
165
+ /**
166
+ * @type {Function}
167
+ * @private
168
+ */
169
+ this._tileLoadEventListener = () => {};
170
+
171
+ /**
172
+ * @type {Function}
173
+ * @private
174
+ */
175
+ this._vectorPropertiesChangedListener = () => {};
176
+
177
+ /**
178
+ * zIndex for features with featureStyle // Do we maybe need a global counter ?
179
+ * @type {number}
180
+ * @private
181
+ */
182
+ this._styleZIndex = 0;
183
+ }
184
+
185
+ /**
186
+ * initializes the layer, can be used to defer loading
187
+ * @returns {Promise<void>}
188
+ */
189
+ async initialize() {
190
+ await super.initialize();
191
+ if (!this.tileProvider) {
192
+ this.tileProvider = await tileProviderFactory(this._tileProviderOptions);
193
+ // this.tileProvider = await tileProviderFactory(this._tileProviderOptions);
194
+ this._tileLoadEventListener =
195
+ this.tileProvider.tileLoadedEvent.addEventListener(event => this._handleTileLoaded(event));
196
+ this._vectorPropertiesChangedListener =
197
+ this.vectorProperties.propertyChanged.addEventListener(() => {
198
+ this.reload();
199
+ });
200
+ this.featureProvider = new TileProviderFeatureProvider(this.name, {
201
+ tileProvider: this.tileProvider,
202
+ vectorProperties: this.vectorProperties,
203
+ });
204
+ }
205
+ }
206
+
207
+
208
+ /**
209
+ * @param {import("ol").Feature<import("ol/geom/Geometry").default>} olFeature
210
+ * @returns {?Object}
211
+ */
212
+ objectClickedHandler(olFeature) {
213
+ const actualFeature = olFeature[originalFeatureSymbol] || olFeature;
214
+ if (this.vectorProperties.getAllowPicking(actualFeature)) {
215
+ if (olFeature[hidden] || olFeature[globalHidden]) {
216
+ return null;
217
+ }
218
+ return {
219
+ id: actualFeature.getId(),
220
+ feature: actualFeature,
221
+ };
222
+ }
223
+ return null;
224
+ }
225
+
226
+ /**
227
+ * @param {VectorClickedObject} object
228
+ * @returns {?GenericFeature}
229
+ */
230
+ getGenericFeatureFromClickedObject(object) {
231
+ return getGenericFeatureFromClickedObject(object, this);
232
+ }
233
+
234
+ /**
235
+ * @returns {number}
236
+ * @private
237
+ */
238
+ _getNextStyleZIndex() {
239
+ this._styleZIndex += 1;
240
+ return this._styleZIndex;
241
+ }
242
+
243
+ /**
244
+ * @param {TileLoadedEvent} event
245
+ * @private
246
+ */
247
+ _handleTileLoaded({ rtree }) {
248
+ rtree.all().map(item => item.value).forEach((feature) => {
249
+ const featureStyle = /** @type {import("ol/style/Style").default} */ (feature.getStyle());
250
+ if (featureStyle && featureStyle instanceof Style) {
251
+ featureStyle.setZIndex(this._getNextStyleZIndex());
252
+ }
253
+ feature[vcsLayerName] = this.name;
254
+ feature.getStyleFunction = () => {
255
+ return this._featureStyle.bind(this);
256
+ };
257
+ if (this.tileProvider.trackFeaturesToTiles) {
258
+ synchronizeFeatureVisibility(this.featureVisibility, this.globalHider, feature);
259
+ }
260
+ });
261
+ }
262
+
263
+ /**
264
+ *
265
+ * @returns {Array<Function>}
266
+ * @private
267
+ */
268
+ _setupFeatureVisibilityHandlers() {
269
+ if (!this.tileProvider.trackFeaturesToTiles) {
270
+ return [];
271
+ }
272
+ return [
273
+ this.featureVisibility.changed.addEventListener(({ action, ids }) => {
274
+ const tileIdsChanged = new Set();
275
+ ids.forEach((id) => {
276
+ const tileIds = this.tileProvider.featureIdToTileIds.get(id);
277
+ if (tileIds) {
278
+ tileIds.forEach((tileId) => {
279
+ const rtree = this.tileProvider.rtreeCache.get(tileId);
280
+ const tileProviderRTreeEntry = rtree.all().find(item => item.value.getId() === id);
281
+ if (tileProviderRTreeEntry) {
282
+ const feature = tileProviderRTreeEntry.value;
283
+ tileIdsChanged.add(tileId);
284
+ if (action === FeatureVisibilityAction.HIGHLIGHT) {
285
+ feature[highlighted] = this.featureVisibility.highlightedObjects[id].style;
286
+ } else if (action === FeatureVisibilityAction.UNHIGHLIGHT) {
287
+ delete feature[highlighted];
288
+ } else if (action === FeatureVisibilityAction.HIDE) {
289
+ feature[hidden] = true;
290
+ } else if (action === FeatureVisibilityAction.SHOW) {
291
+ delete feature[hidden];
292
+ }
293
+ }
294
+ });
295
+ }
296
+ });
297
+ this.updateTiles([...tileIdsChanged]);
298
+ }),
299
+
300
+ this.globalHider.changed.addEventListener(({ action, ids }) => {
301
+ const tileIdsChanged = new Set();
302
+ ids.forEach((id) => {
303
+ const tileIds = this.tileProvider.featureIdToTileIds.get(id);
304
+ if (tileIds) {
305
+ tileIds.forEach((tileId) => {
306
+ const rtree = this.tileProvider.rtreeCache.get(tileId);
307
+ const tileProviderRTreeEntry = rtree.all().find(item => item.value.getId() === id);
308
+ if (tileProviderRTreeEntry) {
309
+ const feature = tileProviderRTreeEntry.value;
310
+ tileIdsChanged.add(tileId);
311
+ if (action === FeatureVisibilityAction.HIDE) {
312
+ feature[globalHidden] = true;
313
+ } else if (action === FeatureVisibilityAction.SHOW) {
314
+ delete feature[globalHidden];
315
+ }
316
+ }
317
+ });
318
+ }
319
+ });
320
+ this.updateTiles([...tileIdsChanged]);
321
+ }),
322
+ ];
323
+ }
324
+
325
+ /**
326
+ * rerenders the specified tiles
327
+ * rendering happens async
328
+ * @param {Array<string>} tileIds
329
+ * @api
330
+ */
331
+ updateTiles(tileIds) {
332
+ this.getImplementations()
333
+ .forEach((impl) => {
334
+ /** @type {VectorTileImplementation} */ (impl).updateTiles(tileIds);
335
+ });
336
+ }
337
+
338
+ /**
339
+ * calculates the style the feature has to be rendered
340
+ * @param {import("ol").Feature<import("ol/geom/Geometry").default>} feature
341
+ * @param {number} resolution
342
+ * @returns {Array<import("ol/style/Style").default>}
343
+ * @private
344
+ */
345
+ _featureStyle(feature, resolution) {
346
+ let style;
347
+ if (feature[hidden] || feature[globalHidden]) {
348
+ return [];
349
+ }
350
+ if (feature[highlighted]) { // priority highlighted features
351
+ ({ style } = feature[highlighted]);
352
+ } else if (this.style instanceof DeclarativeStyleItem) { // if declarative use layerStyle
353
+ ({ style } = this.style);
354
+ } else { // if vectorStyle use featureStyle
355
+ style = feature.getStyle() || this.style.style;
356
+ }
357
+ return getStylesArray(style, feature, resolution);
358
+ }
359
+
360
+ /**
361
+ * @returns {VectorTileImplementationOptions}
362
+ */
363
+ getImplementationOptions() {
364
+ return {
365
+ ...super.getImplementationOptions(),
366
+ tileProvider: this.tileProvider,
367
+ tileSize: this._tileSize,
368
+ minLevel: this._minLevel,
369
+ maxLevel: this._maxLevel,
370
+ extent: this.extent,
371
+ };
372
+ }
373
+
374
+
375
+ /**
376
+ * @inheritDoc
377
+ * @param {import("@vcmap/core").VcsMap} map
378
+ * @returns {Array<VectorRasterTileCesium|VectorTileOpenlayers>}
379
+ */
380
+ createImplementationsForMap(map) {
381
+ if (map instanceof CesiumMap) {
382
+ return [new VectorRasterTileCesium(map, this.getImplementationOptions())];
383
+ }
384
+
385
+ if (map instanceof Openlayers) {
386
+ return [
387
+ new VectorTileOpenlayers(map, this.getImplementationOptions()),
388
+ ];
389
+ }
390
+
391
+ return [];
392
+ }
393
+
394
+ /**
395
+ * @param {(Reference|DeclarativeStyleItemOptions|VectorStyleItemOptions|import("@vcmap/core").StyleItem|string)=} styleOptions
396
+ * @param {VectorStyleItem=} defaultStyle
397
+ * @returns {import("@vcmap/core").StyleItem}
398
+ */
399
+ getStyleOrDefaultStyle(styleOptions, defaultStyle) {
400
+ return super.getStyleOrDefaultStyle(styleOptions, defaultStyle || defaultVectorStyle.clone());
401
+ }
402
+
403
+ /**
404
+ * @inheritDoc
405
+ * @returns {Promise<void>}
406
+ * @api stable
407
+ */
408
+ async activate() {
409
+ await super.activate();
410
+ this._featureVisibilityListener = this._setupFeatureVisibilityHandlers();
411
+ if (this.tileProvider.trackFeaturesToTiles) {
412
+ this.tileProvider.forEachFeature((feature) => {
413
+ synchronizeFeatureVisibility(this.featureVisibility, this.globalHider, feature);
414
+ });
415
+ }
416
+ }
417
+
418
+ /**
419
+ * @inheritDoc
420
+ * @api
421
+ */
422
+ deactivate() {
423
+ super.deactivate();
424
+ this._featureVisibilityListener.forEach((cb) => { cb(); });
425
+ }
426
+
427
+ /**
428
+ * @inheritDoc
429
+ * @api
430
+ */
431
+ destroy() {
432
+ this._featureVisibilityListener.forEach((cb) => { cb(); });
433
+ super.destroy();
434
+ this._tileLoadEventListener();
435
+ if (this.featureProvider) {
436
+ this.featureProvider.destroy();
437
+ }
438
+ if (this.tileProvider) {
439
+ this.tileProvider.destroy();
440
+ }
441
+ this._vectorPropertiesChangedListener();
442
+ if (this.vectorProperties) {
443
+ this.vectorProperties.destroy();
444
+ }
445
+ }
446
+
447
+ /**
448
+ * @inheritDoc
449
+ * @returns {VectorTileOptions}
450
+ */
451
+ getConfigObject() {
452
+ const config = /** @type {VectorTileOptions} */ (super.getConfigObject());
453
+ const defaultOptions = VectorTile.getDefaultOptions();
454
+
455
+ if (this._maxLevel !== defaultOptions.maxLevel) {
456
+ config.maxLevel = this._maxLevel;
457
+ }
458
+
459
+ if (this._minLevel !== defaultOptions.minLevel) {
460
+ config.minLevel = this._minLevel;
461
+ }
462
+
463
+ const vectorPropertiesConfig = this.vectorProperties.getVcsMeta();
464
+ if (Object.keys(vectorPropertiesConfig).length > 0) {
465
+ config.vectorProperties = vectorPropertiesConfig;
466
+ }
467
+
468
+ if (this.tileProvider) {
469
+ const tileProviderConfig = this.tileProvider.getConfigObject();
470
+ config.tileProvider = tileProviderConfig;
471
+ } else if (this._tileProviderOptions) {
472
+ config.tileProvider = this._tileProviderOptions;
473
+ }
474
+
475
+ return config;
476
+ }
477
+ }
478
+
479
+ VcsClassRegistry.registerClass(VectorTile.className, VectorTile);
480
+ export default VectorTile;
@@ -0,0 +1,165 @@
1
+ import WFSFormat from 'ol/format/WFS.js';
2
+ import axios from 'axios';
3
+ import Vector from './vector.js';
4
+ import Projection from '../util/projection.js';
5
+ import { VcsClassRegistry } from '../classRegistry.js';
6
+
7
+ /**
8
+ * @typedef {VectorOptions} WFSOptions
9
+ * @property {string|Array<string>} featureType - required parameter of the featureType to load. Supply an array for multiples
10
+ * @property {string} featureNS - required parameter, namespace used for the feature prefix
11
+ * @property {string} featurePrefix - required parameter, feature prefix
12
+ * @property {Object|undefined} getFeatureOptions - additional config for [ol/format/WFS/writeGetFeature]{@link https://openlayers.org/en/latest/apidoc/ol.format.WFS.html} excluding featureType, featureNS and featurePrefix
13
+ * @api
14
+ */
15
+
16
+ /**
17
+ * WFS Vector Layer
18
+ * @class
19
+ * @export
20
+ * @extends {Vector}
21
+ * @api
22
+ */
23
+ class WFS extends Vector {
24
+ static get className() { return 'vcs.vcm.layer.WFS'; }
25
+
26
+ /**
27
+ * @returns {WFSOptions}
28
+ */
29
+ static getDefaultOptions() {
30
+ return {
31
+ ...Vector.getDefaultOptions(),
32
+ featureType: [],
33
+ featureNS: '',
34
+ featurePrefix: '',
35
+ getFeatureOptions: {},
36
+ };
37
+ }
38
+
39
+ /**
40
+ * @param {WFSOptions} options
41
+ */
42
+ constructor(options) {
43
+ const proj = new Projection(options.projection).getConfigObject();
44
+ proj.alias = [`http://www.opengis.net/gml/srs/epsg.xml#${/** @type {string} */ (proj.epsg).match(/\d+/)[0]}`];
45
+ options.projection = proj;
46
+ super(options);
47
+
48
+ /** @type {Array<string>} */
49
+ this.featureType = Array.isArray(options.featureType) ? options.featureType : [options.featureType];
50
+
51
+ /**
52
+ * @type {string}
53
+ * @todo should this not be an Object with definition and prefix?
54
+ */
55
+ this.featureNS = options.featureNS;
56
+
57
+ /** @type {string} */
58
+ this.featurePrefix = options.featurePrefix;
59
+
60
+ /** @type {!Object} */
61
+ this.getFeaturesOptions = options.getFeatureOptions || {};
62
+
63
+ /** @type {import("ol/format/WFS").default} */
64
+ this.wfsFormat = new WFSFormat({
65
+ featureNS: this.featureNS,
66
+ featureType: this.featureType,
67
+ });
68
+
69
+ /**
70
+ * @type {Promise<void>|null}
71
+ * @private
72
+ */
73
+ this._dataFetchedPromise = null;
74
+ }
75
+
76
+ /**
77
+ * @inheritDoc
78
+ * @returns {Promise<void>}
79
+ */
80
+ async initialize() {
81
+ if (!this.initialized) {
82
+ await this.fetchData();
83
+ }
84
+ return super.initialize();
85
+ }
86
+
87
+ /**
88
+ * @inheritDoc
89
+ * @returns {Promise<void>}
90
+ */
91
+ async reload() {
92
+ if (this._dataFetchedPromise) {
93
+ this.removeAllFeatures();
94
+ this._dataFetchedPromise = null;
95
+ await this.fetchData();
96
+ }
97
+ return super.reload();
98
+ }
99
+
100
+ /**
101
+ * Fetches the data for the layer. If data is already fetched returns a resolved Promise
102
+ * @returns {Promise<void>}
103
+ * @api
104
+ */
105
+ fetchData() {
106
+ if (this._dataFetchedPromise) {
107
+ return this._dataFetchedPromise;
108
+ }
109
+ if (this.url != null) {
110
+ const requestDocument = this.wfsFormat
111
+ .writeGetFeature(/** @type {import("ol/format/WFS").WriteGetFeatureOptions} */ ({
112
+ featureNS: this.featureNS,
113
+ featurePrefix: this.featurePrefix,
114
+ featureTypes: this.featureType,
115
+ srsName: this.projection.epsg,
116
+ ...this.getFeaturesOptions,
117
+ }));
118
+ const postData = new XMLSerializer().serializeToString(requestDocument);
119
+ this._dataFetchedPromise = axios.post(this.url, postData, {
120
+ headers: {
121
+ 'Content-Type': 'application/text+xml',
122
+ },
123
+ })
124
+ .then((response) => {
125
+ this._parseWFSData(response.data);
126
+ })
127
+ .catch((err) => {
128
+ this.getLogger().info(`Could not send request for loading layer content (${err.message})`);
129
+ return Promise.reject(err);
130
+ });
131
+
132
+ return this._dataFetchedPromise;
133
+ }
134
+ this.getLogger().warning('Could not load WFS layer, no url is set');
135
+ return Promise.reject(new Error('missing url in WFS layer'));
136
+ }
137
+
138
+ /**
139
+ * @param {Element} obj
140
+ * @private
141
+ */
142
+ _parseWFSData(obj) {
143
+ const features = this.wfsFormat.readFeatures(obj);
144
+ this.addFeatures(features);
145
+ }
146
+
147
+ /**
148
+ * @inheritDoc
149
+ * @returns {WFSOptions}
150
+ */
151
+ getConfigObject() {
152
+ const config = /** @type {WFSOptions} */ (super.getConfigObject());
153
+
154
+ config.featureType = this.featureType.slice();
155
+ config.featureNS = this.featureNS;
156
+ config.featurePrefix = this.featurePrefix;
157
+ if (Object.keys(this.getFeaturesOptions).length > 0) {
158
+ config.getFeatureOptions = this.getFeaturesOptions;
159
+ }
160
+ return config;
161
+ }
162
+ }
163
+
164
+ VcsClassRegistry.registerClass(WFS.className, WFS);
165
+ export default WFS;