@vcmap/core 5.0.0-rc.3 → 5.0.0-rc.30

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 (236) hide show
  1. package/LICENSE.md +1 -1
  2. package/README.md +12 -5
  3. package/build/postinstall.js +14 -3
  4. package/index.d.ts +3477 -2007
  5. package/index.js +169 -131
  6. package/package.json +25 -27
  7. package/src/category/category.js +483 -0
  8. package/src/category/categoryCollection.js +153 -0
  9. package/src/cesium/cesium3DTileFeature.js +2 -2
  10. package/src/cesium/cesium3DTilePointFeature.js +1 -1
  11. package/src/cesium/cesiumVcsCameraPrimitive.js +16 -8
  12. package/src/cesium/entity.js +29 -0
  13. package/src/cesium/wallpaperMaterial.js +5 -3
  14. package/src/classRegistry.js +169 -0
  15. package/src/{vcs/vcm/util/featureProvider → featureProvider}/abstractFeatureProvider.js +49 -46
  16. package/src/{vcs/vcm/util/featureProvider → featureProvider}/tileProviderFeatureProvider.js +13 -5
  17. package/src/{vcs/vcm/util/featureProvider → featureProvider}/wmsFeatureProvider.js +56 -26
  18. package/src/{vcs/vcm/interaction → interaction}/abstractInteraction.js +33 -21
  19. package/src/{vcs/vcm/interaction → interaction}/coordinateAtPixel.js +40 -21
  20. package/src/{vcs/vcm/interaction → interaction}/eventHandler.js +131 -26
  21. package/src/{vcs/vcm/interaction → interaction}/featureAtPixelInteraction.js +108 -53
  22. package/src/interaction/featureProviderInteraction.js +58 -0
  23. package/src/{vcs/vcm/interaction → interaction}/interactionChain.js +40 -41
  24. package/src/{vcs/vcm/interaction → interaction}/interactionType.js +24 -31
  25. package/src/{vcs/vcm/layer/cesium/cesiumTilesetCesium.js → layer/cesium/cesiumTilesetCesiumImpl.js} +67 -55
  26. package/src/{vcs/vcm/layer → layer}/cesium/clusterContext.js +33 -8
  27. package/src/{vcs/vcm/layer/cesium/dataSourceCesium.js → layer/cesium/dataSourceCesiumImpl.js} +24 -13
  28. package/src/layer/cesium/openStreetMapCesiumImpl.js +32 -0
  29. package/src/{vcs/vcm/layer/cesium/rasterLayerCesium.js → layer/cesium/rasterLayerCesiumImpl.js} +12 -9
  30. package/src/{vcs/vcm/layer/cesium/singleImageCesium.js → layer/cesium/singleImageCesiumImpl.js} +19 -9
  31. package/src/{vcs/vcm/layer/cesium/terrainCesium.js → layer/cesium/terrainCesiumImpl.js} +6 -6
  32. package/src/{vcs/vcm/layer/cesium/tmsCesium.js → layer/cesium/tmsCesiumImpl.js} +21 -10
  33. package/src/{vcs/vcm/layer/cesium/vectorCesium.js → layer/cesium/vectorCesiumImpl.js} +93 -35
  34. package/src/layer/cesium/vectorContext.js +363 -0
  35. package/src/{vcs/vcm/layer/cesium/vectorRasterTileCesium.js → layer/cesium/vectorRasterTileCesiumImpl.js} +21 -13
  36. package/src/{vcs/vcm/layer → layer}/cesium/vectorTileImageryProvider.js +58 -21
  37. package/src/{vcs/vcm/layer/cesium/wmsCesium.js → layer/cesium/wmsCesiumImpl.js} +20 -9
  38. package/src/{vcs/vcm/layer/cesium/wmtsCesium.js → layer/cesium/wmtsCesiumImpl.js} +24 -13
  39. package/src/{vcs/vcm/layer → layer}/cesium/x3dmHelper.js +6 -3
  40. package/src/{vcs/vcm/layer/cesiumTileset.js → layer/cesiumTilesetLayer.js} +71 -108
  41. package/src/{vcs/vcm/layer/czml.js → layer/czmlLayer.js} +23 -20
  42. package/src/{vcs/vcm/layer/dataSource.js → layer/dataSourceLayer.js} +55 -90
  43. package/src/{vcs/vcm/layer → layer}/featureLayer.js +89 -74
  44. package/src/{vcs/vcm/layer/featureStore.js → layer/featureStoreLayer.js} +197 -150
  45. package/src/{vcs/vcm/layer/featureStoreChanges.js → layer/featureStoreLayerChanges.js} +150 -92
  46. package/src/{vcs/vcm/layer/featureStoreState.js → layer/featureStoreLayerState.js} +1 -2
  47. package/src/{vcs/vcm/layer → layer}/featureVisibility.js +114 -82
  48. package/src/{vcs/vcm/layer → layer}/geojsonHelpers.js +84 -69
  49. package/src/{vcs/vcm/layer/geojson.js → layer/geojsonLayer.js} +30 -27
  50. package/src/{vcs/vcm/layer → layer}/globalHider.js +25 -39
  51. package/src/{vcs/vcm/layer → layer}/layer.js +171 -96
  52. package/src/{vcs/vcm/layer → layer}/layerImplementation.js +13 -6
  53. package/src/{vcs/vcm/layer → layer}/layerState.js +0 -1
  54. package/src/{vcs/vcm/layer → layer}/layerSymbols.js +2 -1
  55. package/src/{vcs/vcm/layer/oblique/layerOblique.js → layer/oblique/layerObliqueImpl.js} +7 -5
  56. package/src/{vcs/vcm/layer → layer}/oblique/obliqueHelpers.js +76 -31
  57. package/src/{vcs/vcm/layer/oblique/vectorOblique.js → layer/oblique/vectorObliqueImpl.js} +198 -80
  58. package/src/{vcs/vcm/layer/openStreetMap.js → layer/openStreetMapLayer.js} +59 -40
  59. package/src/layer/openlayers/layerOpenlayersImpl.js +165 -0
  60. package/src/layer/openlayers/openStreetMapOpenlayersImpl.js +28 -0
  61. package/src/layer/openlayers/rasterLayerOpenlayersImpl.js +44 -0
  62. package/src/{vcs/vcm/layer/openlayers/singleImageOpenlayers.js → layer/openlayers/singleImageOpenlayersImpl.js} +8 -7
  63. package/src/{vcs/vcm/layer/openlayers/tileDebugOpenlayers.js → layer/openlayers/tileDebugOpenlayersImpl.js} +7 -6
  64. package/src/{vcs/vcm/layer/openlayers/tmsOpenlayers.js → layer/openlayers/tmsOpenlayersImpl.js} +12 -10
  65. package/src/{vcs/vcm/layer/openlayers/vectorOpenlayers.js → layer/openlayers/vectorOpenlayersImpl.js} +21 -12
  66. package/src/{vcs/vcm/layer/openlayers/vectorTileOpenlayers.js → layer/openlayers/vectorTileOpenlayersImpl.js} +18 -12
  67. package/src/{vcs/vcm/layer/openlayers/wmsOpenlayers.js → layer/openlayers/wmsOpenlayersImpl.js} +9 -8
  68. package/src/{vcs/vcm/layer/openlayers/wmtsOpenlayers.js → layer/openlayers/wmtsOpenlayersImpl.js} +19 -12
  69. package/src/{vcs/vcm/layer/pointCloud.js → layer/pointCloudLayer.js} +42 -39
  70. package/src/{vcs/vcm/layer → layer}/rasterLayer.js +86 -37
  71. package/src/{vcs/vcm/layer/singleImage.js → layer/singleImageLayer.js} +25 -22
  72. package/src/layer/terrainHelpers.js +98 -0
  73. package/src/{vcs/vcm/layer/terrain.js → layer/terrainLayer.js} +26 -18
  74. package/src/{vcs/vcm/layer → layer}/tileLoadedHelper.js +13 -8
  75. package/src/{vcs/vcm/layer → layer}/tileProvider/mvtTileProvider.js +51 -8
  76. package/src/layer/tileProvider/staticGeojsonTileProvider.js +87 -0
  77. package/src/{vcs/vcm/layer → layer}/tileProvider/tileProvider.js +200 -89
  78. package/src/{vcs/vcm/layer → layer}/tileProvider/urlTemplateTileProvider.js +54 -13
  79. package/src/{vcs/vcm/layer/tms.js → layer/tmsLayer.js} +22 -22
  80. package/src/layer/vectorHelpers.js +129 -0
  81. package/src/{vcs/vcm/layer/vector.js → layer/vectorLayer.js} +124 -94
  82. package/src/{vcs/vcm/layer → layer}/vectorProperties.js +419 -107
  83. package/src/{vcs/vcm/layer → layer}/vectorSymbols.js +11 -1
  84. package/src/{vcs/vcm/layer/vectorTile.js → layer/vectorTileLayer.js} +181 -116
  85. package/src/{vcs/vcm/layer/wfs.js → layer/wfsLayer.js} +33 -23
  86. package/src/{vcs/vcm/layer → layer}/wmsHelpers.js +14 -7
  87. package/src/{vcs/vcm/layer/wms.js → layer/wmsLayer.js} +53 -32
  88. package/src/{vcs/vcm/layer/wmts.js → layer/wmtsLayer.js} +56 -42
  89. package/src/{vcs/vcm/maps → map}/baseOLMap.js +83 -35
  90. package/src/{vcs/vcm/maps → map}/cameraLimiter.js +75 -32
  91. package/src/{vcs/vcm/maps/cesium.js → map/cesiumMap.js} +429 -276
  92. package/src/{vcs/vcm/maps → map}/mapState.js +0 -1
  93. package/src/{vcs/vcm/maps/oblique.js → map/obliqueMap.js} +132 -97
  94. package/src/{vcs/vcm/maps/openlayers.js → map/openlayersMap.js} +69 -45
  95. package/src/{vcs/vcm/maps/map.js → map/vcsMap.js} +118 -46
  96. package/src/oblique/defaultObliqueCollection.js +62 -0
  97. package/src/{vcs/vcm/oblique → oblique}/helpers.js +221 -78
  98. package/src/{vcs/vcm/oblique/ObliqueCollection.js → oblique/obliqueCollection.js} +145 -54
  99. package/src/{vcs/vcm/oblique/ObliqueDataSet.js → oblique/obliqueDataSet.js} +62 -32
  100. package/src/{vcs/vcm/oblique/ObliqueImage.js → oblique/obliqueImage.js} +58 -26
  101. package/src/{vcs/vcm/oblique/ObliqueImageMeta.js → oblique/obliqueImageMeta.js} +9 -9
  102. package/src/{vcs/vcm/oblique/ObliqueProvider.js → oblique/obliqueProvider.js} +85 -35
  103. package/src/{vcs/vcm/oblique/ObliqueView.js → oblique/obliqueView.js} +45 -5
  104. package/src/{vcs/vcm/oblique/ObliqueViewDirection.js → oblique/obliqueViewDirection.js} +3 -5
  105. package/src/{vcs/vcm/oblique → oblique}/parseImageJson.js +62 -28
  106. package/src/ol/feature.js +34 -1
  107. package/src/ol/geom/circle.js +14 -5
  108. package/src/ol/geom/geometryCollection.js +14 -8
  109. package/src/ol/render/canvas/canvasTileRenderer.js +11 -10
  110. package/src/overrideClassRegistry.js +214 -0
  111. package/src/style/arcStyle.js +453 -0
  112. package/src/style/arrowStyle.js +304 -0
  113. package/src/{vcs/vcm/util/style → style}/declarativeStyleItem.js +147 -82
  114. package/src/{vcs/vcm/util/style → style}/shapesCategory.js +8 -8
  115. package/src/style/styleFactory.js +32 -0
  116. package/src/{vcs/vcm/util/style → style}/styleHelpers.js +24 -26
  117. package/src/style/styleItem.js +174 -0
  118. package/src/{vcs/vcm/util/style → style}/vectorStyleItem.js +230 -156
  119. package/src/{vcs/vcm/util/style → style}/writeStyle.js +7 -12
  120. package/src/{vcs/vcm/util → util}/clipping/clippingObject.js +84 -52
  121. package/src/{vcs/vcm/util → util}/clipping/clippingObjectManager.js +56 -23
  122. package/src/{vcs/vcm/util → util}/clipping/clippingPlaneHelper.js +149 -88
  123. package/src/{vcs/vcm/util → util}/collection.js +28 -10
  124. package/src/util/editor/createFeatureSession.js +195 -0
  125. package/src/util/editor/editFeaturesSession.js +325 -0
  126. package/src/util/editor/editGeometrySession.js +452 -0
  127. package/src/util/editor/editorHelpers.js +300 -0
  128. package/src/util/editor/editorSessionHelpers.js +132 -0
  129. package/src/util/editor/editorSymbols.js +21 -0
  130. package/src/util/editor/interactions/createBBoxInteraction.js +154 -0
  131. package/src/util/editor/interactions/createCircleInteraction.js +119 -0
  132. package/src/util/editor/interactions/createLineStringInteraction.js +119 -0
  133. package/src/util/editor/interactions/createPointInteraction.js +73 -0
  134. package/src/util/editor/interactions/createPolygonInteraction.js +136 -0
  135. package/src/util/editor/interactions/editFeaturesMouseOverInteraction.js +88 -0
  136. package/src/util/editor/interactions/editGeometryMouseOverInteraction.js +119 -0
  137. package/src/util/editor/interactions/ensureHandlerSelectionInteraction.js +50 -0
  138. package/src/util/editor/interactions/insertVertexInteraction.js +103 -0
  139. package/src/util/editor/interactions/mapInteractionController.js +119 -0
  140. package/src/util/editor/interactions/removeVertexInteraction.js +42 -0
  141. package/src/util/editor/interactions/selectFeatureMouseOverInteraction.js +152 -0
  142. package/src/util/editor/interactions/selectMultiFeatureInteraction.js +165 -0
  143. package/src/util/editor/interactions/selectSingleFeatureInteraction.js +120 -0
  144. package/src/util/editor/interactions/translateVertexInteraction.js +60 -0
  145. package/src/util/editor/selectFeaturesSession.js +303 -0
  146. package/src/util/editor/transformation/create2DHandlers.js +339 -0
  147. package/src/util/editor/transformation/create3DHandlers.js +678 -0
  148. package/src/util/editor/transformation/extrudeInteraction.js +106 -0
  149. package/src/util/editor/transformation/rotateInteraction.js +201 -0
  150. package/src/util/editor/transformation/scaleInteraction.js +201 -0
  151. package/src/util/editor/transformation/transformationHandler.js +178 -0
  152. package/src/util/editor/transformation/transformationTypes.js +88 -0
  153. package/src/util/editor/transformation/translateInteraction.js +263 -0
  154. package/src/util/editor/validateGeoemetry.js +24 -0
  155. package/src/{vcs/vcm/util → util}/exclusiveManager.js +6 -3
  156. package/src/{vcs/vcm/util → util}/extent.js +26 -20
  157. package/src/util/featureconverter/arcToCesium.js +121 -0
  158. package/src/{vcs/vcm/util → util}/featureconverter/circleToCesium.js +70 -37
  159. package/src/{vcs/vcm/util → util}/featureconverter/convert.js +94 -16
  160. package/src/util/featureconverter/extent3D.js +284 -0
  161. package/src/{vcs/vcm/util → util}/featureconverter/featureconverterHelper.js +253 -94
  162. package/src/util/featureconverter/lineStringToCesium.js +343 -0
  163. package/src/util/featureconverter/pointHelpers.js +413 -0
  164. package/src/{vcs/vcm/util → util}/featureconverter/pointToCesium.js +157 -107
  165. package/src/{vcs/vcm/util → util}/featureconverter/polygonToCesium.js +57 -24
  166. package/src/util/fetch.js +34 -0
  167. package/src/{vcs/vcm/util → util}/geometryHelpers.js +25 -17
  168. package/src/{vcs/vcm/util → util}/indexedCollection.js +27 -8
  169. package/src/{vcs/vcm/util → util}/isMobile.js +8 -2
  170. package/src/{vcs/vcm/util → util}/layerCollection.js +109 -19
  171. package/src/util/locale.js +12 -0
  172. package/src/{vcs/vcm/util → util}/mapCollection.js +170 -63
  173. package/src/util/math.js +193 -0
  174. package/src/util/overrideCollection.js +261 -0
  175. package/src/{vcs/vcm/util → util}/projection.js +23 -31
  176. package/src/{vcs/vcm/util → util}/urlHelpers.js +5 -3
  177. package/src/{vcs/vcm/util → util}/viewpoint.js +83 -57
  178. package/src/vcsApp.js +657 -0
  179. package/src/{vcs/vcm/event/vcsEvent.js → vcsEvent.js} +2 -3
  180. package/src/vcsModule.js +130 -0
  181. package/src/vcsModuleHelpers.js +136 -0
  182. package/src/{vcs/vcm/object.js → vcsObject.js} +3 -10
  183. package/tests/data/dynamicPointCzml.json +53 -0
  184. package/tests/data/oblique/imageData/imagev34.json +136 -0
  185. package/tests/data/oblique/imageData/imagev35.json +307 -0
  186. package/tests/data/oblique/imageData/imagev35PerImageSize.json +333 -0
  187. package/tests/data/oblique/tiledImageData/12/2199/1342.json +11056 -0
  188. package/tests/data/oblique/tiledImageData/12/2199/1343.json +11236 -0
  189. package/tests/data/oblique/tiledImageData/12/2199/1344.json +11077 -0
  190. package/tests/data/oblique/tiledImageData/12/2200/1342.json +11036 -0
  191. package/tests/data/oblique/tiledImageData/12/2200/1343.json +11277 -0
  192. package/tests/data/oblique/tiledImageData/12/2200/1344.json +11131 -0
  193. package/tests/data/oblique/tiledImageData/12/2201/1342.json +10870 -0
  194. package/tests/data/oblique/tiledImageData/12/2201/1343.json +11492 -0
  195. package/tests/data/oblique/tiledImageData/12/2201/1344.json +10909 -0
  196. package/tests/data/oblique/tiledImageData/image.json +70 -0
  197. package/tests/data/terrain/13/8800/6485.terrain +0 -0
  198. package/tests/data/terrain/13/8800/6486.terrain +0 -0
  199. package/tests/data/terrain/13/8801/6485.terrain +0 -0
  200. package/tests/data/terrain/13/8801/6486.terrain +0 -0
  201. package/tests/data/terrain/layer.json +127 -0
  202. package/tests/data/testGeoJSON.json +149 -0
  203. package/tests/data/tile.pbf +0 -0
  204. package/tests/unit/helpers/cesiumHelpers.js +326 -0
  205. package/tests/unit/helpers/getFileNameFromUrl.js +12 -0
  206. package/tests/unit/helpers/helpers.js +32 -0
  207. package/tests/unit/helpers/imageHelpers.js +24 -0
  208. package/tests/unit/helpers/importJSON.js +15 -0
  209. package/tests/unit/helpers/obliqueData.js +102 -0
  210. package/tests/unit/helpers/obliqueHelpers.js +115 -0
  211. package/tests/unit/helpers/openlayersHelpers.js +25 -0
  212. package/tests/unit/helpers/terrain/terrainData.js +47 -0
  213. package/src/vcs/vcm/classRegistry.js +0 -106
  214. package/src/vcs/vcm/globalCollections.js +0 -11
  215. package/src/vcs/vcm/interaction/featureProviderInteraction.js +0 -54
  216. package/src/vcs/vcm/layer/buildings.js +0 -17
  217. package/src/vcs/vcm/layer/cesium/openStreetMapCesium.js +0 -29
  218. package/src/vcs/vcm/layer/cesium/pointCloudCesium.js +0 -58
  219. package/src/vcs/vcm/layer/cesium/vectorContext.js +0 -167
  220. package/src/vcs/vcm/layer/openlayers/layerOpenlayers.js +0 -79
  221. package/src/vcs/vcm/layer/openlayers/openStreetMapOpenlayers.js +0 -27
  222. package/src/vcs/vcm/layer/openlayers/rasterLayerOpenlayers.js +0 -121
  223. package/src/vcs/vcm/layer/terrainHelpers.js +0 -119
  224. package/src/vcs/vcm/layer/tileProvider/staticGeojsonTileProvider.js +0 -67
  225. package/src/vcs/vcm/layer/tileProvider/tileProviderFactory.js +0 -28
  226. package/src/vcs/vcm/layer/vectorHelpers.js +0 -206
  227. package/src/vcs/vcm/util/dateTime.js +0 -60
  228. package/src/vcs/vcm/util/featureProvider/featureProviderHelpers.js +0 -51
  229. package/src/vcs/vcm/util/featureconverter/extent3d.js +0 -154
  230. package/src/vcs/vcm/util/featureconverter/lineStringToCesium.js +0 -171
  231. package/src/vcs/vcm/util/locale.js +0 -53
  232. package/src/vcs/vcm/util/math.js +0 -71
  233. package/src/vcs/vcm/util/splitScreen.js +0 -233
  234. package/src/vcs/vcm/util/style/styleFactory.js +0 -48
  235. package/src/vcs/vcm/util/style/styleItem.js +0 -243
  236. /package/src/{vcs/vcm/util/featureProvider → featureProvider}/featureProviderSymbols.js +0 -0
