@vcmap/core 6.0.0-rc.9 → 6.0.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 (203) hide show
  1. package/README.md +4 -1
  2. package/dist/cesium.d.ts +117 -0
  3. package/dist/index.d.ts +14 -6
  4. package/dist/index.js +12 -4
  5. package/dist/index.js.map +1 -1
  6. package/dist/ol.d.ts +1 -0
  7. package/dist/src/cesium/cesium3DTileFeature.d.ts +2 -1
  8. package/dist/src/cesium/cesium3DTileFeature.js +13 -1
  9. package/dist/src/cesium/cesium3DTileFeature.js.map +1 -1
  10. package/dist/src/cesium/cesium3DTilePointFeature.js +2 -0
  11. package/dist/src/cesium/cesium3DTilePointFeature.js.map +1 -1
  12. package/dist/src/cesium/entity.js +3 -0
  13. package/dist/src/cesium/entity.js.map +1 -1
  14. package/dist/src/interaction/featureAtPixelInteraction.d.ts +4 -12
  15. package/dist/src/interaction/featureAtPixelInteraction.js +6 -27
  16. package/dist/src/interaction/featureAtPixelInteraction.js.map +1 -1
  17. package/dist/src/layer/cesium/openStreetMapCesiumImpl.js +2 -4
  18. package/dist/src/layer/cesium/openStreetMapCesiumImpl.js.map +1 -1
  19. package/dist/src/layer/cesium/rasterLayerCesiumImpl.d.ts +4 -0
  20. package/dist/src/layer/cesium/rasterLayerCesiumImpl.js +15 -0
  21. package/dist/src/layer/cesium/rasterLayerCesiumImpl.js.map +1 -1
  22. package/dist/src/layer/cesium/singleImageCesiumImpl.js +2 -6
  23. package/dist/src/layer/cesium/singleImageCesiumImpl.js.map +1 -1
  24. package/dist/src/layer/cesium/terrainCesiumImpl.js +3 -0
  25. package/dist/src/layer/cesium/terrainCesiumImpl.js.map +1 -1
  26. package/dist/src/layer/cesium/tmsCesiumImpl.js +1 -4
  27. package/dist/src/layer/cesium/tmsCesiumImpl.js.map +1 -1
  28. package/dist/src/layer/cesium/vcsTile/vcsChildTile.d.ts +12 -0
  29. package/dist/src/layer/cesium/vcsTile/vcsChildTile.js +18 -0
  30. package/dist/src/layer/cesium/vcsTile/vcsChildTile.js.map +1 -0
  31. package/dist/src/layer/cesium/vcsTile/vcsDebugTile.d.ts +21 -0
  32. package/dist/src/layer/cesium/vcsTile/vcsDebugTile.js +89 -0
  33. package/dist/src/layer/cesium/vcsTile/vcsDebugTile.js.map +1 -0
  34. package/dist/src/layer/cesium/vcsTile/vcsNoDataTile.d.ts +11 -0
  35. package/dist/src/layer/cesium/vcsTile/vcsNoDataTile.js +17 -0
  36. package/dist/src/layer/cesium/vcsTile/vcsNoDataTile.js.map +1 -0
  37. package/dist/src/layer/cesium/vcsTile/vcsQuadtreeTileProvider.d.ts +39 -0
  38. package/dist/src/layer/cesium/vcsTile/vcsQuadtreeTileProvider.js +192 -0
  39. package/dist/src/layer/cesium/vcsTile/vcsQuadtreeTileProvider.js.map +1 -0
  40. package/dist/src/layer/cesium/vcsTile/vcsTileHelpers.d.ts +52 -0
  41. package/dist/src/layer/cesium/vcsTile/vcsTileHelpers.js +73 -0
  42. package/dist/src/layer/cesium/vcsTile/vcsTileHelpers.js.map +1 -0
  43. package/dist/src/layer/cesium/vcsTile/vcsVectorTile.d.ts +23 -0
  44. package/dist/src/layer/cesium/vcsTile/vcsVectorTile.js +87 -0
  45. package/dist/src/layer/cesium/vcsTile/vcsVectorTile.js.map +1 -0
  46. package/dist/src/layer/cesium/vectorCesiumImpl.js +1 -1
  47. package/dist/src/layer/cesium/vectorCesiumImpl.js.map +1 -1
  48. package/dist/src/layer/cesium/vectorTileCesiumImpl.d.ts +19 -0
  49. package/dist/src/layer/cesium/vectorTileCesiumImpl.js +63 -0
  50. package/dist/src/layer/cesium/vectorTileCesiumImpl.js.map +1 -0
  51. package/dist/src/layer/cesium/wmsCesiumImpl.js +1 -4
  52. package/dist/src/layer/cesium/wmsCesiumImpl.js.map +1 -1
  53. package/dist/src/layer/cesium/wmtsCesiumImpl.js +1 -4
  54. package/dist/src/layer/cesium/wmtsCesiumImpl.js.map +1 -1
  55. package/dist/src/layer/layer.d.ts +5 -0
  56. package/dist/src/layer/layer.js +5 -0
  57. package/dist/src/layer/layer.js.map +1 -1
  58. package/dist/src/layer/openStreetMapLayer.d.ts +32 -2
  59. package/dist/src/layer/openStreetMapLayer.js +35 -1
  60. package/dist/src/layer/openStreetMapLayer.js.map +1 -1
  61. package/dist/src/layer/openlayers/openStreetMapOpenlayersImpl.js +2 -0
  62. package/dist/src/layer/openlayers/openStreetMapOpenlayersImpl.js.map +1 -1
  63. package/dist/src/layer/openlayers/rasterLayerOpenlayersImpl.d.ts +2 -0
  64. package/dist/src/layer/openlayers/rasterLayerOpenlayersImpl.js +4 -0
  65. package/dist/src/layer/openlayers/rasterLayerOpenlayersImpl.js.map +1 -1
  66. package/dist/src/layer/openlayers/singleImageOpenlayersImpl.js +2 -0
  67. package/dist/src/layer/openlayers/singleImageOpenlayersImpl.js.map +1 -1
  68. package/dist/src/layer/openlayers/tmsOpenlayersImpl.js +2 -0
  69. package/dist/src/layer/openlayers/tmsOpenlayersImpl.js.map +1 -1
  70. package/dist/src/layer/openlayers/vectorTileOpenlayersImpl.d.ts +1 -7
  71. package/dist/src/layer/openlayers/vectorTileOpenlayersImpl.js +3 -35
  72. package/dist/src/layer/openlayers/vectorTileOpenlayersImpl.js.map +1 -1
  73. package/dist/src/layer/openlayers/wmsOpenlayersImpl.js +4 -0
  74. package/dist/src/layer/openlayers/wmsOpenlayersImpl.js.map +1 -1
  75. package/dist/src/layer/openlayers/wmtsOpenlayersImpl.js +2 -0
  76. package/dist/src/layer/openlayers/wmtsOpenlayersImpl.js.map +1 -1
  77. package/dist/src/layer/pointCloudLayer.d.ts +0 -1
  78. package/dist/src/layer/pointCloudLayer.js +2 -3
  79. package/dist/src/layer/pointCloudLayer.js.map +1 -1
  80. package/dist/src/layer/rasterLayer.d.ts +44 -3
  81. package/dist/src/layer/rasterLayer.js +43 -0
  82. package/dist/src/layer/rasterLayer.js.map +1 -1
  83. package/dist/src/layer/tileProvider/mvtTileProvider.d.ts +0 -5
  84. package/dist/src/layer/tileProvider/mvtTileProvider.js +0 -12
  85. package/dist/src/layer/tileProvider/mvtTileProvider.js.map +1 -1
  86. package/dist/src/layer/tileProvider/staticFeatureTileProvider.d.ts +14 -0
  87. package/dist/src/layer/tileProvider/staticFeatureTileProvider.js +44 -0
  88. package/dist/src/layer/tileProvider/staticFeatureTileProvider.js.map +1 -0
  89. package/dist/src/layer/tileProvider/tileProvider.d.ts +8 -2
  90. package/dist/src/layer/tileProvider/tileProvider.js +17 -1
  91. package/dist/src/layer/tileProvider/tileProvider.js.map +1 -1
  92. package/dist/src/layer/vectorLayer.d.ts +1 -1
  93. package/dist/src/layer/vectorLayer.js.map +1 -1
  94. package/dist/src/layer/vectorTileLayer.d.ts +13 -3
  95. package/dist/src/layer/vectorTileLayer.js +43 -13
  96. package/dist/src/layer/vectorTileLayer.js.map +1 -1
  97. package/dist/src/map/cesiumMap.d.ts +8 -1
  98. package/dist/src/map/cesiumMap.js +17 -6
  99. package/dist/src/map/cesiumMap.js.map +1 -1
  100. package/dist/src/ol/feature.js +7 -0
  101. package/dist/src/ol/feature.js.map +1 -1
  102. package/dist/src/style/declarativeStyleItem.js +2 -68
  103. package/dist/src/style/declarativeStyleItem.js.map +1 -1
  104. package/dist/src/util/displayQuality/displayQuality.d.ts +1 -0
  105. package/dist/src/util/displayQuality/displayQuality.js +12 -1
  106. package/dist/src/util/displayQuality/displayQuality.js.map +1 -1
  107. package/dist/src/util/editor/createFeatureSession.d.ts +8 -4
  108. package/dist/src/util/editor/createFeatureSession.js +35 -11
  109. package/dist/src/util/editor/createFeatureSession.js.map +1 -1
  110. package/dist/src/util/editor/editGeometrySession.d.ts +2 -1
  111. package/dist/src/util/editor/editGeometrySession.js +33 -12
  112. package/dist/src/util/editor/editGeometrySession.js.map +1 -1
  113. package/dist/src/util/editor/editorHelpers.d.ts +1 -0
  114. package/dist/src/util/editor/editorHelpers.js +6 -0
  115. package/dist/src/util/editor/editorHelpers.js.map +1 -1
  116. package/dist/src/util/editor/editorSessionHelpers.d.ts +1 -6
  117. package/dist/src/util/editor/editorSessionHelpers.js +5 -16
  118. package/dist/src/util/editor/editorSessionHelpers.js.map +1 -1
  119. package/dist/src/util/editor/interactions/editGeometryMouseOverInteraction.js +3 -2
  120. package/dist/src/util/editor/interactions/editGeometryMouseOverInteraction.js.map +1 -1
  121. package/dist/src/util/editor/interactions/removeVertexInteraction.d.ts +1 -1
  122. package/dist/src/util/editor/interactions/removeVertexInteraction.js +2 -2
  123. package/dist/src/util/editor/interactions/removeVertexInteraction.js.map +1 -1
  124. package/dist/src/util/editor/interactions/segmentLengthInteraction.d.ts +16 -0
  125. package/dist/src/util/editor/interactions/segmentLengthInteraction.js +167 -0
  126. package/dist/src/util/editor/interactions/segmentLengthInteraction.js.map +1 -0
  127. package/dist/src/util/editor/interactions/translateVertexInteraction.js +2 -6
  128. package/dist/src/util/editor/interactions/translateVertexInteraction.js.map +1 -1
  129. package/dist/src/util/editor/interactions/translationSnapping.js +3 -2
  130. package/dist/src/util/editor/interactions/translationSnapping.js.map +1 -1
  131. package/dist/src/util/featureconverter/clampedPrimitive.d.ts +2 -2
  132. package/dist/src/util/featureconverter/clampedPrimitive.js +24 -2
  133. package/dist/src/util/featureconverter/clampedPrimitive.js.map +1 -1
  134. package/dist/src/util/featureconverter/convert.js +12 -3
  135. package/dist/src/util/featureconverter/convert.js.map +1 -1
  136. package/dist/src/util/geometryHelpers.d.ts +9 -1
  137. package/dist/src/util/geometryHelpers.js +54 -4
  138. package/dist/src/util/geometryHelpers.js.map +1 -1
  139. package/dist/src/util/math.d.ts +12 -0
  140. package/dist/src/util/math.js +21 -0
  141. package/dist/src/util/math.js.map +1 -1
  142. package/dist/src/util/projection.js +1 -1
  143. package/dist/src/util/projection.js.map +1 -1
  144. package/dist/tests/unit/helpers/cesiumHelpers.d.ts +2 -2
  145. package/dist/tests/unit/helpers/cesiumHelpers.js +2 -1
  146. package/dist/tests/unit/helpers/cesiumHelpers.js.map +1 -1
  147. package/index.ts +26 -2
  148. package/package.json +3 -3
  149. package/src/cesium/cesium.d.ts +117 -0
  150. package/src/cesium/cesium3DTileFeature.ts +20 -1
  151. package/src/cesium/cesium3DTilePointFeature.ts +3 -0
  152. package/src/cesium/entity.ts +7 -0
  153. package/src/interaction/featureAtPixelInteraction.ts +8 -39
  154. package/src/layer/cesium/openStreetMapCesiumImpl.ts +2 -4
  155. package/src/layer/cesium/rasterLayerCesiumImpl.ts +19 -0
  156. package/src/layer/cesium/singleImageCesiumImpl.ts +2 -6
  157. package/src/layer/cesium/terrainCesiumImpl.ts +3 -0
  158. package/src/layer/cesium/tmsCesiumImpl.ts +1 -4
  159. package/src/layer/cesium/vcsTile/vcsChildTile.ts +31 -0
  160. package/src/layer/cesium/vcsTile/vcsDebugTile.ts +154 -0
  161. package/src/layer/cesium/vcsTile/vcsNoDataTile.ts +30 -0
  162. package/src/layer/cesium/vcsTile/vcsQuadtreeTileProvider.ts +290 -0
  163. package/src/layer/cesium/vcsTile/vcsTileHelpers.ts +134 -0
  164. package/src/layer/cesium/vcsTile/vcsVectorTile.ts +149 -0
  165. package/src/layer/cesium/vectorCesiumImpl.ts +1 -1
  166. package/src/layer/cesium/vectorTileCesiumImpl.ts +91 -0
  167. package/src/layer/cesium/wmsCesiumImpl.ts +1 -4
  168. package/src/layer/cesium/wmtsCesiumImpl.ts +1 -4
  169. package/src/layer/layer.ts +5 -0
  170. package/src/layer/openStreetMapLayer.ts +64 -2
  171. package/src/layer/openlayers/openStreetMapOpenlayersImpl.ts +2 -0
  172. package/src/layer/openlayers/rasterLayerOpenlayersImpl.ts +6 -0
  173. package/src/layer/openlayers/singleImageOpenlayersImpl.ts +2 -0
  174. package/src/layer/openlayers/tmsOpenlayersImpl.ts +2 -0
  175. package/src/layer/openlayers/vectorTileOpenlayersImpl.ts +3 -37
  176. package/src/layer/openlayers/wmsOpenlayersImpl.ts +4 -0
  177. package/src/layer/openlayers/wmtsOpenlayersImpl.ts +2 -0
  178. package/src/layer/pointCloudLayer.ts +2 -3
  179. package/src/layer/rasterLayer.ts +81 -2
  180. package/src/layer/tileProvider/mvtTileProvider.ts +0 -18
  181. package/src/layer/tileProvider/staticFeatureTileProvider.ts +61 -0
  182. package/src/layer/tileProvider/tileProvider.ts +27 -2
  183. package/src/layer/vectorLayer.ts +1 -1
  184. package/src/layer/vectorTileLayer.ts +72 -17
  185. package/src/map/cesiumMap.ts +28 -6
  186. package/src/ol/feature.ts +10 -0
  187. package/src/ol/ol.d.ts +1 -0
  188. package/src/style/declarativeStyleItem.ts +2 -72
  189. package/src/util/displayQuality/displayQuality.ts +13 -1
  190. package/src/util/editor/createFeatureSession.ts +51 -13
  191. package/src/util/editor/editGeometrySession.ts +41 -10
  192. package/src/util/editor/editorHelpers.ts +13 -0
  193. package/src/util/editor/editorSessionHelpers.ts +6 -20
  194. package/src/util/editor/interactions/editGeometryMouseOverInteraction.ts +4 -4
  195. package/src/util/editor/interactions/removeVertexInteraction.ts +3 -4
  196. package/src/util/editor/interactions/segmentLengthInteraction.ts +227 -0
  197. package/src/util/editor/interactions/translateVertexInteraction.ts +3 -10
  198. package/src/util/editor/interactions/translationSnapping.ts +4 -4
  199. package/src/util/featureconverter/clampedPrimitive.ts +53 -5
  200. package/src/util/featureconverter/convert.ts +18 -2
  201. package/src/util/geometryHelpers.ts +63 -4
  202. package/src/util/math.ts +28 -0
  203. package/src/util/projection.ts +1 -1
