OSMnx 主要关注于从OpenStreetMap下载地理数据并构建路网图,没有内置计算等时线的功能。但是可以利用 OSMnx 获取的路网数据与 networkx结合,通过OSMnx 构建的路网图G,再利用 networkx 的最短路径算法来估计旅行时间,可以计算出从某一起点到图中所有其他点的最短路径,或者在限定时间内可到达的所有地点。为了计算等时线,可以选择一个或多个中心点,然后确定一系列时间间隔(如5分钟、10分钟等),对每个时间间隔应用算法,找出在此时间内能够到达的所有地点集合。
完整代码#运行环境 Python 3.11
# 导入必要的库
import geopandas as gpd # 用于处理地理空间数据
import matplotlib.pyplot as plt # 用于绘图和可视化
import networkx as nx # 用于创建和操作复杂网络
import osmnx as ox # 用于获取和分析开源街道地图数据
from shapely.geometry import LineString, Point, Polygon # 用于创建几何对象
# 配置分析参数
place = "Siming Qu, Xiamen,Fujian,China" # 分析地点:中国福建省厦门市思明区
network_type = "walk" # 网络类型:步行
trip_times = [5, 10, 15, 20, 25] # 感兴趣的旅行时间(分钟)
travel_speed = 4.5 # 行走速度(千米/小时)
# 使用osmnx获取指定地点的步行网络图
G = ox.graph_from_place(place, network_type=network_type)
# 定义一个自定义经纬度点,作为等时线中心
custom_longitude, custom_latitude = 118.074649, 24.456570
# 找到网络中最接近该经纬度的节点
center_node = ox.distance.nearest_nodes(G, custom_longitude, custom_latitude)
# 将网络投影到UTM坐标系,以便于距离计算
G = ox.project_graph(G)
# 为网络中的每条边添加旅行时间属性,基于给定的行走速度
meters_per_minute = travel_speed * 1000 / 60
for _, _, _, data in G.edges(data=True, keys=True):
data["time"] = data["length"] / meters_per_minute
# 为每个旅行时间生成等时线多边形
isochrone_polys = [] # 存储等时线多边形
for trip_time in sorted(trip_times, reverse=True): # 逆序遍历旅行时间,从最大开始
# 创建以中心节点为中心,旅行时间为半径的子图
subgraph = nx.ego_graph(G, center_node, radius=trip_time, distance="time")
# 提取子图所有节点的坐标并转换为Point对象
node_points = [Point((data["x"], data["y"])) for node, data in subgraph.nodes(data=True)]
# 合并所有点为一个GeoSeries,然后计算其凸包得到等时线多边形
bounding_poly = gpd.GeoSeries(node_points).unary_union.convex_hull
isochrone_polys.append(bounding_poly)
# 将等时线多边形转换为GeoDataFrame
gdf = gpd.GeoDataFrame(geometry=isochrone_polys)
# 设置matplotlib的字体,以便支持中文显示
plt.rcParams['font.sans-serif'] = ['SimHei'] # 使用黑体
plt.rcParams['axes.unicode_minus'] = False # 正确显示负号
# 绘制底图
fig, ax = ox.plot_graph(G, show=False, close=False, edge_color="#999999", edge_alpha=0.2, node_size=0, figsize=(10, 10))
# 创建颜色映射,为不同的等时线分配颜色
cmap = plt.cm.plasma
colors = [cmap(i / len(trip_times)) for i in range(len(trip_times))]
# 在底图上绘制等时线多边形,并为每个等时圈添加标签
for idx, poly in enumerate(isochrone_polys):
gpd.GeoSeries([poly]).plot(ax=ax, color=colors[idx], edgecolor="none", alpha=0.6, label=f"{trip_times[idx]}分钟")
# 添加图例
legend_patches = [plt.Rectangle((0, 0), 1, 1, fc=color) for color in colors]
# 生成倒序的标签列表(这里不知道什么原因输出的标签是反的,所以增加了个倒序调整)
reversed_labels = [f"{t}分钟" for t in reversed(trip_times)]
# 添加图例,使用倒序的标签列表
ax.legend(handles=legend_patches, labels=reversed_labels, title="等时圈", loc='upper right', bbox_to_anchor=(1, 1))
# 保存绘制的地图为图片文件
output_image_path = "siming_qu_isochrones.png"
plt.savefig(output_image_path, dpi=300, bbox_inches='tight')
# 显示绘制的地图
plt.show()
# 输出保存路径信息
print(f"等时线地图已保存至: {output_image_path}")
等时圈结果如下图,并保存为png,可以通过调整出发坐标点、和所在地方路网来调整数据;
place = "Siming Qu, Xiamen,Fujian,China" # 路网
custom_longitude, custom_latitude = 118.074649, 24.456570 #出发坐标点
通行方式也可以选择,包括步行、骑车、驾驶;
network_type = "walk" # 'bike','drive'
通行时间分级,和通行时间也可以相应调整;
trip_times = [5, 10, 15, 20, 25] # 感兴趣的旅行时间(分钟)
travel_speed = 4.5 # 行走速度(千米/小时)
文章仅用于分享个人学习成果与个人存档之用,分享知识,如有侵权,请联系作者进行删除。所有信息均基于作者的个人理解和经验,不代表任何官方立场或权威解读。