python腳本實(shí)現(xiàn)下載高德離線底圖瓦片并使用
在內(nèi)網(wǎng)環(huán)境中開(kāi)發(fā),無(wú)法使用高德在線瓦片服務(wù),需要下載到本地或者部署到內(nèi)網(wǎng)服務(wù)器中進(jìn)行使用,如何下載離線瓦片呢,可以使用python腳本進(jìn)行
以下是完整代碼
import math # 新增這行,導(dǎo)入math模塊
import requests
import os
from PIL import Image
from urllib.parse import quote
import time
# 高德瓦片下載配置
class AmapTileDownloader:
def __init__(self, save_path='amap_tiles', zoom_range=(1, 18)):
"""
初始化下載器
:param save_path: 瓦片保存根路徑
:param zoom_range: 縮放級(jí)別范圍(高德瓦片縮放級(jí)1-18)
"""
self.save_path = save_path
self.zoom_range = zoom_range
# 高德瓦片服務(wù)地址(矢量底圖,可替換為衛(wèi)星圖)
# 矢量底圖:http://webrd0{1-4}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}
# 衛(wèi)星底圖:http://webst0{1-4}.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}
self.tile_url_template = "http://webrd0{server}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}"
# 服務(wù)節(jié)點(diǎn)(避免單節(jié)點(diǎn)請(qǐng)求頻繁被限制)
self.servers = [1, 2, 3, 4]
self.headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'
}
def mercator2tile(self, lon, lat, zoom):
"""
經(jīng)緯度轉(zhuǎn)瓦片坐標(biāo)(墨卡托投影)
:param lon: 經(jīng)度
:param lat: 緯度
:param zoom: 縮放級(jí)別
:return: x, y 瓦片坐標(biāo)
"""
lat_rad = lat * 3.141592653589793 / 180.0
n = 2.0 ** zoom
x = int((lon + 180.0) / 360.0 * n)
y = int((1.0 - (math.log(math.tan(lat_rad) + (1 / math.cos(lat_rad)))) / math.pi) / 2.0 * n)
return x, y
def download_tile(self, x, y, z, server=1):
"""
下載單個(gè)瓦片
:param x: 瓦片x坐標(biāo)
:param y: 瓦片y坐標(biāo)
:param z: 縮放級(jí)別
:param server: 服務(wù)節(jié)點(diǎn)(1-4)
:return: 是否下載成功
"""
# 拼接瓦片URL
tile_url = self.tile_url_template.format(server=server, x=x, y=y, z=z)
# 構(gòu)建保存路徑:根路徑/縮放級(jí)別/x坐標(biāo)/y坐標(biāo).png
tile_save_path = os.path.join(self.save_path, str(z), str(x))
os.makedirs(tile_save_path, exist_ok=True)
tile_file = os.path.join(tile_save_path, f"{y}.png")
# 避免重復(fù)下載
if os.path.exists(tile_file):
print(f"瓦片 {z}/{x}/{y} 已存在,跳過(guò)")
return True
try:
# 發(fā)送請(qǐng)求(添加超時(shí)和重試)
response = requests.get(tile_url, headers=self.headers, timeout=10)
response.raise_for_status() # 拋出HTTP錯(cuò)誤
# 保存瓦片
with open(tile_file, 'wb') as f:
f.write(response.content)
# 校驗(yàn)圖片是否有效
try:
img = Image.open(tile_file)
img.verify()
print(f"成功下載:{z}/{x}/{y}")
return True
except:
os.remove(tile_file)
print(f"瓦片無(wú)效,已刪除:{z}/{x}/{y}")
return False
except Exception as e:
print(f"下載失敗 {z}/{x}/{y}:{str(e)}")
return False
def download_area(self, min_lon, min_lat, max_lon, max_lat):
"""
下載指定經(jīng)緯度范圍的瓦片
:param min_lon: 最小經(jīng)度
:param max_lon: 最大經(jīng)度
:param min_lat: 最小緯度
:param max_lat: 最大緯度
"""
import math # 延遲導(dǎo)入,避免初始化時(shí)依賴
print(f"開(kāi)始下載范圍:[{min_lon},{min_lat}] - [{max_lon},{max_lat}]")
print(f"縮放級(jí)別范圍:{self.zoom_range[0]} - {self.zoom_range[1]}")
for z in range(self.zoom_range[0], self.zoom_range[1] + 1):
# 計(jì)算范圍對(duì)應(yīng)的瓦片坐標(biāo)
min_x, min_y = self.mercator2tile(min_lon, max_lat, z) # 注意lat反轉(zhuǎn)
max_x, max_y = self.mercator2tile(max_lon, min_lat, z)
print(f"\n縮放級(jí)別 {z}:瓦片范圍 x[{min_x}-{max_x}], y[{min_y}-{max_y}]")
server_idx = 0 # 輪詢服務(wù)節(jié)點(diǎn)
# 遍歷所有瓦片坐標(biāo)
for x in range(min_x, max_x + 1):
for y in range(min_y, max_y + 1):
# 輪詢服務(wù)節(jié)點(diǎn)
server = self.servers[server_idx % len(self.servers)]
server_idx += 1
# 下載瓦片(添加小延遲,避免請(qǐng)求過(guò)快被限制)
self.download_tile(x, y, z, server)
time.sleep(0.1) # 可根據(jù)實(shí)際情況調(diào)整
print("\n所有瓦片下載完成!")
# ------------------- 示例使用 -------------------
if __name__ == "__main__":
# 初始化下載器:保存路徑+縮放級(jí)別(建議先測(cè)試1-10級(jí),級(jí)別越高瓦片越多)
downloader = AmapTileDownloader(save_path='amap_tiles', zoom_range=(1, 10))
# 下載指定區(qū)域(示例:北京市中心經(jīng)緯度范圍,可替換為自己需要的區(qū)域)
# 經(jīng)緯度可從高德地圖拾?。篽ttps://lbs.amap.com/console/show/picker
min_lon, min_lat = 116.30, 39.80 # 左下角經(jīng)緯度
max_lon, max_lat = 116.50, 40.00 # 右上角經(jīng)緯度
downloader.download_area(min_lon, min_lat, max_lon, max_lat)以上測(cè)試代碼下載的是北京市中心偏南部的核心區(qū)域離線瓦片服務(wù)
具體結(jié)構(gòu)如下圖所示:

