2.2.0 • Published 5 years ago

leaflet.pm v2.2.0

Weekly downloads
1,659
License
MIT
Repository
github
Last release
5 years ago

Demo (click here)

Demo

Are you using leaflet.pm for commercial projects?\ Check out Geoman and consider subscribing to the Leaflet.PM Supporter Plan to support development of advanced leaflet.pm features. You will also get prioritized support and consultation.

Documentation

Installation

Install via npm

npm i leaflet.pm

Install Manually

Download leaflet.pm.css and leaflet.pm.min.js and include them in your project.

Include via CDN

CSS

<link rel="stylesheet" href="https://unpkg.com/leaflet.pm@latest/dist/leaflet.pm.css" />

JS

<script src="https://unpkg.com/leaflet.pm@latest/dist/leaflet.pm.min.js"></script>

Include as ES6 Module

import 'leaflet.pm';
import 'leaflet.pm/dist/leaflet.pm.css';

Getting Started

Init Leaflet.PM

Just include leaflet.pm.min.js right after Leaflet. It initializes itself. If you want certain layers to be ignored by leaflet.pm, pass pmIgnore: true to their options when creating them. Example:

L.marker([51.50915, -0.096112], { pmIgnore: true }).addTo(map);

Leaflet.PM Toolbar

You can add a toolbar to the map to use leaflet.pm features via a user interface.

// add leaflet.pm controls with some options to the map
map.pm.addControls({
  position: 'topleft',
  drawCircle: false,
});

See the available options in the table below.

OptionDefaultDescription
position'topleft'toolbar position, possible values are 'topleft', 'topright', 'bottomleft', 'bottomright'
drawMarkertrueadds button to draw markers
drawCircleMarkertrueadds button to draw circle markers
drawPolylinetrueadds button to draw rectangle
drawRectangletrueadds button to draw rectangle
drawPolygontrueadds button to draw polygon
drawCircletrueadds button to draw circle
editModetrueadds button to toggle edit mode for all layers
dragModetrueadds button to toggle drag mode for all layers
cutPolygontrueadds button to cut a hole in a polygon
removalModetrueadds a button to remove layers

If you are wondering how e.g. the drawPolygon button will enable drawing mode with specific options, here it is: Simply enable drawing mode programatically, pass it your options and disable it again. The options will persist, even when the mode is enabled/disabled via the toolbar.

Example:

// make markers not snappable during marker draw
map.pm.enableDraw('Marker', { snappable: false });
map.pm.disableDraw('Marker');

// let polygons finish their shape on double click
map.pm.enableDraw('Polygon', { finishOn: 'dblclick' });
map.pm.disableDraw('Polygon');

All available options are specified in the Drawing Mode Section below.

Drawing Mode

Use Drawing Mode on a map like this

// enable polygon drawing mode
map.pm.enableDraw('Polygon', {
  snappable: true,
  snapDistance: 20,
});

// disable drawing mode
map.pm.disableDraw('Polygon');

Currently available shapes are Marker, Circle, Line, Rectangle, Polygon and Cut. You can get an array of all available shapes with:

map.pm.Draw.getShapes();

See the available options in the table below.

OptionDefaultDescription
snappabletrueenable snapping to other layers vertices for precision drawing. Can be disabled by holding the ALT key.
snapDistance20the distance to another vertex when a snap should happen
snapMiddlefalseallow snapping to the middle of a layers segments (between two vertexes)
tooltipstrueshow helpful tooltips for your user
allowSelfIntersectiontrueallow self intersections
templineStyle{ color: 'red' },leaflet path options for the lines between drawn vertices/markers.
hintlineStyle{ color: 'red', dashArray: [5, 5] }leaflet path options for the helper line between last drawn vertex and the cursor.
cursorMarkertrueshow a marker at the cursor
finishOnnullleaflet layer event to finish the drawn shape, like 'dblclick'. Here's a list.
markerStyle{ draggable: true }leaflet marker options (only for drawing markers).

You can listen to map events to hook into the drawing procedure like this:

map.on('pm:drawstart', e => {
  console.log(e);
});

Here's a list of map events you can listen to:

EventParamsDescription
pm:drawstarteCalled when drawing mode is enabled. Payload includes the shape type and working layer
pm:drawendeCalled when drawing mode is disabled. Payload includes the shape type.
pm:createeCalled when a shape is drawn/finished. Payload includes shape type and the drawn layer

There are also several events for layers during draw. Register an event like this:

// listen to vertexes being added to currently drawn layer (called workingLayer)
map.on('pm:drawstart', ({ workingLayer }) => {
  workingLayer.on('pm:vertexadded', e => {
    console.log(e);
  });
});

Here's a list of layer events you can listen to:

