Cannot access event.layer in Leaflet.Geoman - leaflet

I am using Leaflet-Geoman to draw on map. Drawing and editing works perfectly.
When the user has finished drawing I need to access the layer with the drawing for further processing. See an example here:
map.on('pm:drawend', function(event) {
console.log(event);
console.log(event.layer);
});
This returns "TypeError: event.layer is undefined". How can I get the layer of the event?

The pm:drawend event has no layer object.
You have to use pm:create:
map.on('pm:create', function(event) {
console.log(event);
console.log(event.layer);
});

Related

Does there exist a function to tell if the current tileLayer is **already** loaded?

I want to programmatically flyTo to a new location, then once arriving at the new location and the tiles in the new location are loaded, I would like to do the next step.
Using the load event does not work if the new location is very close to the origin, since they are already loaded, so no new load event would be fired. Nevertheless, the code still needs to handle whether the visible tiles are loaded, since it is possible that the new location is quite far from the origin.
How do I tell if the current tile layer is already loaded? Something like map.whenReady, which is fired immediately if the map is already ready, unlike tileLayer.on("load"), which won't be fired if the tile layer is already loaded.
Sample code that doesn't work:
map.on("moveend zoomend", function(){
baseLayer.on("load", function(){
// do something
});
});
map.flyTo(latlng);
If the tile layer is already loaded, the "load" event won't fire, and do something won't be executed.
What I would like to have:
map.on("moveend zoomend", function(){
baseLayer.whenLoaded(function(){
// do something
});
});
map.flyTo(latlng);
How to achieve this in Leaflet?
As already answered on github, it's easy to implement whenReady in your own code using Leaflet extension methods, like this:
L.GridLayer.include({
whenReady: function (callback, context) {
if (!this._loading) {
callback.call(context || this, {target: this});
} else {
this.on('load', callback, context);
}
return this;
},
});
This is not the most elegant solution, but I think you could solve your problem using TileLayer isLoading() method that returns true if any tile in the grid layer has not finished loading.
map.on("moveend zoomend", function(){
baseLayer.on("load", function(){
doSomething("load: YES");
});
if (!baseLayer.isLoading()) doSomething("load: NO");
});
function doSomething(info) {
alert("do something - " + info);
}

Leaflet-geoman remove button not working after bind a new layer click function

I need to bind a custom click function on the drawn shapes. I'm using the following code for that:
map.on('pm:create', function(e) {
e.layer.on('click', function(e) {
document.getElementById('info-pane').style.display = 'block';
});
});
When I bind this new click function, I'm not able to remove the shape anymore. When I am in the remove mode, the click is triggering the show info-pane instead of remove the shape.
How can I bind a custom click function to the shapes without "deactivate" any leaflet-geoman functionality such as the Remove ?
Well,
Including this L.DomEvent.stopPropagation(e); seems to be working now.
map.on('pm:create', function(e) {
e.layer.on('click', function(e) {
document.getElementById('info-pane').style.display = 'block';
});
L.DomEvent.stopPropagation(e);
});

Leaflet Choropleth Map - switch to Leaflet 1.2

I have a problem with my map. I switched to Leaflet 1.2 and one of the functions is not working correctly.
The code is here:
http://mapaszlakow.eu/mapa1.2.html
When activating an overlay which is geojson via js and clicking a bicycle route it zooms in to a route but it is not highlighted and the info window does not show up.
Here is exactly the same example that is working but on the older version of Leaflet (I think it is 0.7).
http://mapaszlakow.eu/
I can't locate the problem, the only thing I did is switching to Leaflet 1.2, I will be greatful for help.
EDIT: I believe, the problem is somewhere here:
function select(layer) {
info.update(layer.feature.properties);
if (selected !== null) {
var previous = selected;
}
map.fitBounds(layer.getBounds());
selected = layer;
if (previous) {
dehighlight(previous);
}
}
var selected = null;
I've tested your code from http://mapaszlakow.eu/mapa1.2.html and it works almost fine - on hover it highlights route correctly, on click it zooms to route extent - except from showing the popup info. To fix this please check out the fiddle I made from your code:
http://jsfiddle.net/5z17y5oL/18/ (this fiddle must be accessed through http because your server doesn't serve data with https)
The main difference is that I passed parameter to info.update(e.feature.properties); occurrences.
EDIT
My edited fiddle is here: http://jsfiddle.net/5z17y5oL/25/
So I moved the info.update(e.feature.properties); to be called from layer click listener. On map clicked layer style is reset and info is clearing as it's receiving null.
.....
onEachFeature: function(feature, layer) {
layer.on({
.....
'click': function(e) {
select(e.target);
info.update(e.feature.properties);
}
});
map.on({
'click': function(e) {
bicyclegeojson.resetStyle(layer);
info.update(null);
selected = null;
}
});
....
//end of EDIT
One more thing - you have small error, you should change this line:
map.addControl(layerControl).addTo(map);
to
map.addControl(layerControl);

How to remove previous layer when draw new?

Current behaviour of Draw plugin is add every new drawing layer to the map:
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);
});
but how to improve this code to get it remove every previous layer when user draw new one? I can't understand how to call: map.removeLayer(layer); and say it that I want to remove previous, but not current layer.
Assuming you want to remove all layers on map, you could use a code similar to that one at the beginning of your "draw:created" event listener:
map.eachLayer(function (layer) {
map.removeLayer(layer);
});
(but I think that would also remove your Tile Layers, so maybe you should add some checks in there)
Should you use an intermediate drawnItems Feature Group, you could also simply use the .clearLayers() method:
drawnItems.clearLayers();

Is there a way to filter geojson by clicking polygon in Leaflet?

I have implemented a geojson filter using toggle buttons with a LayerGroup, but would like to know if anyone has been successful with same behavior using on-map mouseclicks.
Example: map of world countries. click on Italy polygon results in only Italy being visible. Click outside Italy to show all countries again. Hope my question is clear.
It's just a matter of hooking on to the click event of the layer, clearing the group and add that single layer. Also hook on to the map click, remove the single layer and restore the rest. Here's a quick-n-dirty example:
// vars to store stuff
var geojson, source, selected;
// Load the collection
$.getJSON(url, function (collection) {
// Store collection for later use
source = collection;
// Create layer and add collection
geojson = L.geoJson(collection, {
// On each feature in collection
'onEachFeature': function (feature, layer) {
// Attach click handler
layer.on('click', function () {
// Set selected flag
selected = true;
// Clear the entire layer
geojson.clearLayers();
// Add the feature
geojson.addData(feature);
// Fit layer to map
map.fitBounds(layer.getBounds());
});
}
}).addTo(map);
});
// Attach to map click
map.on('click', function () {
// Check if something's selected
if (selected) {
// Clear the entire layer
geojson.clearLayers();
// Restore the collection
geojson.addData(source);
// Fit map to collection
map.fitBounds(geojson.getBounds());
}
});
Here's a working example on Plunker: http://plnkr.co/edit/o5Q0p3?p=preview