question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

How to make features drawn with leaflet.draw always snap to other features dynamically drawn?

See original GitHub issue

Hi,

during drawing with leaflet.draw, the features will snap. But if they are drawn and made editable they won’t. How to solve this? Do I really have to manage all objects to refresh the guideLayers to make them snapping again?

// Create a map in the "map" div, set the view to a given place and zoom
var map = L.map('map').setView([48.48922, 1.40033], 13);

// Add scale
L.control.scale().addTo(map);

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

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

// Snapping
guideLayers = new Array();

// Initialise the draw control and pass it the FeatureGroup of editable layers
var drawControl = new L.Control.Draw({
    draw: {
        polyline: { guideLayers: guideLayers },
        marker: { guideLayers: guideLayers },
        polygon: false,
        rectangle: false,
        circle: false
    },
    edit: {
        featureGroup: drawnItems,
        edit: false
        // Delete still remains useable
    }
});
map.addControl(drawControl);

map.on('draw:created', function (event) {
    var type = event.layerType;
    var layer = event.layer;
    if(type === 'marker') {
        // Make marker draggable
        layer.options.draggable = true;
    }
    else {
        // Make line editable
        layer.editing.enable();
        // Activate snapping - does not work ... :(
        layer.snapediting = new L.Handler.PolylineSnap(map,layer);
        layer.snapediting.addGuideLayer(guideLayers);
        layer.snapediting.enable();
    }

    // Add to drawnItems
    drawnItems.addLayer(layer);
    // Add newly drawn feature to list of snappable features
    guideLayers.push(layer);
});

Tried it with adding a for-loop at the end of the draw:created event but sadly it doesn’t work

    for(var i = 0;i < guideLayers.length;i++) {
        console.log('layer ' + i + ' refreshed');
        guideLayers[i].snapediting.addGuideLayer(guideLayers);
    }

Thanks

Issue Analytics

  • State:closed
  • Created 10 years ago
  • Comments:12 (1 by maintainers)

github_iconTop GitHub Comments

1reaction
ghafner1commented, Apr 5, 2017

Hi to all, I have had the same problem and found solutio using L.Draw. There a few things which have to be observed in next code:

map.on(L.Draw.Event.CREATED, function (event) {
	var type = event.layerType;
	layer = event.layer;
	layer.addTo(map);
	if (type === 'marker') {
		// Do marker specific actions			  
		layer.options.draggable = true;
		layer.snapediting = new L.Handler.MarkerSnap(map, layer);
	} 
	else
	{
		// Make line editable
		layer.editing.enable();		
		// Activate snapping
		layer.snapediting = new L.Handler.PolylineSnap(map, layer);				
	}
		// Add the currently drawn layer to the snap list of the already drawn layers
		for(var i = 0;i < guideLayers.length; i++) {			
			layer.snapediting.addGuideLayer(guideLayers[i]);
		}
		// Enable snap editing
		layer.snapediting.enable();					
			
		// add new drawn feature to list od drawnItems features
		drawnItems.addLayer(layer);
		// Add newly drawn feature to list of snappable features
		guideLayers.push(layer);
			
		// Do whatever else you need to. (save to db; add to map etc)	
});

The main hint to solve mentionde problem was line 4: layer.addTo(map);. To be able to snap with already existing layers ( when we Edit newly created layer) we have to add him to map. The other lines are important to but were metioned earlire on current topic.

P.S. the rest of code, abow code metionde earlier, was:

var map = L.map('map', { center: new L.LatLng(48.48988, 1.39638), zoom: 14 });
// Leaflet Draw
		var drawnItems = new L.FeatureGroup();
        map.addLayer(drawnItems);             
        
        var guideLayer =
            L.polyline([
                [48.505431207150885, 1.3999843597412107],
                [48.50335551764662, 1.398911476135254],
                [48.50173471468476, 1.3994693756103516],
                [48.49974418399956, 1.3991689682006836],
                [48.49684355649577, 1.3993835449218748],
                [48.4956206932084, 1.398611068725586],
                [48.49465375716902, 1.3980531692504883],
                [48.49419872206354, 1.3975811004638672],
                [48.492406981637345, 1.3971948623657227],
                [48.49156797030711, 1.396486759185791],
                [48.49067206152607, 1.3961219787597656],
                [48.48988, 1.39638],
                [48.489342389949364, 1.394963264465332],
                [48.48864554279267, 1.3944590091705322],
                [48.487628697617744, 1.3940191268920896],
                [48.485666057669334, 1.3944482803344727],
                [48.48541005555473, 1.3942551612854002],
                [48.48461359626773, 1.3942766189575195],
                [48.483489998505746, 1.3933539390563965],
                [48.48164098598135, 1.3928818702697754],
                [48.480232846617845, 1.3912296295166016],
                [48.479450530080534, 1.3906073570251463],
                [48.478511734309954, 1.3902640342712402],
                [48.47714618217502, 1.389319896697998],
                [48.47600819398379, 1.388998031616211]
            ], {
                    weight: 5,
                    color: 'red',
                    opacity: 1.0
                }).addTo(map);

        var marker = L.marker([48.488, 1.395]).addTo(map);
        marker.snapediting = new L.Handler.MarkerSnap(map, marker);
        marker.snapediting.addGuideLayer(guideLayer);
        marker.snapediting.enable();
        var road = L.polyline([
            [48.48922, 1.40033],
            [48.48935, 1.39981],
            [48.48948, 1.3976],
            [48.48986, 1.39634]
        ], {
            color: 'green',
            opacity: 1.0
        }).addTo(map);

        road.snapediting = new L.Handler.PolylineSnap(map, road);
        road.snapediting.addGuideLayer(guideLayer);
        road.snapediting.enable();
        marker.snapediting.addGuideLayer(road);

        var guideLayers = [guideLayer, road];
        drawnItems.addLayer(guideLayer);
        drawnItems.addLayer(road);
        
        var drawControl = new L.Control.Draw({			
		position: 'topleft',
            draw: {
                polyline: true,
                polygon: true,
                circle: false,
                marker: true,               
                poly: {
				allowIntersection: false
			}
            },           
            edit: 
            {
                featureGroup: drawnItems,                               
                remove: true
            }
        });    
        map.addControl(drawControl);
        
        drawControl.setDrawingOptions({
            polyline: { guideLayers: guideLayers},
            polygon: { guideLayers: guideLayers, snapDistance: 5 },
            marker: { guideLayers: guideLayers, snapVertices: false },
            rectangle: false,
            circle: false
        });
0reactions
bastyencommented, Aug 22, 2016

i think #30 resolve this

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to initiate the draw function without toolbar? - Stack ...
I want to initiate drawing a polygon without using the toolbar from leaflet.draw . I've managed to find the property that allows editing...
Read more >
Leaflet Draw Documentation
This tells the plugin which FeatureGroup contains the layers that should be editable. The featureGroup can contain 0 or more features with geometry...
Read more >
Documentation - a JavaScript library for interactive maps
To set the restriction dynamically, use setMaxBounds method. renderer, Renderer, *, The default method for drawing vector layers on the map.
Read more >
How to highlight marker dynamically with leaflet and leaflet draw
I am trying to make a selection via drawing a rectangle (or any shape) with leaflet draw. The selected features should be highlighted....
Read more >
4.6 Drawing & User Editing | Mapping in LeafletJS - YouTube
Mapster has decided to make all its courses, content, and code free from now on! Enjoy this free course on how to use...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found