重庆建筑面shp数据处理:面积重算与人口分摊全流程解析
2026/9/17 6:05:00 网站建设 项目流程

简介:覆盖城市与农村的重庆市建筑物面数据,以shp格式提供建筑面要素及面积、人口等属性信息。数据面向GIS数据分析师、城乡规划研究者与环境工程从业者,适用于城市内涝治理、SWMM模型构建、智慧城市与碳中和背景下的下垫面分析,也可用于建筑能源建模、城乡空间规划与区域发展趋势评价。资源包共6个文件,大小约309.41MB,包含shp几何主体、dbf属性表、prj投影定义、shx空间索引、cpg字符编码和xml元数据,导入ArcGIS或QGIS即可打开建筑轮廓;dbf中记录的面积、人口字段可直接用于查询统计和空间关联分析。目前已有919人浏览学习。整体数据粒度较细,用户既能快速获取准确的建筑轮廓底图,也可结合人口字段开展灾损评估、不透水面比率计算、屋顶光伏潜力评价或子汇水区划分,为内涝模拟与可持续发展相关研究提供可靠的空间数据支撑。

1. 一份带面积和人口信息的重庆建筑面 shp,先别急着算

一份带面积字段、又挂着人口信息的重庆建筑物面数据(城市+农村 shp 格式),在 GIS 项目里属于“想用又不敢直接用”的数据。建筑面要素决定它适合做空间统计底数:城市部分能算建成区密度、容积率强度、步行圈覆盖楼栋数;农村部分能配合宅基地盘点和空心村分析。面积与人口两个属性同时出现,意味着能支撑人均建筑面积、公共设施缺口这类跨口径计算。常见做法是先把坐标系和面积单位校准,再按城市/农村分组汇总和分摊,最后导出统计表或轻量三维数据。这份数据对做国土空间规划、城市体检、应急评估和 GIS 数据处理的人都有用,下面各章把每一步的可复现命令和参数讲透。

2. 先读字段和坐标系:重庆建筑面数据的面积与人口信息怎么确认口径

2.1 打开 shp 前先看 .prj:重庆地区该用哪套投影

拿到 shp 不要直接拖进软件就算面积。一套 shp 由 .shp、.dbf、.shx、.prj 四个文件组成,其中 .prj 记录坐标系。重庆建筑面数据常见两种出处:测绘部门成果常是 CGCS2000 高斯 3 度带投影,互联网采集或开放平台整理出来的则多为 WGS84 经纬度。前者能直接量算平面面积,后者必须先做投影转换,否则面积函数返回的是“度平方”,数字完全没有现实意义。

在 QGIS 里加载后,右键图层 → 属性 → 信息面板能看到当前 CRS;命令行用 ogrinfo 更快:

ogrinfo -so chongqing_building.shp chongqing_building

-so表示只输出图层概要,不遍历全部几何;最后的图层名一般等于文件名主体。输出里重点看 Spatial Reference、Feature Count 和字段列表,坐标系名里如果出现 3-degree Gauss-Kruger,通常可以直接按投影坐标算平面面积;如果显示 EPSG:4326,后面第 3 章那步投影转换不能省。用文本编辑器直接打开 .prj 也能看到类似PROJCS["CGCS2000 / 3-degree Gauss-Kruger CM 105E"]的字符串。

重庆东西跨约 5 个经度,同一套高斯投影带覆盖不了全境,不同区县给的成果可能分属不同带。常见选型见下表:

坐标系EPSG适用区域面积计算方式
CGCS2000 3 度带 CM 105E4546重庆西部区县及主城大部投影平面面积
CGCS2000 3 度带 CM 108E4547万州、奉节、巫山等东部区县投影平面面积
WGS84 / UTM 48N32648兜底方案,东部超 108°E 时改用 32649平面面积
WGS 84 经纬度4326只做显示和空间查询不适合直接量算

提示:如果要做全重庆统一汇总,推荐自建一个 Albers 等积投影,中央经线取 107°E,两条标准纬线取北纬 25° 与 47°,面积误差在各区县分布更均匀。

CGCS2000 与 WGS84 的椭球差异在几十公里尺度下的平面面积误差约为十万分之一,县区级统计可以忽略。若 .prj 缺失,先在 QGIS“图层 → 设置图层 CRS”里手动指认,不要让软件用默认 4326 硬算。

2.2 用 GeoPandas 盘点字段:面积、人口、城市/农村到底叫什么名

