leaflet-draw

Vector drawing plugin for Leaflet

Important

Leaflet.draw 0.2.3+ requires Leaflet 0.7 or higher.

#Leaflet.draw Adds support for drawing and editing vectors and markers on Leaflet maps. Check out the demo.

Leaflet.draw 0.2.0 changes a LOT of things from 0.1. Please see BREAKING CHANGES for how to upgrade.

Using the plugin
Advanced Options
Common tasks
Thanks

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.

// create a map in the "map" div, set the view to a given place and zoom 
var map = L.map('map', {drawControl: true}).setView([51.505, -0.09], 13);
 
// add an OpenStreetMap tile layer 
L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
    attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);

To use the edit toolbar you must initialise the Leaflet.draw control and manually add it to the map.

// create a map in the "map" div, set the view to a given place and zoom 
var map = L.map('map').setView([51.505, -0.09], 13);
 
// add an OpenStreetMap tile layer 
L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
    attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);
 
// Initialise the FeatureGroup to store editable layers 
var drawnItems = new L.FeatureGroup();
map.addLayer(drawnItems);
 
// Initialise the draw control and pass it the FeatureGroup of editable layers 
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.

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:

PropertyTypeDescription
layerPolyline/Polygon/Rectangle/Circle/MarkerLayer that was just created.
layerTypeStringThe 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') {
        // Do marker specific actions 
    }
 
    // Do whatever else you need to. (save to db, add to map etc) 
    map.addLayer(layer);
});
PropertyTypeDescription
layersLayerGroupList 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) {
        //do whatever you want, most likely save back to db 
    });
});

Triggered when layers have been removed (and saved) from the FeatureGroup.

PropertyTypeDescription
layersLayerGroupList of all layers just removed from the map.

Triggered when the user has chosen to draw a particular vector or marker.

PropertyTypeDescription
layerTypeStringThe type of layer this is. One of: polyline, polygon, rectangle, circle, marker

Triggered when the user has finished a particular vector or marker.

PropertyTypeDescription
layerTypeStringThe type of layer this is. One of: polyline, polygon, rectangle, circle, marker

Triggered when the user starts edit mode by clicking the edit tool button.

PropertyTypeDescription
handlerStringThe type of edit this is. One of: edit

Triggered when the user has finshed editing (edit mode) and saves edits.

PropertyTypeDescription
handlerStringThe type of edit this is. One of: edit

Triggered when the user starts remove mode by clicking the remove tool button.

PropertyTypeDescription
handlerStringThe type of edit this is. One of: remove

Triggered when the user has finished removing shapes (remove mode) and saves.

PropertyTypeDescription
handlerStringThe type of edit this is. One of: remove

You can configure the plugin by using the different options listed here.

These options make up the root object that is used when initialising the Leaflet.draw control.

OptionTypeDefaultDescription
positionString'topleft'The initial position of the control (one of the map corners). See control positions.
drawDrawOptions{}The options used to configure the draw toolbar.
editEditOptionsfalseThe options used to configure the edit toolbar.

These options will allow you to configure the draw toolbar and its handlers.

OptionTypeDefaultDescription
polylinePolylineOptions{ }Polyline draw handler options. Set to false to disable handler.
polygonPolygonOptions{ }Polygon draw handler options. Set to false to disable handler.
rectangleRectangleOptions{ }Rectangle draw handler options. Set to false to disable handler.
circleCircleOptions{ }Circle draw handler options. Set to false to disable handler.
markerMarkerOptions{ }Marker draw handler options. Set to false to disable handler.

The following options will allow you to configure the individual draw handlers.

Polyline and Polygon drawing handlers take the same options.

OptionTypeDefaultDescription
allowIntersectionBooltrueDetermines if line segments can cross.
drawErrorObjectSee codeConfiguration options for the error that displays if an intersection is detected.
guidelineDistanceNumber20Distance in pixels between each guide dash.
shapeOptionsLeaflet Polyline optionsSee codeThe options used when drawing the polyline/polygon on the map.
metricBooltrueDetermines which measurement system (metric or imperial) is used.
zIndexOffsetNumber2000This should be a high number to ensure that you can draw over all other layers on the map.
repeatModeBoolfalseDetermines if the draw tool remains enabled after drawing a shape.

Polygon options include all of the Polyline options plus the option to show the approximate area.

OptionTypeDefaultDescription
showAreaBoolfalseShow 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.

OptionTypeDefaultDescription
shapeOptionsLeaflet Path optionsSee codeThe options used when drawing the rectangle on the map.
repeatModeBoolfalseDetermines if the draw tool remains enabled after drawing a shape.

OptionTypeDefaultDescription
shapeOptionsLeaflet Path optionsSee codeThe options used when drawing the circle on the map.
repeatModeBoolfalseDetermines if the draw tool remains enabled after drawing a shape.

OptionTypeDefaultDescription
iconLeaflet IconL.Icon.Default()The icon displayed when drawing a marker.
zIndexOffsetNumber2000This should be a high number to ensure that you can draw over all other layers on the map.
repeatModeBoolfalseDetermines if the draw tool remains enabled after drawing a shape.

These options will allow you to configure the draw toolbar and its handlers.

OptionTypeDefaultDescription
featureGroupLeaflet FeatureGroupnullThis is the FeatureGroup that stores all editable shapes. THIS IS REQUIRED FOR THE EDIT TOOLBAR TO WORK
editEditHandlerOptions{ }Edit handler options. Set to false to disable handler.
removeDeleteHandlerOptions{ }Delete handler options. Set to false to disable handler.

OptionTypeDefaultDescription
selectedPathOptionsLeaflet Path optionsSee codeThe 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.

OptionTypeDefaultDescription

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.

// Set the button title text for the polygon button 
L.drawLocal.draw.toolbar.buttons.polygon = 'Draw a sexy polygon!';
 
// Set the tooltip start text for the rectangle 
L.drawLocal.draw.handlers.rectangle.tooltip.start = 'Not telling...';

The following examples outline some common tasks.

The following example will show you how to:

  1. Change the position of the control's toolbar.
  2. Customize the styles of a vector layer.
  3. Use a custom marker.
  4. 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, // Restricts shapes to simple polygons 
            drawError: {
                color: '#e1e100', // Color the shape will turn when intersects 
                message: '<strong>Oh snap!<strong> you can\'t draw that!' // Message that will show when intersect 
            },
            shapeOptions: {
                color: '#bada55'
            }
        },
        circle: false, // Turns off this drawing tool 
        rectangle: {
            shapeOptions: {
                clickable: false
            }
        },
        marker: {
            icon: new MyCustomMarker()
        }
    },
    edit: {
        featureGroup: editableLayers, //REQUIRED!! 
        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!');
    }
 
    drawnItems.addLayer(layer);
});

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
    }
});

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
    }
});

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'
        }
    }
});

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.

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.