如何用Geopandas判断多边形是否在目标区域内并清理数据
解决GeoDataFrame几何筛选问题:保留指定区域内的图形
问题分析
你要实现的是删除localities表(绿色区域)以外的几何图形,核心是判断待清理GeoDataFrame中的几何是否完全处于任意一个绿色区域内部。之前用overlaps函数不符合需求,原因如下:
overlaps的逻辑是两个几何有交集但互不包含,和你要的“处于内部”完全不匹配;- 逐行遍历
iterrows的方式效率极低,Geopandas本身支持矢量化操作,没必要做循环; - 当前代码只要找到一个重叠就保留,会误留那些部分重叠但不在内部的图形。
正确实现方案
方案1:使用空间连接(推荐,效率最高)
Geopandas的gpd.sjoin可以直接基于空间关系筛选数据,用predicate='within'(待清理几何在绿色区域内)来精准筛选:
import geopandas as gpd from ..config import db def transform(gdf: gpd.GeoDataFrame) -> gpd.GeoDataFrame: # 读取绿色区域数据 locality_data = gpd.GeoDataFrame.from_postgis( sql='SELECT * FROM localities', con=db.engine, geom_col='geometry' ) # 先过滤掉待清理数据中的空几何 gdf = gdf[~gdf['geometry'].isna()] # 空间连接:只保留在localities内部的几何 filtered_gdf = gpd.sjoin( gdf, locality_data, how='inner', predicate='within' ) # 移除连接带来的额外列,保留原gdf的字段 filtered_gdf = filtered_gdf[gdf.columns] # 重置索引 return filtered_gdf.reset_index(drop=True)
方案2:合并绿色区域为单一几何,批量判断
如果localities的几何没有重叠,可以合并成一个MultiPolygon,再批量判断待清理几何是否在其中:
import geopandas as gpd from shapely.ops import unary_union from ..config import db def transform(gdf: gpd.GeoDataFrame) -> gpd.GeoDataFrame: locality_data = gpd.GeoDataFrame.from_postgis( sql='SELECT * FROM localities', con=db.engine, geom_col='geometry' ) # 过滤空几何 gdf = gdf[~gdf['geometry'].isna()] # 合并所有绿色区域为单一几何 combined_localities = unary_union(locality_data['geometry']) # 筛选出在合并区域内的几何 filtered_gdf = gdf[gdf['geometry'].within(combined_localities)] return filtered_gdf.reset_index(drop=True)
关键说明
predicate='within'表示待清理几何完全在绿色区域内部,和predicate='contains'(绿色区域包含待清理几何)逻辑等价,选哪个都可以;- 空间连接是矢量化操作,比逐行循环快几个数量级,大数据量下必须用这种方式;
- 先过滤空几何能避免后续空间运算报错。
内容的提问来源于stack exchange,提问作者D4-Ramirez
相关产品推荐
相关产品推荐