字段名是这份数据里最需要确认的东西。shp 的 dbf 格式字段名最长 10 个字符,中文通常被转成拼音或缩写,所以不要假设它叫“面积”和“人口”。先跑一段代码把家底盘清楚:

import geopandas as gpd # encoding 参数对应 .dbf 字符集,测绘成果常见 gbk gdf = gpd.read_file("chongqing_building.shp", encoding="utf-8") print(gdf.crs) print(gdf.shape) print(gdf.columns.tolist()) print(gdf.dtypes) print(gdf.describe())

read_file的 encoding 参数控制属性表编码,读出来中文是乱码就把 utf-8 换成 gbk 重试。shape给出要素数和字段数,columns.tolist()列出全部字段名,常见命名有AREAMJ(面积),POPRENKOU(人口),TYPECZNC(城镇/农村)。describe()会打印数值型字段的 count、min、max:人口字段最大值才 20,说明是楼栋级;最大值上万,说明是村级聚合值,这个判断第 4 章还要用到。确认无误后,再决定是保留原始 shp 还是把清洗结果导出成新的 shp 文件,避免在原文件上反复改。

2.3 面积字段的两种口径:几何面积与属性面积要分开对待

属性里的面积未必等于几何面积。常见三种情况:一是按投影坐标直接算的平面面积;二是 QGIS 中$area按椭球计算的椭球面积;三是人工修正口径,比如农村图斑扣除了挑出墙体的雨棚部分。判断方法:在 QGIS 里选中一个矩形轮廓清晰的楼,用测量线工具量长宽相乘,再与属性面积对比,差 5% 以内说明几何与属性基本一致。

另一个容易踩的口径问题是“基底面积 vs 建筑面积”。建筑面要素的几何轮廓是基底,占地面积由它决定;但人口信息对应的是居住空间,高层住宅需要基底乘楼层数才能得到建筑面积。标题里同时给出面积和人口,常见处理是把面积字段先当作基底面积,再补一个楼层字段折算;若数据里没有楼层字段,第 4 章的分摊只能用基底面积,结果要备注“未含楼层系数”。

提示:如果 AREA 字段最大值只有几百,单位可能不是平方米,而是已经换算过的公顷或万平米,先统一成平方米再做任何汇总。

3. 面积重算与几何修复:重庆城市和农村建筑面的量算细节

3.1 为什么不能在 WGS84 经纬度下直接算面积

前面说 4326 下面算面积没有现实意义,这里把数值量级讲透。EPSG:4326 的几何单位是十进制度数,几何面积函数返回“平方度”。在北纬 30 度附近,1 度经度约 96 公里,1 度纬度约 111 公里,一个“平方度”接近一万平方公里量级;一栋 100 平方米的楼在这个坐标系里算出来是一串不直观的小数,既无法换算成真实平方米,也不能参与任何统计。

常见错误是算完“平方度”后乘一个固定系数修正。这个系数只在某个纬度带成立,重庆从江津到城口纬度差近 4 度,同一系数跨区县误差会被放大,项目验收时经不起抽查。正确做法是先整层重投影到 4546 或 4547,再在投影坐标系里算面积。QGIS 中对应操作是“处理工具箱 → 矢量通用 → 重投影图层”,目标 CRS 搜索框里直接输 4546;GeoPandas 里就是后面代码中的一行to_crs

3.2 用 QGIS 字段计算器重算面积并对比原字段

打开属性表 → 字段计算器,勾选“创建新字段”,字段名填 area_m2,类型选浮点数,精度 2。表达式填:

round(area($geometry), 2)

area()返回当前工程 CRS 单位下的面积,工程 CRS 是投影坐标系时输出就是平方米。算完后新建一个偏差字段:

round("AREA" - "area_m2", 2)

按偏差字段降序排序,把偏差大的要素挑出来逐一看。如果原字段普遍比新算的大 10% 以上,检查它是不是建筑面积(已含楼层)口径;如果偏差集中在某个乡镇,多半是该区域做过一次边界修正,但属性表没有同步更新。

做全重庆市汇总时,我一般不用area($geometry),而是用$area,并在“工程 → 选项 → 坐标与测量”把椭球体设为 GRS 80。$area按椭球计算大地面积,对跨分带、跨中央经线的要素比平面面积更接近地表真实值。两种结果的差在重庆主城区通常不到 0.1%,但东北、东南边缘县能到 0.5% 以上,出报告时要把这个口径写明。

3.3 用 GeoPandas 批量检查无效几何并重新算面积

