一种Python爬取百度地图瓦片的方式

瓦片是互联网地图webGIS组织地图数据的一种方式,最近的一个项目需要获取一定区域内的百度地图瓦片;ArcGIS的一个插件ArcBruTile支持很多地图源(如OSM、Bing)的瓦片获取,但是没有百度地图的,Github上的一些项目(如pyMap)也不支持百度瓦片的下载,
因此打算自己去获取。开始是想用百度API的静态图服务,但是我只有一个区域的边界矩形(MBR),而它接受的参数是中心点坐标和zoom的尺度,其请求URL的核心参数为center=116.403,39.914&width=1024&height=1024&zoom=11,要分块下载很麻烦,想了很多办法去算坐标和进行坐标距离换算,走了一些弯路,后来发现百度地图有一个隐晦的支持参数为x,y,z的调用,而x,y的变化是比较有规律的,因此只需要有边界的x和y再叠加就行。我是下载区域内的小图片再拼接为大图使用的,最后有上万张小图片,合并为一个200多MB的大图。

下载下来的瓦片

具体实现过程如下:

1,获取图片

百度坐标拾取系统网页,先按F12调出控制台,用坐标反查定位到左下坐标,并且调好层级,我要用的是17级的地图,然后找到一张图片手动确定x1和y1;(虽然有逻辑可以根据坐标和层级算x和y,但百度地图版的实现起来还是费些时间的,我没找到现成的代码,如果读者有发现或写过实现这个功能的代码欢迎在评论里告知,非常感谢),再定位到边界的右上角,同样确定好x2,y2,然后用requests库写获取图片的代码,比较建议先定y,改x,我用先循环y的方式保存的图片合并起来更复杂些,循环下去;可以得到整个区域的图片;

百度坐标拾取系统采用瓦片底图

(先验知识:百度地图的瓦片是从左下角算的,而不是Google Map的左上角开始;)

import requests
#from PIL import Image

def getTileByXYZ(): #根据x,y,z参数获取瓦片
    z=17
    xidx=[22568,22676]
    yidx=[6898,7008]
    for y in range(yidx[0],yidx[1]+1):
        for x in range(xidx[0],xidx[1]+1):
            url="http://online3.map.bdimg.com/tile/?qt=tile&x={x}&y={y}&z=17&styles=pl" \
                "&scaler=1&udt=20180601".format(x=x,y=y)
            savePngByXYZ(url, x, y, z)
        print(y)
        
def savePngByXYZ(url,x,y,z=17): #保存图片
    r = requests.get(url)
    sname="./cdZoomImg/cd_{x}_{y}.png".format(x=x,y=y) #这里建议保存编码是y_x 这样下面合并图片也要适当改代码
    with open(sname, 'ab') as pngf:
        for chunk in r.iter_content(chunk_size=1024):
            if chunk:
                pngf.write(chunk)
                pngf.flush()

2,合并瓦片

一共爬了1万多张瓦片,花了40多分钟(这个要看计算机性能),每张瓦片是256*256像素的方形区域;接下来就是合并的过程了,本来打算一次性合并完毕,但是弄得电脑内存不足了,于是先合并x相同的图片到另一个文件夹,形成一个个长条形的图片,每张尺寸变成了256*28672像素,再跑一遍把这些图片合并到一起,就形成了一张27648*28672的地图图片,可以用来作为ArcGIS一些空间分析的底图。


逐步合并瓦片
import os
import glob
from PIL import Image

def complieImg():
    #命名规则:cd_x_y.png 左下坐标系
    #同一个x 同1列,y增加,图片在上面
    #假设输入排好序了
    p = "./chengduImg" 
    plst = glob.glob(os.path.join(p, '*.png'))

    xmin=((plst[0].split("\\")[1]).split(".")[0]).split('_')[1]
    alst=[] #3维
    qlst=[]
    for f in plst:
        w=((f.split("\\")[1]).split(".")[0]).split('_') #['cd', '22568', '6898']
        w[0] = f
        if w[1]==xmin:
            qlst.append(w.copy())
        else:
            alst.append(qlst.copy())
            xmin=w[1]
            qlst=[]
    m2 = [256*len(alst[0]), 256 * len(alst)]
    #im2=Image.new('RGBA', (m2[0], m2[1]))
    print(m2)
    psave = "./complexLevel"
    iw=0
    for k in alst:#k里面装的是x相同的值,y应该递增
        plen=len(k)
        msize = [256, 256 * (plen+1)]
        print(msize)
        toImage = Image.new('RGBA', (msize[0], msize[1]))
        for i in range(plen):
            fromImage = Image.open(k[plen - i - 1][0])
            toImage.paste(fromImage, (0 * msize[0], i * msize[0]))

        sname="/m_{x}.png".format(x=k[0][1])
        iw+=1
        
        toImage.save(psave+sname)

    


def complieImgInY():
    #合并长条形图片,x变化,y不变 长图是complieImg()里生成的
    p = "./complexLevel" #chengduImg
    plst = glob.glob(os.path.join(p, '*.png'))

    xmin=((plst[0].split("\\")[1]).split(".")[0]).split('_')[1]
    ima21=Image.open(plst[0])
    w=np.array(ima21).shape
    print(w)
    psave = "D:/wexcel"
    plen=len(plst)
    msize = [w[1]*plen/2, w[0]/2]
    print(msize)
    toImage = Image.new('RGBA', (int(msize[0]), int(msize[1])))
    for i in range(plen):
        fromImage = Image.open(plst[i])
        fromImage=fromImage.resize((int(256/2),int(msize[1])), Image.ANTIALIAS)
        toImage.paste(fromImage, (int(i * 256/2), 0))

    sname="/chengduMap.png"

    toImage.save(psave+sname) #保存图片


最后得到一张200多MB的整合图片。最后代码更新于github_QLWeilcf

OutputImg

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,692评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,482评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,995评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,223评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,245评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,208评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,091评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,929评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,346评论 1 311
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,570评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,739评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,437评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,037评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,677评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,833评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,760评论 2 369
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,647评论 2 354

推荐阅读更多精彩内容