如何预加载已知边界的Leaflet瓦片以在浏览器缓存中快速显示?

17

我正在开发一个网页应用程序,它在Leaflet地图上显示动画标记。该地图会自动缩放到第一个动画边界,然后播放动画,接着缩放到第二个动画边界并播放第二个动画,以此类推......

我的问题是OpenStreetMap瓦片加载时间有时会超过动画持续时间,因此当标记动画结束时,地图仅部分加载或甚至未加载。

由于我从一开始就知道我要缩放的所有边界,因此我想提前进行ajax调用以下载所有有用的瓦片图像(在任何动画开始之前),以确保它们在浏览器缓存中当我需要它们时可用。

我已经搜索了很多,但我找不到一种方法来从Leaflet边界获取瓦片URL列表。是否有一种方法可以手动在浏览器缓存中加载已知范围和缩放级别的瓦片?

解决方案 感谢YaFred的答案:

以下是预加载带有20%填充的“mypolyline”周围瓦片的代码:

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;
    }
}

它结合了他的两个答案。当动画正在运行时,我现在能够预加载接下来要到来的瓷砖。 它工作得非常好。

1个回答

14

有两个问题:

1/ 如何预加载瓦片?

瓦片是图像。您只需要创建对这些图像的引用。请参见JavaScript Preloading Images

2/ 当您知道边界时,必须加载哪些瓦片?

请查看https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames

我在这里做了一个示例,应该会有所帮助。当您移动地图时,它将从下一个缩放级别预加载瓦片:https://yafred.github.io/leaflet-tests/20170311-preloading-tiles/

它首先使用以下代码计算出您边界每个角落所需的瓦片:

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))); }

然后,它计算哪些瓷砖在边界内。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接