GeoPandas 缓冲区分析 buffer 的单位为什么不对?投影坐标系是关键
问题场景:为什么 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 问题。记住一个原则:经纬度负责定位,投影坐标负责量算。先投影,再缓冲,再按需要转回展示坐标系,结果才可信。