Editing feature layers
This sample uses the Leaflet Editable plugin (coupled with the Leaflet.Path.Drag plugin) to help users manipulate the geometry of features from a hosted feature service and pass the edits back to the server.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Editing feature layers</title>
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
<!-- Load Leaflet from CDN -->
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css"
integrity="sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A=="
crossorigin=""/>
<script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js"
integrity="sha512-XQoYMqMTK8LvdxXYG3nZ448hOEQiglfqkJs1NOQV44cWnUrBc8PkAOcXy20w0vlaXaVUearIOBhiXZ5V3ynxwA=="
crossorigin=""></script>
<!-- Load Esri Leaflet from CDN -->
<script src="https://unpkg.com/esri-leaflet@2.5.3/dist/esri-leaflet.js"
integrity="sha512-K0Vddb4QdnVOAuPJBHkgrua+/A9Moyv8AQEWi0xndQ+fqbRfAFd47z4A9u1AW/spLO0gEaiE1z98PK1gl5mC5Q=="
crossorigin=""></script>
<style>
body { margin:0; padding:0; }
#map { position: absolute; top:0; bottom:0; right:0; left:0; }
</style>
</head>
<body>
<script src="https://unpkg.com/leaflet.path.drag@0.0.6/src/Path.Drag.js"></script>
<script src="https://unpkg.com/leaflet-editable@1.2.0/src/Leaflet.Editable.js"></script>
<div id="map"></div>
<script type="text/javascript">
// make sure double clicking the map *only* triggers the editing workflow
var map = L.map('map', {
editable: true,
doubleClickZoom: false
}).setView([37.345, -110.875], 5);
L.esri.basemapLayer('Topographic').addTo(map);
// create a feature layer and add it to the map
var wildfireDistricts = L.esri.featureLayer({
url: 'https://sampleserver6.arcgisonline.com/arcgis/rest/services/Wildfire/FeatureServer/2'
}).addTo(map);
// create a generic control to invoke editing
L.EditControl = L.Control.extend({
options: {
position: 'topleft',
callback: null,
kind: '',
html: ''
},
// when the control is added to the map, wire up its DOM dynamically and add a click listener
onAdd: function (map) {
var container = L.DomUtil.create('div', 'leaflet-control leaflet-bar');
var link = L.DomUtil.create('a', '', container);
link.href = '#';
link.title = 'Create a new ' + this.options.kind;
link.innerHTML = this.options.html;
L.DomEvent
.on(link, 'click', L.DomEvent.stop)
.on(link, 'click', function () {
window.LAYER = this.options.callback.call(map.editTools);
}, this);
return container;
}
});
// extend the control to draw polygons
L.NewPolygonControl = L.EditControl.extend({
options: {
position: 'topleft',
callback: map.editTools.startPolygon,
kind: 'polygon',
html: '▰'
}
});
// extend the control to draw rectangles
L.NewRectangleControl = L.EditControl.extend({
options: {
position: 'topleft',
callback: map.editTools.startRectangle,
kind: 'rectangle',
html: '⬛'
}
});
// add the two new controls to the map
map.addControl(new L.NewPolygonControl());
map.addControl(new L.NewRectangleControl());
// when users CMD/CTRL click an active editable feature,
// remove it from the map and delete it from the service
wildfireDistricts.on('click', function (e) {
if ((e.originalEvent.ctrlKey || e.originalEvent.metaKey) && e.layer.editEnabled()) {
// delete expects an id, not the whole geojson object
wildfireDistricts.deleteFeature(e.layer.feature.id);
}
});
// when users double click a graphic, toggle its editable status
// but when deselecting via double click, pass the geometry update to the service
wildfireDistricts.on('dblclick', function (e) {
e.layer.toggleEdit();
if (!e.layer.editEnabled()) {
wildfireDistricts.updateFeature(e.layer.toGeoJSON());
}
});
// when a new feature is drawn using one of the custom controls,
// pass the edit to the featureLayer service
map.on('editable:drawing:commit', function (e) {
wildfireDistricts.addFeature(e.layer.toGeoJSON(), function (error, response) {
if (error || !response.success) {
console.log(error, response);
}
// now that the L.esri.featureLayer instance will manage this new feature,
// remove any temporary features from the map that were created by the Editable plugin
map.editTools.featuresLayer.clearLayers();
});
// disable editing
e.layer.toggleEdit();
});
</script>
</body>
</html>