如何在浏览器缓存中预加载已知边界的 Leaflet tiles 以便更快地显示?
How to preload Leaflet tiles of known bounds in browser cache for faster display?
我正在开发一个在 Leaflet 地图上显示动画标记的 Web 应用程序。地图以编程方式缩放到第一个动画范围,然后播放动画,然后地图缩放到第二个动画范围并播放第二个动画,依此类推...
我的问题是 OpenStreetMap 瓦片加载时间有时会超过动画持续时间,因此当标记动画结束时地图会部分加载甚至未加载。
正如我从一开始就知道我要放大的所有边界,我想提前 ajax 调用以下载所有有用的图块图像(在任何动画开始之前)以确保当我需要它们时,它们在浏览器缓存中。
我搜索了很多,但没有找到从 Leaflet 边界获取图块 URL 列表的方法。有没有办法在已知边界和缩放级别的浏览器缓存中手动加载图块?
解决方案 感谢 YaFred 的回答:
这是预加载 "mypolyline" 附近的图块并填充 20% 的代码:
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;
}
}
它结合了他的两个答案。当动画为 运行 时,我现在可以为下一个动画预加载图块。它的效果非常好。
一题有2题:
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))); }
然后,它会计算哪些图块在边界内。
我正在开发一个在 Leaflet 地图上显示动画标记的 Web 应用程序。地图以编程方式缩放到第一个动画范围,然后播放动画,然后地图缩放到第二个动画范围并播放第二个动画,依此类推...
我的问题是 OpenStreetMap 瓦片加载时间有时会超过动画持续时间,因此当标记动画结束时地图会部分加载甚至未加载。
正如我从一开始就知道我要放大的所有边界,我想提前 ajax 调用以下载所有有用的图块图像(在任何动画开始之前)以确保当我需要它们时,它们在浏览器缓存中。
我搜索了很多,但没有找到从 Leaflet 边界获取图块 URL 列表的方法。有没有办法在已知边界和缩放级别的浏览器缓存中手动加载图块?
解决方案 感谢 YaFred 的回答:
这是预加载 "mypolyline" 附近的图块并填充 20% 的代码:
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;
}
}
它结合了他的两个答案。当动画为 运行 时,我现在可以为下一个动画预加载图块。它的效果非常好。
一题有2题:
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))); }
然后,它会计算哪些图块在边界内。