GeoPandas sjoin 怎么选谓词:within、intersects、contains 与 nearest 的区别

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

问题场景

GeoPandas 的 `sjoin` 用起来很方便,但很多结果错并不是代码错,而是谓词选错了。点落面、面压面、线穿面、最近设施匹配,本质上是不同空间关系。如果不区分 `within`、`intersects`、`contains` 和 `nearest`,输出行数和业务含义都会偏掉。

判断 `sjoin` 谓词时,不要从函数名出发,而要从业务问题出发:你到底想证明“在内部”“有相交”“包含别人”,还是“最近”?

核心原理与判断框架

`within` 适合目标几何落在另一个几何内部;`contains` 是反向语义;`intersects` 只要求几何有交;`sjoin_nearest` 则不依赖相交,而是基于距离找最近对象。四者看起来接近,但输出逻辑完全不同。

谓词 含义 典型场景
within 要素位于另一要素内部 点属于哪个行政区
contains 要素包含另一要素 面包含哪些点
intersects 几何有交即可 道路穿过缓冲区
nearest 空间上最近 最近公交站、最近医院

实操流程

  1. 先确认两个图层 CRS 一致,距离相关任务优先用投影坐标。
  2. 写出业务语义,再映射到谓词,不要反过来。
  3. 对返回结果抽样可视化,检查是否符合空间直觉。
  4. 如果结果行数异常,先看是否一对多匹配,而不是先怀疑代码。

项目避坑与质量检查

`intersects` 看似通用,实际最容易被滥用。它会把边界接触、轻微相交都算进去,不一定符合业务定义。

例如“设施属于街道”通常更适合 `within`,而不是 `intersects`。边界点是否算入,也应该在项目里提前定义。

FAQ

点落在边界线上,用 within 还是 intersects?

边界点用 `within` 可能不匹配,`intersects` 会匹配。要看业务规则。

sjoin_nearest 需要相交吗?

不需要。它按距离找最近对象,但要特别注意坐标系单位。

返回记录比原表多很多正常吗?

正常,说明一个要素匹配到了多个对象。应回到空间关系本身判断是否合理。

总结

GeoPandas `sjoin` 的关键是把空间语义说清楚。先定义业务关系,再选谓词,再检查结果样本,才能避免“代码能跑、结果不对”的常见问题。