UNPKG

terriajs

Version:

Geospatial data visualization platform.

150 lines (133 loc) 5.32 kB
/*global require*/ "use strict"; var defined = require('terriajs-cesium/Source/Core/defined'); var Cartesian3 = require('terriajs-cesium/Source/Core/Cartesian3'); var CustomDataSource = require('terriajs-cesium/Source/DataSources/CustomDataSource'); /** * Callback for when a point is moved. * @callback PointMovedCallback * @param {CustomDataSource} customDataSource Contains all point entities that user has selected so far */ /** * For letting user drag existing points in Leaflet ViewerMode only. * * @alias LeafletDragPoints * @constructor * * @param {Terria} terria The Terria instance. * @param {PointMovedCallback} pointMovedCallback A function that is called when a point is moved. */ var LeafletDragPoints = function(terria, pointMovedCallback) { this._terria = terria; this._setUp = false; this.type = "Leaflet"; /** * Callback that occurs when point is moved. Function takes a CustomDataSource which is a list of PointEntities. * @type {PointMovedCallback} * @default undefined */ this._pointMovedCallback = pointMovedCallback; /** * List of entities that can be dragged, which is populated with user-created points only. * @type {CustomDataSource} */ this._draggableObjects = new CustomDataSource(); /** * Whether user is currently dragging point. * @type {Bool} */ this._dragInProgress = false; /** * For determining whether a drag has just occurred, to avoid deleting a point at the end of the drag. * @type {Number} */ this.dragCount = 0; }; /** * Set up the drag point helper so that attempting to drag a point will move the point. */ LeafletDragPoints.prototype.setUp = function() { if (this._setUp) { return; } if (!defined(this._terria.leaflet) || !defined(this._terria.leaflet.map)) { // Test context or something has gone *so* badly wrong return; } this._terria.leaflet.scene.featureMousedown.addEventListener(this._onMouseDownOnPoint, this); this._setUp = true; }; /** * Function that is called when the user clicks and holds on a point that was previously drawn. * * @param {Entity} entity The entity that user mouse downs on. */ LeafletDragPoints.prototype._onMouseDownOnPoint = function(entity) { if (!defined(this._draggableObjects.entities) || this._draggableObjects.entities.length === 0) { return; } var dragEntity = this._draggableObjects.entities.values.filter(function(dragObjEntity) { // Not necessarily same entity, but will have same id. return dragObjEntity.id === entity.id; })[0]; if (defined(dragEntity)) { // The touch events below don't actually work because Leaflet doesn't // expose these events. See here for a possible workaround: // https://github.com/Leaflet/Leaflet/issues/1542 this._terria.leaflet.map.on('mousemove', this._onMouseMove, this); this._terria.leaflet.map.on('touchmove', this._onMouseMove, this); this._terria.leaflet.map.on('mouseup', this._onMouseUp, this); this._terria.leaflet.map.on('touchend', this._onMouseUp, this); this._dragInProgress = true; this._entityDragged = dragEntity; this._terria.currentViewer.pauseMapInteraction(); this._originalPosition = dragEntity.position; } }; /** * Function that is called when the mouse moves. * * @param {Leaflet.MouseEvent} move Information about the move such as the final position of the mouse. */ LeafletDragPoints.prototype._onMouseMove = function(move) { if (!this._dragInProgress) { return; } this.dragCount = this.dragCount + 1; if (defined(this._entityDragged)) { this._entityDragged.position = Cartesian3.fromDegrees(move.latlng.lng, move.latlng.lat); } }; /** * Function that is called when the user releases the mousedown click. * * @param {Leaflet.MouseEvent} e Information about where the event occurred. */ LeafletDragPoints.prototype._onMouseUp = function(e) { if (this._dragInProgress && Cartesian3.fromDegrees(e.latlng.lng, e.latlng.lat) !== this._originalPosition) { this._pointMovedCallback(this._draggableObjects); } this._terria.leaflet.map.off('mousemove', this._onMouseMove, this); this._terria.leaflet.map.off('touchmove', this._onMouseMove, this); this._terria.leaflet.map.off('mouseup', this._onMouseUp, this); this._terria.leaflet.map.off('touchend', this._onMouseUp, this); this._dragInProgress = false; this._terria.currentViewer.resumeMapInteraction(); }; /** * Update the list of draggable objects with a new list of entities that are able to be dragged. We are only interested * in entities that the user has drawn. * * @param {CustomDataSource} entities Entities that user has drawn on the map. */ LeafletDragPoints.prototype.updateDraggableObjects = function(entities) { this._draggableObjects = entities; }; /** * A clean up function to call when destroying the object. */ LeafletDragPoints.prototype.destroy = function() { this._setUp = false; }; module.exports = LeafletDragPoints;