点与shapefile坐标单位不统一导致空间掩膜全False的解决方法
问题定位
你的判断完全准确,掩膜输出全为False的核心原因是坐标参考系统不匹配:插值生成的alt_x、alt_y是LambertConformal投影下的米制坐标,数值范围在数十万到百万米级;但你将shapefile转换为EPSG:4326(WGS84经纬度坐标系)后,几何坐标是-180180、-9090区间的角度值,两套坐标数值量级差了6个数量级,shapely判定所有网格点都不在矢量边界范围内,自然返回全False结果。
解决思路
做空间包含判断时必须保证矢量边界和待判断网格点的坐标参考系统完全一致,两种实现路径都可以:
- 路径1:将shapefile转换为和插值网格完全相同的LambertConformal投影,直接用米制坐标做掩膜计算(推荐,少一次坐标转换,计算效率和精度更高)
- 路径2:将插值网格的米制坐标反算为经纬度坐标,再和转为EPSG:4326的shapefile做判断
具体代码修正
首先补全原代码缺失的依赖导入,再调整shapefile坐标转换、掩膜计算的逻辑:
# 补全原代码缺失的导入 import geopandas import shapely.vectorized # --- 你原有读取数据、坐标转换、插值的代码全部保持不变 --- # 读取shapefile后,不要转EPSG:4326,直接匹配绘图用的兰伯特投影 cat_gdf = geopandas.read_file('MB_AGregion_Perim_South.shp') # 直接从cartopy投影对象提取proj4定义,保证和网格坐标投影完全一致 cat_gdf_lambert = cat_gdf.to_crs(crs.proj4_init) # 将所有面要素合并为单个几何对象,用于批量掩膜判断 boundary_poly = cat_gdf_lambert.dissolve().geometry.iloc[0] # 生成掩膜 mask = shapely.vectorized.contains(boundary_poly, alt_x, alt_y) # 对温度插值结果应用掩膜,范围外设为空值NaN,绘图时自动不渲染 tem_masked = np.where(mask, data, np.nan)
后续调用pcolormesh绘制填色图时,将传入的温度数据替换为tem_masked即可,最终效果就仅会在shapefile边界范围内显示温度着色。
注意事项
- 你代码中使用的LambertConformal是自定义中心经纬度的投影,没有对应的通用EPSG编码,直接调用cartopy投影对象的
proj4_init属性获取投影定义传给geopandas,是保证投影完全匹配最稳妥的方式,不要手动硬编码投影参数避免出错。 - 不需要额外做图形裁剪,将范围外数值设为NaN后,matplotlib会自动跳过NaN区域的渲染,边界外就是透明的,能正常显示底下的底图要素。
- 所有涉及空间计算的环节,只要出现结果全True/全False、位置完全偏移的问题,第一时间检查参与计算的两个数据源CRS是否完全一致。
内容的提问来源于stack exchange,提问作者QHoang
相关产品推荐
相关产品推荐

