SuperAPI AI 工具集

geopandas

数据与分析

查看项目

更新于 10-15 09:11

技能介绍

用途

GeoPandas 扩展了 pandas,使其能够对几何类型执行空间操作。它结合了 pandas 和 shapely 的能力,用于地理空间数据分析,处理包括 Shapefile、GeoJSON 和 GeoPackage 文件在内的地理空间矢量数据。

安装

uv pip install geopandas

可选依赖:

# 交互式地图
uv pip install folium

# 地图分类方案
uv pip install mapclassify

# 更快的 I/O 操作(2-4 倍加速)
uv pip install pyarrow

# PostGIS 数据库支持
uv pip install psycopg2
uv pip install geoalchemy2

# 底图
uv pip install contextily

# 制图投影
uv pip install cartopy

快速开始

import geopandas as gpd

# 读取空间数据
gdf = gpd.read_file("data.geojson")

# 基本探索
print(gdf.head())
print(gdf.crs)
print(gdf.geometry.geom_type)

# 简单绘图
gdf.plot()

# 重投影到不同 CRS
gdf_projected = gdf.to_crs("EPSG:3857")

# 计算面积(使用投影 CRS 以保证精度)
gdf_projected['area'] = gdf_projected.geometry.area

# 保存到文件
gdf.to_file("output.gpkg")

核心概念

数据结构

  • GeoSeries:带有空间操作的几何向量
  • GeoDataFrame:带有几何列的表格式数据结构

读写数据

GeoPandas 可读写多种格式:Shapefile、GeoJSON、GeoPackage、PostGIS、Parquet。

# 带过滤读取
gdf = gpd.read_file("data.gpkg", bbox=(xmin, ymin, xmax, ymax))

# 使用 Arrow 加速写入
gdf.to_file("output.gpkg", use_arrow=True)

坐标参考系

始终检查和管理 CRS 以确保空间操作准确:

# 检查 CRS
print(gdf.crs)

# 重投影(转换坐标)
gdf_projected = gdf.to_crs("EPSG:3857")

# 设置 CRS(仅在元数据缺失时)
gdf = gdf.set_crs("EPSG:4326")

常见操作

几何操作

缓冲、简化、质心、凸包、仿射变换:

# 缓冲 10 个单位
buffered = gdf.geometry.buffer(10)

# 按容差简化
simplified = gdf.geometry.simplify(tolerance=5, preserve_topology=True)

# 获取质心
centroids = gdf.geometry.centroid

空间分析

空间连接、叠加操作、融合:

# 空间连接(相交)
joined = gpd.sjoin(gdf1, gdf2, predicate='intersects')

# 最近邻连接
nearest = gpd.sjoin_nearest(gdf1, gdf2, max_distance=1000)

# 叠加相交
intersection = gpd.overlay(gdf1, gdf2, how='intersection')

# 按属性融合
dissolved = gdf.dissolve(by='region', aggfunc='sum')

可视化

创建静态和交互式地图:

# 分级统计图
gdf.plot(column='population', cmap='YlOrRd', legend=True)

# 交互式地图
gdf.explore(column='population', legend=True).save('map.html')

# 多图层地图
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
gdf1.plot(ax=ax, color='blue')
gdf2.plot(ax=ax, color='red')

常见工作流

加载、转换、分析、导出

# 1. 加载数据
gdf = gpd.read_file("data.shp")

# 2. 检查并转换 CRS
print(gdf.crs)
gdf = gdf.to_crs("EPSG:3857")

# 3. 执行分析
gdf['area'] = gdf.geometry.area
buffered = gdf.copy()
buffered['geometry'] = gdf.geometry.buffer(100)

# 4. 导出结果
gdf.to_file("results.gpkg", layer='original')
buffered.to_file("results.gpkg", layer='buffered')

空间连接与聚合

# 将点连接到多边形
points_in_polygons = gpd.sjoin(points_gdf, polygons_gdf, predicate='within')

# 按多边形聚合
aggregated = points_in_polygons.groupby('index_right').agg({
    'value': 'sum',
    'count': 'size'
})

# 合并回多边形
result = polygons_gdf.merge(aggregated, left_index=True, right_index=True)

多源数据整合

# 从不同来源读取
roads = gpd.read_file("roads.shp")
buildings = gpd.read_file("buildings.geojson")
parcels = gpd.read_postgis("SELECT * FROM parcels", con=engine, geom_col='geom')

# 确保 CRS 匹配
buildings = buildings.to_crs(roads.crs)
parcels = parcels.to_crs(roads.crs)

# 执行空间操作
buildings_near_roads = buildings[buildings.geometry.distance(roads.union_all()) < 50]

性能提示

  • 使用空间索引:GeoPandas 在大多数操作中自动创建空间索引
  • 读取时过滤:使用 bbox、mask 或 where 参数仅加载所需数据
  • 使用 Arrow 进行 I/O:添加 use_arrow=True 可实现 2-4 倍更快的读写
  • 简化几何:当精度不重要时,使用 .simplify() 降低复杂度
  • 批量操作:向量化操作比逐行迭代快得多
  • 使用合适的 CRS:投影 CRS 用于面积/距离,地理 CRS 用于可视化

最佳实践

  • 空间操作前始终检查 CRS
  • 面积和距离计算使用投影 CRS
  • 空间连接或叠加前匹配 CRS
  • 操作前使用 .is_valid 验证几何
  • 修改几何列时使用 .copy() 避免副作用
  • 分析时简化保留拓扑
  • 现代工作流使用 GeoPackage 格式(优于 Shapefile)
  • 在 sjoin_nearest 中设置 max_distance 以获得更好性能