如何在Python(Jupyter Notebook)中展示伊朗地点的地图路线?
解决方案:无需付费API在Jupyter Notebook展示伊朗地点路线
针对你遇到的OSMnx无法生成路线的问题,大概率是默认Overpass API节点的访问限制或伊朗区域路网数据的获取问题。下面提供一套基于免费开源工具的可行方案,全程无需付费API:
步骤1:读取Excel中的经纬度数据
先用pandas加载你的Excel文件,确保经纬度格式正确:
import pandas as pd # 替换为你的Excel文件路径 df = pd.read_excel("iran_locations.xlsx") # 强制转换为数值类型,避免格式错误 df["纬度"] = pd.to_numeric(df["纬度"], errors="coerce") df["经度"] = pd.to_numeric(df["经度"], errors="coerce") # 过滤无效的经纬度数据 df = df.dropna(subset=["纬度", "经度"])
步骤2:解决路网获取问题(替代OSMnx默认方式)
推荐使用pyrosm直接下载/加载伊朗的OSM路网数据,比OSMnx更稳定:
安装依赖
pip install pyrosm networkx folium shapely
加载伊朗路网
import pyrosm import networkx as nx from shapely.geometry import Point # 首次运行会自动下载伊朗最新OSM数据(约几百MB),后续可加载本地文件 osm = pyrosm.OSM("iran-latest.osm.pbf") # 提取驾车路网(支持driving/walking/cycling三种类型) drive_network = osm.get_network(network_type="driving")
步骤3:计算地点间的最短路径
先给每个经纬度匹配路网中最近的节点,再用NetworkX计算最短路径:
def find_closest_node(graph, lat, lon): """找到离目标经纬度最近的路网节点""" target_point = Point(lon, lat) closest_node = None min_distance = float("inf") for node, attrs in graph.nodes(data=True): node_point = Point(attrs["x"], attrs["y"]) distance = target_point.distance(node_point) if distance < min_distance: min_distance = distance closest_node = node return closest_node # 给每个地点匹配最近节点 df["closest_node"] = df.apply(lambda row: find_closest_node(drive_network, row["纬度"], row["经度"]), axis=1) # 计算连续地点间的路径 routes = [] for i in range(len(df) - 1): start_node = df.iloc[i]["closest_node"] end_node = df.iloc[i+1]["closest_node"] try: # 按路径长度计算最短路径 route = nx.shortest_path(drive_network, start_node, end_node, weight="length") routes.append(route) except nx.NetworkXNoPath: print(f"⚠️ 无路径连接:{df.iloc[i]['地点名称']} → {df.iloc[i+1]['地点名称']}")
步骤4:在Jupyter中可视化路线
用folium生成交互式地图,直接在Notebook中展示:
import folium # 以第一个地点为地图中心 map_center = [df.iloc[0]["纬度"], df.iloc[0]["经度"]] m = folium.Map(location=map_center, zoom_start=8) # 添加地点标记 for _, row in df.iterrows(): folium.Marker( location=[row["纬度"], row["经度"]], popup=row["地点名称"], icon=folium.Icon(color="blue") ).add_to(m) # 添加路线 for route in routes: # 提取路线的经纬度坐标 route_coords = [(drive_network.nodes[node]["y"], drive_network.nodes[node]["x"]) for node in route] folium.PolyLine( locations=route_coords, color="red", weight=3, opacity=0.7 ).add_to(m) # 在Notebook中显示地图 m
备选方案:修复OSMnx的使用问题
如果你坚持用OSMnx,可以尝试切换Overpass API节点,解决访问限制:
import osmnx as ox # 替换为可用的Overpass备用节点 ox.config(overpass_endpoint="https://overpass.kumi.systems/api/interpreter") # 尝试获取指定区域的路网 G = ox.graph_from_point((35.6892, 51.3890), dist=10000, network_type="drive")
注意事项
- 伊朗部分偏远地区的OSM路网数据可能不完整,导致无法生成路径,属于数据本身的限制;
pyrosm下载的pbf文件可重复使用,下次运行直接加载本地文件即可;- 如果路径计算速度慢,可以考虑裁剪路网到你需要的区域,减少计算量。
内容的提问来源于stack exchange,提问作者Arman Alaei
相关产品推荐
相关产品推荐