从公开渠道整理的建筑面数据,几何拓扑问题比预想的多。常见问题是自相交、重复环和零宽度的退化面,QGIS 里显示成红色感叹号。批量处理用 GeoPandas 加 shapely:

import geopandas as gpd from shapely.validation import make_valid gdf = gpd.read_file("chongqing_building.shp", encoding="gbk") gdf = gdf.to_crs(4546) # 按数据位置选用 4546 或 4547 before = gdf.geometry.is_valid print(f"invalid: {before.sum()} / {len(gdf)}") # 只修无效要素,避免整层重写 mask = ~before gdf.loc[mask, "geometry"] = gdf.loc[mask, "geometry"].apply(make_valid) # 重算面积,单位平方米 gdf["area_m2"] = gdf.geometry.area print(gdf["area_m2"].describe()) # 按城市/农村字段分组汇总,换算成平方千米 summary = gdf.groupby("TYPE")["area_m2"].agg(["sum", "count"]) summary["sum_km2"] = summary["sum"] / 1e6 print(summary)

is_valid判断每个几何的拓扑有效性,返回布尔序列;make_valid来自 shapely.validation,会把自相交面拆成多个合法面,理论上修复后面积会略有变化。只对无效要素做修复,可以保留其余几何原样不动。groupby("TYPE")假设 TYPE 是城市/农村分类字段,如果它是 0/1 编码,先跑一遍value_counts(dropna=False)看分布再分组。

3.3.1 修复后面积异常的三个排查方向

修复后结果与原字段对不上号时,从三个方向排查。其一,修复后面积极小或为 0,说明几何退化成了线或点,这类要素用gdf[gdf.geometry.area == 0]筛出来,按原始属性决定删除还是保留占位。其二,出现面积超过 10 万平方米的“楼”,多半是多部件几何里混入了宗地边界或自然村落的残留面,按面积分位数把尾部切掉。其三,修复后面积普遍比原字段小一截,回到 2.3 节说的口径问题:原字段很可能是建筑面积,几何面积只是基底,两者本来就不该相等。

4. 城市与农村划分、人口信息粒度与面积加权分摊

4.1 先判读 TYPE 字段:城市/农村分类的三种常见编码

城市/农村分类字段看起来简单,实际拿到手常见三种编码:字符型(“城”“乡”或 C/R)、整数型(1/2)以及国土空间用地分类码(110 城镇住宅、203 村庄等)。先看分布再动手:

print(gdf["TYPE"].value_counts(dropna=False))

输出里要特别留意 NaN。空值建筑往往来自卫星影像自动解译时的漏标,处理时不要直接填成“城市”。常见做法是用区县级行政区划 shp 做空间连接:落在城镇开发边界或街道辖区内的空值补“城市”,其余补“农村”。QGIS 里的“按位置连接属性”工具可以完成这一步,GeoPandas 用sjoin。各类取值怎么处理,按下表来:

取值样例含义建议处理
城 / 乡直接可读无需转换
1 / 2常见于土地调查数据建字典映射为城市/农村
110、202、203 等国土空间用地分类码按二级类映射归类
空值漏分类或混入非建筑要素空间连接补齐,仍缺失则剔除

4.2 人口信息粒度体检:楼栋级还是村级决定后续算法

标题里的“人口信息”可能是楼栋级(每栋建筑一个估算常住人口),也可能是乡镇或村社级(每个村一个总量,通过行政区代码挂接)。两种数据的用法完全不同,先做粒度体检。看describe()的 max:楼栋级的 max 一般只有几十,村级总量会上千上万。再把人口按 TYPE 分组求和,与统计年鉴的区县常住人口对比,数量级吻合的是村级数据分摊下来的,逐栋有值且总量级对得上的才是楼栋级。

还要检查有没有行政区代码字段,比如 XZQH、XZQHC。有它才能安全做关联,否则只能靠空间位置判断归属。村级人口挂接的代码长这样:

import pandas as pd # pop_table 需包含 code 与 pop 两列 pop_table = pd.read_csv("village_pop.csv", dtype={"code": str}) gdf["XZQH"] = gdf["XZQH"].astype(str) merged = gdf.merge(pop_table, left_on="XZQH", right_on="code", how="left") print(merged["pop"].isna().sum())

merge的 left_on 对应建筑面里的行政区代码,right_on 对应人口表里的代码字段,用 how="left" 保留全部建筑要素。合并后出现空值说明有楼栋落在了没有人口统计的飞地或开发区,后续计算按 NaN 保留,不要直接fillna(0),不然会让有值区域的分摊比例失真。

