在地理信息系统(GIS)中,处理和分析空间数据是理解复杂地理现象、优化资源分配以及支持决策制定的重要步骤。其中一个常见的需求是在交通规划、城市设计等领域中,根据特定的点要素(如公交站点、交叉路口等)来分割或截断线要素(如道路、铁路等)。这不仅有助于精细化管理基础设施,还能为后续的空间分析提供更加精确的基础数据。
本篇文章就基于这个一需求在实际数据处理上通过精准度,ArcGlS Pro本身已经集成这个功能了,但是更多是基于空间距离的远近来识别,会出现某一个点属于某条线路的点,但由于离另一条线更近,而被认为是另一条线的节点,为了避免这个现象,我们通过python脚本来实现这一功能;
这里也贴一下ArcGlS Pro实现方法:在点处分割线 (数据管理)—ArcGIS Pro | 文档
点击【工具箱】→【要素】→【在点处分割线】;

本篇文章,我们依然以厦门的公交线路为例,挑选厦门的几条公交线路作为研究对象;

这里讲一下方法思路和要注意修改一下点图层和线图层的数据路径和字段信息即可;
方法思路
- 先匹配站点与线路的唯一对应关系,然后对于每个站点,计算它到其所属线路的最近点
- 根据相邻站点之间的最近点,对线路进行截断,并提取这两点之间的部分作为新的线段
- 更新线路名称以反映它是哪两个站点之间的线段,然后输出shp图层
完整代码#运行环境 Python 3.11
import geopandas as gpd
from shapely.geometry import LineString, Point
from shapely.ops import nearest_points
import pandas as pd
import re
# 读取线路和站点 shapefile 文件
lines_path = r'D:\data\bus_route.shp'
stations_path = r'D:\data\bus_station.shp'
gdf_lines = gpd.read_file(lines_path) # 读取线路 shapefile
gdf_stations = gpd.read_file(stations_path) # 读取站点 shapefile
# 创建一个空的 GeoDataFrame 用于存储截断后的线路
truncated_lines = gpd.GeoDataFrame(columns=gdf_lines.columns)
# 遍历每条线路,逐条处理
for line_index, line in gdf_lines.iterrows():
# 获取当前线路的坐标
line_coords = list(line.geometry.coords)
# 创建一个字典来存储每个站点对应的最近线路点
station_to_line_points = {}
# 遍历每个站点,找到最近的线路点,确保线路名匹配
for idx, station in gdf_stations.iterrows():
# 只考虑与当前线路名匹配的站点
if station['线路名'] == line['name']:
# 计算当前站点到线路的最近点
nearest_point = nearest_points(line.geometry, station.geometry)[1]
station_to_line_points[station['站名']] = nearest_point
# 找到每个站点在当前线路上的最近点
matched_points = []
for station_name, station_point in station_to_line_points.items():
# 计算当前线路上与站点的最近点
nearest_point = nearest_points(line.geometry, station_point)[1]
matched_points.append((station_name, nearest_point))
# 根据匹配的点进行截断
for i in range(len(matched_points) - 1):
start_station_name, start_point = matched_points[i]
end_station_name, end_point = matched_points[i + 1]
# 找到起始和结束点在原线路中的位置
start_pos = min(range(len(line_coords)), key=lambda j: start_point.distance(Point(line_coords[j])))
end_pos = min(range(len(line_coords)), key=lambda j: end_point.distance(Point(line_coords[j])))
# 确保 start_pos 和 end_pos 的有效性
if start_pos < end_pos and start_pos < len(line_coords) and end_pos < len(line_coords):
# 创建截断后的线段,保持原线路的路径
truncated_line = LineString(line_coords[start_pos:end_pos + 1])
# 创建新的 GeoDataFrame 行
new_line = line.copy()
new_line.geometry = truncated_line
# 使用站点名称创建名称
new_line['name'] = f"{start_station_name}—{end_station_name}"
# 将新行添加到截断后的线路 GeoDataFrame
truncated_lines = pd.concat([truncated_lines, gpd.GeoDataFrame([new_line])], ignore_index=True)
# 保存截断后的线路到新的 shapefile,确保编码为 UTF-8
truncated_lines.to_file(r'D:\data\bus_truncated.shp', encoding='utf-8')
生成线段结果如下,每条线路都基于线路与站点的唯一对应关系进行截断,并生成新的线段;

以我们使用的公交线段为例,我们可以对线段客流量进行赋值从而进行可视化,如果路网本身是双线,我们可以看到二个方向更精细的客流量。如果本身线路是单线,我们也可以通过arcgis 自带的选择要素,点击【编辑器】→【平行复制】功能来实现单线转双线,这一步骤;

给公交线段赋值客流量的效果;

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

1万+

被折叠的 条评论
为什么被折叠?