EventParamsDescription
pm:vertexaddedeCalled when a new vertex is added. Payload includes the new vertex, it's marker, index, working layer and shape type
pm:snapdrageFired during a marker move/drag. Payload includes info about involved layers and snapping calculation.
pm:snapeFired when a vertex is snapped. Payload is the same as in snapdrag
pm:unsnapeFired when a vertex is unsnapped. Payload is the same as in snapdrag
pm:centerplacedeCalled when the center of a circle is placed/moved.

For making the snapping to other layers selective, you can add the "snapIgnore" option to your layers to disable the snapping to them during drawing.

L.geoJSON(data,{
  snapIgnore : true
})
//This layer will be ignored by the snapping engine during drawing

Edit Mode

Let's you edit vertices of layers. Use it like this:

// enable edit mode
layer.pm.enable({
  allowSelfIntersection: false,
});

See the available options in the table below.

OptionDefaultDescription
snappabletrueEnable snapping to other layers vertices for precision drawing. Can be disabled by holding the ALT key.
snapDistance20The distance to another vertex when a snap should happen.
allowSelfIntersectiontrueAllow/Disallow self-intersections on polygons and polylines.
preventMarkerRemovalfalseDisable the removal of markers/vertexes via right click.

The following methods are available for layers under layer.pm:

MethodReturnsDescription
enable(options)-Enables edit mode. The passed options are preserved, even when the mode is enabled via the Toolbar.
disable()-Disables edit mode.
toggleEdit(options)-Toggles edit mode. Passed options are preserved.
enabled()BooleanReturns true if edit mode is enabled. false when disabled.
hasSelfIntersection()BooleanReturns true is the layer has a self intersection.

You can listen to events related to editing on events like this:

// listen to when a layer is changed in edit mode
layer.on('pm:edit', e => {
  console.log(e);
});

The following events are available on a layer instance:

EventParamsDescription
pm:editeFired when a layer is edited.
pm:vertexaddedeFired when a vertex is added
pm:vertexremovedeFired when a vertex is removed
pm:markerdragstarteFired when dragging of a marker which corresponds to a vertex starts
pm:markerdragendeFired when dragging of a vertex-marker ends
pm:snapeFired when a vertex-marker is snapped to another vertex. Also fired on the marker itself.
pm:unsnapeFired when a vertex-marker is unsnapped from a vertex. Also fired on the marker itself.
pm:intersecteWhen allowSelfIntersection: false, this event is fired as soon as a self-intersection is detected.
pm:centerplacedeFired when the center of a circle is moved

You can enable Edit Mode for all layers on a map like this:

// enable global edit mode
map.pm.toggleGlobalEditMode(options);

The following methods are available on map.pm:

MethodReturnsDescription
enableGlobalEditMode(options)-Enables global edit mode.
disableGlobalEditMode()-Disables global edit mode.
toggleGlobalEditMode(options)-Toggles global edit mode.
globalEditEnabled()BooleanReturns true if global edit mode is enabled. false when disabled.

You can also listen to specific edit mode events on the map instance like this:

map.on('pm:globaleditmodetoggled', e => {
  console.log(e);
});

The event has an object with an enabled boolean and a reference to the map.

Drag Mode

// toggle drag mode like this:
map.pm.toggleGlobalDragMode();

The following methods are available on map.pm:

MethodReturnsDescription
toggleGlobalDragMode()-Toggles global drag mode.
globalDragModeEnabled()BooleanReturns true if global drag mode is enabled. false when disabled.

The following events are available on a layer instance:

EventParamsDescription
pm:dragstarteFired when a layer starts being dragged.
pm:drageFired when a layer is dragged.
pm:dragendeFired when a layer stops being dragged.

You can also listen to specific drag mode events on the map instance like this:

map.on('pm:globaldrawmodetoggled', e => {
  console.log(e);
});

The event has an object with an enabled boolean and a reference to the map.

Removal Mode

// toggle drag mode like this:
map.pm.toggleGlobalRemovalMode();

The following methods are available on map.pm:

MethodReturnsDescription
toggleGlobalRemovalMode()-Toggles global removal mode.
globalRemovalEnabled()BooleanReturns true if global removal mode is enabled. false when disabled.

The following events are available on a map instance:

EventParamsDescription
pm:removeeFired when a layer is removed via Removal Mode
layerremoveeStandard Leaflet event. Fired when any layer is removed.

You can also listen to specific removal mode events on the map instance like this:

map.on('pm:globalremovalmodetoggled', e => {
  console.log(e);
});

The event has an object with an enabled boolean and a reference to the map.

Cutting Mode

cut polygon

Enable drawing for the shape "Cut" to draw a polygon that gets subtracted from all underlying polygons. This way you can create holes, cut polygons in half or remove parts of it.