@@ -0,0 +1,195 @@
1
+ import { check } from '@vcsuite/check';
2
+ import { Feature } from 'ol';
3
+ import VcsEvent from '../../vcsEvent.js';
4
+ import {
5
+ GeometryType,
6
+ SessionType,
7
+ setupInteractionChain,
8
+ } from './editorSessionHelpers.js';
9
+ import CreateLineStringInteraction from './interactions/createLineStringInteraction.js';
10
+ import CreateCircleInteraction from './interactions/createCircleInteraction.js';
11
+ import CreateBBoxInteraction from './interactions/createBBoxInteraction.js';
12
+ import CreatePointInteraction from './interactions/createPointInteraction.js';
13
+ import CreatePolygonInteraction from './interactions/createPolygonInteraction.js';
14
+ import VcsApp from '../../vcsApp.js';
15
+ import VectorLayer from '../../layer/vectorLayer.js';
16
+ import { createSync } from '../../layer/vectorSymbols.js';
17
+ import geometryIsValid from './validateGeoemetry.js';
18
+ import ObliqueMap from '../../map/obliqueMap.js';
19
+
20
+ /**
21
+ * @typedef {EditorSession} CreateFeatureSession
22
+ * @property {import("@vcmap/core").GeometryType} geometryType
23
+ * @property {VcsEvent<import("ol").Feature<import("ol/geom").Geometry>>} featureCreated - raised when a feature is created and added to the layer
24
+ * @property {VcsEvent<import("ol").Feature<import("ol/geom").Geometry>|null>} creationFinished - raised when the feature creation was finished. is passed the feature or null if the feature is invalid. invalid feature will be removed from the layer.
25
+ * @property {function():void} finish - finished the current creation. if a current interaction is active, the creationFinished event will be raised.
26
+ */
27
+
28
+ /**
29
+ * Creates an editor session to create features of the given geometry type.
30
+ * While the session is active: Do not change the geometry on the current feature (the last created one)
31
+ * and do not change crucial olcs properties on the feature or the layer (olcs_altitudeMode)
32
+ * @param {import("@vcmap/core").VcsApp} app
33
+ * @param {import("@vcmap/core").VectorLayer} layer
34
+ * @param {GeometryType} geometryType
35
+ * @returns {CreateFeatureSession}
36
+ */
37
+ function startCreateFeatureSession(app, layer, geometryType) {
38
+ check(app, VcsApp);
39
+ check(layer, VectorLayer);
40
+ check(geometryType, Object.values(GeometryType));
41
+
42
+ const {
43
+ interactionChain,
44
+ removed: interactionRemoved,
45
+ destroy: destroyInteractionChain,
46
+ } = setupInteractionChain(app.maps.eventHandler);
47
+
48
+ /**
49
+ * @type {VcsEvent<import("ol").Feature<import("ol/geom").Geometry>>}
50
+ */
51
+ const featureCreated = new VcsEvent();
52
+ /**
53
+ * @type {VcsEvent<import("ol").Feature<import("ol/geom").Geometry>|null>}
54
+ */
55
+ const creationFinished = new VcsEvent();
56
+ /**
57
+ * @type {VcsEvent<void>}
58
+ */
59
+ const stopped = new VcsEvent();
60
+ let isStopped = false;
61
+
62
+ /**
63
+ * @type {CreateLineStringInteraction|CreateCircleInteraction|CreateBBoxInteraction|CreatePointInteraction|CreatePolygonInteraction|null}
64
+ */
65
+ let currentInteraction = null;
66
+ let currentFeature = null;
67
+
68
+ /**
69
+ * Ture if the currently active map is an ObliqueMap. set in setupActiveMap
70
+ * @type {boolean}
71
+ */
72
+ let isOblique = false;
73
+
74
+ let interactionListeners = [];
75
+ const destroyCurrentInteraction = () => {
76
+ if (currentInteraction) {
77
+ interactionChain.removeInteraction(currentInteraction);
78
+ currentInteraction.destroy();
79
+ currentInteraction = null;
80
+ }
81
+ interactionListeners.forEach((cb) => {
82
+ cb();
83
+ });
84
+ interactionListeners = [];
85
+ };
86
+
87
+ const createInteraction = () => {
88
+ destroyCurrentInteraction();
89
+ if (geometryType === GeometryType.Polygon) {
90
+ currentInteraction = new CreatePolygonInteraction();
91
+ } else if (geometryType === GeometryType.Point) {
92
+ currentInteraction = new CreatePointInteraction();
93
+ } else if (geometryType === GeometryType.LineString) {
94
+ currentInteraction = new CreateLineStringInteraction();
95
+ } else if (geometryType === GeometryType.BBox) {
96
+ currentInteraction = new CreateBBoxInteraction();
97
+ } else if (geometryType === GeometryType.Circle) {
98
+ currentInteraction = new CreateCircleInteraction();
99
+ }
100
+
101
+ interactionListeners = [
102
+ currentInteraction.created.addEventListener((geometry) => {
103
+ if (isOblique) {
104
+ /** @type {ObliqueMap} */ (app.maps.activeMap).switchEnabled = false;
105
+ }
106
+ currentFeature = new Feature({ geometry });
107
+ currentFeature[createSync] = true;
108
+ layer.addFeatures([currentFeature]);
109
+ featureCreated.raiseEvent(currentFeature);
110
+ }),
111
+ currentInteraction.finished.addEventListener((geometry) => {
112
+ if (isOblique) {
113
+ /** @type {ObliqueMap} */ (app.maps.activeMap).switchEnabled = true;
114
+ }
115
+ if (currentFeature) {
116
+ delete currentFeature[createSync];
117
+ if (
118
+ !geometry ||
119
+ currentFeature.getGeometry() !== geometry ||
120
+ !geometryIsValid(geometry)
121
+ ) {
122
+ layer.removeFeaturesById([currentFeature.getId()]);
123
+ currentFeature = null;
124
+ }
125
+ }
126
+
127
+ creationFinished.raiseEvent(currentFeature);
128
+ currentFeature = null;
129
+ if (!isStopped) {
130
+ createInteraction();
131
+ }
132
+ }),
133
+ ];
134
+ interactionChain.addInteraction(currentInteraction);
135
+ };
136
+ createInteraction();
137
+
138
+ const resetCurrentInteraction = () => {
139
+ if (currentInteraction) {
140
+ currentInteraction.finish();
141
+ }
142
+ createInteraction();
143
+ };
144
+
145
+ let obliqueImageChangedListener = () => {};
146
+ const setupActiveMap = () => {
147
+ obliqueImageChangedListener();
148
+ const { activeMap } = app.maps;
149
+ isOblique = activeMap instanceof ObliqueMap;
150
+ if (isOblique) {
151
+ obliqueImageChangedListener = /** @type {ObliqueMap} */ (
152
+ activeMap
153
+ ).imageChanged.addEventListener(resetCurrentInteraction);
154
+ } else {
155
+ obliqueImageChangedListener = () => {};
156
+ }
157
+ };
158
+
159
+ const mapChangedListener = app.maps.mapActivated.addEventListener(() => {
160
+ setupActiveMap();
161
+ resetCurrentInteraction();
162
+ });
163
+ setupActiveMap();
164
+
165
+ const stop = () => {
166
+ isStopped = true; // setting stopped true immediately, to prevent the recreation of the interaction chain on finished
167
+ mapChangedListener();
168
+ obliqueImageChangedListener();
169
+ if (currentInteraction) {
170
+ currentInteraction.finish();
171
+ }
172
+ destroyCurrentInteraction();
173
+ destroyInteractionChain();
174
+ stopped.raiseEvent();
175
+ stopped.destroy();
176
+ featureCreated.destroy();
177
+ };
178
+ interactionRemoved.addEventListener(stop);
179
+
180
+ return {
181
+ type: SessionType.CREATE,
182
+ geometryType,
183
+ featureCreated,
184
+ creationFinished,
185
+ stopped,
186
+ finish: () => {
187
+ if (currentInteraction) {
188
+ currentInteraction.finish();
189
+ }
190
+ },
191
+ stop,
192
+ };
193
+ }
194
+
195
+ export default startCreateFeatureSession;
@@ -0,0 +1,325 @@
1
+ import {
2
+ extend as extendExtent,
3
+ createEmpty as createEmptyExtent,
4
+ getCenter,
5
+ isEmpty,
6
+ } from 'ol/extent.js';
7
+ import { getLogger } from '@vcsuite/logger';
8
+
9
+ import VcsEvent from '../../vcsEvent.js';
10
+ import {
11
+ setupInteractionChain,
12
+ SessionType,
13
+ setupScratchLayer,
14
+ } from './editorSessionHelpers.js';
15
+ import createTransformationHandler from './transformation/transformationHandler.js';
16
+ import { TransformationMode } from './transformation/transformationTypes.js';
17
+ import MapInteractionController from './interactions/mapInteractionController.js';
18
+ import TranslateInteraction from './transformation/translateInteraction.js';
19
+ import RotateInteraction from './transformation/rotateInteraction.js';
20
+ import ScaleInteraction from './transformation/scaleInteraction.js';
21
+ import { obliqueGeometry } from '../../layer/vectorSymbols.js';
22
+ import ExtrudeInteraction from './transformation/extrudeInteraction.js';
23
+ import ObliqueMap from '../../map/obliqueMap.js';
24
+ import { ensureFeatureAbsolute } from './editorHelpers.js';
25
+ import CesiumMap from '../../map/cesiumMap.js';
26
+ import EnsureHandlerSelectionInteraction from './interactions/ensureHandlerSelectionInteraction.js';
27
+ import EditFeaturesMouseOverInteraction from './interactions/editFeaturesMouseOverInteraction.js';
28
+ import { ModificationKeyType } from '../../interaction/interactionType.js';
29
+
30
+ /**
31
+ * Saves the original allowPicking settings and sets them to false if CTRL is not pressed.
32
+ * @param {import("ol").Feature} feature
33
+ * @param {Map<string|number, boolean|undefined>} allowPickingMap A map containing the original allowPicking settings for the features. Id is key, setting is value.
34
+ * @param {ModificationKeyType} currentModificationKey The modification key that is currently pressed.
35
+ */
36
+ function setAllowPicking(feature, allowPickingMap, currentModificationKey) {
37
+ if (!allowPickingMap.has(feature.getId())) {
38
+ allowPickingMap.set(feature.getId(), feature.get('olcs_allowPicking'));
39
+ }
40
+ if (currentModificationKey !== ModificationKeyType.CTRL) {
41
+ feature.set('olcs_allowPicking', false);
42
+ }
43
+ }
44
+
45
+ /**
46
+ * Restores the original allowPicking settings for the feature.
47
+ * @param {import("ol").Feature} feature
48
+ * @param {Map<string|number, boolean|undefined>} allowPickingMap A map containing the original allowPicking settings for the features. Id is key, setting is value.
49
+ */
50
+ function clearAllowPicking(feature, allowPickingMap) {
51
+ const allowPicking = allowPickingMap.get(feature.getId());
52
+ if (allowPicking != null) {
53
+ feature.set('olcs_allowPicking', allowPicking);
54
+ } else {
55
+ feature.unset('olcs_allowPicking');
56
+ }
57
+ }
58
+
59
+ /**
60
+ * @typedef {EditorSession} EditFeaturesSession
61
+ * @property {TransformationMode} mode - read only access to the current mode
62
+ * @property {function(number):void} rotate - Function for rotating features. Takes angle in radians as parameter.
63
+ * @property {function(number, number, number):void} translate - Function for translating features. Takes Δx, Δy, Δz as parameters.
64
+ * @property {function(number, number):void} scale - Function for scaling features. Takes sx, sy as parameters.
65
+ * @property {function(TransformationMode):void} setMode
66
+ * @property {import("@vcmap/core").VcsEvent<TransformationMode>} modeChanged
67
+ * @property {function(Array<import("ol").Feature>):void} setFeatures - Sets the features for the edit session.
68
+ * @property {Array<import("ol").Feature>} features - Gets the features of the edit session.
69
+ */
70
+
71
+ /**
72
+ * Creates an editor session to select, translate, rotate & scale the feature on a given layer
73
+ * @param {import("@vcmap/core").VcsApp} app
74
+ * @param {import("@vcmap/core").VectorLayer} layer
75
+ * @param {string} [interactionId] id for registering mutliple exclusive interaction. Needed to run a selection session at the same time as a edit features session.
76
+ * @param {TransformationMode=} [initialMode=TransformationMode.TRANSLATE]
77
+ * @returns {EditFeaturesSession}
78
+ */
79
+ function startEditFeaturesSession(
80
+ app,
81
+ layer,
82
+ interactionId,
83
+ initialMode = TransformationMode.TRANSLATE,
84
+ ) {
85
+ /**
86
+ * @type {VcsEvent<void>}
87
+ */
88
+ const stopped = new VcsEvent();
89
+
90
+ /**
91
+ * The features that are set for the edit session.
92
+ * @type {Array<import("ol").Feature>}
93
+ */
94
+ const currentFeatures = [];
95
+
96
+ // The allow picking prop needs to be set false for the selected features to make sure that the transformation handler can always be selected.
97
+ /**
98
+ * @type {Map<string|number, boolean|undefined>}
99
+ */
100
+ const allowPickingMap = new Map();
101
+ let modificationKey;
102
+ /** Callback to remove the modifier changed listener. */
103
+ const modifierChangedListener =
104
+ app.maps.eventHandler.modifierChanged.addEventListener((mod) => {
105
+ // CTRL is used to modify the current selection set, we must allow picking again so you can deselect a feature
106
+ modificationKey = mod;
107
+ const allowPicking = modificationKey === ModificationKeyType.CTRL;
108
+ currentFeatures.forEach((feature) => {
109
+ feature.set('olcs_allowPicking', allowPicking);
110
+ });
111
+ });
112
+
113
+ const scratchLayer = setupScratchLayer(app.layers);
114
+
115
+ const {
116
+ interactionChain,
117
+ removed: interactionRemoved,
118
+ destroy: destroyInteractionChain,
119
+ } = setupInteractionChain(app.maps.eventHandler, interactionId);
120
+
121
+ const mouseOverInteraction = new EditFeaturesMouseOverInteraction();
122
+ interactionChain.addInteraction(mouseOverInteraction);
123
+
124
+ interactionChain.addInteraction(
125
+ new EnsureHandlerSelectionInteraction(currentFeatures),
126
+ );
127
+
128
+ const mapInteractionController = new MapInteractionController();
129
+ interactionChain.addInteraction(mapInteractionController);
130
+
131
+ let mode = initialMode;
132
+ let destroyTransformation = () => {};
133
+ let transformationHandler;
134
+ const translate = (dx, dy, dz) => {
135
+ transformationHandler?.translate?.(dx, dy, dz);
136
+ currentFeatures.forEach((f) => {
137
+ const geometry = f[obliqueGeometry] ?? f.getGeometry(); // XXX wont work in oblqiue
138
+ geometry.applyTransform((input, output) => {
139
+ const inputLength = input.length;
140
+ for (let i = 0; i < inputLength; i += 3) {
141
+ output[i] = input[i] + dx;
142
+ output[i + 1] = input[i + 1] + dy;
143
+ output[i + 2] = input[i + 2] + dz;
144
+ }
145
+ return output;
146
+ });
147
+ });
148
+ };
149
+
150
+ const rotate = (angle) => {
151
+ let center = transformationHandler?.center;
152
+ if (!center) {
153
+ const extent = createEmptyExtent();
154
+ currentFeatures.forEach((f) => {
155
+ extendExtent(extent, f.getGeometry().getExtent()); // XXX wont work in oblqiue
156
+ });
157
+ if (!isEmpty(extent)) {
158
+ center = getCenter(extent);
159
+ }
160
+ }
161
+ currentFeatures.forEach((f) => {
162
+ const geometry = f[obliqueGeometry] ?? f.getGeometry(); // XXX wont work in oblqiue
163
+ geometry.rotate(angle, center);
164
+ });
165
+ };
166
+
167
+ const scale = (sx, sy) => {
168
+ let center = transformationHandler?.center;
169
+ if (!center) {
170
+ // XXX copy paste
171
+ const extent = createEmptyExtent();
172
+ currentFeatures.forEach((f) => {
173
+ extendExtent(extent, f.getGeometry().getExtent());
174
+ });
175
+ if (!isEmpty(extent)) {
176
+ center = getCenter(extent);
177
+ }
178
+ }
179
+ currentFeatures.forEach((f) => {
180
+ const geometry = f[obliqueGeometry] ?? f.getGeometry();
181
+ geometry.scale(sx, sy, center);
182
+ });
183
+ };
184
+
185
+ const createTransformations = () => {
186
+ destroyTransformation();
187
+
188
+ transformationHandler = createTransformationHandler(
189
+ app.maps.activeMap,
190
+ layer,
191
+ scratchLayer,
192
+ mode,
193
+ );
194
+ transformationHandler.setFeatures(currentFeatures);
195
+
196
+ let interaction;
197
+ if (mode === TransformationMode.TRANSLATE) {
198
+ interaction = new TranslateInteraction(transformationHandler);
199
+ interaction.translated.addEventListener(([dx, dy, dz]) => {
200
+ translate(dx, dy, dz);
201
+ });
202
+ } else if (mode === TransformationMode.EXTRUDE) {
203
+ interaction = new ExtrudeInteraction(transformationHandler);
204
+ interaction.extruded.addEventListener((dz) => {
205
+ currentFeatures.forEach((f) => {
206
+ ensureFeatureAbsolute(f, layer, app.maps.activeMap);
207
+ let extrudedHeight = f.get('olcs_extrudedHeight') ?? 0;
208
+ extrudedHeight += dz;
209
+ f.set('olcs_extrudedHeight', extrudedHeight);
210
+ });
211
+ });
212
+ } else if (mode === TransformationMode.ROTATE) {
213
+ interaction = new RotateInteraction(transformationHandler);
214
+ interaction.rotated.addEventListener(({ angle }) => {
215
+ rotate(angle);
216
+ });
217
+ } else if (mode === TransformationMode.SCALE) {
218
+ interaction = new ScaleInteraction(transformationHandler);
219
+ interaction.scaled.addEventListener(([sx, sy]) => {
220
+ scale(sx, sy);
221
+ });
222
+ } else {
223
+ throw new Error(`Unknown transformation mode ${mode}`);
224
+ }
225
+
226
+ interactionChain.addInteraction(interaction);
227
+
228
+ destroyTransformation = () => {
229
+ interactionChain.removeInteraction(interaction);
230
+ interaction.destroy();
231
+ transformationHandler?.destroy();
232
+ transformationHandler = null;
233
+ };
234
+ };
235
+
236
+ /**
237
+ * @type {VcsEvent<TransformationMode>}
238
+ */
239
+ const modeChanged = new VcsEvent();
240
+ const setMode = (newMode) => {
241
+ if (newMode !== mode) {
242
+ if (
243
+ newMode === TransformationMode.EXTRUDE &&
244
+ !(app.maps.activeMap instanceof CesiumMap)
245
+ ) {
246
+ getLogger('EditFeaturesSession').warning(
247
+ 'Cannot set extrude mode if map is not a CesiumMap',
248
+ );
249
+ } else {
250
+ mode = newMode;
251
+ createTransformations();
252
+ modeChanged.raiseEvent(mode);
253
+ }
254
+ }
255
+ };
256
+ /**
257
+ * @type {function():void}
258
+ */
259
+ let obliqueImageChangedListener = () => {};
260
+ const mapChanged = (map) => {
261
+ obliqueImageChangedListener();
262
+ if (map instanceof ObliqueMap) {
263
+ obliqueImageChangedListener = map.imageChanged.addEventListener(() => {
264
+ createTransformations();
265
+ });
266
+ } else {
267
+ obliqueImageChangedListener = () => {};
268
+ }
269
+ if (mode === TransformationMode.EXTRUDE && !(map instanceof CesiumMap)) {
270
+ setMode(TransformationMode.TRANSLATE);
271
+ } else {
272
+ createTransformations();
273
+ }
274
+ };
275
+ const mapChangedListener = app.maps.mapActivated.addEventListener(mapChanged);
276
+ mapChanged(app.maps.activeMap);
277
+
278
+ const stop = () => {
279
+ destroyTransformation();
280
+ destroyInteractionChain();
281
+ obliqueImageChangedListener();
282
+ mapChangedListener();
283
+ modifierChangedListener();
284
+ currentFeatures.forEach((feature) =>
285
+ clearAllowPicking(feature, allowPickingMap),
286
+ );
287
+ allowPickingMap.clear();
288
+ app.layers.remove(scratchLayer);
289
+ modeChanged.destroy();
290
+ stopped.raiseEvent();
291
+ stopped.destroy();
292
+ };
293
+
294
+ interactionRemoved.addEventListener(stop);
295
+
296
+ return {
297
+ type: SessionType.EDIT_FEATURES,
298
+ stopped,
299
+ stop,
300
+ get mode() {
301
+ return mode;
302
+ },
303
+ modeChanged,
304
+ setMode,
305
+ rotate,
306
+ translate,
307
+ scale,
308
+ setFeatures(features) {
309
+ currentFeatures.forEach((feature) =>
310
+ clearAllowPicking(feature, allowPickingMap),
311
+ );
312
+ currentFeatures.length = 0;
313
+ currentFeatures.push(...features);
314
+ currentFeatures.forEach((feature) =>
315
+ setAllowPicking(feature, allowPickingMap, modificationKey),
316
+ );
317
+ transformationHandler?.setFeatures(features);
318
+ },
319
+ get features() {
320
+ return currentFeatures;
321
+ },
322
+ };
323
+ }
324
+
325
+ export default startEditFeaturesSession;