Spaces:
Running
Running
| /** | |
| * @class L.EditToolbar.Edit | |
| * @aka EditToolbar.Edit | |
| */ | |
| L.EditToolbar.Edit = L.Handler.extend({ | |
| statics: { | |
| TYPE: 'edit' | |
| }, | |
| includes: L.Mixin.Events, | |
| // @method intialize(): void | |
| initialize: function (map, options) { | |
| L.Handler.prototype.initialize.call(this, map); | |
| L.setOptions(this, options); | |
| // Store the selectable layer group for ease of access | |
| this._featureGroup = options.featureGroup; | |
| if (!(this._featureGroup instanceof L.FeatureGroup)) { | |
| throw new Error('options.featureGroup must be a L.FeatureGroup'); | |
| } | |
| this._uneditedLayerProps = {}; | |
| // Save the type so super can fire, need to do this as cannot do this.TYPE :( | |
| this.type = L.EditToolbar.Edit.TYPE; | |
| }, | |
| // @method enable(): void | |
| // Enable the edit toolbar | |
| enable: function () { | |
| if (this._enabled || !this._hasAvailableLayers()) { | |
| return; | |
| } | |
| this.fire('enabled', { handler: this.type }); | |
| //this disable other handlers | |
| this._map.fire(L.Draw.Event.EDITSTART, { handler: this.type }); | |
| //allow drawLayer to be updated before beginning edition. | |
| L.Handler.prototype.enable.call(this); | |
| this._featureGroup | |
| .on('layeradd', this._enableLayerEdit, this) | |
| .on('layerremove', this._disableLayerEdit, this); | |
| }, | |
| // @method disable(): void | |
| // Disable the edit toolbar | |
| disable: function () { | |
| if (!this._enabled) { | |
| return; | |
| } | |
| this._featureGroup | |
| .off('layeradd', this._enableLayerEdit, this) | |
| .off('layerremove', this._disableLayerEdit, this); | |
| L.Handler.prototype.disable.call(this); | |
| this._map.fire(L.Draw.Event.EDITSTOP, { handler: this.type }); | |
| this.fire('disabled', { handler: this.type }); | |
| }, | |
| // @method addHooks(): void | |
| // Add listener hooks for this handler | |
| addHooks: function () { | |
| var map = this._map; | |
| if (map) { | |
| map.getContainer().focus(); | |
| this._featureGroup.eachLayer(this._enableLayerEdit, this); | |
| this._tooltip = new L.Draw.Tooltip(this._map); | |
| this._tooltip.updateContent({ | |
| text: L.drawLocal.edit.handlers.edit.tooltip.text, | |
| subtext: L.drawLocal.edit.handlers.edit.tooltip.subtext | |
| }); | |
| // Quickly access the tooltip to update for intersection checking | |
| map._editTooltip = this._tooltip; | |
| this._updateTooltip(); | |
| this._map | |
| .on('mousemove', this._onMouseMove, this) | |
| .on('touchmove', this._onMouseMove, this) | |
| .on('MSPointerMove', this._onMouseMove, this) | |
| .on(L.Draw.Event.EDITVERTEX, this._updateTooltip, this); | |
| } | |
| }, | |
| // @method removeHooks(): void | |
| // Remove listener hooks for this handler | |
| removeHooks: function () { | |
| if (this._map) { | |
| // Clean up selected layers. | |
| this._featureGroup.eachLayer(this._disableLayerEdit, this); | |
| // Clear the backups of the original layers | |
| this._uneditedLayerProps = {}; | |
| this._tooltip.dispose(); | |
| this._tooltip = null; | |
| this._map | |
| .off('mousemove', this._onMouseMove, this) | |
| .off('touchmove', this._onMouseMove, this) | |
| .off('MSPointerMove', this._onMouseMove, this) | |
| .off(L.Draw.Event.EDITVERTEX, this._updateTooltip, this); | |
| } | |
| }, | |
| // @method revertLayers(): void | |
| // Revert each layer's geometry changes | |
| revertLayers: function () { | |
| this._featureGroup.eachLayer(function (layer) { | |
| this._revertLayer(layer); | |
| }, this); | |
| }, | |
| // @method save(): void | |
| // Save the layer geometries | |
| save: function () { | |
| var editedLayers = new L.LayerGroup(); | |
| this._featureGroup.eachLayer(function (layer) { | |
| if (layer.edited) { | |
| editedLayers.addLayer(layer); | |
| layer.edited = false; | |
| } | |
| }); | |
| this._map.fire(L.Draw.Event.EDITED, { layers: editedLayers }); | |
| }, | |
| _backupLayer: function (layer) { | |
| var id = L.Util.stamp(layer); | |
| if (!this._uneditedLayerProps[id]) { | |
| // Polyline, Polygon or Rectangle | |
| if (layer instanceof L.Polyline || layer instanceof L.Polygon || layer instanceof L.Rectangle) { | |
| this._uneditedLayerProps[id] = { | |
| latlngs: L.LatLngUtil.cloneLatLngs(layer.getLatLngs()) | |
| }; | |
| } else if (layer instanceof L.Circle) { | |
| this._uneditedLayerProps[id] = { | |
| latlng: L.LatLngUtil.cloneLatLng(layer.getLatLng()), | |
| radius: layer.getRadius() | |
| }; | |
| } else if (layer instanceof L.Marker) { // Marker | |
| this._uneditedLayerProps[id] = { | |
| latlng: L.LatLngUtil.cloneLatLng(layer.getLatLng()) | |
| }; | |
| } | |
| } | |
| }, | |
| _getTooltipText: function () { | |
| return ({ | |
| text: L.drawLocal.edit.handlers.edit.tooltip.text, | |
| subtext: L.drawLocal.edit.handlers.edit.tooltip.subtext | |
| }); | |
| }, | |
| _updateTooltip: function () { | |
| this._tooltip.updateContent(this._getTooltipText()); | |
| }, | |
| _revertLayer: function (layer) { | |
| var id = L.Util.stamp(layer); | |
| layer.edited = false; | |
| if (this._uneditedLayerProps.hasOwnProperty(id)) { | |
| // Polyline, Polygon or Rectangle | |
| if (layer instanceof L.Polyline || layer instanceof L.Polygon || layer instanceof L.Rectangle) { | |
| layer.setLatLngs(this._uneditedLayerProps[id].latlngs); | |
| } else if (layer instanceof L.Circle) { | |
| layer.setLatLng(this._uneditedLayerProps[id].latlng); | |
| layer.setRadius(this._uneditedLayerProps[id].radius); | |
| } else if (layer instanceof L.Marker) { // Marker | |
| layer.setLatLng(this._uneditedLayerProps[id].latlng); | |
| } | |
| layer.fire('revert-edited', { layer: layer }); | |
| } | |
| }, | |
| _enableLayerEdit: function (e) { | |
| var layer = e.layer || e.target || e, | |
| pathOptions, poly; | |
| // Back up this layer (if haven't before) | |
| this._backupLayer(layer); | |
| if (this.options.poly) { | |
| poly = L.Util.extend({}, this.options.poly); | |
| layer.options.poly = poly; | |
| } | |
| // Set different style for editing mode | |
| if (this.options.selectedPathOptions) { | |
| pathOptions = L.Util.extend({}, this.options.selectedPathOptions); | |
| // Use the existing color of the layer | |
| if (pathOptions.maintainColor) { | |
| pathOptions.color = layer.options.color; | |
| pathOptions.fillColor = layer.options.fillColor; | |
| } | |
| layer.options.original = L.extend({}, layer.options); | |
| layer.options.editing = pathOptions; | |
| } | |
| if (layer instanceof L.Marker) { | |
| if (layer.editing) { | |
| layer.editing.enable(); | |
| } | |
| layer.dragging.enable(); | |
| layer | |
| .on('dragend', this._onMarkerDragEnd) | |
| // #TODO: remove when leaflet finally fixes their draggable so it's touch friendly again. | |
| .on('touchmove', this._onTouchMove, this) | |
| .on('MSPointerMove', this._onTouchMove, this) | |
| .on('touchend', this._onMarkerDragEnd, this) | |
| .on('MSPointerUp', this._onMarkerDragEnd, this); | |
| } else { | |
| layer.editing.enable(); | |
| } | |
| }, | |
| _disableLayerEdit: function (e) { | |
| var layer = e.layer || e.target || e; | |
| layer.edited = false; | |
| if (layer.editing) { | |
| layer.editing.disable(); | |
| } | |
| delete layer.options.editing; | |
| delete layer.options.original; | |
| // Reset layer styles to that of before select | |
| if (this._selectedPathOptions) { | |
| if (layer instanceof L.Marker) { | |
| this._toggleMarkerHighlight(layer); | |
| } else { | |
| // reset the layer style to what is was before being selected | |
| layer.setStyle(layer.options.previousOptions); | |
| // remove the cached options for the layer object | |
| delete layer.options.previousOptions; | |
| } | |
| } | |
| if (layer instanceof L.Marker) { | |
| layer.dragging.disable(); | |
| layer | |
| .off('dragend', this._onMarkerDragEnd, this) | |
| .off('touchmove', this._onTouchMove, this) | |
| .off('MSPointerMove', this._onTouchMove, this) | |
| .off('touchend', this._onMarkerDragEnd, this) | |
| .off('MSPointerUp', this._onMarkerDragEnd, this); | |
| } else { | |
| layer.editing.disable(); | |
| } | |
| }, | |
| _onMouseMove: function (e) { | |
| this._tooltip.updatePosition(e.latlng); | |
| }, | |
| _onMarkerDragEnd: function (e) { | |
| var layer = e.target; | |
| layer.edited = true; | |
| this._map.fire(L.Draw.Event.EDITMOVE, { layer: layer }); | |
| }, | |
| _onTouchMove: function (e) { | |
| var touchEvent = e.originalEvent.changedTouches[0], | |
| layerPoint = this._map.mouseEventToLayerPoint(touchEvent), | |
| latlng = this._map.layerPointToLatLng(layerPoint); | |
| e.target.setLatLng(latlng); | |
| }, | |
| _hasAvailableLayers: function () { | |
| return this._featureGroup.getLayers().length !== 0; | |
| } | |
| }); | |