首页 编程与开发 Python GeoPandas 空间连接 sjoin 结果为空怎么办?CRS、几何、索引三步排查

GeoPandas 空间连接 sjoin 结果为空怎么办?CRS、几何、索引三步排查

作者: GIS研习社 更新时间:2026-05-23 11:35:12 分类:Python
GeoPandas sjoin 结果为空排查封面图

在使用 GeoPandas 做空间分析时,sjoin 是一个非常常用的函数。比如判断点落在哪个行政区内、将 POI 点位匹配到街道、给采样点批量挂接区县字段等,都离不开空间连接。

但很多初学者会遇到一个典型问题:两个图层在地图上看起来明明有重叠,为什么 geopandas.sjoin() 之后结果为空?

一、先确认:sjoin 结果为空是什么意思

GeoPandas.sjoin() 的作用是根据空间关系连接两个 GeoDataFrame。常见写法如下:

result = gpd.sjoin(points, polygons, how="inner", predicate="within")

如果结果为空,通常表示 GeoPandas 没有找到任何符合空间关系的要素对。常见原因包括:

  • 两个图层 CRS 不一致。
  • CRS 信息缺失或被错误设置。
  • 几何对象为空或无效。
  • predicate 参数用错。
  • 左右表顺序和空间关系不匹配。
  • 数据边界只是看起来接近,但实际没有相交。

二、第一步:检查 CRS 坐标系是否一致

sjoin 结果为空,最常见的原因就是 CRS 不一致。先打印两个图层的 CRS:

print(points.crs)
print(polygons.crs)

如果一个是 EPSG:4326,另一个是 EPSG:3857,就说明两个图层不在同一个坐标系下,需要先统一:

polygons = polygons.to_crs(points.crs)

三、常见 CRS 对比表

CRS常见名称坐标单位常见用途
EPSG:4326WGS84 经纬度GPS、GeoJSON、互联网数据
EPSG:3857Web MercatorWeb 地图底图、瓦片地图
EPSG:4490CGCS2000 经纬度国内测绘数据常见
投影坐标系UTM、高斯克吕格等距离、面积、缓冲区分析

四、注意 set_crs 和 to_crs 的区别

很多人会把 set_crs()to_crs() 混用,这是非常容易导致空间连接为空的坑。

方法作用是否改变坐标值使用场景
set_crs()给数据指定 CRS 标签数据本来有坐标系,但文件里缺失 CRS 信息
to_crs()坐标转换数据已有 CRS,需要转换到另一个 CRS

五、第二步:检查几何是否为空或无效

CRS 没问题之后,下一步要检查 geometry 字段:

print(points.geometry.is_empty.sum())
print(polygons.geometry.is_empty.sum())
print(points.geometry.isna().sum())
print(polygons.geometry.isna().sum())

如果存在空几何,建议先过滤:

points = points[points.geometry.notna() & ~points.geometry.is_empty]
polygons = polygons[polygons.geometry.notna() & ~polygons.geometry.is_empty]

面数据还要检查是否合法:

print(polygons.is_valid.value_counts())
polygons["geometry"] = polygons.geometry.make_valid()

六、第三步:检查 predicate 参数是否用错

predicate 决定空间关系判断方式。点落在面内通常写:

gpd.sjoin(points, polygons, how="inner", predicate="within")

如果左右表顺序反了,就变成了“面是否在点内部”,通常匹配不到。

predicate含义常见场景
within左侧几何在右侧几何内部点匹配行政区
contains左侧几何包含右侧几何面查找内部点
intersects两个几何相交即可面面叠加、线面相交
touches边界接触邻接关系分析

七、推荐的完整排查顺序

  1. 打印两个图层的 crs
  2. 打印两个图层的 total_bounds
  3. 统一 CRS,优先使用 to_crs()
  4. 删除空 geometry。
  5. 修复无效 geometry。
  6. 先用 intersects 测试是否有结果。
  7. 再根据业务需求改成 withincontains 或其他 predicate。
  8. 检查左右表顺序是否写反。

八、总结

GeoPandas 的 sjoin 结果为空,通常不是函数本身的问题,而是数据或参数没有满足空间连接条件。最实用的排查流程是:看 CRS、看 total_bounds、清理 geometry、用 intersects 测试,再换成业务真正需要的 predicate。