Important: the cutted layer will be replaced, not updated. Listen to the pm:cut event to update your layer references in your code. The pm:cut event will provide you with the original layer and returns the resulting layer(s) that is/are added to the map as a Polygon or MultiPolygon.

// enable cutting mode
map.pm.Draw.Cut.enable({
  allowSelfIntersection: false,
});

Available options are the same as in drawing mode.

You can use these methods on map.pm.Draw.Cut to handle Cutting mode:

MethodReturnsDescription
enable(options)-Enable Cutting Mode.
disable()-Disable Cutting Mode
toggle(options)-Toggle Cutting Mode

The following events are available on a layer instance:

EventParamsDescription
pm:cuteFired when the layer being cut

The following events are available on a map instance:

EventParamsDescription
pm:cuteFired when any layer is being cut

Customize

Customize Language

Change the language of user-facing copy in leaflet.pm

map.pm.setLang('de');

Currently available languages are en, de, it, ru, ro, es, fr, pt_br, zh and nl. To add translations to the plugin, you can add a translation file via Pull Request.

You can also provide your own custom translations.

const customTranslation = {
  tooltips: {
    placeMarker: 'Custom Marker Translation',
  },
};

map.pm.setLang('customName', customTranslation, 'en');

The 3rd parameter is the fallback language in case you only want to override a few Strings. See the english translation file for all available strings.

Customize Style

In order to change the style of the lines during draw, pass these options to the enableDraw() function.

// optional options for line style during draw. These are the defaults
var options = {
  // the lines between coordinates/markers
  templineStyle: {
    color: 'red',
  },

  // the line from the last marker to the mouse cursor
  hintlineStyle: {
    color: 'red',
    dashArray: [5, 5],
  },
};

// enable drawing mode for shape - e.g. Poly, Line, Circle, etc
map.pm.enableDraw('Polygon', options);

To customize the style of the drawn layer with leaflet options, you can either pass the options to enableDraw:

// optional options for line style during draw. These are the defaults
var options = {
  templineStyle: {},
  hintlineStyle: {},
  pathOptions: {
    // add leaflet options for polylines/polygons
    color: 'orange',
    fillColor: 'green',
  },
};

// enable drawing mode for shape - e.g. Poly or Line
map.pm.enableDraw('Polygon', options);

or set the options generally:

map.pm.setPathOptions({
  color: 'orange',
  fillColor: 'green',
  fillOpacity: 0.4,
});

Feature Request

I'm adopting the Issue Management of lodash which means, feature requests get the "Feature Request" Label and then get closed. You can upvote existing feature requests (or create new ones). Upvotes make me see how much a feature is requested and prioritize their implementation. Please see the existing Feature Requests here and upvote if you want them to be implemented.

Credit

As I never built a leaflet plugin before, I looked heavily into the code of leaflet.draw to find out how to do stuff. So don't be surprised to see some familiar code.

I also took a hard look at the great L.GeometryUtil for some of my helper functions.

If you want to support the development of leaflet.pm, consider subscribing to the services of Geoman.

2.2.0

5 years ago

2.1.0-beta.14

5 years ago

2.1.0-beta.12

5 years ago

2.1.0-beta.11

5 years ago

2.1.0-beta.8

5 years ago

2.1.0-beta.7

5 years ago

2.1.0

5 years ago

2.0.3

5 years ago

2.0.2

5 years ago

2.0.1

5 years ago

2.0.0

5 years ago

1.2.2

5 years ago

1.2.1

5 years ago

1.2.0

5 years ago

1.1.0

5 years ago

1.0.1

6 years ago

0.25.0

6 years ago

0.24.1

6 years ago

0.24.0

6 years ago

0.23.1

6 years ago

0.23.0

6 years ago

0.22.0

7 years ago

0.21.0

7 years ago

0.20.0

7 years ago

0.19.0

7 years ago

0.18.0

7 years ago

0.17.3

7 years ago

0.17.2

7 years ago

0.17.1

7 years ago

0.17.0

7 years ago

0.16.0

7 years ago

0.15.0

7 years ago

0.14.0

7 years ago

0.13.0

7 years ago

0.12.4

7 years ago

0.12.3

7 years ago

0.12.2

8 years ago

0.12.1

8 years ago

0.12.0

8 years ago

0.11.1

8 years ago

0.11.0

8 years ago

0.10.2

8 years ago

0.10.1

8 years ago

0.10.0

8 years ago

0.9.1

8 years ago

0.9.0

8 years ago

0.8.0

8 years ago

0.7.1

8 years ago

0.7.0

8 years ago

0.6.7

8 years ago

0.6.6

8 years ago

0.6.5

8 years ago

0.6.4

8 years ago

1.0.0

8 years ago