@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,280 @@
1
+ import axios from 'axios';
2
+ import GML2 from 'ol/format/GML2.js';
3
+ import WFS from 'ol/format/WFS.js';
4
+ import GeoJSON from 'ol/format/GeoJSON.js';
5
+ import GML3 from 'ol/format/GML3.js';
6
+ import Point from 'ol/geom/Point.js';
7
+ import { getTransform } from 'ol/proj.js';
8
+ import { parseInteger } from '@vcsuite/parsers';
9
+ import AbstractFeatureProvider from './abstractFeatureProvider.js';
10
+ import Projection, { mercatorProjection } from '../projection.js';
11
+ import { getWMSSource } from '../../layer/wmsHelpers.js';
12
+ import Extent from '../extent.js';
13
+
14
+ /**
15
+ * @typedef {AbstractFeatureProviderOptions} WMSFeatureProviderOptions
16
+ * @property {string|undefined} [responseType='text/xml'] - the response type for the feature info
17
+ * @property {Object|undefined} formatOptions - format options for the GeoJSON, WFS or GML format. To overwrite the gmlFormat option in WFS format, use 'GML', 'GML2' or 'GML3' as string
18
+ * @property {ProjectionOptions|undefined} projection - the projection of the data, if not encoded in the response
19
+ * @property {string} url
20
+ * @property {string} [tilingSchema='geographic'] - either "geographic" or "mercator"
21
+ * @property {number} [maxLevel=18]
22
+ * @property {number} [minLevel=0]
23
+ * @property {import("ol/size").Size} [tileSize=[256,256]]
24
+ * @property {Extent|ExtentOptions|undefined} extent
25
+ * @property {Object<string, string>} parameters
26
+ * @property {string} [version='1.1.1']
27
+ * @api
28
+ */
29
+
30
+ const gmlFormats = {
31
+ GML: GML3,
32
+ GML2,
33
+ GML3,
34
+ };
35
+
36
+ /**
37
+ * @type {Array<string>}
38
+ * @const
39
+ */
40
+ const geojsonFormats = [
41
+ 'application/geojson',
42
+ 'application/json',
43
+ 'application/vnd.geo+json',
44
+ ];
45
+
46
+ /**
47
+ * @param {string} responseType
48
+ * @param {Object} options
49
+ * @returns {null|import("ol/format/Feature").default}
50
+ */
51
+ export function getFormat(responseType, options = {}) {
52
+ if (responseType === 'text/xml') {
53
+ options.gmlFormat = options.gmlFormat ? new gmlFormats[options.gmlFormat]() : new GML2();
54
+ return new WFS(options);
55
+ }
56
+ if (geojsonFormats.includes(responseType)) {
57
+ return new GeoJSON(options);
58
+ }
59
+ if (responseType === 'application/vnd.ogc.gml') {
60
+ return new GML2(options);
61
+ }
62
+ if (responseType === 'application/vnd.ogc.gml/3.1.1') {
63
+ return new GML3(options);
64
+ }
65
+ return null;
66
+ }
67
+
68
+ /**
69
+ * @class
70
+ * @export
71
+ * @extends {AbstractFeatureProvider}
72
+ */
73
+ class WMSFeatureProvider extends AbstractFeatureProvider {
74
+ static get className() { return 'vcs.vcm.util.featureProvider.WMSFeatureProvider'; }
75
+
76
+ /**
77
+ * @returns {WMSFeatureProviderOptions}
78
+ */
79
+ static getDefaultOptions() {
80
+ return {
81
+ ...AbstractFeatureProvider.getDefaultOptions(),
82
+ responseType: 'text/xml',
83
+ style: undefined,
84
+ formatOptions: undefined,
85
+ projection: undefined,
86
+ url: '',
87
+ tilingSchema: 'geographic',
88
+ version: '1.1.1',
89
+ maxLevel: 0,
90
+ minLevel: 0,
91
+ tileSize: [256, 256],
92
+ parameters: {},
93
+ extent: undefined,
94
+ };
95
+ }
96
+
97
+ /**
98
+ * @param {string} layerName
99
+ * @param {WMSFeatureProviderOptions} options
100
+ */
101
+ constructor(layerName, options) {
102
+ super(layerName, options);
103
+ const defaultOptions = WMSFeatureProvider.getDefaultOptions();
104
+
105
+ /**
106
+ * @type {import("@vcmap/core").Extent|null}
107
+ */
108
+ this.extent = null;
109
+ if (options.extent) {
110
+ if (options.extent instanceof Extent) {
111
+ this.extent = options.extent;
112
+ } else {
113
+ this.extent = new Extent(options.extent);
114
+ }
115
+ }
116
+ /** @type {WMSSourceOptions} */
117
+ this._wmsSourceOptions = {
118
+ url: options.url,
119
+ tilingSchema: options.tilingSchema || defaultOptions.tilingSchema,
120
+ maxLevel: parseInteger(options.maxLevel, defaultOptions.maxLevel),
121
+ minLevel: parseInteger(options.minLevel, defaultOptions.minLevel),
122
+ tileSize: options.tileSize || defaultOptions.tileSize,
123
+ parameters: options.parameters,
124
+ version: options.version || defaultOptions.version,
125
+ };
126
+ /**
127
+ * The WMS Source used to generate getFeatureInfo urls
128
+ * @type {import("ol/source/TileWMS").default}
129
+ * @api
130
+ */
131
+ this.wmsSource = getWMSSource(this._wmsSourceOptions);
132
+ /**
133
+ * The response type of the get feature info response, e.g. text/xml
134
+ * @type {string}
135
+ * @api
136
+ */
137
+ this.featureInfoResponseType = options.responseType || defaultOptions.responseType;
138
+ /**
139
+ * @type {Object}
140
+ * @private
141
+ */
142
+ this._formatOptions = options.formatOptions || defaultOptions.formatOptions;
143
+ /**
144
+ * The feature response format determined by the response type. Use formatOptions to configure the underlying ol.format.Feature
145
+ * @type {import("ol/format/Feature").default}
146
+ * @api
147
+ */
148
+ this.featureFormat = getFormat(this.featureInfoResponseType, options.formatOptions);
149
+ /**
150
+ * The feature response projection, if not present in the response format.
151
+ * @type {Projection}
152
+ * @api
153
+ */
154
+ this.projection = options.projection ? new Projection(options.projection) : undefined;
155
+ }
156
+
157
+ /**
158
+ * @param {import("axios").AxiosResponse<*>} response
159
+ * @param {import("ol/coordinate").Coordinate} coordinate
160
+ * @returns {Array<import("ol").Feature<import("ol/geom/Geometry").default>>}
161
+ */
162
+ featureResponseCallback(response, coordinate) {
163
+ const { data } = response;
164
+ /** @type {Array<import("ol").Feature<import("ol/geom/Geometry").default>>} */
165
+ let features;
166
+
167
+ try {
168
+ features = /** @type {Array<import("ol").Feature<import("ol/geom/Geometry").default>>} */
169
+ (this.featureFormat.readFeatures(data, {
170
+ dataProjection: this.projection ? this.projection.proj : undefined,
171
+ featureProjection: mercatorProjection.proj,
172
+ }));
173
+ } catch (ex) {
174
+ this.getLogger().warning('Features could not be read, please verify the featureInfoResponseType with the capabilities from the server');
175
+ return [];
176
+ }
177
+
178
+ if (Array.isArray(features)) {
179
+ features.forEach((feature) => {
180
+ const geometry = feature.getGeometry();
181
+ if (!geometry) {
182
+ feature.setGeometry(new Point(coordinate));
183
+ }
184
+ });
185
+ return features;
186
+ }
187
+
188
+ return [];
189
+ }
190
+
191
+ /**
192
+ * @inheritDoc
193
+ * @param {import("ol/coordinate").Coordinate} coordinate
194
+ * @param {number} resolution
195
+ * @returns {Promise<Array<import("ol").Feature<import("ol/geom/Geometry").default>>>}
196
+ */
197
+ async getFeaturesByCoordinate(coordinate, resolution) {
198
+ const projection = this.wmsSource.getProjection();
199
+ let coords = coordinate;
200
+ if (projection) {
201
+ const transform = getTransform(mercatorProjection.proj, projection);
202
+ coords = transform(coordinate.slice());
203
+ }
204
+
205
+ const metersPerUnit = 111194.87428468118;
206
+ const url = this.wmsSource.getFeatureInfoUrl(
207
+ coords,
208
+ resolution / metersPerUnit,
209
+ projection,
210
+ { INFO_FORMAT: this.featureInfoResponseType },
211
+ );
212
+
213
+ if (url) {
214
+ const response = await axios.get(url);
215
+ return this.featureResponseCallback(response, coordinate)
216
+ .map(f => this.getProviderFeature(f));
217
+ }
218
+ return [];
219
+ }
220
+
221
+ /**
222
+ * @inheritDoc
223
+ * @returns {WMSFeatureProviderOptions}
224
+ */
225
+ getConfigObject() {
226
+ const config = /** @type {WMSFeatureProviderOptions} */ (super.getConfigObject());
227
+ const defaultOptions = WMSFeatureProvider.getDefaultOptions();
228
+ if (this.featureInfoResponseType !== defaultOptions.responseType) {
229
+ config.responseType = this.featureInfoResponseType;
230
+ }
231
+
232
+ if (this._formatOptions !== defaultOptions.formatOptions) {
233
+ config.formatOptions = { ...this._formatOptions };
234
+ }
235
+
236
+ if (this.projection !== defaultOptions.projection) {
237
+ config.projection = this.projection.getConfigObject();
238
+ }
239
+
240
+ config.url = this._wmsSourceOptions.url;
241
+ config.parameters = { ...this._wmsSourceOptions.parameters };
242
+
243
+ if (this._wmsSourceOptions.tilingSchema !== defaultOptions.tilingSchema) {
244
+ config.tilingSchema = this._wmsSourceOptions.tilingSchema;
245
+ }
246
+ if (this._wmsSourceOptions.maxLevel !== defaultOptions.maxLevel) {
247
+ config.maxLevel = this._wmsSourceOptions.maxLevel;
248
+ }
249
+ if (this._wmsSourceOptions.minLevel !== defaultOptions.minLevel) {
250
+ config.minLevel = this._wmsSourceOptions.minLevel;
251
+ }
252
+ if (this._wmsSourceOptions.version !== defaultOptions.version) {
253
+ config.version = this._wmsSourceOptions.version;
254
+ }
255
+ if (
256
+ this._wmsSourceOptions.tileSize[0] !== defaultOptions.tileSize[0] ||
257
+ this._wmsSourceOptions.tileSize[1] !== defaultOptions.tileSize[1]
258
+ ) {
259
+ config.tileSize = this._wmsSourceOptions.tileSize.slice();
260
+ }
261
+ if (this.extent) {
262
+ config.extent = this.extent.getConfigObject();
263
+ }
264
+
265
+ return config;
266
+ }
267
+
268
+ /**
269
+ * @inheritDoc
270
+ */
271
+ destroy() {
272
+ this.wmsSource = undefined;
273
+ this.featureFormat = undefined;
274
+ this.projection = undefined;
275
+ this._formatOptions = undefined;
276
+ super.destroy();
277
+ }
278
+ }
279
+
280
+ export default WMSFeatureProvider;
@@ -0,0 +1,215 @@
1
+ import { circular } from 'ol/geom/Polygon.js';
2
+ import GeometryType from 'ol/geom/GeometryType.js';
3
+ import {
4
+ Cartesian3,
5
+ CircleGeometry,
6
+ GroundPolylineGeometry,
7
+ CircleOutlineGeometry,
8
+ Math as CesiumMath,
9
+ Cartographic,
10
+ PolylineGeometry,
11
+ } from '@vcmap/cesium';
12
+ import { parseNumber } from '@vcsuite/parsers';
13
+ import { addPrimitivesToContext } from './featureconverterHelper.js';
14
+ import Projection from '../projection.js';
15
+
16
+ /**
17
+ * @param {Object} options
18
+ * @param {number} height
19
+ * @param {boolean} perPositionHeight
20
+ * @param {number=} extrudedHeight
21
+ * @returns {Array<import("@vcmap/cesium").CircleGeometry>}
22
+ * @private
23
+ */
24
+ export function createSolidGeometries(options, height, perPositionHeight, extrudedHeight) {
25
+ return [new CircleGeometry({
26
+ ...options,
27
+ height,
28
+ granularity: 0.02,
29
+ extrudedHeight,
30
+ })];
31
+ }
32
+
33
+ /**
34
+ * @param {Object} options
35
+ * @param {number} height
36
+ * @param {boolean} perPositionHeight
37
+ * @param {number=} extrudedHeight
38
+ * @returns {Array<import("@vcmap/cesium").CircleOutlineGeometry>}
39
+ * @private
40
+ */
41
+ export function createOutlineGeometries(options, height, perPositionHeight, extrudedHeight) {
42
+ return [new CircleOutlineGeometry({
43
+ ...options,
44
+ height,
45
+ extrudedHeight,
46
+ granularity: 0.02,
47
+ })];
48
+ }
49
+
50
+ /**
51
+ * @param {Object} options
52
+ * @param {number} height
53
+ * @param {boolean} perPositionHeight
54
+ * @returns {Array<import("@vcmap/cesium").CircleGeometry>}
55
+ * @private
56
+ */
57
+ export function createFillGeometries(options, height, perPositionHeight) {
58
+ return createSolidGeometries(options, height, perPositionHeight, undefined);
59
+ }
60
+
61
+ /**
62
+ * @param {Object} options
63
+ * @param {import("ol/style/Style").default} style
64
+ * @returns {{width: number, positions: Array}}
65
+ * @private
66
+ */
67
+ export function getLineGeometryOptions(options, style) {
68
+ const width = parseNumber(style.getStroke().getWidth(), 1.0);
69
+ const { center, radius } = options;
70
+ const cartographic = Cartographic.fromCartesian(center);
71
+ const wgs84Center = [
72
+ CesiumMath.toDegrees(cartographic.longitude),
73
+ CesiumMath.toDegrees(cartographic.latitude),
74
+ ];
75
+
76
+ // circular returns polygon with GeometryLayout.XY
77
+ const circlePolygon = circular(
78
+ wgs84Center,
79
+ radius,
80
+ 40,
81
+ );
82
+ const pos = circlePolygon.getLinearRing(0).getCoordinates();
83
+ const positions = pos.map((coord) => {
84
+ return Cartesian3.fromDegrees(coord[0], coord[1], cartographic.height);
85
+ });
86
+ return {
87
+ positions,
88
+ width,
89
+ };
90
+ }
91
+
92
+ /**
93
+ * @param {Object} options
94
+ * @param {import("ol/style/Style").default} style
95
+ * @returns {Array<import("@vcmap/cesium").GroundPolylineGeometry>}
96
+ * @private
97
+ */
98
+ export function createGroundLineGeometries(options, style) {
99
+ const lineOptions = getLineGeometryOptions(options, style);
100
+ return [new GroundPolylineGeometry(lineOptions)];
101
+ }
102
+
103
+ /**
104
+ * @param {Object} options
105
+ * @param {import("ol/style/Style").default} style
106
+ * @returns {Array<import("@vcmap/cesium").PolylineGeometry>}
107
+ * @private
108
+ */
109
+ export function createLineGeometries(options, style) {
110
+ const lineOptions = getLineGeometryOptions(options, style);
111
+ return [new PolylineGeometry(lineOptions)];
112
+ }
113
+
114
+ /**
115
+ * extracts the center and radius from the CircleGeometry and converts it to Cartesian3/radius in m
116
+ * @param {import("ol/geom/Circle").default} geometry
117
+ * @param {number} positionHeightAdjustment
118
+ * @returns {{center: import("@vcmap/cesium").Cartesian3, radius: Number}}
119
+ * @private
120
+ */
121
+ export function getGeometryOptions(geometry, positionHeightAdjustment) {
122
+ // olCoordinates of center and radius in WGS84
123
+ const olCenter = geometry.getCenter();
124
+ const olPoint = olCenter.slice();
125
+ olPoint[0] += geometry.getRadius();
126
+ const wgs84Center = Projection.mercatorToWgs84(olCenter, true);
127
+ if (wgs84Center[2] != null) {
128
+ wgs84Center[2] += positionHeightAdjustment;
129
+ }
130
+
131
+ const wgs84Point = Projection.mercatorToWgs84(olPoint, true);
132
+
133
+ // Cesium coordinates of center and radius
134
+ const center = Cartesian3.fromDegrees(wgs84Center[0], wgs84Center[1], wgs84Center[2]);
135
+ const point = Cartesian3.fromDegrees(wgs84Point[0], wgs84Point[1], wgs84Center[2]);
136
+
137
+ // Computation of radius in Cesium 3D
138
+ const radius = Cartesian3.distance(center, point);
139
+ return {
140
+ radius,
141
+ center,
142
+ };
143
+ }
144
+
145
+ /**
146
+ * @param {Array<import("ol/geom/Circle").default>} geometries
147
+ * @returns {Array<import("ol/coordinate").Coordinate>}
148
+ * @private
149
+ */
150
+ export function getCoordinates(geometries) {
151
+ return geometries.map((circle) => {
152
+ return circle.getCenter();
153
+ });
154
+ }
155
+
156
+ /**
157
+ * @type {VectorGeometryFactoryType|null}
158
+ */
159
+ let geometryFactory = null;
160
+
161
+ /**
162
+ * @returns {VectorGeometryFactoryType}
163
+ */
164
+ function getGeometryFactory() {
165
+ if (!geometryFactory) {
166
+ geometryFactory = {
167
+ getCoordinates,
168
+ getGeometryOptions,
169
+ createSolidGeometries,
170
+ createOutlineGeometries,
171
+ createFillGeometries,
172
+ createGroundLineGeometries,
173
+ createLineGeometries,
174
+ };
175
+ }
176
+ return geometryFactory;
177
+ }
178
+
179
+ /**
180
+ * validates if a point is renderable
181
+ * @param {import("ol/geom/Circle").default} circle
182
+ * @returns {boolean}
183
+ */
184
+ export function validateCircle(circle) {
185
+ if (circle.getType() !== GeometryType.CIRCLE) {
186
+ return false;
187
+ }
188
+ const flatCoordinates = circle.getFlatCoordinates();
189
+ const stride = circle.getStride();
190
+ // needs at least one full coordinate + a radius value and a non 0 radius
191
+ if (flatCoordinates && flatCoordinates.length >= stride + 1 && flatCoordinates[stride] !== flatCoordinates[0]) {
192
+ return flatCoordinates.every(value => Number.isFinite(value));
193
+ }
194
+ return false;
195
+ }
196
+
197
+
198
+ /**
199
+ * @param {import("ol").Feature<import("ol/geom/Geometry").default>} feature
200
+ * @param {import("ol/style/Style").default} style
201
+ * @param {Array<import("ol/geom/Circle").default>} geometries
202
+ * @param {import("@vcmap/core").VectorProperties} vectorProperties
203
+ * @param {import("@vcmap/cesium").Scene} scene
204
+ * @param {import("@vcmap/core").VectorContext|import("@vcmap/core").ClusterContext} context
205
+ */
206
+ export default function circleToCesium(feature, style, geometries, vectorProperties, scene, context) {
207
+ if (!style.getFill() && !style.getStroke()) {
208
+ return;
209
+ }
210
+ const circleGeometryFactory = getGeometryFactory();
211
+ const validGeometries = geometries.filter(circle => validateCircle(circle));
212
+ addPrimitivesToContext(
213
+ feature, style, validGeometries, vectorProperties, scene, circleGeometryFactory, context,
214
+ );
215
+ }
@@ -0,0 +1,83 @@
1
+ import Polygon from 'ol/geom/Polygon.js';
2
+ import LineString from 'ol/geom/LineString.js';
3
+ import Circle from 'ol/geom/Circle.js';
4
+ import Point from 'ol/geom/Point.js';
5
+ import MultiPolygon from 'ol/geom/MultiPolygon.js';
6
+ import MultiLineString from 'ol/geom/MultiLineString.js';
7
+ import MultiPoint from 'ol/geom/MultiPoint.js';
8
+ import Style from 'ol/style/Style.js';
9
+ import GeometryCollection from 'ol/geom/GeometryCollection.js';
10
+ import polygonToCesium from './polygonToCesium.js';
11
+ import circleToCesium from './circleToCesium.js';
12
+ import lineStringToCesium from './lineStringToCesium.js';
13
+ import pointToCesium from './pointToCesium.js';
14
+
15
+ /**
16
+ * @param {import("ol").Feature<import("ol/geom/Geometry").default>} feature
17
+ * @param {import("ol/geom/Geometry").default} geometry
18
+ * @param {import("ol/style/Style").default} style
19
+ * @param {import("@vcmap/core").VectorProperties} vectorProperties
20
+ * @param {import("@vcmap/cesium").Scene} scene
21
+ * @param {import("@vcmap/core").VectorContext|import("@vcmap/core").ClusterContext} context
22
+ */
23
+ function convertGeometry(feature, geometry, style, vectorProperties, scene, context) {
24
+ if (geometry instanceof Point) {
25
+ pointToCesium(feature, style, [geometry], vectorProperties, scene, context);
26
+ } else if (geometry instanceof Polygon) {
27
+ polygonToCesium(feature, style, [geometry], vectorProperties, scene, context);
28
+ } else if (geometry instanceof LineString) {
29
+ lineStringToCesium(feature, style, [geometry], vectorProperties, scene, context);
30
+ } else if (geometry instanceof Circle) {
31
+ circleToCesium(feature, style, [geometry], vectorProperties, scene, context);
32
+ } else if (geometry instanceof MultiPoint) {
33
+ pointToCesium(feature, style, geometry.getPoints(), vectorProperties, scene, context);
34
+ } else if (geometry instanceof MultiPolygon) {
35
+ polygonToCesium(feature, style, geometry.getPolygons(), vectorProperties, scene, context);
36
+ } else if (geometry instanceof MultiLineString) {
37
+ lineStringToCesium(feature, style, geometry.getLineStrings(), vectorProperties, scene, context);
38
+ } else if (geometry instanceof GeometryCollection) {
39
+ geometry.getGeometries().forEach((currentGeometry) => {
40
+ convertGeometry(feature, currentGeometry, style, vectorProperties, scene, context);
41
+ });
42
+ }
43
+ }
44
+
45
+ /**
46
+ * @param {void|import("ol/style/Style").StyleLike} style
47
+ * @param {import("ol").Feature<import("ol/geom/Geometry").default>} feature
48
+ * @param {number=} resolution
49
+ * @returns {Array<import("ol/style/Style").default>}
50
+ */
51
+ export function getStylesArray(style, feature, resolution = 1) {
52
+ const styles = [];
53
+ if (typeof style === 'function') {
54
+ styles.push(...getStylesArray(style(feature, resolution), feature, resolution));
55
+ } else if (Array.isArray(style)) {
56
+ style.forEach((currentStyle) => {
57
+ styles.push(...getStylesArray(currentStyle, feature, resolution));
58
+ });
59
+ } else if (style instanceof Style) {
60
+ styles.push(style);
61
+ }
62
+ return styles;
63
+ }
64
+
65
+
66
+ /**
67
+ * function to convert a feature to an array of Cesium.Primitives given a style and default properties. the resulting primitives
68
+ * must be added to the contexts collections here
69
+ * @param {import("ol").Feature<import("ol/geom/Geometry").default>} feature
70
+ * @param {import("ol/style/Style").StyleLike} style
71
+ * @param {import("@vcmap/core").VectorProperties} vectorProperties
72
+ * @param {import("@vcmap/core").VectorContext|import("@vcmap/core").ClusterContext} context
73
+ * @param {import("@vcmap/cesium").Scene} scene
74
+ */
75
+ export default function convert(feature, style, vectorProperties, context, scene) {
76
+ const styles = getStylesArray(feature.getStyle() || style, feature, 0);
77
+ styles.forEach((currentStyle) => {
78
+ const geometry = /** @type {import("ol/geom/Geometry").default} */(currentStyle.getGeometryFunction()(feature));
79
+ if (geometry) {
80
+ convertGeometry(feature, geometry, currentStyle, vectorProperties, scene, context);
81
+ }
82
+ });
83
+ }