3

I have used Leaflet's ImageOverlay to load various image layers onto a Leaflet map div (L.map). The size of the layer files can vary greatly. So some layers load very quickly while others can take a couple of seconds (and not every image layer file actually exists).

I would like to check whether all the layer files requested have been fully loaded before doing something else. I can find out if each individual layer is fully loaded using .on("load", function() { ... }).

For example,

layer1 = L.imageOverlay(...);
layer2 = L.imageOverlay(...);
layer3 = L.imageOverlay(...);

layer1.on("load", function() {console.log("layer1 loaded")});
layer2.on("load", function() {console.log("layer2 loaded")});
layer3.on("load", function() {console.log("layer3 loaded")});

However, when I defined a LayerGroup,

var AllLayers = L.layerGroup([layer1, layer2, layer3]);

and then tried

AllLayers.on("load", function() {console.log("All layers loaded")});

I did not get "All layers loaded" in the console.

I came across a related question on the .on("click") event .on(click) for layer groups in leaflet

I tried to define a layer group using L.featureGroup

var AllLayers = L.featureGroup([layer1, layer2, layer3]);

However, it did not show "All layers loaded" in the console either when all the layers were loaded.

I don't know how I would go about trying the first method answered in the above article.

1 Answer 1

5

A simple way of doing this would be to count load events of individual layers and when count is equal to number of layers, it's done.

Code could then look something like this:

var nLayers = 0;
var nLayersLoaded = 0;

function setLoadEvent(layer) {
  nLayers++;
  layer.on("load", function() {
    nLayersLoaded++;
    if (nLayersLoaded == nLayers) {
      console.log("all layers loaded");
    }
  });
}

setLoadEvent(layer1);
setLoadEvent(layer2);
setLoadEvent(layer3);
14
  • Hmm.. Thanks, TomazicM. I thought this should work. But when I tried this, I immediately got "all layers loaded" displayed in the console without waiting for each individual layer to get fully loaded.
    – kykong
    Commented Feb 18, 2021 at 20:57
  • I forgot to initialize nLayers to 0, corrected now. But even with that, order of doing things is important. First image layers have to be created, but not added to the map, then load events have to be created and only after that image layers added to the map.
    – TomazicM
    Commented Feb 18, 2021 at 21:14
  • So if I add these 3 lines below your codes: layer1.on("load", function() {console.log("layer1 loaded")}); layer2.on("load", function() {console.log("layer2 loaded")}); layer3.on("load", function() {console.log("layer3 loaded")}); The console shows "all layers loaded" first when not all layers were actually loaded. Then, "layer1 loaded", "layer2 loaded", "layer3 loaded". I recognize that this is related to asynchronous javascripting. But I am new to this and I'm not sure how it should be tackled.
    – kykong
    Commented Feb 18, 2021 at 21:36
  • I tested code from the answer, and it works as it's supposed to. You must be doing something wrong in your code.
    – TomazicM
    Commented Feb 18, 2021 at 22:00
  • It turned out that I needed to let var nLayers = nLayersLoaded + nLayers in order to achieve the desired result. It took me hours to investigate the reason. I use Leaflet's setUrl to update or reload the URL of the image already loaded with ImageOverlay. But each time I use setUrl, nLayersLoaded is increased by 1. I don't know the internal workings of setUrl to understand why this would be the case. Does it suggest that a new layer is added every time setUrl is invoked?
    – kykong
    Commented Feb 19, 2021 at 17:13

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.