123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284 |
- /**
- * @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;
- }
- });
|