3

I want to draw a polygon on a leaflet map and afterwards send it to the DB and retrieve all objects that intersect that polygon.

In OpenLayers I did it by using custom function in "featureAdded:" when declaring OpenLayers.Control.DrawFeature.

How can I do the same in leaflet ?

Also , is there an easy way to add custom controls from top right to top left as in OpenLayers control panel ?

2 Answers 2

5

I highly recommend using the Leaflet Draw plugin which is documented here and available from here.

However, for the record lets say you want to do this using your own custom code.

I'll propose a simple application and make some assumptions about the way you might want it to work. I will make an effort to make the code reuseable. Please note that this code is not production ready and does not take into account what should happen if the user wants to draw more than one polygon or how the data should be sent to the server and what it does with the data after it returns it. Those are decisions for you.

Lets assume the following DOM elements:

<div id="map"></div>
<button id="drawPolygon">Draw</button>
<button id="stopDraw">Finish Drawing</button>
<button id="getData">Get Items Inside Polygon</button>

Lets also assume you have set the Leaflet.js map to be attached to the div#map element and have gotten some layers from OpenStreetMap to be visible and all your panning and zooming is working just fine. First lets define some variables.

var drawPolygonButton = document.getElementById('drawPolygon');
var stopDrawButton = document.getElementById('stopDraw');
var getDataButton = document.getElementById('getData');
var currentPolygon = {}; //Empty object to be used later;

Now lets attached an event listen to the Draw button. When the draw button is clicked it will create a new (empty) polygon and attach a listener to the map for click events. If one is heard then the add LatLngToPolygon function is called with the click event passed implicity (meaning it happens without you having to specify that it is there). The click event contains where on the map the click happened.

drawPolygonButton.addEventListener('click', function(){
    currentPolygon = new L.polygon([]).addTo(map);
    map.on('click', addLatLngToPolygon); //Listen for clicks on map.
});

The stop draw function just turns off map click listener so clicks on the map won't add to the polygon.

stopDraw.addEventListener('click', function(){
    map.off('click', addLatLngToPolygon); //Stop listening for clicks on map.
});

This is an example of where your AJAX would go:

   getDataButton.addEventListener('click', function(){
        var data = simplifyLatLngs(currentPolygon.getLatLngs());
        console.log(data);
        //SEND DATA USING AJAX
    });

Using the click event, add a new latlng to the Polygon:

function addLatLngToPolygon(clickEventData){
    currentPolygon.addLatLng(clickEventData.latlng);
}
    

Transform the Leaflet LatLngs into a native array so its easier to send using Ajax.

function simplifyLatLngs(latlngs){
    var x = []; //blank array
    for(var i=0;i<latlngs.length;i++){
            x.push([latlngs[i].lat,latlngs[i].lng]);
    }
    return x;
}
0

I had the same need and looked in leaflet.Editable.js code to find it. All events names are after "L.Editable.BaseEditor = L.Handler.extend".

For example, to make something after the user ended editing a polygon, use this code:

myPolygon = L.polygon(arrayOfLatLon);
myPolygon.addTo(myMap);
myPolygon.on({
   'editable:editing' : function (e) {
      console.log("user has changed something in the polygon");
   }
});

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.