What is leaflet-draw?
The leaflet-draw npm package is an extension for the Leaflet library that adds support for drawing and editing vectors and markers on a map. It provides a user-friendly interface for creating, editing, and deleting various shapes such as polygons, polylines, rectangles, circles, and markers.
What are leaflet-draw's main functionalities?
Drawing Polygons
This feature allows users to draw polygons on the map. The code sample initializes a Leaflet map, adds a tile layer, and sets up the drawing control to enable polygon drawing. When a polygon is created, it is added to the drawn items layer.
L.drawLocal.draw.toolbar.buttons.polygon = 'Draw a polygon';
var map = L.map('map').setView([51.505, -0.09], 13);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19
}).addTo(map);
var drawnItems = new L.FeatureGroup();
map.addLayer(drawnItems);
var drawControl = new L.Control.Draw({
edit: {
featureGroup: drawnItems
},
draw: {
polygon: true
}
});
map.addControl(drawControl);
map.on(L.Draw.Event.CREATED, function (event) {
var layer = event.layer;
drawnItems.addLayer(layer);
});
Drawing Polylines
This feature allows users to draw polylines on the map. The code sample initializes a Leaflet map, adds a tile layer, and sets up the drawing control to enable polyline drawing. When a polyline is created, it is added to the drawn items layer.
L.drawLocal.draw.toolbar.buttons.polyline = 'Draw a polyline';
var map = L.map('map').setView([51.505, -0.09], 13);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19
}).addTo(map);
var drawnItems = new L.FeatureGroup();
map.addLayer(drawnItems);
var drawControl = new L.Control.Draw({
edit: {
featureGroup: drawnItems
},
draw: {
polyline: true
}
});
map.addControl(drawControl);
map.on(L.Draw.Event.CREATED, function (event) {
var layer = event.layer;
drawnItems.addLayer(layer);
});
Drawing Rectangles
This feature allows users to draw rectangles on the map. The code sample initializes a Leaflet map, adds a tile layer, and sets up the drawing control to enable rectangle drawing. When a rectangle is created, it is added to the drawn items layer.
L.drawLocal.draw.toolbar.buttons.rectangle = 'Draw a rectangle';
var map = L.map('map').setView([51.505, -0.09], 13);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19
}).addTo(map);
var drawnItems = new L.FeatureGroup();
map.addLayer(drawnItems);
var drawControl = new L.Control.Draw({
edit: {
featureGroup: drawnItems
},
draw: {
rectangle: true
}
});
map.addControl(drawControl);
map.on(L.Draw.Event.CREATED, function (event) {
var layer = event.layer;
drawnItems.addLayer(layer);
});
Drawing Circles
This feature allows users to draw circles on the map. The code sample initializes a Leaflet map, adds a tile layer, and sets up the drawing control to enable circle drawing. When a circle is created, it is added to the drawn items layer.
L.drawLocal.draw.toolbar.buttons.circle = 'Draw a circle';
var map = L.map('map').setView([51.505, -0.09], 13);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19
}).addTo(map);
var drawnItems = new L.FeatureGroup();
map.addLayer(drawnItems);
var drawControl = new L.Control.Draw({
edit: {
featureGroup: drawnItems
},
draw: {
circle: true
}
});
map.addControl(drawControl);
map.on(L.Draw.Event.CREATED, function (event) {
var layer = event.layer;
drawnItems.addLayer(layer);
});
Drawing Markers
This feature allows users to place markers on the map. The code sample initializes a Leaflet map, adds a tile layer, and sets up the drawing control to enable marker placement. When a marker is created, it is added to the drawn items layer.
L.drawLocal.draw.toolbar.buttons.marker = 'Draw a marker';
var map = L.map('map').setView([51.505, -0.09], 13);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19
}).addTo(map);
var drawnItems = new L.FeatureGroup();
map.addLayer(drawnItems);
var drawControl = new L.Control.Draw({
edit: {
featureGroup: drawnItems
},
draw: {
marker: true
}
});
map.addControl(drawControl);
map.on(L.Draw.Event.CREATED, function (event) {
var layer = event.layer;
drawnItems.addLayer(layer);
});
Other packages similar to leaflet-draw
leaflet.pm
Leaflet.pm is a popular Leaflet plugin that provides similar functionalities to leaflet-draw, including drawing, editing, and deleting shapes on a map. It offers a more modern and actively maintained alternative with additional features like snapping, cutting, and rotating shapes.
leaflet-path-drag
Leaflet-Path-Drag is a Leaflet plugin that allows users to drag and edit polylines and polygons on a map. While it does not provide the full range of drawing tools available in leaflet-draw, it is useful for applications that require simple shape editing capabilities.
Build Status | Leaflet.draw Chat | Leaflet Chat |
---|
| | |
Leaflet.draw
Adds support for drawing and editing vectors and markers on Leaflet maps. Check out the demo.
Supports Leaflet 0.7.x and 1.0.0+ branches.
Upgrading from Leaflet.draw 0.1
Leaflet.draw 0.2.0 changes a LOT of things from 0.1. Please see BREAKING CHANGES for how to upgrade.
Table of Contents
Install
CDN
Using the plugin
Advanced Options
Common tasks
Thanks
## Install
npm
To install the plugin run npm install leaflet-draw
via command line in your project. You must also require this in your project like so: var leafletDraw = require('leaflet-draw');
bower
To install the plugin run bower install leaflet-draw
.
## CDN
Using unpkg
<link rel="stylesheet" href="https://unpkg.com/leaflet-draw@0.4.1/dist/leaflet.draw.css" />
<script src="https://unpkg.com/leaflet-draw@0.4.1/dist/leaflet.draw.js"></script>
Using CDNJS
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/0.4.0/leaflet.draw.css"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/0.4.0/leaflet.draw.js"></script>
## Using the plugin
The default state for the control is the draw toolbar just below the zoom control. This will allow map users to draw vectors and markers. Please note the edit toolbar is not enabled by default.
To add the draw toolbar set the option drawControl: true
in the map options.
var map = L.map('map', {drawControl: true}).setView([51.505, -0.09], 13);
L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
attribution: '© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);
Adding the edit toolbar
To use the edit toolbar you must initialise the Leaflet.draw control and manually add it to the map.
var map = L.map('map').setView([51.505, -0.09], 13);
L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
attribution: '© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);
var drawnItems = new L.FeatureGroup();
map.addLayer(drawnItems);
var drawControl = new L.Control.Draw({
edit: {
featureGroup: drawnItems
}
});
map.addControl(drawControl);
The key here is the featureGroup
option. This tells the plugin which FeatureGroup
contains the layers that should be editable. The featureGroup can contain 0 or more features with geometry types Point
, LineString
, and Polygon
. Leaflet.draw does not work with multigeometry features such as MultiPoint
, MultiLineString
, MultiPolygon
, or GeometryCollection
. If you need to add multigeometry features to the draw plugin, convert them to a FeatureCollection of non-multigeometries (Point
s, LineString
s, or Polygon
s).
Events
Once you have successfully added the Leaflet.draw plugin to your map you will want to respond to the different actions users can initiate. The following events will be triggered on the map:
draw:created
Property | Type | Description |
---|
layer | Polyline/Polygon/Rectangle/Circle/Marker | Layer that was just created. |
layerType | String | The type of layer this is. One of: polyline , polygon , rectangle , circle , marker |
Triggered when a new vector or marker has been created.
map.on('draw:created', function (e) {
var type = e.layerType,
layer = e.layer;
if (type === 'marker') {
}
map.addLayer(layer);
});
draw:edited
Property | Type | Description |
---|
layers | LayerGroup | List of all layers just edited on the map. |
Triggered when layers in the FeatureGroup, initialised with the plugin, have been edited and saved.
map.on('draw:edited', function (e) {
var layers = e.layers;
layers.eachLayer(function (layer) {
});
});
draw:deleted
Triggered when layers have been removed (and saved) from the FeatureGroup.
Property | Type | Description |
---|
layers | LayerGroup | List of all layers just removed from the map. |
draw:drawstart
Triggered when the user has chosen to draw a particular vector or marker.
Property | Type | Description |
---|
layerType | String | The type of layer this is. One of: polyline , polygon , rectangle , circle , marker |
draw:drawstop
Triggered when the user has finished a particular vector or marker.
Property | Type | Description |
---|
layerType | String | The type of layer this is. One of: polyline , polygon , rectangle , circle , marker |
draw:drawvertex
Triggered when a vertex is created on a polyline or polygon.
Property | Type | Description |
---|
layers | LayerGroup | List of all layers just being added from the map. |
draw:editstart
Triggered when the user starts edit mode by clicking the edit tool button.
Property | Type | Description |
---|
handler | String | The type of edit this is. One of: edit |
draw:editmove
Triggered as the user moves a rectangle, circle or marker.
Property | Type | Description |
---|
layer | ILayer | Layer that was just moved. |
draw:editresize
Triggered as the user resizes a rectangle or circle.
Property | Type | Description |
---|
layer | ILayer | Layer that was just moved. |
draw:editvertex
Triggered when a vertex is edited on a polyline or polygon.
Property | Type | Description |
---|
layers | LayerGroup | List of all layers just being edited from the map. |
draw:editstop
Triggered when the user has finshed editing (edit mode) and saves edits.
Property | Type | Description |
---|
handler | String | The type of edit this is. One of: edit |
draw:deletestart
Triggered when the user starts remove mode by clicking the remove tool button.
Property | Type | Description |
---|
handler | String | The type of edit this is. One of: remove |
draw:deletestop
Triggered when the user has finished removing shapes (remove mode) and saves.
Property | Type | Description |
---|
handler | String | The type of edit this is. One of: remove |
## Advanced options
You can configure the plugin by using the different options listed here.
Control.Draw
These options make up the root object that is used when initialising the Leaflet.draw control.
Option | Type | Default | Description |
---|
position | String | 'topleft' | The initial position of the control (one of the map corners). See control positions. |
draw | DrawOptions | {} | The options used to configure the draw toolbar. |
edit | EditPolyOptions | false | The options used to configure the edit toolbar. |
### DrawOptions
These options will allow you to configure the draw toolbar and its handlers.
Option | Type | Default | Description |
---|
polyline | PolylineOptions | { } | Polyline draw handler options. Set to false to disable handler. |
polygon | PolygonOptions | { } | Polygon draw handler options. Set to false to disable handler. |
rectangle | RectangleOptions | { } | Rectangle draw handler options. Set to false to disable handler. |
circle | CircleOptions | { } | Circle draw handler options. Set to false to disable handler. |
marker | MarkerOptions | { } | Marker draw handler options. Set to false to disable handler. |
Draw handler options
The following options will allow you to configure the individual draw handlers.
#### PolylineOptions
Polyline and Polygon drawing handlers take the same options.
Option | Type | Default | Description |
---|
allowIntersection | Bool | true | Determines if line segments can cross. |
drawError | Object | See code | Configuration options for the error that displays if an intersection is detected. |
guidelineDistance | Number | 20 | Distance in pixels between each guide dash. |
shapeOptions | Leaflet Polyline options | See code | The options used when drawing the polyline/polygon on the map. |
metric | Bool | true | Determines which measurement system (metric or imperial) is used. |
zIndexOffset | Number | 2000 | This should be a high number to ensure that you can draw over all other layers on the map. |
repeatMode | Bool | false | Determines if the draw tool remains enabled after drawing a shape. |
#### PolygonOptions
Polygon options include all of the Polyline options plus the option to show the approximate area.
Option | Type | Default | Description |
---|
showArea | Bool | false | Show the area of the drawn polygon in m², ha or km². The area is only approximate and become less accurate the larger the polygon is. |
#### RectangleOptions
Option | Type | Default | Description |
---|
shapeOptions | Leaflet Path options | See code | The options used when drawing the rectangle on the map. |
repeatMode | Bool | false | Determines if the draw tool remains enabled after drawing a shape. |
#### CircleOptions
Option | Type | Default | Description |
---|
shapeOptions | Leaflet Path options | See code | The options used when drawing the circle on the map. |
repeatMode | Bool | false | Determines if the draw tool remains enabled after drawing a shape. |
#### MarkerOptions
Option | Type | Default | Description |
---|
icon | Leaflet Icon | L.Icon.Default() | The icon displayed when drawing a marker. |
zIndexOffset | Number | 2000 | This should be a high number to ensure that you can draw over all other layers on the map. |
repeatMode | Bool | false | Determines if the draw tool remains enabled after drawing a shape. |
### EditPolyOptions
These options will allow you to configure the draw toolbar and its handlers.
Option | Type | Default | Description |
---|
featureGroup | Leaflet FeatureGroup | null | This is the FeatureGroup that stores all editable shapes. THIS IS REQUIRED FOR THE EDIT TOOLBAR TO WORK |
edit | EditHandlerOptions | { } | Edit handler options. Set to false to disable handler. |
remove | DeleteHandlerOptions | { } | Delete handler options. Set to false to disable handler. |
poly | EditPolyOptions | { } | Set polygon editing options |
#### EditHandlerOptions
Option | Type | Default | Description |
---|
selectedPathOptions | Leaflet Path options | See code | The path options for how the layers will look while in edit mode. If this is set to null the editable path options will not be set. |
Note: To maintain the original layer color of the layer use maintainColor: true
within selectedPathOptions
.
E.g. The edit options below will maintain the layer color and set the edit opacity to 0.3.
{
selectedPathOptions: {
maintainColor: true,
opacity: 0.3
}
}
#### DeleteHandlerOptions
Option | Type | Default | Description |
---|
#### EditPolyOptions
Option | Type | Default | Description |
---|
allowIntersection | Bool | true | Determines if line segments can cross. |
#### Customizing language and text in Leaflet.draw
Leaflet.draw uses the L.drawLocal
configuration object to set any text used in the plugin. Customizing this will allow support for changing the text or supporting another language.
See Leaflet.draw.js for the default strings.
E.g.
L.drawLocal.draw.toolbar.buttons.polygon = 'Draw a sexy polygon!';
L.drawLocal.draw.handlers.rectangle.tooltip.start = 'Not telling...';
## Common tasks
The following examples outline some common tasks.
Example Leaflet.draw config
The following example will show you how to:
- Change the position of the control's toolbar.
- Customize the styles of a vector layer.
- Use a custom marker.
- Disable the delete functionality.
var cloudmadeUrl = 'http://{s}.tile.cloudmade.com/BC9A493B41014CAABB98F0471D759707/997/256/{z}/{x}/{y}.png',
cloudmade = new L.TileLayer(cloudmadeUrl, {maxZoom: 18}),
map = new L.Map('map', {layers: [cloudmade], center: new L.LatLng(-37.7772, 175.2756), zoom: 15 });
var editableLayers = new L.FeatureGroup();
map.addLayer(editableLayers);
var MyCustomMarker = L.Icon.extend({
options: {
shadowUrl: null,
iconAnchor: new L.Point(12, 12),
iconSize: new L.Point(24, 24),
iconUrl: 'link/to/image.png'
}
});
var options = {
position: 'topright',
draw: {
polyline: {
shapeOptions: {
color: '#f357a1',
weight: 10
}
},
polygon: {
allowIntersection: false,
drawError: {
color: '#e1e100',
message: '<strong>Oh snap!<strong> you can\'t draw that!'
},
shapeOptions: {
color: '#bada55'
}
},
circle: false,
rectangle: {
shapeOptions: {
clickable: false
}
},
marker: {
icon: new MyCustomMarker()
}
},
edit: {
featureGroup: editableLayers,
remove: false
}
};
var drawControl = new L.Control.Draw(options);
map.addControl(drawControl);
map.on('draw:created', function (e) {
var type = e.layerType,
layer = e.layer;
if (type === 'marker') {
layer.bindPopup('A popup!');
}
editableLayers.addLayer(layer);
});
Disabling a toolbar
If you do not want a particular toolbar in your app you can turn it off by setting the toolbar to false.
var drawControl = new L.Control.Draw({
draw: false,
edit: {
featureGroup: editableLayers
}
});
Disabling a toolbar item
If you want to turn off a particular toolbar item, set it to false. The following disables drawing polygons and markers. It also turns off the ability to edit layers.
var drawControl = new L.Control.Draw({
draw: {
polygon: false,
marker: false
},
edit: {
featureGroup: editableLayers,
edit: false
}
});
Changing a drawing handlers options
You can change a draw handlers options after initialisation by using the setDrawingOptions
method on the Leaflet.draw control.
E.g. to change the colour of the rectangle:
drawControl.setDrawingOptions({
rectangle: {
shapeOptions: {
color: '#0000FF'
}
}
});
Creating a custom build
If you only require certain handlers (and not the UI), you may wish to create a custom build. You can generate the relevant jake command using the build html file.
See edit handlers example which uses only the edit handlers.
Testing
To test you can install the npm dependencies:
npm install
and then use:
jake test
Thanks
Touch friendly version of Leaflet.draw was created and maintained by Michael Guild (https://github.com/michaelguild13).
The touch support was initiated due to a demand for it at National Geographic for their Map Maker Projected (http://mapmaker.education.nationalgeographic.com/) that was created by Michael Guild and Daniel Schep (https://github.com/dschep)
Thanks so much to @brunob, @tnightingale, and @shramov. I got a lot of ideas from their Leaflet plugins.
All the contributors and issue reporters of this plugin rock. Thanks for tidying up my mess and keeping the plugin on track.
The icons used for some of the toolbar buttons are either from http://glyphicons.com/ or inspired by them. <3 Glyphicons!
Finally, @mourner is the man! Thanks for dedicating so much of your time to create the gosh darn best JavaScript mapping library around.