天天看點

python擷取bing地圖釋出自己的TMS服務(一)下載下傳瓦片

QuadKey簡介,如何計算quadkey,在給定level下,把行号tileY和列号tileX轉換為2進制,然後行列交叉存儲,再轉換為4進制,即得到了相應的quadkey。quadkey的優點:四鍵具有幾個有趣的屬性。首先,四鍵的長度(位數)等于相應圖塊的詳細程度。其次,任何圖塊的四鍵以其父圖塊(上一級包含的圖塊)的四鍵開頭。如下例所示,圖塊2是圖塊20到23的父級,圖塊13是圖塊130到133的父級:思路根據選擇的區域計算四鍵,建構下載下傳連結,使用python requests下載下傳影像瓦片。

部分結果

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之家小專欄

文章尾部提供源代碼下載下傳,對本專欄感興趣的話,可以關注一波

GIS之家作品店鋪:GIS之家作品店鋪

GIS之家源碼咨詢:GIS之家webgis入門開發系列demo源代碼咨詢

繼續閱讀