文章目錄
- 相關文獻
- 離線地圖下載
- Folium 使用離線地圖
相關文獻
- Folium — Folium 0.19.5 documentation
- Offline Map Maker
離線地圖下載
我們使用 Offline Map Maker 進行地圖下載。
特別注意:Folium 默認支持 WGS84 坐標系,建議下載 WGS84 坐標系的地圖(比如高德、谷歌等),而類似百度地圖(BD09 坐標系)默認不支持。
由于此軟件收費較貴,也可以通過如下鏈接下載(注意網站是否允許爬蟲)。
[!TIP]
Gaode base map with areas roads labels buildings (China)
http://wprd01.is.autonavi.com/appmaptile?lang=zh_cn&style=7<ype=7&scl=0&size=0&x=417&y=222&z=9
import glob import shutil import math import os import requests from concurrent.futures import ThreadPoolExecutor, as_completed# 下載單個URL的函數 def download_url(url, filename):try:print(f"開始下載: {url}")response = requests.get(url, timeout=10)with open(filename, 'wb') as f:f.write(response.content)print(f"下載完成: {url} -> 保存為 {filename}")return url, Trueexcept Exception as e:print(f"下載失敗: {url}, 錯誤: {e}")return url, Falsedef save_file_with_directories(file_path, content):"""自動創建路徑中的所有目錄,并保存文件內容。:param file_path: 文件路徑,例如 'a/b/c.png':param content: 要寫入的內容(二進制或文本)"""# 獲取文件所在目錄directory = os.path.dirname(file_path)# 如果目錄不為空,則創建目錄(exist_ok=True 表示目錄存在也不會報錯)if directory:os.makedirs(directory, exist_ok=True)# 寫入文件(以二進制方式為例)with open(file_path, 'wb') as f:f.write(content)# 多線程下載器 def multi_thread_download(urls, filenames, output_dir='downloads', max_workers=5):if not os.path.exists(output_dir):os.makedirs(output_dir)futures = []results = []with ThreadPoolExecutor(max_workers=max_workers) as executor:for i, (url, filename) in enumerate(zip(urls, filenames)):filename = os.path.join(output_dir, filename)future = executor.submit(download_url, url, filename)futures.append(future)for future in as_completed(futures):result = future.result()results.append(result)return resultsdef deg2num(lat_deg, lon_deg, zoom):"""根據給定的緯度、經度和縮放級別計算瓦片的X和Y坐標。參數:lat_deg (float): 緯度lon_deg (float): 經度zoom (int): 縮放級別返回:tuple: 包含X和Y坐標的元組"""lat_rad = math.radians(lat_deg)n = 2.0 ** zoomxtile = int((lon_deg + 180.0) / 360.0 * n)ytile = int((1.0 - math.asinh(math.tan(lat_rad)) / math.pi) / 2.0 * n)return (xtile, ytile)def move_file(src_file, dest_file):"""將文件移動到指定路徑,如果路徑不存在則自動創建。:param src_file: 源文件路徑(需要移動的文件):param dest_file: 目標文件夾路徑"""# 獲取源文件的文件名filename = os.path.basename(src_file)# 獲取文件所在目錄directory = os.path.dirname(dest_file)# 如果目錄不為空,則創建目錄(exist_ok=True 表示目錄存在也不會報錯)if directory:os.makedirs(directory, exist_ok=True)# 移動文件shutil.move(src_file, dest_file)print(f"文件已從 '{src_file}' 移動至 '{dest_file}'")# 示例用法 if __name__ == "__main__":left_lon = 113 + 52 / 60right_lon = 114 + 18 / 60top_lat = 22 + 35 / 60bottom_lat = 22 + 8 / 60from_zoom = 9to_zoom = 18i = 0url_list = []filenames = []for zoom in range(from_zoom, to_zoom + 1):x_min, y_min = deg2num(top_lat, left_lon, zoom)x_max, y_max = deg2num(bottom_lat, right_lon, zoom)for x in range(x_min, x_max + 1):for y in range(y_min, y_max + 1):filename = f"{zoom}_{x}_{y}.png"url = f"http://wprd0{i + 1}.is.autonavi.com/appmaptile?lang=zh_cn&style=7<ype=7&scl=0&size=0&x={x}&y={y}&z={zoom}" # 高德地圖url_list.append(url)filenames.append(filename)i = (i + 1) % 4# 開始多線程下載multi_thread_download(url_list, filenames, max_workers=8)for source_file in glob.glob("downloads/*.png"):filename = os.path.basename(source_file)zoom, x, y = filename[:-4].split("_")target_folder = f"{zoom}/{x}/{y}.png"move_file(source_file, target_folder)
Folium 使用離線地圖
import foliumoffline_map_path = 'D:/offlinemaps/Gaode base map with areas roads labels buildings (China)/{z}/{x}/{y}.png' # 離線地圖文件路徑# 創建一個以香港為中心的地圖,zoom_start參數控制初始縮放級別
m = folium.Map(location=[22.5, 114],zoom_start=9,tiles=offline_map_path,attr='Gaode base map with areas roads labels buildings (China)'
)# 在地圖上添加一個標記,默認的標記類型是'Marker'
folium.Marker(location=[22.5, 114], # 標記的位置坐標popup='這里是香港', # 點擊標記時顯示的信息icon=folium.Icon(color='blue') # 標記的顏色
).add_to(m)# 將地圖保存為HTML文件
m.save('hk_map.html')