从传统 GIS 向智能/自动化脚本演进:地铁接驳公交识别的 ArcGIS 与 Python 双路径实践

随着城市轨道交通网络的快速扩张,地铁与地面公交系统的协同接驳已成为提升公共交通整体效率与乘客出行体验的关键环节。作为多模式交通体系中的核心换乘节点,地铁站点周边的公交服务覆盖水平,直接决定了轨道交通的可达性、吸引力与客流集散效能。因此,科学评估并优化地铁与公交线路的空间衔接关系,是推动"轨道+公交"一体化融合发展的基础性工作。

吕厝站位于厦门市思明区与湖里区交界处,是地铁1号线与2号线的换乘枢纽,日均客流量位居全市前列。其周边土地开发高度密集,涵盖商业、办公、居住等多种功能,对高效、便捷的接驳公交服务具有迫切需求。然而,并非所有途经该区域的公交线路都能有效支撑地铁换乘------部分线路仅短暂穿越站点周边,实际服务深度有限;真正具备良好接驳功能的线路,应在地铁站步行可达范围内形成稳定且充分的空间重叠

为此,本研究聚焦于地铁站800米半径的服务圈层(约10分钟步行距离),采用地理信息系统(ArcGIS)空间分析方法和 Python 与 GeoPandas 库二个方法,精准识别在该范围内实际运行轨迹长度超过100米的公交线路。该阈值设定旨在排除仅"擦边"经过或短暂停靠的无效线路,确保筛选结果真实反映具备实质性接驳服务能力的公交资源。通过此项分析,可为公交线网优化、接驳设施布局及换乘引导策略提供精细化、可量化的数据支撑,助力构建更加高效、公平、人性化的城市公共交通体系。

问题:找出某地铁站800米范围内、且在该范围内运行长度超过100米的公交线路;

方法一:ArcGIS 操作

步骤 1:加载数据

将地铁站和公交线路加载到 ArcGIS,本篇文章以吕厝站为例;

步骤 2:创建地铁站 800 米缓冲区

地理处理工具 → 缓冲区;

步骤 3:裁剪公交线路(保留缓冲区内部分)

地理处理工具 → 裁剪,这里有个tips,裁剪之前需要对先对数据做投影,当然这里使用地理处理工具 → 相交,这个工具也可以;

步骤 4:计算每条裁剪后线路的长度

打开 属性表 → 字段计算器

创建新字段:length(单位:米,前提是图层是投影坐标系!)

步骤 5:筛选长度 > 100 米的线路

条件: 按属性选择 "length" > 100 → 导出选中要素;

步骤 6:提取满足条件的线路

右键图层 → 导出 → 将所选要素另存为... → 保存为符合在该范围内运行长度超过100米的公交线路.csv;

步骤 7:回到原始公交线路图层

打开属性表 → 连接(Join)

连接图层:符合在该范围内运行长度超过100米的公交线路.csv

连接字段:line_id

至此,我们就得到了对应地铁站地铁站800米范围内、且在该范围内运行长度超过100米的公交线路;

方法二:Python + GeoPandas(适合批量/自动化)

完整代码#运行环境 Python 3.11

python 复制代码
# -*- coding: utf-8 -*-
import geopandas as gpd
import pandas as pd
import os

# 1. 配置文件路径
ALL_STATIONS_BUFFER_SHP = r"E:\Data\厦门站点800m缓冲区投影.shp"
BUS_LINES_SHP = r"E:\Data\厦门公交线路投影.shp"
OUTPUT_SHP = r"E:\Data\厦门地铁站接驳公交线路_100m以上.shp"

# 2. 读取数据
print("正在加载所有地铁站缓冲区...")
stations_gdf = gpd.read_file(ALL_STATIONS_BUFFER_SHP)

print("正在加载厦门公交线路...")
bus_gdf = gpd.read_file(BUS_LINES_SHP)

# 统一坐标系
if stations_gdf.crs != bus_gdf.crs:
    print("坐标系不一致!正在将公交线路转为缓冲区坐标系...")
    bus_gdf = bus_gdf.to_crs(stations_gdf.crs)
else:
    print("坐标系一致,无需转换")

# 3. 初始化结果列表(存储带站点名的线路)
output_features = []


