地铁系统对城市居民的日常通勤至关重要。地铁可达性,是指城市中各个位置到最近地铁站的便利程度,通常通过时间、距离或交通成本来衡量。高可达性意味着到达地铁站所需的时间越短、交通方式越便捷。它不仅直接影响城市居民的出行选择和通勤效率,也对城市规划、交通布局和可持续发展产生深远的影响。
本文以印度德里为例,详细介绍如何计算并可视化地铁站的可达性。我们将通过数据分析和3D地图展示,直观呈现德里不同区域到最近地铁站的交通便捷程度。
1. 加载库
首先,我们需要加载相关的Python库。这些库将帮助我们进行数据处理、可视化以及地铁站可达性的计算。我们使用的主要库有:
GeoPandas:用于处理地理数据。 OSMnx:用于获取道路网络数据。 Pandana:用于计算可达性。 H3:用于地理空间索引。 Pydeck:用于3D可视化。
import geopandas as gpd
import pandas as pd
import osmnx as ox
import shapely
import pandana as pdna
import h3
import pydeck as pdk
import json
import matplotlib.colors as mp_color
import matplotlib.cm as cmx
2. 数据收集与处理
1)研究区域内的道路网络
我们使用OSMnx库提取感兴趣区域的完整道路网络。道路网络由节点(表示网络的端点或连接点)和边(表示连接它们的路段)组成。以下是从 OSMNx 获取的道路网络示例图:
首先,定义边界范围,再从OpenStreetMap中提取该区域的道路网络:
# 定义边界范围
W, S, E, N = 76.9, 28.4, 77.5, 28.8
bbox = box(W, S, E, N)
# 获取道路网络
osm_network = ox.graph.graph_from_polygon(
bbox, network_type='all', simplify=True
)
2)地铁站点数据
为了计算可达性,我们需要德里区域内所有地铁站的位置信息:
data_url = r"https://github.com/kavyajeetbora/metro_accessibility/raw/master/data/delhi/Delhi_NCR_station_nodes.gpkg"
station_nodes = gpd.read_file(data_url, crs='EPSG:4326')
3)地铁路线数据
metro_line_url = r"https://github.com/kavyajeetbora/metro_accessibility/raw/master/data/delhi/Delhi_NCR_metro_lines.json"
metro_lines = pd.read_json(metro_line_url)
4)地铁站建筑足迹数据
data_url = r"https://raw.githubusercontent.com/kavyajeetbora/metro_accessibility/master/data/delhi/Delhi_NCR_station_buildings.gpkg"
station_buildings = gpd.read_file(data_url, crs='EPSG:4326')
3. 计算地铁可达性
加载了所有必要的数据后,我们将使用Pandana库计算德里区域中任何给定位置到最近地铁站的可达性。
1)创建Pandana网络
首先,将从OSMnx获取的道路网络转化为Pandana可处理的网络格式:
nodes, edges = ox.graph_to_gdfs(osm_network, nodes=True, edges=True)
edges = edges.reset_index()
network = pdna.Network(nodes["x"], nodes["y"], edges["u"], edges["v"], edges[["length"]])
2)计算可达性
通过Pandana库,我们可以计算网络中每个节点到最近地铁站的距离,并将距离值(以米为单位)分配给相应节点。以下代码展示了如何进行计算:
max_distance = 25000 # 最大距离,单位为米
num_pois = 1 # 最近的POI数量
category = 'metro_stations'
network.set_pois(
category=category, maxdist=max_distance, maxitems=num_pois,
x_col=station_nodes['geometry'].x, y_col=station_nodes['geometry'].y
)
accessibility = network.nearest_pois(distance=max_distance, category=category, num_pois=num_pois)
通过这段代码,计算得到每个节点到最近地铁站的距离数据。
def plot_nearest_amenity(accessibility,n):
fig, ax = network.plot(accessibility[n]);
ax.set_facecolor('k');
ax.set_title('Pedestrian accessibility to nearest Metro Stations in Delhi (distance to pois, in meters (n = {}))'.format(category,n), fontsize=14);
return fig
fig = plot_nearest_amenity(accessibility,num_pois)
4. 3D可视化地铁可达性
为了高效地展示整个德里区域的可达性,我们使用了H3空间索引,将所有节点距离聚合为六边形单元格,便于可视化。
APERTURE_SIZE = 9
hex_col = 'hex' + str(APERTURE_SIZE)
distance = nodes.join(accessibility)[['geometry', 1]].rename(columns={1: 'distance_m'})
distance[hex_col] = distance.apply(lambda p: h3.geo_to_h3(p.geometry.y, p.geometry.x, APERTURE_SIZE), 1)
distance_m = distance[[hex_col, 'distance_m']].groupby(hex_col).mean().reset_index()
为了让数据更具可读性,我们还将距离从“米”转换为“分钟”:
distance_m['mins'] = distance_m['distance_m'] / (20 * 16.6667) # 速度为20km/h
distance_m['display_text'] = distance_m['mins'].apply(lambda x: f"Accessibility: {x:.0f} mins")
进一步使用Pydeck库进行3D地图可视化。通过设置自定义的色彩映射,将不同的可达时间通过颜色直观展示。
自定义色彩映射函数:
def create_custom_cmap(values):
colors = ['#42f5da', '#7DDA58', '#DECE58', '#DE8758', '#DE5858']
cmap = mp_color.ListedColormap(colors)
boundaries = values
norm = mp_color.BoundaryNorm(boundaries, len(colors))
return cmap, norm
绘制3D地图:
我们将站点建筑足迹、地铁路线以及计算得到的可达性数据整合进地图中,并通过色彩显示每个区域到最近地铁站的可达时间:
station_layer = pdk.Layer(
'GeoJsonLayer', data=station_buildings, stoked=True, getLineColor=[158, 2, 38, 100],
filled=True, get_fill_color=[158, 2, 38, 100], extruded=True, get_elevation=30, pickable=True
)
route_layer = pdk.Layer(
'PathLayer', data=metro_lines, pickable=True, get_color='color', width_scale=1,
get_path="path", get_width=20
)
# 可视化可达性数据
cmap, norm = create_custom_cmap([0, 5, 10, 20, 40, distance_m['mins'].max()])
xdf = colormap_dataframe(df=distance_m, value_col='mins', cmap=cmap, norm=norm)
layer = create_h3_hex_layer(xdf)
# 设置视图
view_state = pdk.ViewState(latitude=28.6139, longitude=77.2090, zoom=11, bearing=0, pitch=45)
tooltip = {"html": "{display_text}", "style": {"backgroundColor": "#4CAF50", "color": "#FFFFFF"}}
# 渲染3D地图
r = pdk.Deck(layers=[station_layer, layer, route_layer], initial_view_state=view_state, tooltip=tooltip)
r.show()
结语
本文介绍了如何使用 Python 库来计算和可视化印度德里的地铁可达性。通过使用 OSMnx、Pandana、H3 和 Pydeck 等工具包,我们演示了从数据收集、可达性计算到 3D 可视化的完整流程。地铁可达性分析对于城市规划、交通管理和房地产评估具有重要意义。对居民而言,清晰的可达性数据可以用来辅助选择居住和工作地点,提升生活质量。