Search code examples
leafletmarkerpolyline

Leaflet - How to match marker and polyline on drag and drop


I have a project with leafletJS. For example, I have 2 points (A, B) in map. I display it as 2 Markers I must draw a polyline from A to B. I moved marker A and I want to the head of polyline of marker A match to marker A (moved follow marker A). How can I do this? Sorry for my bad English. Thanks all very much.

Truong M.


Solution

  • Given the following L.Latlng's, L.Marker's and L.Polyline:

    var a = new L.LatLng(-45, -90),
        b = new L.LatLng(45, 0),
        c = new L.LatLng(-45, 90);
    
    var marker_a = new L.Marker(a, {draggable: true}).addTo(map),
        marker_b = new L.Marker(b, {draggable: true}).addTo(map),
        marker_c = new L.Marker(c, {draggable: true}).addTo(map);
    
    var polyline = new L.Polyline([a, b, c]).addTo(map);
    

    You'll need to attach eventlisteners and callbacks to your L.Marker's. You could automate this, but i'll keep it simple for now:

    marker_a
        .on('dragstart', dragStartHandler)
        .on('drag', dragHandler)
        .on('dragend', dragEndHandler);
    
    marker_b
        .on('dragstart', dragStartHandler)
        .on('drag', dragHandler)
        .on('dragend', dragEndHandler);
    
    marker_c
        .on('dragstart', dragStartHandler)
        .on('drag', dragHandler)
        .on('dragend', dragEndHandler);
    

    Now on dragstart you'll need to find the latlng from the polyline which corresponds with your marker's latlng and store it's key in your marker instance so you can use it later on:

    function dragStartHandler (e) {
    
        // Get the polyline's latlngs
        var latlngs = polyline.getLatLngs(),
    
            // Get the marker's start latlng
            latlng = this.getLatLng();
    
        // Iterate the polyline's latlngs
        for (var i = 0; i < latlngs.length; i++) {
    
            // Compare each to the marker's latlng
            if (latlng.equals(latlngs[i])) {
    
                // If equals store key in marker instance
                this.polylineLatlng = i;
            }
        }
    }
    

    Now you know the key of the polyline's latlng you can change it when dragging the marker on the dragevent:

    function dragHandler (e) {
    
        // Get the polyline's latlngs
        var latlngs = polyline.getLatLngs(),
    
            // Get the marker's current latlng
            latlng = this.getLatLng();
    
        // Replace the old latlng with the new
        latlngs.splice(this.polylineLatlng, 1, latlng);
    
        // Update the polyline with the new latlngs
        polyline.setLatLngs(latlngs);
    }
    

    Just to be clean and tidy remove the stored key on dragend:

    function dragEndHandler (e) {
    
        // Delete key from marker instance
        delete this.polylineLatlng;
    }
    

    That's it. Here's a working example on Plunker: http://embed.plnkr.co/SJRec3/preview