@@ -5,9 +5,8 @@ import {
5
5
  EventType,
6
6
  ModificationKeyType,
7
7
  } from '../../../interaction/interactionType.js';
8
- import { vertexSymbol } from '../editorSymbols.js';
9
8
  import VcsEvent from '../../../vcsEvent.js';
10
- import type { Vertex } from '../editorHelpers.js';
9
+ import { isVertex, Vertex } from '../editorHelpers.js';
11
10
 
12
11
  /**
13
12
  * This interaction will raise the passed in event for each feature clicked with the vertex symbol
@@ -22,8 +21,8 @@ class RemoveVertexInteraction extends AbstractInteraction {
22
21
  }
23
22
 
24
23
  pipe(event: EventAfterEventHandler): Promise<EventAfterEventHandler> {
25
- if (event.feature && (event.feature as Vertex)[vertexSymbol]) {
26
- this.vertexRemoved.raiseEvent(event.feature as Vertex);
24
+ if (isVertex(event.feature)) {
25
+ this.vertexRemoved.raiseEvent(event.feature);
27
26
  }
28
27
  return Promise.resolve(event);
29
28
  }
@@ -0,0 +1,227 @@
1
+ import { Circle, LineString, Point, Polygon } from 'ol/geom.js';
2
+ import type { Coordinate } from 'ol/coordinate.js';
3
+ import { Style, Text as OLText } from 'ol/style.js';
4
+ import { Feature } from 'ol';
5
+ import { HeightReference } from '@vcmap-cesium/engine';
6
+ import AbstractInteraction, {
7
+ InteractionEvent,
8
+ } from '../../../interaction/abstractInteraction.js';
9
+ import {
10
+ EventType,
11
+ ModificationKeyType,
12
+ } from '../../../interaction/interactionType.js';
13
+ import { isVertex } from '../editorHelpers.js';
14
+ import { vertexIndexSymbol } from '../editorSymbols.js';
15
+ import type VectorLayer from '../../../layer/vectorLayer.js';
16
+ import { is2DLayout } from '../../geometryHelpers.js';
17
+
18
+ import { ecef3DDistance, getMidPoint, spherical2Distance } from '../../math.js';
19
+ import { validityPlaceholder } from './createPolygonInteraction.js';
20
+ import { createSync } from '../../../layer/vectorSymbols.js';
21
+
22
+ type Segment = [Coordinate, Coordinate];
23
+
24
+ function getSegmentForCoordinateIndex(
25
+ geometry: LineString | Polygon | Circle,
26
+ index: number,
27
+ ): Segment[] {
28
+ if (geometry instanceof Circle) {
29
+ return [geometry.getCoordinates() as Segment];
30
+ }
31
+ const flats = geometry.getFlatCoordinates();
32
+ let end;
33
+ let isPolygon = false;
34
+ if (geometry instanceof Polygon) {
35
+ isPolygon = true;
36
+ end = geometry.getEnds()[0];
37
+ } else {
38
+ end = flats.length;
39
+ }
40
+ const stride = geometry.getStride();
41
+ const layout = geometry.getLayout();
42
+
43
+ if (flats.length < stride * 2) {
44
+ return [];
45
+ }
46
+
47
+ let flatIndex = Math.round(index * stride);
48
+ if (index === -1) {
49
+ flatIndex = end - stride;
50
+ }
51
+
52
+ if (flats.length < flatIndex + stride) {
53
+ return [];
54
+ }
55
+
56
+ const previousIndex = index === 0 ? stride : flatIndex - stride;
57
+ let nextIndex;
58
+
59
+ if (isPolygon && !(geometry as Polygon)[validityPlaceholder]) {
60
+ if (flatIndex === 0) {
61
+ nextIndex = end - stride;
62
+ } else if (flatIndex + stride === end) {
63
+ nextIndex = 0;
64
+ } else {
65
+ nextIndex = flatIndex + stride;
66
+ }
67
+ } else if (flatIndex > 0 && flatIndex + stride < end) {
68
+ nextIndex = flatIndex + stride;
69
+ }
70
+
71
+ const getCoordinateFromIndex = is2DLayout(layout)
72
+ ? (i: number): Coordinate => {
73
+ return [flats[i], flats[i + 1]];
74
+ }
75
+ : (i: number): Coordinate => {
76
+ return [flats[i], flats[i + 1], flats[i + 2]];
77
+ };
78
+
79
+ const segments: Segment[] = [
80
+ [getCoordinateFromIndex(flatIndex), getCoordinateFromIndex(previousIndex)],
81
+ ];
82
+
83
+ if (nextIndex != null && flats.length >= nextIndex + stride) {
84
+ segments.push([
85
+ getCoordinateFromIndex(flatIndex),
86
+ getCoordinateFromIndex(nextIndex),
87
+ ]);
88
+ }
89
+
90
+ return segments;
91
+ }
92
+
93
+ function createSegmentsLabels(
94
+ segments: Segment[],
95
+ layer: VectorLayer,
96
+ is3D: boolean,
97
+ ): () => void {
98
+ const features = segments.map((segment) => {
99
+ const midPoint = getMidPoint(segment[0], segment[1]);
100
+ const feature = new Feature({
101
+ geometry: new Point(midPoint),
102
+ });
103
+
104
+ const segmentLength = is3D
105
+ ? ecef3DDistance(segment[0], segment[1])
106
+ : spherical2Distance(segment[0], segment[1]);
107
+
108
+ feature.setStyle(
109
+ new Style({
110
+ text: new OLText({
111
+ text: `${segmentLength.toFixed(2)} m`,
112
+ font: '16px Helvetica, sans-serif',
113
+ }),
114
+ }),
115
+ );
116
+ feature[createSync] = true;
117
+
118
+ return feature;
119
+ });
120
+ layer.addFeatures(features);
121
+
122
+ return () => {
123
+ layer.removeFeaturesById(features.map((f) => f.getId()!));
124
+ features.splice(0);
125
+ };
126
+ }
127
+
128
+ function createSegmentGeometry(
129
+ segment: Segment,
130
+ layer: VectorLayer,
131
+ ): () => void {
132
+ const feature = new Feature({
133
+ geometry: new LineString(segment),
134
+ });
135
+ feature[createSync] = true;
136
+
137
+ const features = [feature];
138
+ layer.addFeatures(features);
139
+
140
+ return () => {
141
+ layer.removeFeaturesById(features.map((f) => f.getId()!));
142
+ features.splice(0);
143
+ };
144
+ }
145
+
146
+ export default class SegmentLengthInteraction extends AbstractInteraction {
147
+ private _scratchLayer: VectorLayer;
148
+
149
+ private _geometry: Polygon | LineString | Circle | undefined;
150
+
151
+ private _isCircle = false;
152
+
153
+ // eslint-disable-next-line class-methods-use-this
154
+ private _removeLabels = (): void => {};
155
+
156
+ // eslint-disable-next-line class-methods-use-this
157
+ private _vectorPropertiesListener = (): void => {};
158
+
159
+ private _is3D = false;
160
+
161
+ creation: boolean;
162
+
163
+ constructor(scratchLayer: VectorLayer, creation: boolean) {
164
+ super(
165
+ creation ? EventType.MOVE : EventType.DRAGEVENTS,
166
+ ModificationKeyType.CTRL | ModificationKeyType.NONE,
167
+ );
168
+
169
+ this._scratchLayer = scratchLayer;
170
+ this._is3D =
171
+ scratchLayer.vectorProperties.altitudeMode === HeightReference.NONE;
172
+ this._vectorPropertiesListener =
173
+ scratchLayer.vectorProperties.propertyChanged.addEventListener(() => {
174
+ this._is3D =
175
+ scratchLayer.vectorProperties.altitudeMode === HeightReference.NONE;
176
+ });
177
+
178
+ this.creation = creation;
179
+ }
180
+
181
+ pipe(event: InteractionEvent): Promise<InteractionEvent> {
182
+ this._removeLabels();
183
+
184
+ if (this._geometry) {
185
+ let index: number | undefined;
186
+ if (this.creation) {
187
+ index = -1;
188
+ } else if (isVertex(event.feature)) {
189
+ index = event.feature[vertexIndexSymbol];
190
+ }
191
+
192
+ if (index != null) {
193
+ const segments = getSegmentForCoordinateIndex(this._geometry, index);
194
+ let removeLabels = createSegmentsLabels(
195
+ segments,
196
+ this._scratchLayer,
197
+ this._is3D,
198
+ );
199
+ if (this._isCircle) {
200
+ const removeTextLabels = removeLabels;
201
+ const removeSegment = createSegmentGeometry(
202
+ segments[0],
203
+ this._scratchLayer,
204
+ );
205
+ removeLabels = (): void => {
206
+ removeTextLabels();
207
+ removeSegment();
208
+ };
209
+ }
210
+ this._removeLabels = removeLabels;
211
+ }
212
+ }
213
+
214
+ return Promise.resolve(event);
215
+ }
216
+
217
+ setGeometry(geometry: LineString | Polygon | Circle): void {
218
+ this._geometry = geometry;
219
+ this._isCircle = geometry instanceof Circle;
220
+ }
221
+
222
+ destroy(): void {
223
+ this._removeLabels();
224
+ this._vectorPropertiesListener();
225
+ super.destroy();
226
+ }
227
+ }
@@ -6,9 +6,8 @@ import {
6
6
  EventType,
7
7
  ModificationKeyType,
8
8
  } from '../../../interaction/interactionType.js';
9
- import { vertexSymbol } from '../editorSymbols.js';
10
9
  import VcsEvent from '../../../vcsEvent.js';
11
- import { Vertex } from '../editorHelpers.js';
10
+ import { isVertex, Vertex } from '../editorHelpers.js';
12
11
  import { emptyStyle } from '../../../style/styleHelpers.js';
13
12
 
14
13
  /**
@@ -42,17 +41,11 @@ class TranslateVertexInteraction extends AbstractInteraction {
42
41
  this._vertex.setStyle(undefined);
43
42
  this._vertex = null;
44
43
  }
45
- event.stopPropagation = true;
46
- } else if (
47
- event.type & EventType.DRAGSTART &&
48
- event.feature &&
49
- (event.feature as Vertex)[vertexSymbol]
50
- ) {
51
- this._vertex = event.feature as Vertex;
44
+ } else if (event.type & EventType.DRAGSTART && isVertex(event.feature)) {
45
+ this._vertex = event.feature;
52
46
  this._vertex.set('olcs_allowPicking', false);
53
47
  this._feature.set('olcs_allowPicking', false);
54
48
  this._vertex.setStyle(emptyStyle);
55
- event.stopPropagation = true;
56
49
  }
57
50
  return Promise.resolve(event);
58
51
  }
@@ -16,8 +16,8 @@ import {
16
16
  SnapType,
17
17
  snapTypes,
18
18
  } from '../snappingHelpers.js';
19
- import { vertexIndexSymbol, vertexSymbol } from '../editorSymbols.js';
20
- import { Vertex } from '../editorHelpers.js';
19
+ import { vertexIndexSymbol } from '../editorSymbols.js';
20
+ import { isVertex } from '../editorHelpers.js';
21
21
  import {
22
22
  alreadySnapped,
23
23
  SnappingInteractionEvent,
@@ -149,9 +149,9 @@ export default class TranslationSnapping extends AbstractInteraction {
149
149
  this._lastCoordinate = undefined;
150
150
  } else if (
151
151
  event.key !== ModificationKeyType.CTRL &&
152
- (event.feature as Vertex | undefined)?.[vertexSymbol]
152
+ isVertex(event.feature)
153
153
  ) {
154
- const index = (event.feature as Vertex)[vertexIndexSymbol];
154
+ const index = event.feature[vertexIndexSymbol];
155
155
  if (event.type === EventType.DRAGSTART) {
156
156
  this._setCoordinates(index);
157
157
  }
@@ -1,6 +1,7 @@
1
1
  import {
2
2
  Cartesian3,
3
3
  Cartographic,
4
+ ClassificationPrimitive,
4
5
  HeightReference,
5
6
  Matrix4,
6
7
  Model,
@@ -37,19 +38,66 @@ function getUpdateHeightCallback(
37
38
  };
38
39
  }
39
40
 
41
+ function getUpdateClassificationHeightCallback(
42
+ primitive: ClassificationPrimitive,
43
+ originalPosition: Cartesian3,
44
+ ): (cartographic: Cartographic) => void {
45
+ return function updatePrimitiveHeight(clampedPosition: Cartographic) {
46
+ Cartographic.toCartesian(
47
+ clampedPosition,
48
+ undefined,
49
+ scratchUpdateHeightCartesian,
50
+ );
51
+
52
+ Cartesian3.subtract(
53
+ scratchUpdateHeightCartesian,
54
+ originalPosition,
55
+ scratchUpdateHeightCartesian,
56
+ );
57
+
58
+ if (primitive.ready) {
59
+ // eslint-disable-next-line no-underscore-dangle
60
+ const innerPrimitive = primitive._primitive as Primitive;
61
+
62
+ const { modelMatrix } = innerPrimitive;
63
+ innerPrimitive.modelMatrix = Matrix4.setTranslation(
64
+ modelMatrix,
65
+ scratchUpdateHeightCartesian,
66
+ new Matrix4(),
67
+ );
68
+ } else {
69
+ // eslint-disable-next-line no-underscore-dangle
70
+ primitive._primitiveOptions!.modelMatrix = Matrix4.setTranslation(
71
+ Matrix4.IDENTITY,
72
+ scratchUpdateHeightCartesian,
73
+ new Matrix4(),
74
+ );
75
+ }
76
+ };
77
+ }
78
+
40
79
  // eslint-disable-next-line import/prefer-default-export
41
80
  export function setupClampedPrimitive(
42
81
  scene: Scene,
43
- primitive: Primitive | Model,
82
+ primitive: Primitive | Model | ClassificationPrimitive,
44
83
  origin: [number, number],
45
84
  heightReference: HeightReference,
46
85
  ): void {
47
86
  const destroy = primitive.destroy.bind(primitive);
48
87
  const originCartographic = mercatorToCartographic(origin);
49
- const callback = getUpdateHeightCallback(
50
- primitive,
51
- Cartographic.toCartesian(originCartographic),
52
- );
88
+ let callback;
89
+ if (primitive instanceof ClassificationPrimitive) {
90
+ callback = getUpdateClassificationHeightCallback(
91
+ primitive,
92
+ Cartographic.toCartesian(originCartographic),
93
+ );
94
+ } else {
95
+ callback = getUpdateHeightCallback(
96
+ primitive,
97
+ Cartographic.toCartesian(originCartographic),
98
+ );
99
+ }
100
+
53
101
  const callbackHandler = scene.updateHeight(
54
102
  originCartographic,
55
103
  callback,
@@ -324,12 +324,23 @@ function getPrimitiveBatches(
324
324
 
325
325
  function getClampedPrimitiveBatches(
326
326
  options: CesiumGeometryOption<'solid' | 'outline' | 'line' | 'fill'>[],
327
+ feature: Feature,
328
+ vectorProperties: VectorProperties,
329
+ scene: Scene,
327
330
  ): PrimitiveBatches {
328
331
  const batches = createPrimitiveBatches();
332
+ const classification = vectorProperties.getClassificationType(feature);
333
+ const classificationSupported = ClassificationPrimitive.isSupported(scene);
329
334
 
330
335
  options.forEach((item) => {
331
336
  if (item.type === 'solid' || item.type === 'fill') {
332
- batches.solidPrimitive.push(item);
337
+ if (classification != null) {
338
+ if (classificationSupported) {
339
+ batches.classificationPrimitive.push(item);
340
+ }
341
+ } else {
342
+ batches.solidPrimitive.push(item);
343
+ }
333
344
  } else if (item.type === 'outline') {
334
345
  batches.outlinePrimitive.push(item);
335
346
  } else if (item.type === 'line') {
@@ -414,7 +425,12 @@ function batchPrimitives(
414
425
 
415
426
  batches.clampedPrimitives.forEach((options, originHash) => {
416
427
  const [x, y, heightReference] = originHash.split(':').map(Number);
417
- const clampedBatches = getClampedPrimitiveBatches(options);
428
+ const clampedBatches = getClampedPrimitiveBatches(
429
+ options,
430
+ feature,
431
+ vectorProperties,
432
+ scene,
433
+ );
418
434
  const clampedItems = batchPrimitives(
419
435
  clampedBatches,
420
436
  feature,
@@ -221,7 +221,62 @@ export function from3Dto2DLayout(geometry: Geometry): void {
221
221
  * @param scene
222
222
  * @param heightReference - clamp to ground will use `scene.getHeightMostDetailed`, terrain will use `sampleTerrainMostDetailed` using the scenes terrain provider
223
223
  */