# 4. 定义长度计算函数
def get_intersection_length(line_geom, buffer_geom):
    if line_geom.is_empty or not line_geom.intersects(buffer_geom):
        return 0.0
    try:
        return line_geom.intersection(buffer_geom).length
    except Exception as e:
        print(f"几何计算错误: {e}")
        return 0.0


# 5. 遍历每个地铁站
for idx, station_row in stations_gdf.iterrows():
    station_name = station_row['地铁站']  # 确保字段名正确
    buffer_geom = station_row.geometry

    print(f"处理站点:{station_name}")

    # 临时复制公交线路用于计算(避免修改原数据)
    temp_bus = bus_gdf.copy()
    temp_bus['in_buffer_len'] = temp_bus.geometry.apply(
        lambda geom: get_intersection_length(geom, buffer_geom)
    )

    # 筛选 >100 米的线路
    qualified = temp_bus[temp_bus['in_buffer_len'] > 100].copy()

    if not qualified.empty:
        # 为每条线路添加站点名称字段
        qualified['station_name'] = station_name
        # 可选:保留相交长度(用于后续分析)
        qualified['buffer_len'] = qualified['in_buffer_len']
        # 仅保留必要字段(避免字段冲突)
        qualified = qualified.drop(columns=['in_buffer_len'])

        # 添加到结果列表
        output_features.append(qualified)

# 6. 合并所有结果
if output_features:
    final_gdf = gpd.GeoDataFrame(pd.concat(output_features, ignore_index=True), crs=bus_gdf.crs)

    # 确保输出目录存在
    os.makedirs(os.path.dirname(OUTPUT_SHP), exist_ok=True)

    # 保存为单一 Shapefile
    final_gdf.to_file(OUTPUT_SHP, encoding='utf-8')
    print(f"\n成功生成统一接驳公交图层!")
    print(f"   共 {len(final_gdf)} 条记录(含重复线路,按站点拆分)")
    print(f"   已保存至:{OUTPUT_SHP}")

    # 显示前几行示例
    sample_cols = ['station_name', 'line_id', 'buffer_len']
    available_cols = [c for c in sample_cols if c in final_gdf.columns]
    if available_cols:
        print("\n示例数据:")
        print(final_gdf[available_cols].head())
else:
    print("\n未找到任何符合条件的接驳公交线路")

print("\n处理完成!")

这个脚本通过遍历每个地铁站的800米缓冲区,筛选出在其中运行长度超过100米的公交线路,并将这些完整线路按所属站点标注后合并输出为一个统一的Shapefile图层,也是实现了同样的功能;

后记:

以前完成的操作需要比较精通arcgis的相关功能,现在ai时代的到来,我们完全可以通过先ai提问来完成这个功能的实现,甚至不需要太多会代码的能力,就像以前说精通Excel,是真的需要会各中函数功能和快捷功能,现在只要告诉ai你的需求,它就阔以帮你找到对应函数或者处理方式,所以本文想表达的是,ai时代我们可以从精通arcgis软件操作过度到通过ai来实现gis功能的需求实现,也就是通过脚本来实现我们本需要通过gis操作才能完整的功能;

文章仅用于分享个人学习成果与个人存档之用,分享知识,如有侵权,请联系作者进行删除。所有信息均基于作者的个人理解和经验,不代表任何官方立场或权威解读。

相关推荐
qw9492 小时前
Python语言概述
开发语言·python
毕设源码-邱学长2 小时前
【开题答辩全过程】以 基于Python的茶叶销售数据可视化分析系统设计实现为例,包含答辩的问题和答案
开发语言·python·信息可视化
人道领域2 小时前
SSM从入门到入土(Spring Bean实例化与依赖注入全解析)
java·开发语言·spring boot·后端
毕设源码-赖学姐2 小时前
【开题答辩全过程】以 基于Java web的宠物领养系统的设计与实现为例,包含答辩的问题和答案
java·开发语言·宠物
小小码农Come on2 小时前
QT常用控件:QListWidget
开发语言·qt
Betelgeuse762 小时前
【Flutter For OpenHarmony】 阶段复盘:从单页Demo到模块化App
flutter·ui·华为·交互·harmonyos
瑞雪兆丰年兮2 小时前
[从0开始学Java|第十三天]面向对象进阶(static&继承)
java·开发语言
小虾米 ~2 小时前
JAVA引用类型
java·开发语言
lly2024062 小时前
C++ 循环
开发语言