如何用Python将CSV的route_linestring列导出为Shapefile与OSM文件
实现方案:将LINESTRING数据导出为Shapefile和OSM文件
先把需要的依赖库安装好,后续操作都要用到它们:
pip install geopandas shapely lxml
一、导出为Shapefile
Geopandas是处理空间数据导出最顺手的工具,它能直接把Shapely几何对象转换成标准Shapefile。注意:你之前存到CSV里的route_linestring其实是字符串格式的WKT(Well-Known Text),所以第一步得把它解析回Shapely的LineString对象。
完整代码如下:
import pandas as pd import geopandas as gpd from shapely.wkt import loads # 读取处理后的CSV文件 df = pd.read_csv('batch.csv') # 过滤无效行,解析WKT格式的LINESTRING为Shapely几何对象 valid_df = df[df['selected_distance'] != -100].copy() valid_df['geometry'] = valid_df['route_linestring'].apply(lambda x: loads(x) if pd.notna(x) else None) # 创建GeoDataFrame,设置坐标系为WGS84(EPSG:4326,对应经纬度坐标) gdf = gpd.GeoDataFrame(valid_df, geometry='geometry', crs='EPSG:4326') # 导出为Shapefile,配套的.shx/.dbf等文件会自动生成 gdf.to_file('taxi_routes.shp', driver='ESRI Shapefile')
运行后你就能得到包含所有有效行程路线的Shapefile,直接用QGIS等GIS软件就能打开查看。
二、导出为OSM文件
OSM是XML格式,核心结构包含节点(node)、路径(way)和标签(tag)。咱们需要把每个LINESTRING拆成单独的节点,再用这些节点组成way,最后加上行程相关的标签。
这里用Python内置的XML工具手动生成OSM文件,不需要额外的复杂库:
import pandas as pd import xml.etree.ElementTree as ET import xml.dom.minidom as minidom from shapely.wkt import loads def export_to_osm(csv_path, output_path): # 读取并过滤有效数据 df = pd.read_csv(csv_path) valid_df = df[df['selected_distance'] != -100].dropna(subset=['route_linestring']) # 初始化OSM根节点 osm = ET.Element('osm', version='0.6', generator='taxi-route-exporter') node_id = -1 # 自定义节点用负数ID,避免和官方OSM节点ID冲突 way_id = -1 for _, row in valid_df.iterrows(): # 解析LINESTRING为Shapely对象 line = loads(row['route_linestring']) node_refs = [] # 逐个创建坐标节点 for lon, lat in line.coords: node = ET.SubElement(osm, 'node', id=str(node_id), lat=str(lat), lon=str(lon)) node_refs.append(str(node_id)) node_id -= 1 # 创建Way对象,引用刚才的节点 way = ET.SubElement(osm, 'way', id=str(way_id)) for ref in node_refs: ET.SubElement(way, 'nd', ref=ref) # 添加自定义标签,可根据需求修改(比如行程ID、距离等) ET.SubElement(way, 'tag', k='highway', v='service') ET.SubElement(way, 'tag', k='taxi_trip_id', v=str(row.get('trip_id', 'unknown'))) ET.SubElement(way, 'tag', k='trip_distance', v=str(row['selected_distance'])) way_id -= 1 # 美化XML格式并保存 rough_xml = ET.tostring(osm, 'utf-8') parsed_xml = minidom.parseString(rough_xml) pretty_xml = parsed_xml.toprettyxml(indent=" ") with open(output_path, 'w', encoding='utf-8') as f: f.write(pretty_xml) # 调用函数导出OSM文件 export_to_osm('batch.csv', 'taxi_routes.osm')
这段代码会生成标准的OSM文件,每个出租车行程对应一个way,包含了完整的路线节点和自定义属性标签,你可以直接用JOSM等OSM编辑工具打开查看。
内容的提问来源于stack exchange,提问作者abs8090
相关产品推荐
相关产品推荐

