Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to preload Leaflet tiles of known bounds in browser cache for faster display?

I'm developing a web application which displays animated markers on a Leaflet map. The map is programmatically zoomed to the first animation bounds, then the animation is played, then the map is zoomed to the second animation bounds and the second animation is played, and so on...

My problem is that the OpenStreetMap tiles loading time sometimes exceeds the animation duration so the map is partially loaded or even not loaded when the marker animation reaches its end.

As i know from the beginning all the bounds i'm going to zoom on, i would like to make ajax calls to download all useful tiles images in advance (before any animation starts) to be sure they are in the browser cache when i need them.

I have searched a lot and i don't find a way to get a list of tiles URLs from Leaflet bounds. Is there a way to manually load tiles in browser cache for known bounds and zoom level ?

SOLUTION thanks to YaFred answer :

Here is the code to preload tiles around "mypolyline" with 20% padding :

var bounds = mypolyline.getBounds().pad(0.2);
var zoom = map.getBoundsZoom(bounds);
var east = bounds.getEast();
var west = bounds.getWest();
var north = bounds.getNorth();
var south = bounds.getSouth();

var dataEast = long2tile(east, zoom);
var dataWest = long2tile(west, zoom);
var dataNorth = lat2tile(north, zoom);
var dataSouth = lat2tile(south, zoom);

for(var y = dataNorth; y < dataSouth + 1; y++) {
    for(var x = dataWest; x < dataEast + 1; x++) {
        var url = 'https://a.tile.openstreetmap.fr/osmfr/' + zoom + '/' + x + '/' + y + '.png';
        var img=new Image();
        img.src=url;
    }
}

It combines his two answers. When an animation is running, I'm now able to preload tiles for the next to come. It works fantastically.

like image 916
Julien V Avatar asked Mar 10 '17 23:03

Julien V


1 Answers

There are 2 questions in one:

1/ How to preload tiles ?

Tiles are images. You just have to create a reference to these images. Look at JavaScript Preloading Images

2/ What tiles must you load when you know the boundaries ?

Take a look at https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames

I cooked an example here that should be helpful. It's preloading tiles from the next zoom level when you move the map: https://yafred.github.io/leaflet-tests/20170311-preloading-tiles/

It first calculates which tiles you need for each corner of your boundaries with following code:

function long2tile(lon,zoom) { return (Math.floor((lon+180)/360*Math.pow(2,zoom))); }
function lat2tile(lat,zoom)  { return (Math.floor((1-Math.log(Math.tan(lat*Math.PI/180) + 1/Math.cos(lat*Math.PI/180))/Math.PI)/2 *Math.pow(2,zoom))); }

then, it calculates which tiles are inside the boundaries.

like image 139
YaFred Avatar answered Nov 04 '22 02:11

YaFred