求助:计算GDB边界内总人口结果严重偏高(附Python代码)
问题分析与解决方案
核心问题是直接对人口密度栅格求和,忽略了每个像元对应的实际面积。人口密度栅格的每个像元值是「单位面积内的人口数」,必须乘以像元面积才能得到该像元的总人口,累加后才是区域真实总人口。
具体修正步骤:
- 移除多余的
xds["mask"] = 0,该操作会引入无效维度干扰计算。 - 重投影后,计算每个像元的实际面积(当前CRS单位为km,面积单位对应平方公里)。
- 将人口密度与像元面积相乘得到单像元人口数,再求和得到区域总人口。
修正后的代码
import geopandas as gpd import rioxarray as rxr # 加载边界文件 df = gpd.read_file("WDPA_WDOECM_May2024_Public_COG.gdb") # 加载人口密度GeoTiff - 移除多余的mask设置 xds = rxr.open_rasterio("cog_general_2020.tif", masked=True, from_disk=True) # 重投影到刚果中心的保面积投影 target_crs = "+proj=cea +lat_0=1.346245 +lon_0=17.150298 +units=km" df = df.to_crs(target_crs) xds = xds.rio.reproject(target_crs) # 筛选Lac Télé边界 lactele = df[df['NAME'] == 'Lac Télé'] xds_lactele = xds.rio.clip(lactele.geometry.values, df.crs, from_disk=True) # 计算每个像元的面积(平方公里) pixel_area = xds_lactele.rio.set_spatial_dims(x_dim="x", y_dim="y").rio.calculate_area() # 密度×像元面积得到单像元人口,求和得到区域总人口 total_pop = (xds_lactele * pixel_area).where(xds_lactele > 0).sum().compute() print(f"区域总人口: {total_pop.values[0]:.0f}")
额外验证建议
- 查看栅格元数据确认密度单位(常见为「人/平方公里」或「人/平方米」),确保面积单位与之匹配。若原数据为「人/平方米」,需将面积转换为平方米(乘以1e6)。
- 可视化裁剪后的
xds_lactele,确认边界内栅格范围是否符合预期,排除误裁剪情况。
内容的提问来源于stack exchange,提问作者utra
相关产品推荐
相关产品推荐

