如何用Python批量下载卫星地图
这篇文章是我17年写的。
前言
作为城乡规划的学生,有时需要某一个城市片区的卫星地图作为设计作业的底图,地图从何来?百度?高德?谷歌?但是它们都只提供了浏览的服务啊。市面上倒是有不少自动的地图下载器。什么Bigemap啊、水经注啊、91卫图,啥的,但是它们都不是完全免费的(免费版有水印),想要授权就要帮它们推广或者花钱买。蛋疼。。。
然而作为会编程的人,怎么能让这种事情难住?
网上有不少文章分析了地理坐标系、投影坐标系的原理,还有各大地图网站瓦片的分割方式,也有提供下载的网址,只要把瓦片坐标系和缩放级别填到指定的位置,就可以下载到地图的瓦片。
参考文章如下:
客户端地图拼图算法解析
WGS84经纬度坐标与web墨卡托之间的转换【转】
国内主要地图瓦片坐标系定义及计算原理
Google 地图切片URL地址解析
腾讯与百度地图瓦片规则分析
看了这些文章以后,就会理解网络地图的分片原理,并且知道在浏览器中,是可以看到这些瓦片的地址的,只要我们知道从经纬度到瓦片坐标的转换方法,就可以在已知经纬度范围的情况下,下载这一范围内的地图。
谷歌地图
对于坐标偏移问题,国内的经纬度坐标在WGS-84的基础上经过了一些偏移(不是单纯的线性,但是在一定范围内长度面积什么的还是不会变形的,不然国内地图怎么导航?),也就是在高德等地图上采集到的坐标并不是WGS-84的坐标,而是GCJ-02坐标。在参考文章中用的谷歌的源就是国内的源(.cn结尾嘛)。不过对于当底图来看就够用了,实测应该使用http://www.google.cn/maps/采集到的经纬度来进行下载前的坐标获取。
难道瓦片坐标也进行了相应的偏移?
再次详细试验,发现gl参数决定了卫星图是否会偏移。
假设不加这个参数,会按WGS-84来,会和路线图有偏移(因为路线图只有GCJ-02的版本)
加了这个参数(gl=CN)就会使卫星图也变成GCJ-02。
也就是说,如果你使用www.google.cn/maps或者ditu.google.cn来获取坐标,那么最后你还按照这个坐标进行瓦片的获取,同时加上gl参数即可。如果你想按照WGS-84来获取坐标,那么就访问国际版的谷歌地图
,获取瓦片时不加gl参数就好了。
瓦片参数解析:http://mt{index}.google.com/vt/lyrs={style}&hl=zh-CN&gl=CN&src=app&x={x}&y={y}&z={z}"
{index}为0到3,分别为谷歌的4个服务器,随便取一个就行~
{style}为地图的类型,比如卫星图、路线图什么的.
m:路线图
t:地形图
p:带标签的地形图
s:卫星图
y:带标签的卫星图
h:标签层(路名、地名等)
其中m路线图和s卫星图是我们想要的。
{x}{y}{z} 则分别是瓦片坐标的xy和缩放级别z,z取0-22。但是我测试发现卫星图最大只能取到20。不过即使是路线图,到20级也就足够用了。
对于python3,可以用urllib.request库进行图片的下载,然后用PIL.Image库(pillow)进行图片的合并。
如果想下载快一些,还可以使用多线程。
高德地图
高德地图的坐标是GCJ-02坐标(国内的所有地图都是,有的还进行了二次加偏)
至于怎么在高德地图上看坐标:高德地图怎么看经纬度
还是谷歌方便啊,直接地址栏就有,汗。。。。
高德的瓦片分割方式和谷歌的一样。
这里是瓦片的下载网址:http://wprd03.is.autonavi.com/appmaptile?style=7&x=427289&y=227618&z=19
经过我的测试
style=7是路线图,6的话是卫星图。其他就不知道了。
实际测试中style=8好像是单独的路线层,背景为透明,结合ltype参数还有不同效果,这个以后可以慢慢摸索。我只下载最基本的图,这里就不深入讨论了。不过也基本够用了。一般不也就要这两个这吗?
x和y自然就是瓦片的坐标,z自然是缩放级别了。高德的z取值范围是[1,19]。不过卫星图实测只能取到18。
wprd03想必是和谷歌一样,有多个服务器提供服务。测试下来可以取到01 到 04。
也就是说,把同样的xyz从谷歌地图(中国版)填到高德里面,可以得到同一块地方的瓦片!
百度地图等
从资料看,百度的坐标在GCJ-02的基础上二次加偏形成了BD-09。百度的瓦片分割方式也和高德谷歌不一样,处理起来略麻烦,就不管了~~
腾讯地图则是瓦片坐标原点在左下角,而谷歌在左上角。xy的输入方式是进行一定的编码。
好麻烦。。。感觉有俩就够用了,其他的就不管了。
源代码参见我的Github项目
https://github.com/modyuan/getmap