@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.
- package/LICENSE.md +21 -0
- package/README.md +44 -0
- package/build/postinstall.js +44 -0
- package/index.js +139 -0
- package/package.json +92 -0
- package/src/cesium/cesium3DTileFeature.js +9 -0
- package/src/cesium/cesium3DTilePointFeature.js +9 -0
- package/src/cesium/cesiumVcsCameraPrimitive.js +146 -0
- package/src/cesium/wallpaperMaterial.js +64 -0
- package/src/ol/feature.js +47 -0
- package/src/ol/geom/circle.js +24 -0
- package/src/ol/geom/geometryCollection.js +33 -0
- package/src/ol/render/canvas/canvasTileRenderer.js +179 -0
- package/src/ol/source/ClusterEnhancedVectorSource.js +39 -0
- package/src/ol/source/VcsCluster.js +37 -0
- package/src/vcs/vcm/classRegistry.js +106 -0
- package/src/vcs/vcm/event/vcsEvent.js +89 -0
- package/src/vcs/vcm/globalCollections.js +11 -0
- package/src/vcs/vcm/interaction/abstractInteraction.js +149 -0
- package/src/vcs/vcm/interaction/coordinateAtPixel.js +102 -0
- package/src/vcs/vcm/interaction/eventHandler.js +425 -0
- package/src/vcs/vcm/interaction/featureAtPixelInteraction.js +286 -0
- package/src/vcs/vcm/interaction/featureProviderInteraction.js +54 -0
- package/src/vcs/vcm/interaction/interactionChain.js +124 -0
- package/src/vcs/vcm/interaction/interactionType.js +114 -0
- package/src/vcs/vcm/layer/buildings.js +17 -0
- package/src/vcs/vcm/layer/cesium/cesiumTilesetCesium.js +359 -0
- package/src/vcs/vcm/layer/cesium/clusterContext.js +95 -0
- package/src/vcs/vcm/layer/cesium/dataSourceCesium.js +171 -0
- package/src/vcs/vcm/layer/cesium/openStreetMapCesium.js +29 -0
- package/src/vcs/vcm/layer/cesium/pointCloudCesium.js +58 -0
- package/src/vcs/vcm/layer/cesium/rasterLayerCesium.js +110 -0
- package/src/vcs/vcm/layer/cesium/singleImageCesium.js +49 -0
- package/src/vcs/vcm/layer/cesium/terrainCesium.js +80 -0
- package/src/vcs/vcm/layer/cesium/tmsCesium.js +54 -0
- package/src/vcs/vcm/layer/cesium/vectorCesium.js +255 -0
- package/src/vcs/vcm/layer/cesium/vectorContext.js +167 -0
- package/src/vcs/vcm/layer/cesium/vectorRasterTileCesium.js +116 -0
- package/src/vcs/vcm/layer/cesium/vectorTileImageryProvider.js +246 -0
- package/src/vcs/vcm/layer/cesium/wmsCesium.js +71 -0
- package/src/vcs/vcm/layer/cesium/wmtsCesium.js +101 -0
- package/src/vcs/vcm/layer/cesium/x3dmHelper.js +22 -0
- package/src/vcs/vcm/layer/cesiumTileset.js +376 -0
- package/src/vcs/vcm/layer/czml.js +141 -0
- package/src/vcs/vcm/layer/dataSource.js +259 -0
- package/src/vcs/vcm/layer/featureLayer.js +261 -0
- package/src/vcs/vcm/layer/featureStore.js +647 -0
- package/src/vcs/vcm/layer/featureStoreChanges.js +360 -0
- package/src/vcs/vcm/layer/featureStoreState.js +19 -0
- package/src/vcs/vcm/layer/featureVisibility.js +435 -0
- package/src/vcs/vcm/layer/geojson.js +185 -0
- package/src/vcs/vcm/layer/geojsonHelpers.js +450 -0
- package/src/vcs/vcm/layer/globalHider.js +157 -0
- package/src/vcs/vcm/layer/layer.js +752 -0
- package/src/vcs/vcm/layer/layerImplementation.js +102 -0
- package/src/vcs/vcm/layer/layerState.js +17 -0
- package/src/vcs/vcm/layer/layerSymbols.js +6 -0
- package/src/vcs/vcm/layer/oblique/layerOblique.js +76 -0
- package/src/vcs/vcm/layer/oblique/obliqueHelpers.js +175 -0
- package/src/vcs/vcm/layer/oblique/vectorOblique.js +469 -0
- package/src/vcs/vcm/layer/openStreetMap.js +194 -0
- package/src/vcs/vcm/layer/openlayers/layerOpenlayers.js +79 -0
- package/src/vcs/vcm/layer/openlayers/openStreetMapOpenlayers.js +27 -0
- package/src/vcs/vcm/layer/openlayers/rasterLayerOpenlayers.js +121 -0
- package/src/vcs/vcm/layer/openlayers/singleImageOpenlayers.js +49 -0
- package/src/vcs/vcm/layer/openlayers/tileDebugOpenlayers.js +39 -0
- package/src/vcs/vcm/layer/openlayers/tmsOpenlayers.js +62 -0
- package/src/vcs/vcm/layer/openlayers/vectorOpenlayers.js +118 -0
- package/src/vcs/vcm/layer/openlayers/vectorTileOpenlayers.js +177 -0
- package/src/vcs/vcm/layer/openlayers/wmsOpenlayers.js +55 -0
- package/src/vcs/vcm/layer/openlayers/wmtsOpenlayers.js +141 -0
- package/src/vcs/vcm/layer/pointCloud.js +162 -0
- package/src/vcs/vcm/layer/rasterLayer.js +294 -0
- package/src/vcs/vcm/layer/singleImage.js +119 -0
- package/src/vcs/vcm/layer/terrain.js +122 -0
- package/src/vcs/vcm/layer/terrainHelpers.js +123 -0
- package/src/vcs/vcm/layer/tileLoadedHelper.js +72 -0
- package/src/vcs/vcm/layer/tileProvider/mvtTileProvider.js +104 -0
- package/src/vcs/vcm/layer/tileProvider/staticGeojsonTileProvider.js +67 -0
- package/src/vcs/vcm/layer/tileProvider/tileProvider.js +584 -0
- package/src/vcs/vcm/layer/tileProvider/tileProviderFactory.js +28 -0
- package/src/vcs/vcm/layer/tileProvider/urlTemplateTileProvider.js +106 -0
- package/src/vcs/vcm/layer/tms.js +121 -0
- package/src/vcs/vcm/layer/vector.js +632 -0
- package/src/vcs/vcm/layer/vectorHelpers.js +206 -0
- package/src/vcs/vcm/layer/vectorProperties.js +1391 -0
- package/src/vcs/vcm/layer/vectorSymbols.js +40 -0
- package/src/vcs/vcm/layer/vectorTile.js +480 -0
- package/src/vcs/vcm/layer/wfs.js +165 -0
- package/src/vcs/vcm/layer/wms.js +270 -0
- package/src/vcs/vcm/layer/wmsHelpers.js +65 -0
- package/src/vcs/vcm/layer/wmts.js +235 -0
- package/src/vcs/vcm/maps/baseOLMap.js +257 -0
- package/src/vcs/vcm/maps/cameraLimiter.js +219 -0
- package/src/vcs/vcm/maps/cesium.js +1192 -0
- package/src/vcs/vcm/maps/map.js +511 -0
- package/src/vcs/vcm/maps/mapState.js +17 -0
- package/src/vcs/vcm/maps/oblique.js +536 -0
- package/src/vcs/vcm/maps/openlayers.js +205 -0
- package/src/vcs/vcm/object.js +92 -0
- package/src/vcs/vcm/oblique/ObliqueCollection.js +572 -0
- package/src/vcs/vcm/oblique/ObliqueDataSet.js +357 -0
- package/src/vcs/vcm/oblique/ObliqueImage.js +247 -0
- package/src/vcs/vcm/oblique/ObliqueImageMeta.js +126 -0
- package/src/vcs/vcm/oblique/ObliqueProvider.js +433 -0
- package/src/vcs/vcm/oblique/ObliqueView.js +130 -0
- package/src/vcs/vcm/oblique/ObliqueViewDirection.js +40 -0
- package/src/vcs/vcm/oblique/helpers.js +483 -0
- package/src/vcs/vcm/oblique/parseImageJson.js +248 -0
- package/src/vcs/vcm/util/clipping/clippingObject.js +386 -0
- package/src/vcs/vcm/util/clipping/clippingObjectManager.js +312 -0
- package/src/vcs/vcm/util/clipping/clippingPlaneHelper.js +413 -0
- package/src/vcs/vcm/util/collection.js +193 -0
- package/src/vcs/vcm/util/dateTime.js +60 -0
- package/src/vcs/vcm/util/exclusiveManager.js +135 -0
- package/src/vcs/vcm/util/extent.js +124 -0
- package/src/vcs/vcm/util/featureProvider/abstractFeatureProvider.js +196 -0
- package/src/vcs/vcm/util/featureProvider/featureProviderHelpers.js +51 -0
- package/src/vcs/vcm/util/featureProvider/featureProviderSymbols.js +11 -0
- package/src/vcs/vcm/util/featureProvider/tileProviderFeatureProvider.js +62 -0
- package/src/vcs/vcm/util/featureProvider/wmsFeatureProvider.js +280 -0
- package/src/vcs/vcm/util/featureconverter/circleToCesium.js +215 -0
- package/src/vcs/vcm/util/featureconverter/convert.js +83 -0
- package/src/vcs/vcm/util/featureconverter/extent3d.js +154 -0
- package/src/vcs/vcm/util/featureconverter/featureconverterHelper.js +591 -0
- package/src/vcs/vcm/util/featureconverter/lineStringToCesium.js +171 -0
- package/src/vcs/vcm/util/featureconverter/pointToCesium.js +359 -0
- package/src/vcs/vcm/util/featureconverter/polygonToCesium.js +229 -0
- package/src/vcs/vcm/util/geometryHelpers.js +172 -0
- package/src/vcs/vcm/util/indexedCollection.js +158 -0
- package/src/vcs/vcm/util/isMobile.js +12 -0
- package/src/vcs/vcm/util/layerCollection.js +216 -0
- package/src/vcs/vcm/util/locale.js +53 -0
- package/src/vcs/vcm/util/mapCollection.js +363 -0
- package/src/vcs/vcm/util/math.js +71 -0
- package/src/vcs/vcm/util/projection.js +348 -0
- package/src/vcs/vcm/util/splitScreen.js +233 -0
- package/src/vcs/vcm/util/style/declarativeStyleItem.js +631 -0
- package/src/vcs/vcm/util/style/shapesCategory.js +67 -0
- package/src/vcs/vcm/util/style/styleFactory.js +48 -0
- package/src/vcs/vcm/util/style/styleHelpers.js +555 -0
- package/src/vcs/vcm/util/style/styleItem.js +226 -0
- package/src/vcs/vcm/util/style/vectorStyleItem.js +927 -0
- package/src/vcs/vcm/util/style/writeStyle.js +48 -0
- package/src/vcs/vcm/util/urlHelpers.js +16 -0
- 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;
|