Geopandas空间连接报错:'NoneType' object has no attribute 'intersection'
解决空间连接中的
AttributeError: 'NoneType' object has no attribute 'intersection'问题 我来帮你搞定这个空间连接的报错——你遇到的这个错误,本质是RTree空间索引构建失败,返回了空值,所以调用intersection方法时直接炸了。之前只移除空几何的操作不足以解决问题,试试下面几个针对性方案:
1. 彻底清理无效几何(空值、无效形状全过滤)
你当前只筛选了几何类型,但有些数据可能存在坐标为空、自相交多边形等无效情况,直接导致索引构建失败:
处理充电桩点数据:
# 先干掉经纬度为空的行,避免生成无效Point charge_points = charge_points.dropna(subset=['longitude', 'latitude']) # 重新创建Point几何 geometry = [Point(xy) for xy in zip(charge_points['longitude'], charge_points['latitude'])] charge_points = gpd.GeoDataFrame(charge_points, crs='epsg:4326', geometry=geometry) # 过滤掉无效的Point(比如坐标超出合理范围的) charge_points = charge_points[charge_points.geometry.is_valid]
处理LSOA多边形数据:
LSOA_polygons = gpd.read_file('https://raw.githubusercontent.com/gausie/LSOA-2011-GeoJSON/master/lsoa.geojson') # 同时过滤空几何和无效几何 LSOA_polygons = LSOA_polygons[LSOA_polygons.geometry.notna() & LSOA_polygons.geometry.is_valid] # 修复轻微无效的多边形(比如自相交问题,buffer(0)是常用技巧) LSOA_polygons['geometry'] = LSOA_polygons.geometry.buffer(0)
2. 检查RTree与Geopandas的版本兼容性
你用的rtree-0.9.3是2020年的旧版本,很可能和当前安装的Geopandas版本不兼容,导致索引构建异常。建议升级到稳定版:
pip install --upgrade rtree
如果升级后遇到spatialindex相关错误,用conda安装更省心:
conda install spatialindex
3. 转换为平面坐标系再执行空间连接
你当前用的EPSG:4326是球面地理坐标系,RTree在处理这类坐标时偶尔会出问题。换成英国本地的平面坐标系(比如EPSG:27700,英国国家格网)试试:
# 转换坐标系 charge_points = charge_points.to_crs('epsg:27700') LSOA_polygons = LSOA_polygons.to_crs('epsg:27700') # 再执行空间连接 charge_points_LSOA = gpd.sjoin(charge_points, LSOA_polygons, how="inner", op='intersects')
4. 手动构建索引绕过自动构建问题
如果自动构建索引还是失败,那就手动实现空间匹配逻辑:
from rtree import index # 为LSOA多边形手动构建RTree索引 idx = index.Index() for i, geom in enumerate(LSOA_polygons.geometry): idx.insert(i, geom.bounds) # 手动匹配点和多边形 matches = [] for left_idx, left_geom in charge_points.geometry.items(): if not left_geom.is_valid: continue # 先通过索引找候选多边形 candidate_ids = list(idx.intersection(left_geom.bounds)) # 再精确判断是否相交 for right_idx in candidate_ids: right_geom = LSOA_polygons.geometry.iloc[right_idx] if left_geom.intersects(right_geom): matches.append({ 'left_idx': left_idx, 'right_idx': right_idx }) # 合并结果 matches_df = pd.DataFrame(matches) charge_points_LSOA = charge_points.merge( LSOA_polygons, left_index=True, right_index=True, left_on='left_idx', right_on='right_idx', suffixes=('_left', '_right') )
优先试试方案1和3,这两个是这类报错的常见解决思路,大概率能搞定你的问题。
内容的提问来源于stack exchange,提问作者camnesia
相关产品推荐
相关产品推荐

