Replace Leaflet.draw with Leaflet.Editable, closes #100
This commit is contained in:
parent
76e2618bbf
commit
69e53233ba
7 changed files with 429 additions and 59 deletions
|
|
@ -111,8 +111,8 @@ Copyright (c) 2013, Turistforeningen, Hans Kristian Flaatten. All rights reserve
|
||||||
Copyright (c) 2013 Felix Bache; [MIT License](https://github.com/MrMufflon/Leaflet.Elevation/blob/master/LICENSE)
|
Copyright (c) 2013 Felix Bache; [MIT License](https://github.com/MrMufflon/Leaflet.Elevation/blob/master/LICENSE)
|
||||||
* [D3.js](https://github.com/mbostock/d3)
|
* [D3.js](https://github.com/mbostock/d3)
|
||||||
Copyright (c) 2013, Michael Bostock. All rights reserved.; [3-clause BSD License](https://github.com/mbostock/d3/blob/master/LICENSE)
|
Copyright (c) 2013, Michael Bostock. All rights reserved.; [3-clause BSD License](https://github.com/mbostock/d3/blob/master/LICENSE)
|
||||||
* [Leaflet.draw](https://github.com/Leaflet/Leaflet.draw)
|
* [Leaflet.Editable](https://github.com/Leaflet/Leaflet.Editable)
|
||||||
Copyright 2012 Jacob Toye; [MIT License](https://github.com/Leaflet/Leaflet.draw/blob/master/MIT-LICENCE.txt)
|
Yohan Boniface; WTFPL licence
|
||||||
* [Leaflet Control Geocoder](https://github.com/perliedman/leaflet-control-geocoder)
|
* [Leaflet Control Geocoder](https://github.com/perliedman/leaflet-control-geocoder)
|
||||||
Copyright (c) 2012 [sa3m](https://github.com/sa3m), Copyright (c) 2013 Per Liedman; [2-clause BSD License](https://github.com/perliedman/leaflet-control-geocoder/blob/master/LICENSE)
|
Copyright (c) 2012 [sa3m](https://github.com/sa3m), Copyright (c) 2013 Per Liedman; [2-clause BSD License](https://github.com/perliedman/leaflet-control-geocoder/blob/master/LICENSE)
|
||||||
* [leaflet-plugins](https://github.com/shramov/leaflet-plugins)
|
* [leaflet-plugins](https://github.com/shramov/leaflet-plugins)
|
||||||
|
|
|
||||||
13
bower.json
13
bower.json
|
|
@ -15,7 +15,6 @@
|
||||||
"leaflet-routing": "nrenner/leaflet-routing#leaflet-1.0",
|
"leaflet-routing": "nrenner/leaflet-routing#leaflet-1.0",
|
||||||
"async": "~0.9.2",
|
"async": "~0.9.2",
|
||||||
"d3": "~3.5.5",
|
"d3": "~3.5.5",
|
||||||
"leaflet.draw": "~0.4.9",
|
|
||||||
"bootstrap": "4.0.0-alpha.5",
|
"bootstrap": "4.0.0-alpha.5",
|
||||||
"DataTables": "~1.10.13",
|
"DataTables": "~1.10.13",
|
||||||
"leaflet.elevation": "MrMufflon/Leaflet.Elevation#master",
|
"leaflet.elevation": "MrMufflon/Leaflet.Elevation#master",
|
||||||
|
|
@ -29,7 +28,8 @@
|
||||||
"font-awesome": "^4.7.0",
|
"font-awesome": "^4.7.0",
|
||||||
"bootstrap-select": "hugdx/bootstrap-select#patch-1",
|
"bootstrap-select": "hugdx/bootstrap-select#patch-1",
|
||||||
"leaflet-sidebar": "^0.1.9",
|
"leaflet-sidebar": "^0.1.9",
|
||||||
"autosize": "^3.0.20"
|
"autosize": "^3.0.20",
|
||||||
|
"leaflet.editable": "^1.1.0"
|
||||||
},
|
},
|
||||||
"overrides": {
|
"overrides": {
|
||||||
"leaflet": {
|
"leaflet": {
|
||||||
|
|
@ -53,15 +53,6 @@
|
||||||
"src/L.Routing.Edit.js"
|
"src/L.Routing.Edit.js"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"leaflet.draw": {
|
|
||||||
"main": [
|
|
||||||
"dist/leaflet.draw-src.js",
|
|
||||||
"dist/leaflet.draw.css",
|
|
||||||
"dist/images/*.png",
|
|
||||||
"dist/images/*.svg"
|
|
||||||
],
|
|
||||||
"dependencies": null
|
|
||||||
},
|
|
||||||
"bootstrap-select": {
|
"bootstrap-select": {
|
||||||
"main": [
|
"main": [
|
||||||
"js/bootstrap-select.js",
|
"js/bootstrap-select.js",
|
||||||
|
|
|
||||||
|
|
@ -226,3 +226,40 @@ table.dataTable.display tbody tr.odd:hover,
|
||||||
table.dataTable.display tbody tr.even:hover {
|
table.dataTable.display tbody tr.even:hover {
|
||||||
background-color: rgba(255,255,0,0.2);
|
background-color: rgba(255,255,0,0.2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* No-go areas
|
||||||
|
*/
|
||||||
|
|
||||||
|
.nogo-delete-marker {
|
||||||
|
text-align: center;
|
||||||
|
line-height: 16px;
|
||||||
|
font-size: 11px;
|
||||||
|
border-radius: 8px;
|
||||||
|
}
|
||||||
|
.leaflet-touch .nogo-delete-marker {
|
||||||
|
border-radius: 12px;
|
||||||
|
line-height: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* tooltip */
|
||||||
|
|
||||||
|
.editing-tooltip,
|
||||||
|
.editing-tooltip-create {
|
||||||
|
color: #fff;
|
||||||
|
background-color: rgba(0,0,0,0.7);
|
||||||
|
/* for direction arrows that inherit */
|
||||||
|
border-color: rgba(0,0,0,0.7);
|
||||||
|
/* no border but still set a color for direction arrows */
|
||||||
|
border-width: 0px;
|
||||||
|
}
|
||||||
|
.editing-tooltip-create {
|
||||||
|
/* no (invisible) direction arrow for cursor tooltip */
|
||||||
|
border-color: transparent;
|
||||||
|
}
|
||||||
|
.leaflet-tooltip-bottom:before {
|
||||||
|
border-bottom-color: inherit;
|
||||||
|
}
|
||||||
|
.leaflet-tooltip-right:before {
|
||||||
|
border-right-color: inherit;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,12 +13,13 @@
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}()),
|
}()),
|
||||||
touchScreenDetectable = touchScreen !== null;
|
touchScreenDetectable = touchScreen !== null,
|
||||||
|
touch = touchScreenDetectable ? touchScreen : L.Browser.touch;
|
||||||
|
|
||||||
BR.Browser = {
|
BR.Browser = {
|
||||||
touchScreen: touchScreen,
|
touchScreen: touchScreen,
|
||||||
touchScreenDetectable: touchScreenDetectable
|
touchScreenDetectable: touchScreenDetectable,
|
||||||
|
touch: touch
|
||||||
};
|
};
|
||||||
|
|
||||||
}());
|
}());
|
||||||
|
|
@ -235,6 +235,8 @@
|
||||||
map.addControl(sidebar);
|
map.addControl(sidebar);
|
||||||
|
|
||||||
nogos.addTo(map);
|
nogos.addTo(map);
|
||||||
|
nogos.preventRoutePointOnCreate(routing);
|
||||||
|
|
||||||
map.addControl(new BR.OpacitySlider({
|
map.addControl(new BR.OpacitySlider({
|
||||||
callback: L.bind(routing.setOpacity, routing)
|
callback: L.bind(routing.setOpacity, routing)
|
||||||
}));
|
}));
|
||||||
|
|
|
||||||
|
|
@ -1,55 +1,115 @@
|
||||||
L.drawLocal.draw.toolbar.buttons.circle = 'Draw no-go area (circle)';
|
BR.NogoAreas = L.Control.extend({
|
||||||
L.drawLocal.edit.toolbar.buttons.edit = 'Edit no-go areas';
|
statics: {
|
||||||
L.drawLocal.edit.toolbar.buttons.remove = 'Delete no-go areas';
|
MSG_BUTTON: 'Draw no-go area (circle)',
|
||||||
|
MSG_BUTTON_CANCEL: 'Cancel drawing no-go area',
|
||||||
|
MSG_CREATE: 'Click and drag to draw circle',
|
||||||
|
MSG_DISABLED: 'Click to edit',
|
||||||
|
MSG_ENABLED: '□ = move / resize, <span class="fa fa-trash-o"></span> = delete,<br>click circle to quit editing',
|
||||||
|
STATE_CREATE: 'no-go-create',
|
||||||
|
STATE_CANCEL: 'cancel-no-go-create'
|
||||||
|
},
|
||||||
|
|
||||||
|
style: {
|
||||||
|
color: '#f06eaa',
|
||||||
|
weight: 4,
|
||||||
|
opacity: 0.5,
|
||||||
|
fillColor: null, //same as color by default
|
||||||
|
fillOpacity: 0.2,
|
||||||
|
dashArray: null
|
||||||
|
},
|
||||||
|
|
||||||
|
editStyle: {
|
||||||
|
color: '#fe57a1',
|
||||||
|
opacity: 0.6,
|
||||||
|
dashArray: '10, 10',
|
||||||
|
fillOpacity: 0.1
|
||||||
|
},
|
||||||
|
|
||||||
BR.NogoAreas = L.Control.Draw.extend({
|
|
||||||
initialize: function () {
|
initialize: function () {
|
||||||
this.drawnItems = new L.FeatureGroup();
|
this._wasRouteDrawing = false;
|
||||||
|
|
||||||
L.Control.Draw.prototype.initialize.call(this, {
|
|
||||||
draw: {
|
|
||||||
position: 'topleft',
|
|
||||||
polyline: false,
|
|
||||||
polygon: false,
|
|
||||||
circle: true,
|
|
||||||
rectangle: false,
|
|
||||||
marker: false
|
|
||||||
},
|
|
||||||
edit: {
|
|
||||||
featureGroup: this.drawnItems,
|
|
||||||
//edit: false,
|
|
||||||
edit: {
|
|
||||||
selectedPathOptions: {
|
|
||||||
//opacity: 0.8
|
|
||||||
}
|
|
||||||
},
|
|
||||||
remove: true
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
|
|
||||||
onAdd: function (map) {
|
onAdd: function (map) {
|
||||||
map.addLayer(this.drawnItems);
|
var self = this;
|
||||||
|
|
||||||
map.on('draw:created', function (e) {
|
this.drawnItems = new L.FeatureGroup().addTo(map);
|
||||||
var layer = e.layer;
|
this.drawnItems.on('click', function(e) {
|
||||||
this.drawnItems.addLayer(layer);
|
L.DomEvent.stop(e);
|
||||||
|
e.layer.toggleEdit();
|
||||||
|
});
|
||||||
|
|
||||||
|
var editTools = this.editTools = map.editTools = new L.Editable(map, {
|
||||||
|
circleEditorClass: BR.DeletableCircleEditor,
|
||||||
|
// FeatureGroup instead of LayerGroup to propagate events to members
|
||||||
|
editLayer: new L.FeatureGroup().addTo(map),
|
||||||
|
featuresLayer: this.drawnItems
|
||||||
|
});
|
||||||
|
|
||||||
|
var button = L.easyButton({
|
||||||
|
states: [{
|
||||||
|
stateName: BR.NogoAreas.STATE_CREATE,
|
||||||
|
icon: 'fa-ban',
|
||||||
|
title: BR.NogoAreas.MSG_BUTTON,
|
||||||
|
onClick: function (control) {
|
||||||
|
// initial radius of 0 to detect click, see DeletableCircleEditor.onDrawingMouseUp
|
||||||
|
var opts = L.extend({radius: 0}, self.style);
|
||||||
|
editTools.startCircle(null, opts);
|
||||||
|
|
||||||
|
control.state('cancel-no-go-create');
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
stateName: BR.NogoAreas.STATE_CANCEL,
|
||||||
|
icon: 'fa-ban active',
|
||||||
|
title: BR.NogoAreas.MSG_BUTTON_CANCEL,
|
||||||
|
onClick: function (control) {
|
||||||
|
editTools.stopDrawing();
|
||||||
|
control.state('no-go-create');
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
}).addTo(map);
|
||||||
|
|
||||||
|
this.editTools.on('editable:drawing:end', function (e) {
|
||||||
|
button.state(BR.NogoAreas.STATE_CREATE);
|
||||||
|
|
||||||
|
setTimeout(L.bind(function () {
|
||||||
|
// turn editing off after create; async to still fire 'editable:vertex:dragend'
|
||||||
|
e.layer.disableEdit();
|
||||||
|
}, this), 0);
|
||||||
|
}, this);
|
||||||
|
|
||||||
|
this.editTools.on('editable:vertex:dragend editable:deleted', function (e) {
|
||||||
this._fireUpdate();
|
this._fireUpdate();
|
||||||
}, this);
|
}, this);
|
||||||
|
|
||||||
map.on('draw:editstart', function (e) {
|
this.editTools.on('editable:enable', function (e) {
|
||||||
this.drawnItems.eachLayer(function (layer) {
|
e.layer.setStyle(this.editStyle);
|
||||||
layer.on('edit', function(e) {
|
}, this);
|
||||||
this._fireUpdate();
|
this.editTools.on('editable:disable', function (e) {
|
||||||
}, this);
|
e.layer.setStyle(this.style);
|
||||||
}, this);
|
|
||||||
}, this);
|
}, this);
|
||||||
|
|
||||||
map.on('draw:deleted', function (e) {
|
this.tooltip = new BR.EditingTooltip(map, editTools, button);
|
||||||
this._fireUpdate();
|
this.tooltip.enable();
|
||||||
|
|
||||||
|
// dummy, no own representation, delegating to EasyButton
|
||||||
|
return L.DomUtil.create('div');
|
||||||
|
},
|
||||||
|
|
||||||
|
// prevent route waypoint added after circle create (map click after up)
|
||||||
|
preventRoutePointOnCreate: function(routing) {
|
||||||
|
this.editTools.on('editable:drawing:start', function (e) {
|
||||||
|
this._wasRouteDrawing = routing.isDrawing();
|
||||||
|
routing.draw(false);
|
||||||
}, this);
|
}, this);
|
||||||
|
|
||||||
return L.Control.Draw.prototype.onAdd.call(this, map);
|
// after create
|
||||||
|
this.editTools.on('editable:drawing:end', function (e) {
|
||||||
|
if (this._wasRouteDrawing) {
|
||||||
|
setTimeout(function () {
|
||||||
|
routing.draw(true);
|
||||||
|
}, 0);
|
||||||
|
}
|
||||||
|
}, this);
|
||||||
},
|
},
|
||||||
|
|
||||||
getOptions: function() {
|
getOptions: function() {
|
||||||
|
|
@ -60,17 +120,292 @@ BR.NogoAreas = L.Control.Draw.extend({
|
||||||
|
|
||||||
setOptions: function(options) {
|
setOptions: function(options) {
|
||||||
var nogos = options.nogos;
|
var nogos = options.nogos;
|
||||||
this.drawnItems.clearLayers();
|
this._clear();
|
||||||
if (nogos) {
|
if (nogos) {
|
||||||
for (var i = 0; i < nogos.length; i++) {
|
for (var i = 0; i < nogos.length; i++) {
|
||||||
|
nogos[i].setStyle(this.style);
|
||||||
this.drawnItems.addLayer(nogos[i]);
|
this.drawnItems.addLayer(nogos[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_clear: function () {
|
||||||
|
this.drawnItems.clearLayers();
|
||||||
|
},
|
||||||
|
|
||||||
|
clear: function () {
|
||||||
|
this._clear();
|
||||||
|
this._fireUpdate();
|
||||||
|
},
|
||||||
|
|
||||||
_fireUpdate: function () {
|
_fireUpdate: function () {
|
||||||
this.fire('update', {options: this.getOptions()});
|
this.fire('update', {options: this.getOptions()});
|
||||||
|
},
|
||||||
|
|
||||||
|
getFeatureGroup: function() {
|
||||||
|
return this.drawnItems;
|
||||||
|
},
|
||||||
|
|
||||||
|
getEditGroup: function() {
|
||||||
|
return this.editTools.editLayer;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
BR.NogoAreas.include(L.Mixin.Events);
|
BR.NogoAreas.include(L.Mixin.Events);
|
||||||
|
|
||||||
|
|
||||||
|
L.Editable.prototype.createVertexIcon = function (options) {
|
||||||
|
return BR.Browser.touch ? new L.Editable.TouchVertexIcon(options) : new L.Editable.VertexIcon(options);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
BR.EditingTooltip = L.Handler.extend({
|
||||||
|
options: {
|
||||||
|
closeTimeout: 2000
|
||||||
|
},
|
||||||
|
|
||||||
|
initialize: function (map, editTools, button) {
|
||||||
|
this.map = map;
|
||||||
|
this.editTools = editTools;
|
||||||
|
this.button = button;
|
||||||
|
},
|
||||||
|
|
||||||
|
addHooks: function () {
|
||||||
|
// hack: listen to EasyButton click (instead of editable:drawing:start),
|
||||||
|
// to get mouse position from event for initial tooltip location
|
||||||
|
L.DomEvent.addListener(this.button.button, 'click', this._addCreate, this);
|
||||||
|
|
||||||
|
this.editTools.featuresLayer.on('layeradd', this._bind, this);
|
||||||
|
|
||||||
|
this.editTools.on('editable:drawing:end', this._postCreate, this);
|
||||||
|
this.editTools.on('editable:enable', this._enable, this);
|
||||||
|
this.editTools.on('editable:disable', this._disable, this);
|
||||||
|
},
|
||||||
|
|
||||||
|
removeHooks: function () {
|
||||||
|
L.DomEvent.removeListener(this.button.button, 'click', this._addCreate, this);
|
||||||
|
|
||||||
|
this.editTools.featuresLayer.off('layeradd', this._bind, this);
|
||||||
|
|
||||||
|
this.editTools.off('editable:drawing:end', this._postCreate, this);
|
||||||
|
this.editTools.off('editable:enable', this._enable, this);
|
||||||
|
this.editTools.off('editable:disable', this._disable, this);
|
||||||
|
},
|
||||||
|
|
||||||
|
_bind: function (e) {
|
||||||
|
// Position tooltip at bottom of circle, less distracting than
|
||||||
|
// sticky with cursor or at center.
|
||||||
|
|
||||||
|
var layer = e.layer;
|
||||||
|
layer.bindTooltip(BR.NogoAreas.MSG_DISABLED, {
|
||||||
|
direction: 'bottom',
|
||||||
|
className: 'editing-tooltip'
|
||||||
|
});
|
||||||
|
|
||||||
|
// Override to set position to south instead of center (circle latlng);
|
||||||
|
// works better with zooming than updating offset to match radius
|
||||||
|
layer.openTooltip = function (layer, latlng) {
|
||||||
|
if (!latlng && layer instanceof L.Layer) {
|
||||||
|
latlng = L.latLng(layer.getBounds().getSouth(), layer.getLatLng().lng);
|
||||||
|
}
|
||||||
|
L.Layer.prototype.openTooltip.call(this, layer, latlng);
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
_addCreate: function (e) {
|
||||||
|
// button cancel
|
||||||
|
if (!this.editTools.drawing()) return;
|
||||||
|
|
||||||
|
var initialLatLng = this.map.mouseEventToLatLng(e);
|
||||||
|
var tooltip = L.tooltip({
|
||||||
|
// no effect with map tooltip
|
||||||
|
sticky: true,
|
||||||
|
// offset wrong with 'auto' when switching direction
|
||||||
|
direction: 'right',
|
||||||
|
offset: L.point(5, 28),
|
||||||
|
className: 'editing-tooltip-create'
|
||||||
|
});
|
||||||
|
|
||||||
|
// self-reference hack for _moveTooltip, as tooltip is not bound to layer
|
||||||
|
tooltip._tooltip = tooltip;
|
||||||
|
|
||||||
|
// simulate sticky feature (follow mouse) for map tooltip without layer
|
||||||
|
var onOffMove = function (e) {
|
||||||
|
var onOff = (e.type === 'tooltipclose') ? 'off' : 'on';
|
||||||
|
this._map[onOff]('mousemove', this._moveTooltip, this);
|
||||||
|
}
|
||||||
|
this.map.on('tooltipopen', onOffMove, tooltip);
|
||||||
|
this.map.on('tooltipclose', onOffMove, tooltip);
|
||||||
|
|
||||||
|
var onTooltipRemove = function (e) {
|
||||||
|
this.map.off('tooltipopen', onOffMove, e.tooltip);
|
||||||
|
this.map.off('tooltipclose', onOffMove, e.tooltip);
|
||||||
|
this.map.off('tooltipclose', onTooltipRemove, this);
|
||||||
|
e.tooltip._tooltip = null;
|
||||||
|
}
|
||||||
|
this.map.on('tooltipclose', onTooltipRemove, this);
|
||||||
|
|
||||||
|
tooltip.setTooltipContent(BR.NogoAreas.MSG_CREATE);
|
||||||
|
this.map.openTooltip(tooltip, initialLatLng);
|
||||||
|
|
||||||
|
var closeTooltip = function () {
|
||||||
|
this.map.closeTooltip(tooltip);
|
||||||
|
};
|
||||||
|
this.editTools.once('editable:editing editable:drawing:cancel', closeTooltip, this);
|
||||||
|
|
||||||
|
if (BR.Browser.touch) {
|
||||||
|
// can't move with cursor on touch devices, so show at start pos for a few seconds
|
||||||
|
setTimeout(L.bind(closeTooltip, this), this.options.closeTimeout);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_postCreate: function () {
|
||||||
|
// editing is disabled by another handler, tooltip won't stay open before
|
||||||
|
this.editTools.once('editable:disable', function (e) {
|
||||||
|
|
||||||
|
// show for a few seconds, as mouse often not hovering circle after create
|
||||||
|
e.layer.openTooltip(e.layer);
|
||||||
|
setTimeout(function () {
|
||||||
|
e.layer.closeTooltip();
|
||||||
|
}, this.options.closeTimeout);
|
||||||
|
}, this);
|
||||||
|
},
|
||||||
|
|
||||||
|
_enable: function (e) {
|
||||||
|
e.layer.setTooltipContent(BR.NogoAreas.MSG_ENABLED);
|
||||||
|
|
||||||
|
this.editTools.once('editable:editing', function(e) {
|
||||||
|
e.layer.closeTooltip();
|
||||||
|
}, this);
|
||||||
|
},
|
||||||
|
|
||||||
|
_disable: function (e) {
|
||||||
|
e.layer.setTooltipContent(BR.NogoAreas.MSG_DISABLED);
|
||||||
|
|
||||||
|
setTimeout(function () {
|
||||||
|
e.layer.closeTooltip();
|
||||||
|
}, this.options.closeTimeout);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
BR.DeletableCircleEditor = L.Editable.CircleEditor.extend({
|
||||||
|
|
||||||
|
_computeDeleteLatLng: function () {
|
||||||
|
// While circle is not added to the map, _radius is not set.
|
||||||
|
var delta = (this.feature._radius || this.feature._mRadius) * Math.cos(Math.PI / 4),
|
||||||
|
point = this.map.project(this.feature._latlng);
|
||||||
|
return this.map.unproject([point.x - delta, point.y - delta]);
|
||||||
|
},
|
||||||
|
|
||||||
|
_updateDeleteLatLng: function () {
|
||||||
|
this._deleteLatLng.update(this._computeDeleteLatLng());
|
||||||
|
this._deleteLatLng.__vertex.update();
|
||||||
|
},
|
||||||
|
|
||||||
|
_addDeleteMarker: function() {
|
||||||
|
if (!this.enabled()) return;
|
||||||
|
this._deleteLatLng = this._computeDeleteLatLng();
|
||||||
|
return new BR.DeleteMarker(this._deleteLatLng, this);
|
||||||
|
},
|
||||||
|
|
||||||
|
_delete: function() {
|
||||||
|
this.disable();
|
||||||
|
this.tools.featuresLayer.removeLayer(this.feature);
|
||||||
|
},
|
||||||
|
|
||||||
|
delete: function() {
|
||||||
|
this._delete();
|
||||||
|
this.fireAndForward('editable:deleted');
|
||||||
|
},
|
||||||
|
|
||||||
|
initialize: function (map, feature, options) {
|
||||||
|
L.Editable.CircleEditor.prototype.initialize.call(this, map, feature, options);
|
||||||
|
this._deleteLatLng = this._computeDeleteLatLng();
|
||||||
|
|
||||||
|
// FeatureGroup instead of LayerGroup to propagate events to members
|
||||||
|
this.editLayer = new L.FeatureGroup();
|
||||||
|
},
|
||||||
|
|
||||||
|
addHooks: function () {
|
||||||
|
L.Editable.CircleEditor.prototype.addHooks.call(this);
|
||||||
|
if (this.feature) {
|
||||||
|
this._addDeleteMarker();
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
|
||||||
|
reset: function () {
|
||||||
|
L.Editable.CircleEditor.prototype.reset.call(this);
|
||||||
|
this._addDeleteMarker();
|
||||||
|
},
|
||||||
|
|
||||||
|
onDrawingMouseDown: function (e) {
|
||||||
|
this._deleteLatLng.update(e.latlng);
|
||||||
|
L.Editable.CircleEditor.prototype.onDrawingMouseDown.call(this, e);
|
||||||
|
},
|
||||||
|
|
||||||
|
// override to cancel/remove created circle when added by click instead of drag, because:
|
||||||
|
// - without resize, edit handles stacked on top of each other
|
||||||
|
// - makes event handling more complicated (editable:vertex:dragend not called)
|
||||||
|
onDrawingMouseUp: function (e) {
|
||||||
|
if (this.feature.getRadius() > 0) {
|
||||||
|
this.commitDrawing(e);
|
||||||
|
} else {
|
||||||
|
this.cancelDrawing(e);
|
||||||
|
this._delete();
|
||||||
|
}
|
||||||
|
e.originalEvent._simulated = false;
|
||||||
|
L.Editable.PathEditor.prototype.onDrawingMouseUp.call(this, e);
|
||||||
|
},
|
||||||
|
|
||||||
|
onVertexMarkerDrag: function (e) {
|
||||||
|
this._updateDeleteLatLng();
|
||||||
|
L.Editable.CircleEditor.prototype.onVertexMarkerDrag.call(this, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
BR.DeleteMarker = L.Marker.extend({
|
||||||
|
|
||||||
|
options: {
|
||||||
|
draggable: false,
|
||||||
|
icon: L.divIcon({
|
||||||
|
iconSize: BR.Browser.touch ? new L.Point(24, 24) : new L.Point(16, 16),
|
||||||
|
className: 'leaflet-div-icon fa fa-trash-o nogo-delete-marker'
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
initialize: function (latlng, editor, options) {
|
||||||
|
// derived from L.Editable.VertexMarker.initialize
|
||||||
|
|
||||||
|
// We don't use this._latlng, because on drag Leaflet replace it while
|
||||||
|
// we want to keep reference.
|
||||||
|
this.latlng = latlng;
|
||||||
|
this.editor = editor;
|
||||||
|
L.Marker.prototype.initialize.call(this, latlng, options);
|
||||||
|
|
||||||
|
this.latlng.__vertex = this;
|
||||||
|
this.editor.editLayer.addLayer(this);
|
||||||
|
|
||||||
|
// to keep small circles editable, make sure delete button is below drag handle
|
||||||
|
// (not using "+ 1" to place at bottom of other vertex markers)
|
||||||
|
this.setZIndexOffset(editor.tools._lastZIndex);
|
||||||
|
},
|
||||||
|
|
||||||
|
onAdd: function (map) {
|
||||||
|
L.Marker.prototype.onAdd.call(this, map);
|
||||||
|
this.on('click', this.onClick);
|
||||||
|
},
|
||||||
|
|
||||||
|
onRemove: function (map) {
|
||||||
|
delete this.latlng.__vertex;
|
||||||
|
this.off('click', this.onClick);
|
||||||
|
L.Marker.prototype.onRemove.call(this, map);
|
||||||
|
},
|
||||||
|
|
||||||
|
onClick: function (e) {
|
||||||
|
this.editor.delete();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
|
||||||
|
|
@ -295,4 +295,8 @@ BR.Routing = L.Routing.extend({
|
||||||
L.Routing.prototype._keyupListener.call(this, e);
|
L.Routing.prototype._keyupListener.call(this, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
,isDrawing: function () {
|
||||||
|
return this._draw._enabled;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue