0

I am attempting to fire an event when the base layer changes in a Leaflet Map. It seems that the event is only firing on the "second" time the layer changes? Here is a fiddle to display an alert on baselayerchange, showing this condition.

https://jsfiddle.net/frugardc/x5p2nLrs/112/

Here is the code

// center of the map
var center = [-33.8650, 151.2094];
// Set up the OSM layer
var l1 = L.tileLayer(
  'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
  maxZoom: 18
});
var l2 = L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
   attribution: '&copy; <a 
href="http://osm.org/copyright">OpenStreetMap</a> contributors'
});
// Create the map
var map = L.map('map',{layers: [l1,l2]}).setView(center, 3);

baseLayers = {
  'Map 1': l1,
  'Map 2': l2
};
L.control.layers(baseLayers,{}).addTo(map);

map.on('baselayerchange', function(e) {
  alert('Changed to ' + e.name);
});
// add a marker in the given location
L.marker(center).addTo(map);
0

3 Answers 3

2

I examined behaviour of internal _onLayerChange event handler which fires 'baselayerchange' event. Event is fired only when base layer is added.

So the story goes like this. If map is created with

var map = L.map('map',{layers: [l1,l2]});

both layers are added to the map at time of creation. When you initialy select the other layer, previous one is removed and select one shown. Since it does not need to be added, 'baselayerchange' event is not fired. If you then select the other layer, it has to be added (since it was removed) and 'baselayerchange' event is fired.

You can verify this if you initialy select the layer that is already shown (this will remove the other layer) and then the other layer. In this case 'baselayerchange' event is fired.

One possible solution is to create map only with initial layer:

var map = L.map('map',{layers: [l1]});

In this case event is fired even at the first display of map and at every subsequent change of layer.

3
  • This seems like a bug, no? Since the event does not fire even when the layer changes?
    – frugardc
    Commented Oct 27, 2017 at 17:26
  • Also, I don't think your suggestion works. The event fires when the page loads and the layer is added, but when the selection changes in the layer control, it still takes a second change before the event fires.
    – frugardc
    Commented Oct 27, 2017 at 17:40
  • It works for me instantly, no delay. I tried it in IE11, Firefox ans Chrome, but it's true that I'm using Leaflet 1.2. I see in your jsfiddle you are using Leaflet 1.0.0. beta 2.
    – TomazicM
    Commented Oct 27, 2017 at 20:05
2

It sounds like a bug. What @TomazicM says is true, and if you want to maintain your pictures without adding them dynamically you can just do that through the bindings as below. You just add your first image to the layer (this will be your initial selected image), then you bind all other through L.control.layers() function as below.

        var firstImage = imagesInstances[0];

        leaflet = L.map('map', {
            ...
            layers : [firstImage]
        });

        leaflet.on('baselayerchange', function(){
            console.log("LAYER HAS BEEN CHANGED.");
        })

        var layerBindings = {};
        for (var i = 0; i < imagesInstances.length; i++)
        {
            layerBindings[i.toString()] = imagesInstances[i];
        }

        L.control.layers(layerBindings, null).addTo(leaflet);
1

Remove one of the layers from your map options

var map = L.map('map',{layers: [l1]}).setView(center, 3);

Leaftlet - Control.Layers Creation

Note that all base layers should be passed in the base layers object, but only one should be added to the map during map instantiation

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.