如何驗(yàn)證離線瓦片是否可用呢?
可以快速創(chuàng)建一個(gè)html文件,使用leafle 引入./amap_tiles/{z}/{x}/{y}.png下載的離線瓦片快速實(shí)現(xiàn)一個(gè)基礎(chǔ)地圖展示,代碼如下
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>Leaflet加載高德離線瓦片</title>
<!-- 引入Leaflet的CSS和JS(在線CDN) -->
<link rel="stylesheet" rel="external nofollow" />
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
<!-- 引入高德坐標(biāo)系適配插件(解決偏移問(wèn)題) -->
<script src="https://unpkg.com/leaflet.gridlayer.ChinaProvider@1.0.2/dist/leaflet.ChineseTmsProviders.js"></script>
<style>
/* 讓地圖占滿整個(gè)頁(yè)面 */
#map {
width: 100vw;
height: 100vh;
margin: 0;
padding: 0;
}
</style>
</head>
<body>
<div id="map"></div>
<script>
// 1. 初始化地圖(中心點(diǎn)設(shè)為你下載的區(qū)域,這里是北京)
var map = L.map('map', {
// 禁用地圖縮放超出瓦片范圍
minZoom: 1,
maxZoom: 10, // 對(duì)應(yīng)你下載的最大縮放級(jí)別
zoomControl: true // 顯示縮放控件
}).setView([39.908823, 116.397470], 8); // 中心點(diǎn)經(jīng)緯度+初始縮放級(jí)別
// 2. 加載本地高德離線瓦片
L.tileLayer('./amap_tiles/{z}/{x}/{y}.png', { // 對(duì)應(yīng)瓦片目錄結(jié)構(gòu)
attribution: '高德離線瓦片', // 地圖版權(quán)說(shuō)明
tileSize: 256, // 高德瓦片默認(rèn)尺寸256x256
noWrap: true, // 禁止地圖水平循環(huán)
// 瓦片加載失敗時(shí)顯示的占位圖
errorTileUrl: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAIElEQVQ4T2NkYGAQYcAP3uCTZhw1gGGYhAGBZIA/nYDCgBDAm9BGDWAAJyRCgLaBCAAgXwixzAS0pgAAAABJRU5ErkJggg=='
}).addTo(map);
// 可選:添加比例尺控件
L.control.scale({
imperial: false, // 不顯示英制單位
maxWidth: 200
}).addTo(map);
</script>
</body>
</html>在本地服務(wù)中運(yùn)行html文件:

到此這篇關(guān)于python腳本實(shí)現(xiàn)下載高德離線底圖瓦片并使用的文章就介紹到這了,更多相關(guān)python下載高德離線瓦片內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
使用python獲取csv文本的某行或某列數(shù)據(jù)的實(shí)例
下面小編就為大家分享一篇使用python獲取csv文本的某行或某列數(shù)據(jù)的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-04-04
基于python實(shí)現(xiàn)藍(lán)牙通信代碼實(shí)例
這篇文章主要介紹了基于python實(shí)現(xiàn)藍(lán)牙通信代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-11-11
Python?MCPInspector調(diào)試思路詳解
這篇文章主要介紹了Python?MCPInspector調(diào)試思路詳解,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2025-05-05
Anaconda3中的Jupyter notebook添加目錄插件的實(shí)現(xiàn)
這篇文章主要介紹了Anaconda3中的Jupyter notebook添加目錄插件的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-05-05
Python如何把Spark數(shù)據(jù)寫(xiě)入ElasticSearch
這篇文章主要介紹了Python如何把Spark數(shù)據(jù)寫(xiě)入ElasticSearch,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-04-04
利用python實(shí)現(xiàn)簡(jiǎn)單的循環(huán)購(gòu)物車功能示例代碼
購(gòu)物車對(duì)我們每位開(kāi)發(fā)者來(lái)說(shuō)應(yīng)該都不陌生,下面這篇文章主要給大家介紹了利用python實(shí)現(xiàn)簡(jiǎn)單的循環(huán)購(gòu)物車功能的相關(guān)資料,文中給出了詳細(xì)的示例代碼供大家參考學(xué)習(xí),需要的朋友們下面來(lái)一起看看吧。2017-07-07

