GeoPandas 缓冲区分析 buffer 的单位为什么不对?投影坐标系是关键

Python
Dr.GIS
wowwwai GIS研习社 · 工具流程与项目排障

问题场景:为什么 buffer(1000) 不是 1000 米

使用 GeoPandas 做缓冲区分析时,很多人会直接写 gdf.buffer(1000),以为得到的是 1000 米缓冲区。结果一打开地图,缓冲区巨大到离谱,或者形状在不同纬度看起来很奇怪。这个问题不是 GeoPandas 算错了,而是坐标系单位被误解了。

GeoPandas 的几何计算基于当前坐标值本身。数据如果是 EPSG:4326,经纬度单位是“度”,不是“米”。此时 buffer(1000) 的含义是 1000 度,当然不可能得到合理结果。只要涉及距离、面积、邻近关系,第一步都应该检查 CRS。

核心原理:buffer 使用当前 CRS 的单位

GeoPandas 底层依赖 Shapely 做几何运算。Shapely 不理解地球曲率,也不会自动判断米和度。它只把坐标当作平面坐标处理。因此,在经纬度坐标系下做 buffer,是最常见的空间分析误区之一

坐标系类型 坐标单位 是否适合 buffer 距离分析
EPSG:4326 不适合直接做米级缓冲
UTM 投影 适合中小范围距离分析
地方高斯投影 适合工程和区域项目

推荐代码流程

import geopandas as gpd

gdf = gpd.read_file("points.geojson")
print(gdf.crs)

gdf_m = gdf.to_crs(epsg=32650)
gdf_m["geometry"] = gdf_m.buffer(1000)

out = gdf_m.to_crs(epsg=4326)
out.to_file("buffer_1km.geojson", driver="GeoJSON")

代码中的 EPSG:32650 只是示例,实际项目要根据研究区选择合适分带。中国区域还常见 CGCS2000 高斯克吕格投影。不要机械复制 EPSG,投影选错同样会带来距离误差。

投影怎么选才稳

  • 研究区较小且跨带不明显时,可选当地 UTM 分带。
  • 工程项目有指定坐标系时,应使用项目要求的投影。
  • 全国尺度分析不适合用单一局部投影做精确距离,应考虑分区处理或测地线方法。
  • 输出给 Web 地图展示时,再转换回 EPSG:4326 或 EPSG:3857。

项目避坑:用面积反查缓冲是否合理

点的 1000 米圆形缓冲区面积理论上约为 3.14 平方公里。随机抽几个结果算面积,如果数量级明显不对,说明 CRS 或单位仍有问题。

这个检查非常简单,却能快速发现“看起来像缓冲区、实际单位错误”的结果。正式分析前做一次面积抽查,比后期解释错误结果要省事得多。

FAQ

GeoPandas 会自动选择投影坐标系吗?

不会。GeoPandas 会保留和转换 CRS,但不会替你判断哪个投影最适合项目。

为什么转到 EPSG:3857 后 buffer 也有误差?

Web Mercator 适合网页显示,不适合严肃距离和面积统计。纬度越高,变形越明显。

面数据可以直接 buffer 吗?

可以,但前提仍是使用合适的投影坐标系,并检查自相交或无效几何。

总结

GeoPandas 的 buffer 问题,本质是 CRS 问题。记住一个原则:经纬度负责定位,投影坐标负责量算。先投影,再缓冲,再按需要转回展示坐标系,结果才可信。