4.3 用面积加权把村级人口分摊到建筑面,并验证总量

当人口只在村级时,分摊的前提假设是“同一村里人均居住面积相近”。城市楼房用基底面积直接分摊不合理,要尽量折算成建筑面积,农村独栋农房则可以直接用基底面积。折算与分摊代码如下:

# 有效居住面积:农村用基底,城市按楼层折算 if "FLOOR" in merged.columns: merged["eff_area"] = merged.apply( lambda r: r["area_m2"] * r["FLOOR"] if r["TYPE"] == "城" else r["area_m2"], axis=1, ) else: merged["eff_area"] = merged["area_m2"] # 村内面积占比 merged["share"] = merged.groupby("XZQH")["eff_area"].transform( lambda s: s / s.sum() ) # 楼栋人口估算 = 村级总人口 × 面积占比 merged["pop_est"] = merged["share"] * merged["pop"]

groupby("XZQH")["eff_area"].transform把每个村内部的 eff_area 归一化到 0 到 1,得到每栋楼在该村内的面积占比;pop_est是占比乘村级总人口,量纲是“人/栋”。这一步的假设是人口密度在村内均匀,农村空心村和城市老旧小区会偏低或偏高,结果只能用于总量级评估,不能当作单栋实测值。做完后验证:merged.groupby("XZQH")["pop_est"].sum()应该能还原回村级总量;再把全市 pop_est 求和与七普常住人口对比,偏差在 20% 以内说明口径可用,超过则回查楼层字段是否缺失。

5. 三招收尾:shp 转 txt、只保留外边界线、为 3dtiles 做预处理

5.1 shp 转 txt / CSV:把属性与坐标导出来做统计

数据清洗完,下一步通常是出统计表或入数仓。shp 转 CSV 时最容易翻车的是编码和坐标:

ogr2ogr -f CSV chongqing_building.csv chongqing_building.shp \ -t_srs EPSG:4326 -lco GEOMETRY=AS_XY \ -lco WRITE_BOM=YES -lco ENCODING=UTF-8

-t_srs EPSG:4326先把坐标转成经纬度,否则 AS_XY 导出的是投影坐标下的 X/Y,单独拿出去对不上地图底图;WRITE_BOM=YES让 Excel 打开 UTF-8 文件不乱码;ENCODING=UTF-8覆盖属性字符集。只想导人口和面积时加-select AREA,POP,TYPE减少体积。反过来,如果手里是 Excel 经纬度表要生成 shp,QGIS“添加分隔文本图层”直接导入再导出即可,没必要在 ArcMap 里绕一圈。

5.2 只保留外边界线:从建筑面提取组团轮廓

建筑面数据做展示时经常只要轮廓线。单栋建筑用 QGIS“提取边界”工具即可;如果想把一个村或街道的所有建筑合并成一个组团轮廓,需要先融合再取外环,PostGIS 写法如下:

SELECT XZQH, ST_ExteriorRing((ST_Dump(ST_Union(geom))).geom) AS boundary FROM buildings GROUP BY XZQH;

ST_Union先做拓扑合并,内部共边会消掉;ST_Dump把合并后的多部件拆成单个连通块;ST_ExteriorRing只取外环,得到的就是边界线。几十万栋建筑直接 Union 会非常慢,先用 XZQH 分组控制数据规模。这一步产出的轮廓线可以用于制图晕边、计算建成区形状指标,也可以转成 KML 在移动端核对。

5.3 为 shp 转 3dtiles 做预处理

建筑面数据是三维白模的常见底料。转 3dtiles 前先保证几何有效、坐标系统一,再转 WGS84 经纬度:

ogr2ogr -f GeoJSON chongqing_building.geojson chongqing_building.shp \ -t_srs EPSG:4326 -lco RFC7946=NO

GeoJSON 对坐标精度默认保留有限位数,多边形坐标保留 7 位小数对应厘米级误差,做白模足够;RFC7946=NO是为了避免某些转换工具强制改写坐标轴方向,这个开关在调试别的地市数据时能少踩坑。转出的 GeoJSON 配高度字段或楼层字段拉伸成体块,再进入三维管线生成 3dtiles。收尾验证:加载进场景后随机挑 10 栋楼,对比影像底图的位置和轮廓重合度,偏差超过一个楼宽就回头查坐标转换那一步,而不是怀疑渲染引擎。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询