leaflet-polyline-segment-edit
Version:
An extension to Leaflet.draw to allow editing large polylines one chunk at the time
2 lines (1 loc) • 4.22 kB
JavaScript
!function(t){"function"==typeof define&&define.amd?define(t):t()}((function(){"use strict";L.Draw.Event.LINESEGMENTEDIT="draw:linesegment:editstart",L.Edit.PolySegmentEditing=L.Handler.extend({initialize:function(t,e,i){this._map=t,this._polyline=e,i=L.setOptions(this,i),this._setDefaultStyles(),this.segmentSize=i.segmentSize?i.segmentSize:100,this.segmentSize=Math.max(this.segmentSize,2),this._segments=[],this.segmentBeingEdited=null,this.layerGroup=L.layerGroup(),this._initLineSegments()},addHooks:function(){this._addSegmentsToMap()},removeHooks:function(){this.segmentBeingEdited&&this.segmentBeingEdited.stopEditing(),this._removeSegmentsFromMap()},_setDefaultStyles:function(){this.options.style||(this.options.style={});var t=L.Draw.Polyline.prototype.options.shapeOptions;this.options.style.hover=this.options.style.hover||t,this.options.style.default=this.options.style.default||t,this.options.style.editing=this.options.style.editing||t},_initLineSegments:function(){for(var t=L.LineUtil.isFlat(this._polyline._latlngs),e=t||L.LineUtil.isFlat(this._polyline._latlngs[0])?[this._polyline._latlngs]:this._polyline._latlngs,i=0;i<e.length;i++)for(var n=t?[e[i]]:e[i],s=0;s<n.length;s++)for(var o=n[s],l=0,r=0,h=null;r<o.length;){r=Math.min(l+this.segmentSize,o.length);var a=o.slice(l,r);r===o.length&&a.push(o[0]);var g=new L.Edit.LineSegment([a],{startIndexOnRing:l,endIndexOnRing:r,previous:h,next:null,polylineIndex:i,ringIndex:s,style:this.options.style});g.setStyle(this.options.style.default),this._segments.push(g),l=r-1,h&&(h.options.next=g),h=g}},_addSegmentsToMap:function(){for(var t=0;t<this._segments.length;t++)this._segments[t].on("edit",this._onSegmentEdit,this),this._segments[t].on("start",this._onEditingStart,this),this.layerGroup.addLayer(this._segments[t]);this._map.addLayer(this.layerGroup)},_removeSegmentsFromMap:function(){this.layerGroup.clearLayers();for(var t=0;t<this._segments.length;t++)this._segments[t].off("edit",this._onSegmentEdit,this),this._segments[t].off("start",this._onEditingStart,this);this._map.removeLayer(this.layerGroup)},_onEditingStart:function(t){this.segmentBeingEdited&&this.segmentBeingEdited.stopEditing(),this.segmentBeingEdited=t.target},_onSegmentEdit:function(t){var e=t.target,i=e.options,n=L.LineUtil.isFlat(this._polyline._latlngs),s=!n&&!L.LineUtil.isFlat(this._polyline._latlngs[0]),o=this._polyline._latlngs,l=s?o[i.polylineIndex][i.ringIndex]:n?o:o[i.polylineIndex],r=l.slice(0,i.startIndexOnRing),h=l.slice(i.endIndexOnRing),a=r.concat(e._latlngs[0],h);s?o[i.polylineIndex][i.ringIndex]=a:o=a,this._polyline.setLatLngs(o),this._redrawNeighbours(e),this._updateRingIndices(e),this._map.fire(L.Draw.Event.LINESEGMENTEDIT,{layer:this._polyline})},_redrawNeighbours:function(t){t.options.previous&&(t.options.previous._latlngs[0][t.options.previous._latlngs[0].length-1]=t._latlngs[0][0],t.options.previous.redraw()),t.options.next&&(t.options.next._latlngs[0][0]=t._latlngs[0][t._latlngs[0].length-1],t.options.next.redraw())},_updateRingIndices:function(t){for(var e=t;e.options.previous;)e=e.options.previous;for(var i=0,n=0;e;)n=i+e._latlngs[0].length,e.options.startIndexOnRing=i,e.options.endIndexOnRing=n,i=n-1,e=e.options.next}}),L.Edit.LineSegment=L.Polyline.extend({initialize:function(t,e){e=Object.assign(e,{original:{},editing:{}}),L.Polyline.prototype.initialize.call(this,t,e),this.currentStyle=this.options.style.default},onAdd:function(t){L.Path.prototype.onAdd.call(this,t),this.on("mouseover",this._onHover),this.on("mouseout",this._onBlur),this.on("click",this._onClick)},onRemove:function(t){L.Path.prototype.onRemove.call(this,t),this.off("mouseover",this._onHover),this.off("mouseout",this._onBlur),this.off("click",this._onClick)},stopEditing:function(){this.editing.enabled()&&(this.editing.disable(),this._setCurrentStyle(this.options.style.default))},_onHover:function(){this.setStyle(this.options.style.hover),L.Browser.ie||L.Browser.opera||L.Browser.edge||this.bringToFront()},_onBlur:function(){this.setStyle(this.currentStyle)},_onClick:function(){this.fire("start"),this.editing.enable(),this._setCurrentStyle(this.options.style.editing)},_setCurrentStyle:function(t){this.currentStyle=t,this.setStyle(t)}})}));