我正在使用Python和Cartopy创建一个地图应用程序,并尝试使用开源地图图块作为背景,以获得比默认的Cartopy地图更多的选项。
它非常适合……
该 “缩放”级别基于四叉树 。基本上增加“缩放”分辨率会使拼块数量增加四倍。
所以:
zoom level 0: 4^0 = 1 tile(s) to cover the globe zoom level 1: 4^1 = 4 tile(s) to cover the globe ... zoom level 7: 4^7 = 16,384 tile(s) to cover the globe ... zoom level 14: 4^14 = 268,435,456 tile(s) to cover the globe
因此,如果您要求大面积的高缩放级别的平铺,您最终可以请求 的 很多 强> 瓷砖。
在Tiler对象上有一个有用但未记录的方法 find_images 。它的实现不是太多毛: https://github.com/SciTools/cartopy/blob/v0.16.0/lib/cartopy/io/img_tiles.py#L103-L122 。
find_images
使用此方法,我们实际上可以看到将用于给定范围的切片。重要的是,范围需要在贴砖机的坐标系中提供(几乎完全是Web Mercator)。
In [1]: import cartopy.io.img_tiles as cimgt In [2]: import shapely.geometry as sgeom In [3]: import cartopy.crs as ccrs In [4]: tiler = cimgt.OSM() In [5]: pt = 45.068466, -66.45477 In [6]: target = sgeom.box(pt[0] - 1.5, pt[1] - 1.5, pt[0] + 1.5, pt[1] + 1.5) In [7]: target_mercator = tiler.crs.project_geometry(target, ccrs.Geodetic()).geoms[0]
因此,在所有部件到位的情况下,我们可以开始找出我们需要在特定缩放级别绘制的图块:
对于您指定的目标,在缩放级别0,我们需要以下切片 (x, y, z) :
(x, y, z)
In [8]: list(tiler.find_images(target_mercator, 0)) Out[8]: [(0, 0, 0)]
对于z = 1,它仍然只有一个图块:
In [9]: list(tiler.find_images(target_mercator, 1)) Out[9]: [(1, 1, 1)]
但是对于z = 2,我们明显越过了tile边界,因为我们现在需要两个tile来覆盖目标域:
In [10]: list(tiler.find_images(target_mercator, 2)) Out[10]: [(2, 2, 2), (2, 3, 2)] Naturally, the list grows as we increase the zoom level: In [11]: list(tiler.find_images(target_mercator, 3)) Out[11]: [(4, 5, 3), (5, 5, 3), (4, 6, 3), (5, 6, 3)] In [12]: list(tiler.find_images(target_mercator, 6)) Out[12]: [(39, 47, 6), (40, 47, 6), (39, 48, 6), (40, 48, 6)]
当我们达到z = 7时,我们发现我们需要8个图块来表示相关区域:
In [13]: list(tiler.find_images(target_mercator, 7)) Out[13]: [(79, 94, 7), (79, 95, 7), (80, 94, 7), (80, 95, 7), (79, 96, 7), (79, 97, 7), (80, 96, 7), (80, 97, 7)]
我相信你可以看到它的发展方向,但让我们尝试你的缩放级别14来找出我们需要多少个瓷砖。为节省电力和阅读时间,我们只需打印该列表的长度......
In [14]: len(list(tiler.find_images(target_mercator, 14))) Out[14]: 47334
是的,因此请求所需范围的缩放级别14需要您下载256x256(8位彩色图像PNG)的~47,000个图块。 z = 0平铺( https://a.tile.openstreetmap.org/0/0/0.png )压缩大约8882个字节,所以假设这是典型的,你最终会下载~420420588字节(400MB)。为了将这些数据保存在内存中,您还需要大约2.9GB的RAM。最后,要将这些数据重新投影到PlateCarree,你需要至少加倍这个数量的RAM,这就是假设一个高效的重投影实现(而不是cartopy)。
希望这能告诉你 为什么 你的代码似乎需要很长时间 - 你要求它做一个 批量 工作的。有一些讨论是关于当请求过多的瓷砖时是否应该警告纸箱,但它总是归结为一个不合理的数字(你可能实际上) 想 拿这么多瓷砖!)。我们还谈到了自动缩放级别选择 - 这就是它 真的可行 如果有足够的需求。
HTH