文章目录
相关文献
离线地图下载
我们使用 Offline Map Maker 进行地图下载。
特别注意:Folium 默认支持 WGS84 坐标系,建议下载 WGS84 坐标系的地图(比如高德、谷歌等),而类似百度地图(BD09 坐标系)默认不支持。

由于此软件收费较贵,也可以通过如下链接下载(注意网站是否允许爬虫)。
!TIP
Gaode base map with areas roads labels buildings (China)
pythonimport 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, True except Exception as e: print(f"下载失败: {url}, 错误: {e}") return url, False def 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 results def 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 ** zoom xtile = 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 / 60 right_lon = 114 + 18 / 60 top_lat = 22 + 35 / 60 bottom_lat = 22 + 8 / 60 from_zoom = 9 to_zoom = 18 i = 0 url_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 使用离线地图
python
import folium
offline_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')
