2

I'm working on a weather map project with Leaflet. I have several weather parameters as PNG overlays. For each parameter there's 60 PNG files, representing different points in time. I have implemented a simple routine which will allow the user to step forward and backward through time like this:

function getUrl(parameter,time) {
    return '/charts/leaflet/'+parameter+'-'+time+'.png';
}

function setUrls(time) {
    console.log(time);
    levels.setUrl(getUrl('levels',time));
    capesfc.setUrl(getUrl('capesfc',time));
}

var increaseTime = L.Toolbar2.Action.extend({
    options: {
        toolbarIcon: {
            html: '<i class="fa fa-step-forward" />',
            tooltip: 'increase time'
        }
    },
    addHooks: function () {
        if (timeIndex < 160) timeIndex++;
        else timeIndex = 100;
        setUrls(timeIndex);
    }
});
var decreaseTime = L.Toolbar2.Action.extend({
    options: {
        toolbarIcon: {
            html: '<i class="fa fa-step-backward" />',
            tooltip: 'decrease time'
        }
    },
    addHooks: function () {
        if (timeIndex > 100) timeIndex--;
        else timeIndex = 160;
        setUrls(timeIndex);
   }
});

As you can see, my system is based on directly changing the layer URL which will trigger Leaflet to reload the layer from the new URL. Unfortunately, as the files are about 400k each, that creates somewhat of a delay and flicker. I was planning to include some animation function and/or a quick scroll through some slider and for that it's to stuttery. Is there a way to force the caching of the images or a smarter way to handle things alltogether, e.g. when a layer is selected, Leaflet could preload all layers or something like that?

6
  • Service workers. See developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API/… and serviceworke.rs . Make it so on every fetch request coming from the main thread, the service worker fetches and caches some other corresponding resource from the network. Jun 24, 2019 at 14:06
  • Simplest solution would be to create image layer for every one of 60 images and wait till all layers are loaded (with message: Loading ...) . Now insetad of changing layer URL you just display next/previous layer.
    – TomazicM
    Jun 24, 2019 at 18:52
  • @IvanSanchez: I will have a look, thanks! Jun 25, 2019 at 15:15
  • @TomazicM: Yeah, I thought about that but I have maps for plenty of parameters which also partially should overlay each other. That would end up in a huge memory mess. Although it would be a nice test for memory leaks in the browser :D. Jun 25, 2019 at 15:17
  • Stefan. How did you insert that funnction you came up with? I'm still new to Leaflet JS, and have zero knowledge on Javascript, but I'd like to put a similar feature in place for my website 😅 Oct 8, 2021 at 14:03

1 Answer 1

0

In the end, I just wrote a function that turns on a spinner, loads all images into img objects and turns off the spinner. Not elegant but it makes the current modern browsers cache the images.

function preloadImages(parameter)
{
  $('#spinner').show();
  for (var time = 100; time <= 160; time++) {
    new Image().src=getUrl(parameter,time);
  }
  $('#spinner').hide();
}
´´´

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.