@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,171 @@
1
+ import { Cartesian3, WallGeometry, WallOutlineGeometry, GroundPolylineGeometry, PolylineGeometry } from '@vcmap/cesium';
2
+ import GeometryType from 'ol/geom/GeometryType.js';
3
+ import { parseNumber } from '@vcsuite/parsers';
4
+ import Projection from '../projection.js';
5
+ import { addPrimitivesToContext } from './featureconverterHelper.js';
6
+ import { getFlatCoordinatesFromSimpleGeometry } from '../geometryHelpers.js';
7
+
8
+ /**
9
+ * @param {Object} options
10
+ * @param {number} height
11
+ * @param {boolean} perPositionHeight
12
+ * @param {number=} extrudedHeight
13
+ * @returns {Array<import("@vcmap/cesium").WallGeometry>}
14
+ * @private
15
+ */
16
+ export function createSolidGeometries(options, height, perPositionHeight, extrudedHeight) {
17
+ return [WallGeometry.fromConstantHeights({
18
+ ...options,
19
+ maximumHeight: !perPositionHeight ? height : undefined,
20
+ minimumHeight: extrudedHeight,
21
+ })];
22
+ }
23
+
24
+ /**
25
+ * @param {Object} options
26
+ * @param {number} height
27
+ * @param {boolean} perPositionHeight
28
+ * @param {number=} extrudedHeight
29
+ * @returns {Array<import("@vcmap/cesium").WallOutlineGeometry>}
30
+ * @private
31
+ */
32
+ export function createOutlineGeometries(options, height, perPositionHeight, extrudedHeight) {
33
+ // maxium and minimum are flipped, to create the same perPositionHeight behaviour as in polygons
34
+ // WallGeometries extrudes down instead of up, so we switch the behaviour and extrude in the other direction
35
+ return [WallOutlineGeometry.fromConstantHeights({
36
+ ...options,
37
+ maximumHeight: !perPositionHeight ? height : undefined,
38
+ minimumHeight: extrudedHeight,
39
+ })];
40
+ }
41
+
42
+ /**
43
+ * @param {Object} options
44
+ * @param {number} height
45
+ * @param {boolean} perPositionHeight
46
+ * @returns {Array}
47
+ * @private
48
+ */
49
+ // eslint-disable-next-line no-unused-vars
50
+ export function createFillGeometries(options, height, perPositionHeight) {
51
+ return [];
52
+ }
53
+
54
+
55
+ /**
56
+ * @param {Object} options
57
+ * @param {import("ol/style/Style").default} style
58
+ * @returns {Array<import("@vcmap/cesium").GroundPolylineGeometry>}
59
+ * @private
60
+ */
61
+ export function createGroundLineGeometries(options, style) {
62
+ const width = parseNumber(style.getStroke().getWidth(), 1.0);
63
+ return [new GroundPolylineGeometry({
64
+ ...options,
65
+ width,
66
+ })];
67
+ }
68
+
69
+ /**
70
+ * @param {Object} options
71
+ * @param {import("ol/style/Style").default} style
72
+ * @returns {Array<import("@vcmap/cesium").PolylineGeometry>}
73
+ * @private
74
+ */
75
+ export function createLineGeometries(options, style) {
76
+ const width = parseNumber(style.getStroke().getWidth(), 1.0);
77
+ return [new PolylineGeometry({
78
+ ...options,
79
+ width,
80
+ })];
81
+ }
82
+
83
+ /**
84
+ * extracts the center and radius from the CircleGeometry and converts it to Cartesian3/radius in m
85
+ * @param {import("ol/geom/LineString").default} geometry
86
+ * @param {number} positionHeightAdjustment
87
+ * @returns {Object}
88
+ * @private
89
+ */
90
+ export function getGeometryOptions(geometry, positionHeightAdjustment) {
91
+ const coords = geometry.getCoordinates();
92
+ const positions = coords.map((coord) => {
93
+ const wgs84Coords = Projection.mercatorToWgs84(coord);
94
+ if (wgs84Coords[2] != null) {
95
+ wgs84Coords[2] += positionHeightAdjustment;
96
+ }
97
+ return Cartesian3.fromDegrees(wgs84Coords[0], wgs84Coords[1], wgs84Coords[2]);
98
+ });
99
+ return { positions };
100
+ }
101
+
102
+ /**
103
+ * @param {Array<import("ol/geom/LineString").default>} geometries
104
+ * @returns {Array<import("ol/coordinate").Coordinate>}
105
+ * @private
106
+ */
107
+ export function getCoordinates(geometries) {
108
+ const coordinates = [];
109
+ geometries.forEach((lineString) => {
110
+ coordinates.push(...getFlatCoordinatesFromSimpleGeometry(lineString));
111
+ });
112
+ return coordinates;
113
+ }
114
+
115
+ /**
116
+ * @type {VectorGeometryFactoryType|null}
117
+ */
118
+ let geometryFactory = null;
119
+
120
+ /**
121
+ * @returns {VectorGeometryFactoryType}
122
+ */
123
+ function getGeometryFactory() {
124
+ if (!geometryFactory) {
125
+ geometryFactory = {
126
+ getCoordinates,
127
+ getGeometryOptions,
128
+ createSolidGeometries,
129
+ createOutlineGeometries,
130
+ createFillGeometries,
131
+ createGroundLineGeometries,
132
+ createLineGeometries,
133
+ };
134
+ }
135
+ return geometryFactory;
136
+ }
137
+
138
+ /**
139
+ * validates if a lineString is renderable
140
+ * @param {import("ol/geom/LineString").default} lineString
141
+ * @returns {boolean}
142
+ */
143
+ export function validateLineString(lineString) {
144
+ if (lineString.getType() !== GeometryType.LINE_STRING) {
145
+ return false;
146
+ }
147
+ const flatCoordinates = lineString.getFlatCoordinates();
148
+ const minimumValues = lineString.getStride() * 2;
149
+ if (flatCoordinates && flatCoordinates.length >= minimumValues) {
150
+ return flatCoordinates.every(value => Number.isFinite(value));
151
+ }
152
+ return false;
153
+ }
154
+
155
+ /**
156
+ * converts a linestring to a a cesium primitive, with optional labels
157
+ * @param {import("ol").Feature<import("ol/geom/Geometry").default>} feature
158
+ * @param {import("ol/style/Style").default} style
159
+ * @param {Array<import("ol/geom/LineString").default>} geometries
160
+ * @param {import("@vcmap/core").VectorProperties} vectorProperties
161
+ * @param {import("@vcmap/cesium").Scene} scene
162
+ * @param {import("@vcmap/core").VectorContext|import("@vcmap/core").ClusterContext} context
163
+ */
164
+ export default function lineStringToCesium(feature, style, geometries, vectorProperties, scene, context) {
165
+ if (!style.getFill() && !style.getStroke()) {
166
+ return;
167
+ }
168
+ const lineGeometryFactory = getGeometryFactory();
169
+ const validGeometries = geometries.filter(lineString => validateLineString(lineString));
170
+ addPrimitivesToContext(feature, style, validGeometries, vectorProperties, scene, lineGeometryFactory, context);
171
+ }
@@ -0,0 +1,359 @@
1
+ import {
2
+ Cartesian3,
3
+ Color,
4
+ HeightReference,
5
+ VerticalOrigin,
6
+ Cartesian2,
7
+ Transforms,
8
+ Matrix4,
9
+ Model,
10
+ HeadingPitchRoll,
11
+ LabelStyle,
12
+ ModelAnimationLoop,
13
+ Cartographic,
14
+ HorizontalOrigin,
15
+ } from '@vcmap/cesium';
16
+ import Icon from 'ol/style/Icon.js';
17
+ import GeometryType from 'ol/geom/GeometryType.js';
18
+ import ImageState from 'ol/ImageState.js';
19
+ import { parseNumber } from '@vcsuite/parsers';
20
+ import {
21
+ createLinePrimitive,
22
+ getHeightInfo,
23
+ } from './featureconverterHelper.js';
24
+ import Projection from '../projection.js';
25
+ import { createLineGeometries } from './lineStringToCesium.js';
26
+ import { getCesiumColor } from '../style/styleHelpers.js';
27
+ import { sampleCesiumTerrainMostDetailed } from '../../layer/terrainHelpers.js';
28
+
29
+ /**
30
+ * @param {Array<import("ol/geom/Point").default>} geometries
31
+ * @returns {Array<import("ol/coordinate").Coordinate>}
32
+ * @private
33
+ */
34
+ export function getCoordinates(geometries) {
35
+ return geometries.map((point) => {
36
+ return point.getCoordinates();
37
+ });
38
+ }
39
+
40
+ /**
41
+ * @param {import("ol").Feature<import("ol/geom/Geometry").default>} feature
42
+ * @param {import("ol/style/Style").default} style
43
+ * @param {import("@vcmap/cesium").HeightReference} heightReference
44
+ * @param {import("@vcmap/core").VectorProperties} vectorProperties
45
+ * @returns {Object|null}
46
+ */
47
+ export function getBillboardOptions(feature, style, heightReference, vectorProperties) {
48
+ const imageStyle = style.getImage();
49
+ if (imageStyle) {
50
+ // ImageStyles should always have an opacity value between 0 and 1, default white Color
51
+ const color = new Color(1.0, 1.0, 1.0, imageStyle.getOpacity());
52
+
53
+ let image = null;
54
+ if (imageStyle instanceof Icon) {
55
+ imageStyle.load();
56
+ if (imageStyle.getImageState() === ImageState.LOADING) {
57
+ image = new Promise((resolve, reject) => {
58
+ const imageChangeListener = () => {
59
+ if (imageStyle.getImageState() === ImageState.LOADED || imageStyle.getImageState() === ImageState.EMPTY) {
60
+ resolve(imageStyle.getImage(1));
61
+ imageStyle.unlistenImageChange(imageChangeListener);
62
+ } else if (imageStyle.getImageState() === ImageState.ERROR) {
63
+ reject();
64
+ imageStyle.unlistenImageChange(imageChangeListener);
65
+ }
66
+ };
67
+ imageStyle.listenImageChange(imageChangeListener);
68
+ });
69
+ }
70
+ }
71
+ if (!image) {
72
+ image = imageStyle.getImage(1);
73
+ }
74
+ const options = {
75
+ image,
76
+ color,
77
+ scale: imageStyle.getScale(),
78
+ heightReference,
79
+ verticalOrigin: VerticalOrigin.BOTTOM,
80
+ id: feature.getId(),
81
+ };
82
+
83
+ options.eyeOffset = vectorProperties.getEyeOffset(feature);
84
+ options.scaleByDistance = vectorProperties.getScaleByDistance(feature);
85
+
86
+ return options;
87
+ }
88
+ return null;
89
+ }
90
+
91
+ /**
92
+ * extracts cesium label options from a feature and style
93
+ * @param {import("ol").Feature<import("ol/geom/Geometry").default>} feature
94
+ * @param {import("ol/style/Style").default} style style.getText().getFill() is set by default to be #333,
95
+ * if no fill is required set Fill empty by using style.getText().setFill()
96
+ * @param {import("@vcmap/cesium").HeightReference} heightReference
97
+ * @param {import("@vcmap/core").VectorProperties} vectorProperties
98
+ * @returns {Object|null}
99
+ */
100
+ export function getLabelOptions(feature, style, heightReference, vectorProperties) {
101
+ const textStyle = style.getText();
102
+ const text = textStyle ? textStyle.getText() : null;
103
+ if (text) {
104
+ const options = {};
105
+
106
+ options.text = text;
107
+
108
+ options.heightReference = heightReference;
109
+
110
+ const offsetX = textStyle.getOffsetX() || 0;
111
+ const offsetY = textStyle.getOffsetY() || 0;
112
+ options.pixelOffset = new Cartesian2(offsetX, offsetY);
113
+
114
+ const font = textStyle.getFont();
115
+ if (font) {
116
+ options.font = font;
117
+ }
118
+
119
+ const fill = textStyle.getFill();
120
+ const stroke = textStyle.getStroke();
121
+
122
+ let labelStyle;
123
+ if (fill) {
124
+ options.fillColor = getCesiumColor(fill.getColor(), [0, 0, 0, 1]);
125
+ labelStyle = LabelStyle.FILL;
126
+ }
127
+ if (stroke) {
128
+ options.outlineWidth = parseNumber(stroke.getWidth(), 1.0);
129
+ options.outlineColor = getCesiumColor(stroke.getColor(), [0, 0, 0, 1]);
130
+ labelStyle = LabelStyle.OUTLINE;
131
+ }
132
+ if (fill && stroke) {
133
+ labelStyle = LabelStyle.FILL_AND_OUTLINE;
134
+ }
135
+ options.style = labelStyle;
136
+
137
+ let horizontalOrigin;
138
+ switch (textStyle.getTextAlign()) {
139
+ case 'left':
140
+ horizontalOrigin = HorizontalOrigin.LEFT;
141
+ break;
142
+ case 'right':
143
+ horizontalOrigin = HorizontalOrigin.RIGHT;
144
+ break;
145
+ case 'center':
146
+ default:
147
+ horizontalOrigin = HorizontalOrigin.CENTER;
148
+ }
149
+ options.horizontalOrigin = horizontalOrigin;
150
+
151
+ let verticalOrigin;
152
+ switch (textStyle.getTextBaseline()) {
153
+ case 'top':
154
+ verticalOrigin = VerticalOrigin.TOP;
155
+ break;
156
+ case 'middle':
157
+ verticalOrigin = VerticalOrigin.CENTER;
158
+ break;
159
+ case 'bottom':
160
+ verticalOrigin = VerticalOrigin.BOTTOM;
161
+ break;
162
+ case 'alphabetic':
163
+ verticalOrigin = VerticalOrigin.TOP;
164
+ break;
165
+ case 'hanging':
166
+ verticalOrigin = VerticalOrigin.BOTTOM;
167
+ break;
168
+ default:
169
+ verticalOrigin = VerticalOrigin.BASELINE;
170
+ }
171
+ options.verticalOrigin = verticalOrigin;
172
+ options.eyeOffset = vectorProperties.getEyeOffset(feature);
173
+ options.scaleByDistance = vectorProperties.getScaleByDistance(feature);
174
+
175
+ return options;
176
+ }
177
+ return null;
178
+ }
179
+
180
+ /**
181
+ * @param {import("ol").Feature<import("ol/geom/Geometry").default>} feature
182
+ * @param {Array<import("ol/coordinate").Coordinate>} wgs84Positions
183
+ * @param {Array<import("@vcmap/cesium").Cartesian3>} positions
184
+ * @param {import("@vcmap/core").VectorProperties} vectorProperties
185
+ * @param {import("@vcmap/cesium").Scene} scene
186
+ * @returns {null|Array<import("@vcmap/cesium").Model>}
187
+ */
188
+ export function getModelOptions(feature, wgs84Positions, positions, vectorProperties, scene) {
189
+ const modelOptions = vectorProperties.getModel(feature);
190
+ if (modelOptions) {
191
+ const scale = Cartesian3.fromArray(modelOptions.scale);
192
+ const headingPitchRoll = HeadingPitchRoll.fromDegrees(modelOptions.heading, modelOptions.pitch, modelOptions.roll);
193
+ return positions.map((position, index) => {
194
+ const modelMatrix = Matrix4.multiply(
195
+ Transforms.headingPitchRollToFixedFrame(position, headingPitchRoll),
196
+ Matrix4.fromScale(scale),
197
+ new Matrix4(),
198
+ );
199
+
200
+ const additionalModelOptions = vectorProperties.getModelOptions(feature);
201
+ const model = Model.fromGltf({
202
+ url: modelOptions.url,
203
+ modelMatrix,
204
+ ...additionalModelOptions,
205
+ });
206
+
207
+ if (!wgs84Positions[index][2]) {
208
+ sampleCesiumTerrainMostDetailed(
209
+ /** @type {import("@vcmap/cesium").CesiumTerrainProvider} */ (scene.globe.terrainProvider),
210
+ [Cartographic.fromCartesian(position)],
211
+ )
212
+ .then(([cartoWithNewHeight]) => {
213
+ if (!model.isDestroyed()) {
214
+ model.modelMatrix = Matrix4.multiply(
215
+ Transforms.headingPitchRollToFixedFrame(Cartographic.toCartesian(cartoWithNewHeight), headingPitchRoll),
216
+ Matrix4.fromScale(scale),
217
+ new Matrix4(),
218
+ );
219
+ }
220
+ })
221
+ .catch(() => {});
222
+ }
223
+
224
+ model.readyPromise.then(() => {
225
+ model.activeAnimations.addAll({
226
+ loop: ModelAnimationLoop.REPEAT,
227
+ });
228
+ });
229
+ return model;
230
+ });
231
+ }
232
+ return null;
233
+ }
234
+
235
+ /**
236
+ * validates if a point is renderable
237
+ * @param {import("ol/geom/Point").default} point
238
+ * @returns {boolean}
239
+ */
240
+ export function validatePoint(point) {
241
+ if (point.getType() !== GeometryType.POINT) {
242
+ return false;
243
+ }
244
+ const flatCoordinates = point.getFlatCoordinates();
245
+ if (flatCoordinates && flatCoordinates.length >= 2) {
246
+ return flatCoordinates.every(value => Number.isFinite(value));
247
+ }
248
+ return false;
249
+ }
250
+
251
+ /**
252
+ * returns positions (cartesian3) and WGS84 coordinates
253
+ * @param {Array<import("ol/coordinate").Coordinate>} coordinates
254
+ * @param {VectorHeightInfo} heightInfo
255
+ * @returns {{positions:Array<import("@vcmap/cesium").Cartesian3>, wgs84Positions:Array<import("ol/coordinate").Coordinate>}}
256
+ */
257
+ export function getCartesian3AndWGS84FromCoordinates(coordinates, heightInfo) {
258
+ const wgs84Positions = new Array(coordinates.length);
259
+ const positions = new Array(coordinates.length);
260
+ const heightValue = heightInfo.groundLevel +
261
+ heightInfo.storeyHeightsAboveGround.reduce((sum, currentValue) => sum + currentValue, 0);
262
+ coordinates.forEach((coord, index) => {
263
+ wgs84Positions[index] = Projection.mercatorToWgs84(coord, true);
264
+ let height = null;
265
+ if (heightInfo.heightReference === HeightReference.RELATIVE_TO_GROUND) {
266
+ height = heightInfo.heightAboveGroundAdjustment;
267
+ } else {
268
+ height = heightValue;
269
+ }
270
+ positions[index] = Cartesian3.fromDegrees(coord[0], coord[1], height);
271
+ });
272
+ return {
273
+ positions,
274
+ wgs84Positions,
275
+ };
276
+ }
277
+
278
+ /**
279
+ * @param {Array<import("ol/coordinate").Coordinate>} wgs84Positions
280
+ * @param {VectorHeightInfo} heightInfo
281
+ * @param {Array<import("@vcmap/cesium").Cartesian3>} positions
282
+ * @param {import("ol/style/Style").default} style
283
+ * @returns {Array<import("@vcmap/cesium").PolylineGeometry>}
284
+ * @private
285
+ */
286
+ export function getLineGeometries(wgs84Positions, heightInfo, positions, style) {
287
+ const lineGeometries = [];
288
+ const heightValueCorrection = heightInfo.skirt +
289
+ heightInfo.storeyHeightsBelowGround.reduce((sum, currentValue) => sum + currentValue, 0);
290
+ for (let i = 0; i < wgs84Positions.length; i++) {
291
+ const pointPosition = wgs84Positions[i];
292
+ let heightValue = pointPosition[2] != null ? pointPosition[2] : heightInfo.groundLevel;
293
+ heightValue -= heightValueCorrection;
294
+ const secondPoint = Cartesian3.fromDegrees(pointPosition[0], pointPosition[1], heightValue);
295
+ const linePositions = [positions[i], secondPoint];
296
+ lineGeometries.push(...createLineGeometries({ positions: linePositions }, style));
297
+ }
298
+ return lineGeometries;
299
+ }
300
+
301
+ /**
302
+ * @param {import("ol").Feature<import("ol/geom/Geometry").default>} feature
303
+ * @param {import("ol/style/Style").default} style
304
+ * @param {Array<import("ol/geom/Point").default>} geometries
305
+ * @param {import("@vcmap/core").VectorProperties} vectorProperties
306
+ * @param {import("@vcmap/cesium").Scene} scene
307
+ * @param {import("@vcmap/core").VectorContext|import("@vcmap/core").ClusterContext} context
308
+ */
309
+ export default function pointToCesium(feature, style, geometries, vectorProperties, scene, context) {
310
+ if (!style.getImage() && !(style.getText() && style.getText().getText())) {
311
+ return;
312
+ }
313
+ const validGeometries = geometries.filter(point => validatePoint(point));
314
+
315
+ // no geometries, so early escape
316
+ if (!validGeometries.length) {
317
+ return;
318
+ }
319
+
320
+ const coordinates = getCoordinates(validGeometries);
321
+ const heightInfo = getHeightInfo(feature, vectorProperties, coordinates);
322
+ let { heightReference } = heightInfo;
323
+ const allowPicking = vectorProperties.getAllowPicking(feature);
324
+
325
+ const { positions, wgs84Positions } = getCartesian3AndWGS84FromCoordinates(coordinates, heightInfo);
326
+
327
+ const modelOptions = getModelOptions(feature, wgs84Positions, positions, vectorProperties, scene);
328
+ if (modelOptions) {
329
+ context.addPrimitives(modelOptions, feature, allowPicking);
330
+ } else {
331
+ if (heightInfo.extruded && style.getStroke()) {
332
+ const lineGeometries = getLineGeometries(wgs84Positions, heightInfo, positions, style);
333
+ if (lineGeometries.length) {
334
+ heightReference = HeightReference.NONE;
335
+ const linePrimitive =
336
+ createLinePrimitive(scene, vectorProperties, allowPicking, feature, lineGeometries, style, false);
337
+ if (linePrimitive) {
338
+ context.addPrimitives([linePrimitive], feature, allowPicking);
339
+ }
340
+ }
341
+ }
342
+
343
+ const bbOptions = getBillboardOptions(feature, style, heightReference, vectorProperties);
344
+ if (bbOptions) {
345
+ const bbOptionsperPosition = positions.map((position) => {
346
+ return { ...bbOptions, position };
347
+ });
348
+ context.addBillboards(bbOptionsperPosition, feature, allowPicking);
349
+ }
350
+
351
+ const labelOptions = getLabelOptions(feature, style, heightReference, vectorProperties);
352
+ if (labelOptions) {
353
+ const labelOptionsPerPosition = positions.map((position) => {
354
+ return { ...labelOptions, position };
355
+ });
356
+ context.addLabels(labelOptionsPerPosition, feature, allowPicking);
357
+ }
358
+ }
359
+ }