如何从Shapefile或MULTILINE类型CSV文件提取经纬度?
从Shapefile或MULTILINE类型CSV提取经纬度点的方法
一、处理Shapefile
方法1:用GeoPandas(推荐,更直观)
GeoPandas对地理空间数据的处理更友好,能直接解析几何对象并提取坐标。示例代码:
import geopandas as gpd # 读取Shapefile gdf = gpd.read_file("your_shapefile.shp") # 确保数据是WGS84坐标系(EPSG:4326),如果不是就转换 if gdf.crs != "EPSG:4326": gdf = gdf.to_crs("EPSG:4326") # 遍历每个要素,提取经纬度点 lat_lon_list = [] for geom in gdf.geometry: # 判断几何类型,处理LineString或MultiLineString if geom.type == "LineString": coords = list(geom.coords) lat_lon_list.extend([(lon, lat) for lon, lat in coords]) elif geom.type == "MultiLineString": for line in geom.geoms: coords = list(line.coords) lat_lon_list.extend([(lon, lat) for lon, lat in coords]) # 输出前5个点示例 for point in lat_lon_list[:5]: print(f"经度: {point[0]}, 纬度: {point[1]}")
方法2:用Fiona(底层处理)
如果之前用Fiona失败,大概率是没正确处理几何类型或坐标系。示例代码:
import fiona from shapely.geometry import shape from pyproj import Transformer # 打开Shapefile with fiona.open("your_shapefile.shp", "r") as src: # 获取源坐标系EPSG代码 src_epsg = src.crs.to_epsg() # 初始化坐标转换器(转为WGS84) transformer = Transformer.from_crs(f"EPSG:{src_epsg}", "EPSG:4326", always_xy=True) lat_lon_list = [] for feature in src: geom = shape(feature["geometry"]) if geom.type == "LineString": coords = list(geom.coords) # 转换坐标 coords = [transformer.transform(lon, lat) for lon, lat in coords] lat_lon_list.extend([(lon, lat) for lon, lat in coords]) elif geom.type == "MultiLineString": for line in geom.geoms: coords = list(line.coords) coords = [transformer.transform(lon, lat) for lon, lat in coords] lat_lon_list.extend([(lon, lat) for lon, lat in coords]) # 输出前5个点示例 for point in lat_lon_list[:5]: print(f"经度: {point[0]}, 纬度: {point[1]}")
二、处理MULTILINE类型CSV
默认CSV中存储的是WKT格式的MULTILINESTRING字符串(比如MULTILINESTRING ((x1 y1, x2 y2), (x3 y3, x4 y4))),用Shapely解析:
import pandas as pd from shapely.wkt import loads from pyproj import Transformer # 读取CSV,假设几何列名为"geometry" df = pd.read_csv("your_csv.csv") # 初始化坐标转换器(示例:从Web墨卡托转为WGS84,根据实际源坐标系调整) transformer = Transformer.from_crs("EPSG:3857", "EPSG:4326", always_xy=True) lat_lon_list = [] for wkt_str in df["geometry"]: geom = loads(wkt_str) if geom.type == "MultiLineString": for line in geom.geoms: coords = list(line.coords) coords = [transformer.transform(lon, lat) for lon, lat in coords] lat_lon_list.extend([(lon, lat) for lon, lat in coords]) elif geom.type == "LineString": coords = list(geom.coords) coords = [transformer.transform(lon, lat) for lon, lat in coords] lat_lon_list.extend([(lon, lat) for lon, lat in coords]) # 输出前5个点示例 for point in lat_lon_list[:5]: print(f"经度: {point[0]}, 纬度: {point[1]}")
关键注意事项
- 坐标系转换:必须确保最终输出的是WGS84(EPSG:4326)的经纬度,否则提取的是平面坐标(单位多为米),不是真实经纬度。
- 几何类型判断:Shapefile或CSV中的几何可能是
LineString或MultiLineString,需要分别处理,避免报错。 - 依赖安装:用pip安装所需库:
pip install geopandas fiona shapely pyproj pandas
内容的提问来源于stack exchange,提问作者sneha_jerin
相关产品推荐
相关产品推荐

