部分结果
bing地图瓦片使用QuadKey作为命名方式。
QuadKey简介
如何计算quadkey
在给定level下,把行号tileY和列号tileX转换为2进制,然后行列交叉存储,再转换为4进制,即得到了相应的quadkey。
quadkey的优点
四键具有几个有趣的属性。首先,四键的长度(位数)等于相应图块的详细程度。其次,任何图块的四键以其父图块(上一级包含的图块)的四键开头。如下例所示,图块2是图块20到23的父级,图块13是图块130到133的父级:
思路
根据选择的区域计算四键,构建下载链接,使用python requests下载影像瓦片。
# -*- coding: utf-8 -*- """下载区域影像 从第一层到指定层 """ import requests import os.path import QuadKey.quadkey as quadkey import shutil import secrets as secrets # 下载的最细层 tileZoom = 5 rootTileDir = "tiles_cache" lat_min = -90 lat_max = 90 lon_min = -180 lon_max = 180 # MS doesn't want you hardcoding the URLs to the tile server. This request asks for the Aerial # url template. Replace {quadkey} response = requests.get("https://dev.virtualearth.net/REST/V1/Imagery/Metadata/Aerial?key=%s" % (secrets.bingKey)) # 返回结果 data = response.json() print(data) # grabs the data we need from the response. # 例如:http://ecn.{subdomain}.tiles.virtualearth.net/tiles/a{quadkey}.jpeg?g=7786 tileUrlTemplate = data['resourceSets'][0]['resources'][0]['imageUrl'] # 例如:['t0', 't1', 't2', 't3'] imageDomains = data['resourceSets'][0]['resources'][0]['imageUrlSubdomains'] if (os.path.exists(rootTileDir) == False): os.mkdir(rootTileDir) bingTilesDir = os.path.join(rootTileDir, "bing") if (os.path.exists(bingTilesDir) == False): os.mkdir(bingTilesDir) def get_tiles_by_pixel(tilePixel): """ 下载该点之上的瓦片 :param lat: :param lon: :return: """ """get pixel coordinates""" # tilePixel = quadkey.TileSystem.geo_to_pixel((lat, lon), tileZoom) # print(tilePixel) pixel = tilePixel geo = quadkey.TileSystem.pixel_to_geo(pixel, tileZoom) # 计算四键 qk = quadkey.from_geo(geo, tileZoom) # 四键 qkStr = str(qk) # qkArray = [] for index in range(tileZoom): qkArray.append(qkStr[0:index + 1]) print(qkArray) # 存放路径 for qk in qkArray: # 下载影像 tileFileName = "%s/%s.jpg" % (bingTilesDir, qk) if (os.path.exists(tileFileName)): # already downloaded ok = 1 else: print("下载中", end='') url = tileUrlTemplate.replace("{subdomain}", imageDomains[0]) url = url.replace("{quadkey}", qk) url = "%s&key=%s" % (url, secrets.bingKey) response = requests.get(url, stream=True) print(response) with open(tileFileName, 'wb') as out_file: shutil.copyfileobj(response.raw, out_file) del response neededTile = True # 左上为原点 tilePixelMax = quadkey.TileSystem.geo_to_pixel((lat_max, lon_max), tileZoom) tilePixelMin = quadkey.TileSystem.geo_to_pixel((lat_min, lon_min), tileZoom) print(tilePixelMax) print(tilePixelMin) for x in range(tilePixelMin[0], tilePixelMax[0], 256): for y in range(tilePixelMax[1], tilePixelMin[1], 246): get_tiles_by_pixel((x, y)) # get_tiles(lat_max, lon_max) # get_tiles(lat_max, lon_min) # get_tiles(lat_min, lon_max) # get_tiles(lat_min, lon_min) print('下载完毕')
接下来要做的事
- 大量瓦片的有效管理(因为数据量巨大,查询移动很不方便。有兴趣可以计算一下这个量有多大)
- python发布tms服务
- 瓦片拼接成tif等格式
更多的详情见小专栏文章:GIS之家小专栏
文章尾部提供源代码下载,对本专栏感兴趣的话,可以关注一波