Search code examples
javascriptleafletleaflet.draw

Leaflet - allow user to draw a Polyline with only two points?


Leaflet draw allows users to draw lines on a map. There's an example at https://leaflet.github.io/Leaflet.draw/docs/examples/full.html

I want my users to be able to draw lines consisting of only two points. That is, they click, a marker goes down, they move their mouse, click again, and a line is drawn between the two points.

With the default options, the user has to either click the last point again, or the "finish" button.

Screenshot of a map with some lines drawn on it.

Looking at the documentation for Polyline - http://leaflet.github.io/Leaflet.draw/docs/leaflet-draw-latest.html#polylineoptions - there are several options, but none which specify the maximum number of points a line can have.

Is it possible to set a maximum number of nodes for a line? Or to automatically detect when the second point has been drawn?


Solution

  • You can do this using logic with Javascript.

    I have written an example quickly bellow on how to do this with comments explaining the resolution process :

    // We have the initialisation of the map above
    
    /**
     * We create an object to store the coordinates of the two points
     **/
    let coordinates = {
        point1: {
            lat: null,
            lng: null
        },
        point2: {
            lat: null,
            lng: null
        }
    }
    
    // Here I created a custom Icon so we can add a custom className to it 
    const iconMap = L.icon({
        iconUrl: "https://unpkg.com/[email protected]/dist/images/marker-icon.png",
    
        iconSize:     [25, 41],
        iconAnchor:   [12, 41],
        popupAnchor:  [1, -34],
        className: 'originMarker'
    });
    
    let markerOrigin = null;
    
    function onMapClick(e) {
        if (
                coordinates.point1.lat === null && coordinates.point1.lng === null
            &&  coordinates.point2.lat === null && coordinates.point2.lng === null
        ) {
            coordinates.point1.lat = e.latlng.lat;
            coordinates.point1.lng = e.latlng.lng;
    
            // We add the marker to the map since it is the first point of the line
            markerOrigin = L.marker(
                [ e.latlng.lat, e.latlng.lng ],
                { icon: iconMap }
            ).addTo(map);
        } else if (
            coordinates.point1.lat !== null
            && coordinates.point1.lng !== null
            && coordinates.point2.lat === null
            && coordinates.point2.lng === null
        ) {
            coordinates.point2.lat = e.latlng.lat;
            coordinates.point2.lng = e.latlng.lng;
            
            // We have enough points (2) to create a line
            const line = [
                [ coordinates.point1.lat, coordinates.point1.lng ],
                [ coordinates.point2.lat, coordinates.point2.lng ]
            ];
    
            L.polyline(line, {color: 'red'}).addTo(map);
            
            // we remove the marker
            document.getElementsByClassName('originMarker')[0].remove();
        } else {
            coordinates.point1.lat = e.latlng.lat;
            coordinates.point1.lng = e.latlng.lng;
    
            coordinates.point2.lat = null;
            coordinates.point2.lng = null;
    
            markerOrigin = L.marker(
                [ e.latlng.lat, e.latlng.lng ],
                { icon: iconMap }
            ).addTo(map);
        }
    
        console.log(coordinates);
    }
    
    // we bind a function to the map to detect the click event
    map.on('click', onMapClick);