224
- export async function placeGeometryOnGround(
224
+ export async function placeGeometryOnSurface(
225
+ geometry: Geometry,
226
+ scene: Scene,
227
+ heightReference:
228
+ | HeightReference.CLAMP_TO_GROUND
229
+ | HeightReference.CLAMP_TO_TERRAIN,
230
+ ): Promise<void> {
231
+ const layout = geometry.getLayout();
232
+ const coordinates = geometry.getCoordinates() as any[];
233
+ const flatCoordinates = getFlatCoordinateReferences(geometry, coordinates);
234
+ const drapedCartographics = flatCoordinates.map((c) =>
235
+ mercatorToCartographic(c),
236
+ );
237
+ if (heightReference === HeightReference.CLAMP_TO_GROUND) {
238
+ await scene.sampleHeightMostDetailed(drapedCartographics);
239
+ } else if (scene.terrainProvider.availability) {
240
+ await sampleTerrainMostDetailed(scene.terrainProvider, drapedCartographics);
241
+ } else {
242
+ drapedCartographics.forEach((c) => {
243
+ c.height = 0;
244
+ });
245
+ }
246
+ if (layout === 'XY' || layout === 'XYM') {
247
+ const height = Math.max(...drapedCartographics.map((c) => c.height));
248
+ flatCoordinates.forEach((c, index) => {
249
+ if (layout === 'XYM') {
250
+ flatCoordinates[index][3] = c[2];
251
+ }
252
+ flatCoordinates[index][2] = height;
253
+ });
254
+ } else {
255
+ const maxDiff = flatCoordinates.reduce((acc, coord, index) => {
256
+ const current = drapedCartographics[index].height - coord[2];
257
+ return Math.max(current, acc);
258
+ }, -Infinity);
259
+ if (Number.isFinite(maxDiff) && maxDiff !== 0) {
260
+ flatCoordinates.forEach((_c, index) => {
261
+ flatCoordinates[index][2] += maxDiff;
262
+ });
263
+ }
264
+ }
265
+
266
+ geometry.setCoordinates(
267
+ coordinates,
268
+ layout === 'XYM' || layout === 'XYZM' ? 'XYZM' : 'XYZ',
269
+ );
270
+ }
271
+
272
+ /**
273
+ * Drape a geometry on to the ground (or terrain). The geometry is changed in place. This function
274
+ * will set the layout to a respective 3D layout.
275
+ * @param geometry
276
+ * @param scene
277
+ * @param heightReference - clamp to ground will use `scene.getHeightMostDetailed`, terrain will use `sampleTerrainMostDetailed` using the scenes terrain provider
278
+ */
279
+ export async function drapeGeometryOnSurface(
225
280
  geometry: Geometry,
226
281
  scene: Scene,
227
282
  heightReference:
@@ -234,8 +289,12 @@ export async function placeGeometryOnGround(
234
289
  const cartographics = flatCoordinates.map((c) => mercatorToCartographic(c));
235
290
  if (heightReference === HeightReference.CLAMP_TO_GROUND) {
236
291
  await scene.sampleHeightMostDetailed(cartographics);
237
- } else {
292
+ } else if (scene.terrainProvider.availability) {
238
293
  await sampleTerrainMostDetailed(scene.terrainProvider, cartographics);
294
+ } else {
295
+ cartographics.forEach((c) => {
296
+ c.height = 0;
297
+ });
239
298
  }
240
299
 
241
300
  cartographics.forEach((c, index) => {
@@ -268,7 +327,7 @@ export async function from2Dto3DLayout(
268
327
  | HeightReference.CLAMP_TO_TERRAIN,
269
328
  ): Promise<void> {
270
329
  if (is2DLayout(geometry.getLayout())) {
271
- await placeGeometryOnGround(geometry, scene, heightReference);
330
+ await drapeGeometryOnSurface(geometry, scene, heightReference);
272
331
  }
273
332
  }
274
333
 
@@ -316,7 +375,7 @@ export async function createAbsoluteFeature(
316
375
  if (groundLevel != null) {
317
376
  setZCoordinate(geometry, groundLevel);
318
377
  } else {
319
- await placeGeometryOnGround(
378
+ await drapeGeometryOnSurface(
320
379
  geometry,
321
380
  scene,
322
381
  altitudeMode !== HeightReference.CLAMP_TO_TERRAIN
package/src/util/math.ts CHANGED
@@ -4,6 +4,7 @@ import {
4
4
  Cartographic,
5
5
  } from '@vcmap-cesium/engine';
6
6
  import type { Coordinate } from 'ol/coordinate.js';
7
+ import { getDistance as haversineDistance } from 'ol/sphere.js';
7
8
  import Projection from './projection.js';
8
9
 
9
10
  /**
@@ -225,3 +226,30 @@ export function cartesian2Intersection(
225
226
 
226
227
  return [lineA[0][0] + s * A[0], lineA[0][1] + s * A[1]];
227
228
  }
229
+
230
+ /**
231
+ * calculates the haversine distance between two mercator coordinates.
232
+ * @param p1 - in mercator
233
+ * @param p2 - in mercator
234
+ */
235
+ export function spherical2Distance(p1: Coordinate, p2: Coordinate): number {
236
+ return haversineDistance(
237
+ Projection.mercatorToWgs84(p1),
238
+ Projection.mercatorToWgs84(p2),
239
+ );
240
+ }
241
+
242
+ let ecefDistanceScratch1 = new Cartesian3();
243
+ let ecefDistanceScratch2 = new Cartesian3();
244
+
245
+ /**
246
+ * calculates the 3D distance in ECEF between two mercator coordinates.
247
+ * @param p1 - in mercator
248
+ * @param p2 - in mercator
249
+ */
250
+ export function ecef3DDistance(p1: Coordinate, p2: Coordinate): number {
251
+ ecefDistanceScratch1 = mercatorToCartesian(p1, ecefDistanceScratch1);
252
+ ecefDistanceScratch2 = mercatorToCartesian(p2, ecefDistanceScratch2);
253
+
254
+ return Cartesian3.distance(ecefDistanceScratch1, ecefDistanceScratch2);
255
+ }
@@ -48,7 +48,7 @@ function parseEPSGCode(value?: string | number, prefix = 'EPSG:'): string {
48
48
  const regex = new RegExp(`^(?:${prefix})?(\\d+)`, 'i');
49
49
  const matches = `${value}`.match(regex);
50
50
  if (matches && matches[1]) {
51
- return `${prefix}${matches[1]}`;
51
+ return prefix ? `${prefix}${matches[1]}` : matches[1];
52
52
  }
53
53
  }
54
54
  return '';