10分钟速成!教你计算地铁可达性并一键生成酷炫地图

科技   2024-11-04 17:55   广东  

引言

地铁系统对城市居民的日常通勤至关重要。地铁可达性,是指城市中各个位置到最近地铁站的便利程度,通常通过时间、距离或交通成本来衡量。高可达性意味着到达地铁站所需的时间越短、交通方式越便捷。它不仅直接影响城市居民的出行选择和通勤效率,也对城市规划、交通布局和可持续发展产生深远的影响。

本文以印度德里为例,详细介绍如何计算并可视化地铁站的可达性。我们将通过数据分析和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 获取的道路网络示例图:

img

首先,定义边界范围,再从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)
img

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()
img

结语

本文介绍了如何使用 Python 库来计算和可视化印度德里的地铁可达性。通过使用 OSMnx、Pandana、H3 和 Pydeck 等工具包,我们演示了从数据收集、可达性计算到 3D 可视化的完整流程。地铁可达性分析对于城市规划、交通管理和房地产评估具有重要意义。对居民而言,清晰的可达性数据可以用来辅助选择居住和工作地点,提升生活质量。

点点GIS
一点GIS,一点Python,一点杂谈
 最新文章