@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,102 @@
1
+ import { Cartographic, Cartesian3, Math as CesiumMath } from '@vcmap/cesium';
2
+ import AbstractInteraction from './abstractInteraction.js';
3
+ import Projection, { mercatorProjection } from '../util/projection.js';
4
+ import { EventType, ModificationKeyType } from './interactionType.js';
5
+ import { transformFromImage } from '../oblique/helpers.js';
6
+
7
+ /**
8
+ * @class
9
+ * @extends {AbstractInteraction}
10
+ */
11
+ class CoordinateAtPixel extends AbstractInteraction {
12
+ constructor() {
13
+ super();
14
+ /**
15
+ * @type {import("@vcmap/cesium").Cartographic}
16
+ * @private
17
+ */
18
+ this._scratchCartographic = new Cartographic();
19
+ /**
20
+ * @type {import("@vcmap/cesium").Cartesian3}
21
+ * @private
22
+ */
23
+ this._scratchCartesian = new Cartesian3();
24
+
25
+ this._defaultActive = EventType.ALL;
26
+ this._defaultModificationKey = ModificationKeyType.ALL;
27
+
28
+ this.setActive();
29
+ }
30
+
31
+ /**
32
+ * @inheritDoc
33
+ * @param {InteractionEvent} event
34
+ * @returns {Promise<InteractionEvent>}
35
+ */
36
+ // eslint-disable-next-line class-methods-use-this
37
+ async pipe(event) {
38
+ if (event.map.className === 'vcs.vcm.maps.Cesium') {
39
+ return this._cesiumHandler(event);
40
+ } else if (event.map.className === 'vcs.vcm.maps.Oblique') {
41
+ return CoordinateAtPixel.obliqueHandler(event);
42
+ }
43
+ return event;
44
+ }
45
+
46
+ /**
47
+ * @param {InteractionEvent} event
48
+ * @returns {Promise<InteractionEvent>}
49
+ * @private
50
+ */
51
+ _cesiumHandler(event) {
52
+ const cesiumMap = /** @type {import("@vcmap/core").CesiumMap} */ (event.map);
53
+ const scene = cesiumMap.getScene();
54
+ event.ray = scene.camera.getPickRay(event.windowPosition);
55
+ const pickResult = scene.globe.pick(event.ray, scene, this._scratchCartesian);
56
+ if (!pickResult) {
57
+ event.position = [0, 0, 0];
58
+ } else {
59
+ this._scratchCartographic = Cartographic
60
+ .fromCartesian(pickResult, scene.globe.ellipsoid, this._scratchCartographic);
61
+ event.position = Projection.wgs84ToMercator([
62
+ CesiumMath.toDegrees(this._scratchCartographic.longitude),
63
+ CesiumMath.toDegrees(this._scratchCartographic.latitude),
64
+ this._scratchCartographic.height,
65
+ ], true);
66
+ }
67
+ event.positionOrPixel = event.position;
68
+ return Promise.resolve(event);
69
+ }
70
+
71
+ /**
72
+ * @param {InteractionEvent} event
73
+ * @returns {Promise<InteractionEvent>}
74
+ * @private
75
+ */
76
+ static obliqueHandler(event) {
77
+ const obliqueMap = /** @type {import("@vcmap/core").Oblique} */ (event.map);
78
+ const image = obliqueMap.currentImage;
79
+ if (image) {
80
+ // don't use Terrain for coordinate Transformation if the event is a move or drag event,
81
+ // to avoid requesting the terrain each mousemove...
82
+ // XXX but what about DRAGSTART and DRAGEND? this could be usefull, no?
83
+ const move = event.type & (EventType.MOVE ^ EventType.DRAGEVENTS);
84
+ const pixel = event.position.slice(0, 2);
85
+ if (Number.isFinite(pixel[0]) && Number.isFinite(pixel[1])) {
86
+ return transformFromImage(image, pixel, {
87
+ dontUseTerrain: !!move,
88
+ dataProjection: mercatorProjection.proj,
89
+ }).then((coordinates) => {
90
+ event.obliqueParameters = { pixel };
91
+ event.position = coordinates.coords;
92
+ event.obliqueParameters.estimate = coordinates.estimate;
93
+ return event;
94
+ });
95
+ }
96
+ }
97
+ event.stopPropagation = true;
98
+ return Promise.resolve(event);
99
+ }
100
+ }
101
+
102
+ export default CoordinateAtPixel;
@@ -0,0 +1,425 @@
1
+ import { v4 as uuidv4 } from 'uuid';
2
+ import { Cartesian2 } from '@vcmap/cesium';
3
+
4
+ import { check, checkMaybe } from '@vcsuite/check';
5
+ import { getLogger as getLoggerByName } from '@vcsuite/logger';
6
+ import AbstractInteraction from './abstractInteraction.js';
7
+ import InteractionChain from './interactionChain.js';
8
+ import CoordinateAtPixel from './coordinateAtPixel.js';
9
+ import FeatureAtPixelInteraction from './featureAtPixelInteraction.js';
10
+ import { EventType, PointerEventType } from './interactionType.js';
11
+ import FeatureProviderInteraction from './featureProviderInteraction.js';
12
+ import VcsEvent from '../event/vcsEvent.js';
13
+
14
+ /**
15
+ * @namespace interaction
16
+ * @api
17
+ */
18
+
19
+ /**
20
+ * @typedef {Object} EventHandlerExclusiveInteraction
21
+ * @property {string} id
22
+ * @property {Array<AbstractInteraction>} interactions
23
+ * @property {Array<Function>} cb
24
+ */
25
+
26
+ /**
27
+ * @typedef {Object} MapEvent
28
+ * @property {PointerEventType} pointerEvent
29
+ * @property {import("@vcmap/core").VcsMap} map
30
+ * @property {import("@vcmap/cesium").Cartesian2} windowPosition
31
+ * @property {import("@vcmap/core").ModificationKeyType} key
32
+ * @property {import("@vcmap/core").PointerKeyType} pointer
33
+ * @property {import("ol/coordinate").Coordinate|undefined} position - position in web mercator coordinates
34
+ * @property {import("ol/coordinate").Coordinate|undefined} positionOrPixel - position in web mercator coordinates or image coordinates in Oblique Map Mode
35
+ * @property {boolean|undefined} multipleTouch - vcs:undocumented
36
+ * @property {number|null|undefined} time - vcs:undocumented
37
+ */
38
+
39
+ /**
40
+ * @typedef {Object} LastClick
41
+ * @property {import("@vcmap/cesium").Cartesian2} windowPosition - vcs:undocumented
42
+ * @property {number|null} time - vcs:undocumented
43
+ * @api
44
+ */
45
+
46
+ /**
47
+ * @returns {import("@vcsuite/logger").Logger}
48
+ */
49
+ function getLogger() {
50
+ return getLoggerByName('vcs.vcm.interaction.EventHandler');
51
+ }
52
+
53
+ /**
54
+ * @class
55
+ */
56
+ class EventHandler {
57
+ constructor() {
58
+ /**
59
+ * @type {CoordinateAtPixel}
60
+ * @private
61
+ */
62
+ this._positionInteraction = new CoordinateAtPixel();
63
+ /**
64
+ * @type {FeatureAtPixelInteraction}
65
+ * @private
66
+ */
67
+ this._featureInteraction = new FeatureAtPixelInteraction();
68
+ /**
69
+ * @type {FeatureProviderInteraction}
70
+ * @private
71
+ */
72
+ this._featureProviderInteraction = new FeatureProviderInteraction();
73
+ /**
74
+ * @type {InteractionChain}
75
+ * @private
76
+ */
77
+ this._interactionChain = new InteractionChain([
78
+ this._positionInteraction,
79
+ this._featureInteraction,
80
+ this._featureProviderInteraction,
81
+ ]);
82
+
83
+ /**
84
+ * @type {number}
85
+ */
86
+ this.clickDuration = 400;
87
+
88
+ /**
89
+ * @type {number}
90
+ */
91
+ this.dragDuration = 100;
92
+
93
+ /**
94
+ * @type {null|MapEvent}
95
+ * @private
96
+ */
97
+ this._lastDown = null;
98
+
99
+ /**
100
+ * @type {LastClick}
101
+ * @private
102
+ */
103
+ this._lastClick = {
104
+ time: null,
105
+ windowPosition: new Cartesian2(),
106
+ };
107
+
108
+ /**
109
+ * @type {null|MapEvent}
110
+ * @private
111
+ */
112
+ this._dragging = null;
113
+
114
+ /**
115
+ * @type {boolean}
116
+ * @private
117
+ */
118
+ this._running = false;
119
+
120
+ /**
121
+ * @type {Array<InteractionEvent>}
122
+ * @private
123
+ */
124
+ this._eventQueue = [];
125
+
126
+ /**
127
+ * @type {EventHandlerExclusiveInteraction|null}
128
+ * @private
129
+ */
130
+ this._exclusiveInteraction = null;
131
+
132
+ /**
133
+ * @type {boolean}
134
+ * @private
135
+ */
136
+ this._multiples = false;
137
+ /**
138
+ * Event called, when exclusive events are removed
139
+ * @type {VcsEvent<void>}
140
+ * @api
141
+ */
142
+ this.exclusiveRemoved = new VcsEvent();
143
+ /**
144
+ * Event called, when exclusive events are added
145
+ * @type {VcsEvent<void>}
146
+ * @api
147
+ */
148
+ this.exclusiveAdded = new VcsEvent();
149
+ }
150
+
151
+ /**
152
+ * @type {CoordinateAtPixel}
153
+ * @readonly
154
+ * @api
155
+ */
156
+ get positionInteraction() { return this._positionInteraction; }
157
+
158
+ /**
159
+ * @type {FeatureAtPixelInteraction}
160
+ * @readonly
161
+ * @api
162
+ */
163
+ get featureInteraction() { return this._featureInteraction; }
164
+
165
+ /**
166
+ * @api
167
+ * @readonly
168
+ * @type {FeatureProviderInteraction}
169
+ */
170
+ get featureProviderInteraction() { return this._featureProviderInteraction; }
171
+
172
+ /**
173
+ * A copy of all the EventHandler interactions
174
+ * @readonly
175
+ * @type {AbstractInteraction[]}
176
+ * @api
177
+ */
178
+ get interactions() { return this._interactionChain.chain.slice(); }
179
+
180
+ /**
181
+ * Add a dynamic interaction to the interaction chain. This is the default methodology for
182
+ * user map interactions, such as drawing or measuring. If another exclusive interaction is added,
183
+ * this interaction is removed and a provided callback is called. Use the id parameter to add multiple interactions
184
+ * from the same source (if you don't wish to provide an {@link InteractionChain}
185
+ * @param {AbstractInteraction} interaction
186
+ * @param {Function} removed - the callback for when the interaction is forcefully removed.
187
+ * @param {number=} [index=3] - the position at which to push the interaction
188
+ * @param {string=} id - an id to allow for multiple interactions to belong to the same exclusive registerer
189
+ * @returns {Function} function to remove the interaction with. returns number of removed interactions (0|1)
190
+ * @api
191
+ */
192
+ addExclusiveInteraction(interaction, removed, index = 3, id) {
193
+ check(interaction, AbstractInteraction);
194
+ check(removed, Function);
195
+ check(index, Number);
196
+ checkMaybe(id, String);
197
+
198
+ if (this._exclusiveInteraction && this._exclusiveInteraction.id !== id) {
199
+ this.removeExclusive();
200
+ }
201
+ this._interactionChain.addInteraction(interaction, index);
202
+ if (this._exclusiveInteraction) {
203
+ this._exclusiveInteraction.interactions.push(interaction);
204
+ this._exclusiveInteraction.cb.push(removed);
205
+ } else {
206
+ this._exclusiveInteraction = {
207
+ id: id || uuidv4(),
208
+ cb: [removed],
209
+ interactions: [interaction],
210
+ };
211
+ }
212
+ this.exclusiveAdded.raiseEvent();
213
+ return this._exclusiveUnListen.bind(this, interaction, this._exclusiveInteraction.id);
214
+ }
215
+
216
+ /**
217
+ * Removes any exclusive listeners. Typically only called from the framework to ensure the pubsub listeners are consistent
218
+ * @api
219
+ */
220
+ removeExclusive() {
221
+ if (this._exclusiveInteraction) {
222
+ this._exclusiveInteraction.interactions
223
+ .filter(i => i)
224
+ .forEach((i) => {
225
+ this._interactionChain.removeInteraction(i);
226
+ });
227
+ this._exclusiveInteraction.cb
228
+ .filter(cb => cb)
229
+ .forEach((cb) => {
230
+ cb();
231
+ });
232
+ this._exclusiveInteraction = null;
233
+ this.exclusiveRemoved.raiseEvent();
234
+ }
235
+ }
236
+
237
+ /**
238
+ * Removes an exclusive interaction by its id
239
+ * @param {AbstractInteraction} interaction
240
+ * @param {string} id
241
+ * @returns {number}
242
+ * @private
243
+ */
244
+ _exclusiveUnListen(interaction, id) {
245
+ if (!this._exclusiveInteraction || (this._exclusiveInteraction && this._exclusiveInteraction.id !== id)) {
246
+ return 0;
247
+ }
248
+ const removed = this._interactionChain.removeInteraction(interaction);
249
+ const index = this._exclusiveInteraction.interactions
250
+ .findIndex(candidate => candidate && candidate.id === interaction.id);
251
+ if (index > -1) {
252
+ this._exclusiveInteraction.interactions.splice(index, 1, undefined);
253
+ this._exclusiveInteraction.cb.splice(index, 1, undefined);
254
+ }
255
+ if (this._exclusiveInteraction.interactions.every(i => i === undefined)) {
256
+ this._exclusiveInteraction = null;
257
+ }
258
+ if (removed > -1) {
259
+ this.exclusiveRemoved.raiseEvent();
260
+ }
261
+ return removed !== -1 ? 1 : 0;
262
+ }
263
+
264
+ /**
265
+ * Adds an interaction permanently to the interaction chain. Only add non-interferring
266
+ * interactions in such a fashion (for instance for displaying the cursor position)
267
+ * @param {AbstractInteraction} interaction
268
+ * @param {number=} [index=3] - at what position this interaction should be added. By default, it is added after the featureProviderInteraction
269
+ * @returns {function():number} function to remove the interaction with. returns number of removed interactions (0|1)
270
+ * @api
271
+ */
272
+ addPersistentInteraction(interaction, index = 3) {
273
+ check(interaction, AbstractInteraction);
274
+ check(index, Number);
275
+
276
+ this._interactionChain.addInteraction(interaction, index);
277
+ return () => (this._interactionChain.removeInteraction(interaction) !== -1 ? 1 : 0);
278
+ }
279
+
280
+ /**
281
+ * Handles an event triggered by {@link import("@vcmap/core").VcsMap.pointerInteractionEvent}
282
+ * @param {MapEvent} event
283
+ * @api
284
+ */
285
+ handleMapEvent(event) {
286
+ if (event.pointerEvent === PointerEventType.MOVE) {
287
+ this._mouseMove(event);
288
+ } else if (event.pointerEvent === PointerEventType.DOWN) {
289
+ this._mouseDown(event);
290
+ } else if (event.pointerEvent === PointerEventType.UP) {
291
+ this._mouseUp(event);
292
+ }
293
+ }
294
+
295
+ /**
296
+ * @param {MapEvent} event
297
+ * @private
298
+ */
299
+ _mouseDown(event) {
300
+ if (this._lastDown) {
301
+ this._multiples = true;
302
+ return;
303
+ }
304
+ if (event.windowPosition.x === 0 && event.windowPosition.y === 0) {
305
+ return;
306
+ }
307
+ this._lastDown = event;
308
+ this._lastDown.time = Date.now();
309
+ }
310
+
311
+ /**
312
+ * @param {MapEvent} event
313
+ * @private
314
+ */
315
+ _mouseUp(event) {
316
+ if (event.multipleTouch) {
317
+ this._multiples = true;
318
+ this._lastDown = null;
319
+ return;
320
+ }
321
+ if (this._multiples) {
322
+ this._lastDown = null;
323
+ this._multiples = false;
324
+ return;
325
+ }
326
+
327
+ const actualEvent = /** @type {InteractionEvent} */ (event);
328
+ if (this._dragging) {
329
+ actualEvent.type = EventType.DRAGEND;
330
+ actualEvent.key = this._dragging.key;
331
+ actualEvent.pointer = this._dragging.pointer;
332
+ this._startChain(actualEvent);
333
+ } else if (this._lastDown) {
334
+ if (
335
+ this._lastClick.time &&
336
+ Date.now() - this._lastClick.time < this.clickDuration &&
337
+ Cartesian2.distanceSquared(this._lastClick.windowPosition, actualEvent.windowPosition) < 12
338
+ ) {
339
+ this._lastClick.time = null;
340
+ actualEvent.type = EventType.DBLCLICK;
341
+ } else {
342
+ this._lastClick.time = Date.now();
343
+ Cartesian2.clone(actualEvent.windowPosition, this._lastClick.windowPosition);
344
+ actualEvent.type = EventType.CLICK;
345
+ }
346
+ this._startChain(actualEvent);
347
+ }
348
+ this._dragging = null;
349
+ this._lastDown = null;
350
+ }
351
+
352
+ /**
353
+ * @param {MapEvent} event
354
+ * @private
355
+ */
356
+ _mouseMove(event) {
357
+ let actualEvent = /** @type {InteractionEvent} */ (event);
358
+ if (this._lastDown) {
359
+ if (this._dragging) {
360
+ actualEvent.type = EventType.DRAG;
361
+ actualEvent.key = this._dragging.key;
362
+ actualEvent.pointer = this._dragging.pointer;
363
+ this._startChain(actualEvent, true);
364
+ } else if (!this._dragging && Date.now() - this._lastDown.time > this.dragDuration) {
365
+ actualEvent = { type: EventType.DRAGSTART, ...this._lastDown };
366
+ this._dragging = actualEvent;
367
+ this._startChain(actualEvent, true);
368
+ }
369
+ } else {
370
+ actualEvent.type = EventType.MOVE;
371
+ this._startChain(actualEvent, true);
372
+ }
373
+ }
374
+
375
+ /**
376
+ * @param {InteractionEvent} event
377
+ * @param {boolean=} discardOnRunning if true the event will discarded if an eventHandler is already Running
378
+ * @private
379
+ */
380
+ _startChain(event, discardOnRunning) {
381
+ if (this._running && discardOnRunning) {
382
+ return;
383
+ }
384
+ if (this._running) {
385
+ this._eventQueue.push(event);
386
+ } else {
387
+ this._running = true;
388
+ this._interactionChain
389
+ .pipe(event)
390
+ .then(this._endChain.bind(this))
391
+ .catch((error) => {
392
+ getLogger().error(error.message);
393
+ this._endChain();
394
+ });
395
+ }
396
+ }
397
+
398
+ /**
399
+ * @private
400
+ */
401
+ _endChain() {
402
+ this._running = false;
403
+ if (this._eventQueue.length > 0) {
404
+ this._startChain(this._eventQueue.shift());
405
+ }
406
+ }
407
+
408
+ /**
409
+ * Destroys the event handler and its interaction chain.
410
+ */
411
+ destroy() {
412
+ this.removeExclusive();
413
+ this.exclusiveAdded.destroy();
414
+ this.exclusiveRemoved.destroy();
415
+ this._interactionChain.destroy();
416
+ this._interactionChain = null;
417
+ this._positionInteraction.destroy();
418
+ this._positionInteraction = null;
419
+ this._featureInteraction.destroy();
420
+ this._featureInteraction = null;
421
+ this._eventQueue = [];
422
+ }
423
+ }
424
+
425
+ export default EventHandler;