Giter VIP home page Giter VIP logo

turistforeningen / leaflet.draw Goto Github PK

View Code? Open in Web Editor NEW

This project forked from leaflet/leaflet.draw

4.0 3.0 1.0 813 KB

Vector drawing plugin for Leaflet enhanced with professional and sophisticated drawing functionality, such as snapping, routing and much much more.

Home Page: http://turistforeningen.github.io/Leaflet.draw/examples/snapping.html

License: MIT License

JavaScript 100.00%

leaflet.draw's Introduction

Important

You will need to download the latest Leaflet from master in the Github repo before Leaflet.draw 0.2.0 will work.

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

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

Using the plugin
Advanced Options
Command tasks
Thanks

## 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.

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

// Initialize the FeatureGroup to store editable layers
var drawnItems = new L.FeatureGroup();
map.addLayer(drawnItems);

// Initialize 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 that contains the layers that should be editable.

Events

Once you have successfully added the Leaflet.draw plugin your map you will want to respond to the different actions users can do. 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') {
		// Do marker specific actions
	}

	// Do whatever else you need to. (save to db, add to map etc)
	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, that the plugin was initialized with, 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
	});
});

draw:deleted

Triggered when layers have been 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 finshed a particular vector or marker.

Property Type Description
layerType String The type of layer this is. One of: polyline, polygon, rectangle, circle, marker
## Advanced options

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

These options make up the root object that is used when initializing 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 EditOptions false The options used to configure the edit toolbar.
### DrawOptions

These options will allow you to configure the draw toolbar and it's handlers.

Option Type Default Description
polyline PolylineOptions { title: 'Draw a polyline' } Polyline draw handler options.
polygon PolygonOptions { title: 'Draw a polygon' } Polygon draw handler options.
rectangle RectangleOptions { title: 'Draw a rectangle' } Rectangle draw handler options.
circle CircleOptions { title: 'Draw a circle' } Circle draw handler options.
marker MarkerOptions { title: 'Add a marker' } Marker draw handler options.

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

#### PolylineOptions and PolygonOptions

Polyline and Polygon drawing handlers take the same options.

Option Type Default Description
title String 'Draw a Polyline (Polygon)' The title used for the polyline/polygon button.
allowIntersection Bool true Determines if line segements 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.
zIndexOffset Number 2000 This should be a high number to ensure that you can draw over all other layers on the map.
#### RectangleOptions
Option Type Default Description
title String 'Draw a rectangle.' The title used for the rectangle button.
shapeOptions Leaflet Path options See code The options used when drawing the rectangle on the map.
#### CircleOptions
Option Type Default Description
title String 'Draw a circle.' The title used for the circle button.
shapeOptions Leaflet Path options See code The options used when drawing the circle on the map.
#### MarkerOptions
Option Type Default Description
title String 'Add a marker.' The title used for the marker button.
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.
### EditOptions

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 { title: 'Edit layers' } Edit handler options.
remove DeleteHandlerOptions { title: 'Delete layers' } Delete handler options.
#### EditHandlerOptions
Option Type Default Description
title String 'Edit Layers' The title used for the edit button.
selectedPathOptions Leaflet Path options See code The path options for how the layers will look like while in edit mode. If this is set to null the editable path options will not be set.
#### DeleteHandlerOptions
Option Type Default Description
title String 'Remove Layers' The title used for the delete button.
## Common tasks

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: {
			title: 'Draw a kick ass 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);
});

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 initialization by using the setDrawingOptions method on the Leaflet.draw control.

E.g. to change the colour of the rectangle:

drawControl.setDrawingOptions(
    rectangle: {
        color: '#0000FF'
    }
);
## Thanks

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.

leaflet.draw's People

Contributors

jacobtoye avatar starefossen avatar danzel avatar ajbeaven avatar iirvine avatar jmkelly avatar koppelbakje avatar tmcw avatar mourner avatar yohanboniface avatar guiswa avatar brianherbert avatar ghuntley avatar mapmeld avatar christophe-g avatar

Stargazers

Valerio Marchetti avatar  avatar Steve avatar Robert Seyfriedsberger avatar

Watchers

James Cloos avatar Valerio Marchetti avatar  avatar

leaflet.draw's Issues

Problem with snapping feature

Hi,

it seems that there is a problem with the polyline snapping feature.

When you try to edit a polygon, the snapping function check the proximity to the line composed by all vertex of each polygon on the layers with the point that I'm moving; the problem is that the proximity function use in his computing also the polygon vertex that I'm moving, then the snapping is always done also if I'm not near to another polygon vertex.

I think that the problem can be solved by two ways:

  1. modify the proximity function to omit the polygon that you are editing.

  2. fixing the starting polygon vertex that you are editing and use always there original vertex points in the proximity function during the editing operation.

In my situation I prefer the solution 1 so I have modified the snapTo function from:

snapTo: function (latlng) {
var layers = this.options.snapping.layers;
this._snapVars.minPoint = latlng;
this._snapVars.minDist = Infinity;

// Loop through layers
for (var l1 in layers) {
    for (var l2 in layers[l1]._layers) {
        this._snapVars.map = layers[l1]._layers[l2]._map;

        if (typeof layers[l1]._layers[l2]._latlngs !== "undefined") {
            this._snapToObject(latlng, layers[l1]._layers[l2]);
        } else if (typeof layers[l1]._layers[l2]._layers !== "undefined") {
            for (var l3 in layers[l1]._layers[l2]._layers) {
                this._snapToObject(latlng, layers[l1]._layers[l2]._layers[l3]);
            }
        }   
    }
}

    return this._snapVars.minPoint;

},

to:

snapTo: function (latlng, leaflet_id) {
var layers = this.options.snapping.layers;
this._snapVars.minPoint = latlng;
this._snapVars.minDist = Infinity;

// Loop through layers
for (var l1 in layers) {
    for (var l2 in layers[l1]._layers) {
        this._snapVars.map = layers[l1]._layers[l2]._map;

        if (typeof layers[l1]._layers[l2]._latlngs !== "undefined") {
            if (leaflet_id != layers[l1]._layers[l2]._leaflet_id) {
                this._snapToObject(latlng, layers[l1]._layers[l2]);
            }
        } else if (typeof layers[l1]._layers[l2]._layers !== "undefined") {
            for (var l3 in layers[l1]._layers[l2]._layers) {
                this._snapToObject(latlng, layers[l1]._layers[l2]._layers[l3]);
            }
        }   
    }
}

return this._snapVars.minPoint;

},

and passing to the function the this._poly._leaflet_id value

Snapping problem

@Starefossen, it seems that there are two different behaviors when you draw a polyline/polygon and snap it to another polygon.

  1. Working mode: draw the first polygon, then draw another polygon not near to the first one. Now try to move a vertex of the second polygon near to a vertex of the first one, you can see that the snapping feature is right.

  2. Not working mode: draw the first polygon, then start to draw the second polygon snapping to some vertices of the first one. Now try to move a vertex of the second polygon snapped to a vertex of the first one. You can see a snapping problem (like a gird snapping), besides if you move the vertex not near and, without leaving the editing mode, change the zoom of the map (for example with the mouse wheel) you will see that the vertices of the two polygons are still snapped and also the first polygon will change his form.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.