ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

CMAB中国建筑矢量数据集全解析:从数据字典到三维可视化实践

CMAB中国建筑矢量数据集全解析:从数据字典到三维可视化实践 直接进入正题。这两天在整理城市级三维可视化项目时把 2024 年发布的 CMAB中国多属性建筑矢量数据集重新完整测了一遍。3100 万栋单体建筑带高度、功能、年份、质量分级而且发表在 Sci Data 上这份数据对做城市规划、GIS 分析、三维建模、仿真模拟的人来说价值非常大。这篇文章我完整拆解 CMAB 的数据结构、字段语义、加载处理、三维化流程以及我实际踩过的坑希望能帮你少走弯路。1. CMAB 数据整体认知与核心价值1.1 这份数据到底包含什么CMAB 全称 China Multi-attribute Building dataset2024 年发布在 Scientific Data 期刊上核心单位是“单体建筑轮廓面”覆盖全国范围总量超过 3100 万栋。每一栋建筑除了几何轮廓还附带了一系列结构化属性字段包括省级、市级、区县行政区划编码、中心点经纬度、建筑高度、楼层数、主要功能类型、建成年份、数据质量等级和数据来源标识。用一个直观的比喻以前我们拿到手的建筑数据往往是“一张只有轮廓的白纸”你只知道哪里有房子不知道它多高、哪年建的、用来干什么。CMAB 相当于在这张白纸上叠了一层“登记表”——每栋房子都填好了姓名、年龄、职业和身高。这个差距决定了数据是从“看个大概”到“能做分析”的分水岭。从数据格式上看CMAB 以 shapefile 为主几何类型覆盖 Polygon 和 MultiPolygon因为部分建筑轮廓由多个闭合区域构成属性编码方式沿用了国际主流建筑数据集的风格在 QGIS、ArcGIS、PostGIS 等常规 GIS 工具链里可以直接读取和分析。1.2 解决的核心问题与应用场景CMAB 解决的最核心问题是“全国尺度建筑级空间信息缺失”。过去做全国范围的城市研究要么依靠统计年鉴汇总数据精度只到区县要么依靠遥感影像人工提取成本极高要么依赖 OSM 等众源数据属性字段稀疏。而 CMAB 把“单体建筑的属性化”下沉到了全国层面让很多以前只能“宏观描述”的研究第一次有了“微观计算”的基础。适合的人群和场景我按实践价值排序城市规划与城市体检利用建筑高度、功能、年份做城市空间形态分析识别城中村、老旧小区、产业集聚区支撑城市更新决策。三维可视化与数字孪生建筑高度和楼层数可以直接驱动程序化建模快速生成城市级白模或简模底座配合 UE、Unity 或 Cesium 使用效果非常直观。建筑能耗与碳排放模拟楼层数、建成年份、功能类型是能耗估算的核心输入参数把 CMAB 挂接能耗模型后可以快速产出区域级能耗分布图件。人口分布精细化估算以建筑功能居住/商业/办公和建筑体量为空间权重把区县级人口数据降尺度到建筑级再做公共服务设施配置和应急管理分析。1.3 与其他建筑数据源的横向对比为了说清楚 CMAB 的定位我拉了一张对比表把我实际用过的几类全国尺度建筑数据放一起做了比较数据源覆盖范围建筑数量属性丰富度开放程度典型用途CMAB 2024全国3100 万高度/功能/年份/质量公开论文数据城市级分析、三维底座OSM 建筑轮廓全国重点城市为主数百万级高度/楼层较稀疏完全开放底图叠加、初步三维化遥感解译建筑足迹全国数千万级基本无属性部分开放形态识别、变化检测商业地理信息数据全国数亿级丰富但口径不一商业授权商业选址、精细分析从这张表能看出CMAB 的优势集中在“单体建筑”和“多属性”两个交叉点上。它不完全替代 OSMOSM 在局部更新速度和众包完整性上仍有优势也不替代遥感解译产品解译产品在几何完整性上更统一但它把“形态”和“属性”合并成了一份开箱即用的数据集这是最难得的地方。2. 数据字典与字段设计思路2.1 核心字段逐项解读直接上字段表这是我自己整理并验证过的版本也是后面所有实操的基础。字段名类型说明典型值示例bldg_idvarchar建筑唯一标识B230001provvarchar省级行政区北京市cityvarchar地级市北京市countyvarchar区县朝阳区longitudedouble中心点经度CGCS2000116.4864latitudedouble中心点纬度CGCS200039.9215heightdouble建筑高度米36.5floorsint建筑层数12functionvarchar主要功能类型居住year_builtint建成年份2008qualityvarchar数据精度等级高sourcevarchar数据来源标识测绘/遥感/OSM先说字段设计里我认为最关键的两个点。一个是height和floors并存这在建筑数据里非常关键。因为不同来源的建筑高度精度差异很大遥感影像推算出的高度误差可能有 3-5 米而楼层数往往是人工采集更准。实际分析时我通常取两者校验如果高度÷层高按 3 米估算和层数偏差太大就标记为可疑样本在模型中降权处理。另一个是function字段的分类口径。CMAB 采用了基于用地和建筑实态的混合分类比如“居住”“商业”“办公”“教育”“医疗”等。它不等同于用地分类标准但在建筑尺度分析中非常实用。做功能混合度分析时直接按这个字段聚合统计即可省去了大量属性映射工作。2.2 坐标系与几何语义CMAB 采用的是 CGCS2000 地理坐标系经纬度EPSG 编码为 4490。这一点非常关键因为很多人拿到数据后直接按 WGS84EPSG 4326处理虽然两者在多数地区差异很小但做高精度拼接或长度面积计算时必须先转换到投影坐标系。具体处理建议是这样的全国范围出图时直接用 4490 叠加没问题做城市级面积统计时先按城市边界裁剪再投影到该城市的 CGCS2000 / 高斯-克吕格投影带例如北京地区常用 EPSG 4526然后再计算面积和距离避免经纬度坐标直接算面积导致的严重偏差。经纬度坐标下算面积本身是无效的这一点新手特别容易踩。几何语义上geom字段类型是 Polygon/MultiPolygon代表建筑基底轮廓。需要特别注意的是CMAB 的轮廓是“建筑主体投影”并非产权边界也并非屋顶完整轮廓。做三维建模时默认按矩形体块拉伸即可但遇到特殊形态建筑如 L 形、U 形、带中庭的合院直接拉伸会失真需要结合遥感影像或者手动调整处理。2.3 数据质量分级机制解读quality字段是我认为 CMAB 里最有“工程意识”的设计。它把每一栋建筑的数据可靠程度做了分级常见分级包括“高”“中”“低”或者 1-3 级。这个字段背后反映的是数据生产链路高精度建筑可能来自测绘院矢量成果或高分遥感立体像对低精度建筑可能来自公开地图轮廓和高度估算模型。实际操作中我习惯把 quality 字段用做“信任阈值”。做城市级可视化时高质量区域用精细建模参数低质量区域用占位方块做空间统计时低质量样本只参与数量统计不参与高度均值计算避免个别离群值污染整体结论。这个字段的价值简单说就是给了你“哪里能用、哪里要谨慎”的答案。为了让你更直观理解 quality 的作用我举个例子某个片区的平均建筑高度是 22 米如果把 quality低 的样本也纳入均值结果可能直接变成 35 米因为低质量样本里包含了大量高度估算偏高的工业厂房。筛掉之后结果才回归真实。所以质量分级字段不是可有可无的装饰而是统计可信度的守门员。3. 数据获取与预处理实操3.1 下载与初始检查CMAB 原始数据以 shapefile 格式组织下载后通常按省份或区域分幅压缩包存储。拿到数据后不要急着分析我建议先做一轮“健康检查”检查压缩包完整性确认每个分幅的 .shp、.dbf、.shx、.prj 文件都齐全。用 QGIS 直接拖入 shp 文件检查几何是否能正常显示、属性表是否乱码。查看图层属性里的坐标系描述确认是 CGCS20004490。统计记录数、空值数量、几何类型分布形成初步质量报告。如果 dbf 属性表出现中文乱码通常是编码识别问题。shapefile 的 dbf 属性默认使用 ANSI 编码而不同工具默认读取编码不一致。解决办法是在 QGIS 导入时手动指定编码为 UTF-8 或 GBK或者用 GDAL 命令行工具重新转一份 UTF-8 副本。后续所有工具链统一走 UTF-8能避开大量麻烦。3.2 PostgreSQL/PostGIS 入库实操对于 3100 万栋这种体量直接用 QGIS 打开做全库浏览是不现实的建议入库 PostgreSQL/PostGIS用 SQL 做空间分析和属性处理。我自己在建库时用了一份通用建表 SQL已经验证过可以直接跑CREATE TABLE IF NOT EXISTS cmab_2024 ( bldg_id VARCHAR(32) PRIMARY KEY, prov VARCHAR(32), city VARCHAR(32), county VARCHAR(32), longitude NUMERIC(10, 6), latitude NUMERIC(10, 6), height NUMERIC(8, 2), floors INTEGER, function VARCHAR(32), year_built INTEGER, quality VARCHAR(16), source VARCHAR(64), geom GEOMETRY(Polygon, 4490) ); CREATE INDEX IF NOT EXISTS idx_cmab_geom ON cmab_2024 USING GIST (geom); CREATE INDEX IF NOT EXISTS idx_cmab_city ON cmab_2024 (city); CREATE INDEX IF NOT EXISTS idx_cmab_function ON cmab_2024 (function); CREATE INDEX IF NOT EXISTS idx_cmab_year ON cmab_2024 (year_built);入库时推荐用 ogr2ogr 命令比 GUI 导入快而且可重复执行ogr2ogr -f PostgreSQL PG:dbnamegis userpostgres passwordyourpassword \ -nln cmab_2024 -t_srs EPSG:4490 -lco GEOMETRY_NAMEgeom \ /path/to/cmab_2024.shp如果你拿到的 shp 本身已经是 4490-t_srs EPSG:4490可省略如果是其他坐标系这个参数会自动做一次坐标转换。入库后建议立刻做一轮字段空值统计SELECT count(*) AS total, count(height) AS has_height, count(year_built) AS has_year, count(function) AS has_function, count(*) - count(height) AS missing_height FROM cmab_2024;这个统计结果就是你后续所有分析的“可信度基线”。如果某个字段空值率超过 20%那基于该字段做定量分析时需要格外谨慎最好在报告里注明空值影响范围。3.3 数据清理与质量提升的常见做法数据入库不等于数据可用CMAB 虽然整体质量不错但实际使用前仍建议做一轮清理。我的处理顺序是第一字段类型修正。年份字段在原始 shp 里经常被存成字符串做年代统计前必须先转成整数。QGIS 字段计算器一行就能解决SQL 里也简单ALTER TABLE cmab_2024 ALTER COLUMN year_built TYPE INTEGER USING year_built::integer; ALTER TABLE cmab_2024 ALTER COLUMN floors TYPE INTEGER USING floors::integer;第二几何拓扑修复。相邻建筑轮廓可能存在微小重叠或缝隙这在空间统计时会造成面积重复计算。我习惯用 PostGIS 的ST_MakeValid配合 ST_Union 做一轮批量修复但要注意批量修复会改变部分建筑的几何形态建议先只对检测出问题的要素执行。第三空值分层赋值。对于year_built为空但周边建筑年份齐全的情况可以用“空间邻域均值”回填对于无法回填的我建议保留 NULL 而不是填 0并在元数据文档中标注避免后续分析时把 0 当成真实年份使用。切忌直接删除空值行因为几何要素和属性表的对应关系一旦破坏后续合并会非常痛苦。4. 三维化与二三维联动实战4.1 从二维 shp 到三维体块的基本流程CMAB 最适合展示的姿势我认为就是三维化。把建筑轮廓按高度拉伸成体块叠加到底图上城市天际线立刻就能“立起来”。常规流程是先按城市或格网裁剪数据再用高度字段驱动拉伸。最轻量的方案是 QGIS 的 Qgis2threejs 插件不需要写代码就能生成可交互的 3D 网页场景。具体操作步骤大概是在 QGIS 中加载 CMAB 图层按目标城市或格网范围筛选避免一次加载全国数据导致卡死。打开 Qgis2threejs 插件选择高度字段为height颜色字段可选function或year_built。设置垂直 exaggeration 为 1.0真实比例输出到 HTML 文件。浏览器打开即可看到三维体块叠加遥感影像的效果。这套流程的优点是完全免费、零代码10 分钟能跑通缺点是绘制性能和交互能力有限只适合局部区域和方案沟通场景。如果要做更复杂的城市级三维场景下一步需要进入专业工具链也就是下面要说的 Cesium 与 UE 方向。4.2 基于 Cesium 的 3D Tiles 落地经验Cesium 是三维地球场景的首选之一尤其适合做“大体量、主数据、广视角”的城市级展示。把 CMAB 改造为 3D Tiles 的完整链路我建议用 FME 或第三方转换工具例如由 shp 转 glb/glTF再切片为 3D Tiles也可以直接用部分开源工具链完成。这里我不展开商业工具只讲我实际使用开源路径时的经验。第一步是属性预处理。三维化过程中height字段决定了拉伸高度function和quality决定后续样式的分级配置bldg_id是属性查询的唯一主键。转换前建议把字段重命名为引擎友好的英文名并确认单位统一为米。第二步是三维体块生成。可以将每栋建筑按height生成棱柱体输出为 glTF 或 glb 格式。这里我要提醒一个关键细节crs 转换和单位设置。CMAB 是 4490 地理坐标而大多数三维引擎需要米制投影坐标或地理坐标所以要先做一次坐标转换把经纬度转成 Web Mercator 或高斯投影坐标再进入三维建模流程。第三步是切片发布。把生成的单个建筑模型合并为城市级倾斜摄影或白模数据再按照网格切分为 3D Tiles 分块这样 Cesium 才能按需加载而不是一次渲染全部模型。实际测试中3100 万栋全量切成精细 3D Tiles 规模非常大建议按城市独立切片每座城市单独发布服务。用小范围验证时比较顺利但做城市级全量时我遇到过一次非常典型的性能问题Web 端直接加载所有建筑瓦片导致浏览器崩溃。后来把数据切成 10km x 10km 的网格在 Cesium 中按视野范围动态加载流畅度好了很多。4.3 三维建模的层级策略与属性语义化在城市级三维场景里大量逐栋建模是不现实的。我的经验是按 LOD细节层次进行分级远景用低模单色方块中景用体块高度设色近景才叠加真实纹理和精细模型。CMAB 的quality字段在这里可以充当 LOD 分层阈值比如quality高 的区域近景用精细模型quality低 的区域始终用低模这样能把资源花在看得见的地方。关于建模工具链当前主流的城市级程序化建模工具都是属性驱动的。CMAB 刚好具备height、floors、function、year_built等字段完全符合程序化建模的属性要求。用 CityEngine 规则或者 Blender Geometry Nodes 都能实现按属性批量生成建筑体块。属性语义化到这个环节就开始发挥作用了字段名字必须是引擎认识的规范名比如高度就应叫height层数就应叫floors不能是H或者层数。因此我建议在进入三维工具链之前先做一次属性标准映射。我对属性语义化的体会是它是三维化和后续所有高级分析的隐形基石。很多人在这一步偷懒结果到引擎里发现属性没映射上程序化建模就失败了回头还得重新导数据得不偿失。5. 常见问题与排查技巧实录5.1 数据加载与显示问题症状shp 加载后与底图错位跑到海里去了。排查顺序先看元数据里的坐标系描述再看 .prj 文件是否存在最后用 QGIS 的“图层属性—源”面板确认。CMAB 是 CGCS2000 地理坐标如果工具默认按 WGS84 识别两者差异虽然不大但放到城市级底图下几米偏移还是看得出来的。处理方法是显式指定坐标系再重投影。症状加载后属性表全是乱码。排查顺序shp 的 dbf 属性默认用 ANSI/本地编码存储中文属性名最容易出乱码。解决办法很简单用 QGIS 导入时选择合适编码如 UTF-8 或 GBK或者用 GDAL 的-encoding参数重写一份 UTF-8 副本后续所有工具链统一用 UTF-8。5.2 属性与几何常见坑属性表空值多CMAB 部分字段可能为空尤其是早期的年份字段。处理时我用“分层赋值”策略优先用官方补充资料回填其次用邻居平均最后标记为unknown并在说明文档中标注。切忌直接删除行否则几何要素和属性表的对应关系会错位这种错误排查起来非常费劲。几何重叠与缝隙相邻建筑轮廓在数据生产时可能边界不重合做空间分析时容易造成面积统计偏差。我用“拓扑修复 按最小缝隙阈值合并”的方式处理阈值一般取 0.5 米。注意修复前先备份原始表以免修复结果不理想无法回退。字段类型不匹配年份字段在 shp 里经常被存成字符串做年代统计时直接报错。遇到这种情况先在 QGIS 里用字段计算器转成整型再参与运算。这个坑虽然小但出现频率非常高。5.3 三维化与导出问题速查症状核心原因解决建议模型高度异常单位不一致或高度字段取错检查属性映射与引擎单位设置模型破面/悬空MultiPolygon 未拓扑修复先“修复几何”再导出模型3D Tiles 属性丢失旧字段命名不匹配检查批次表属性名并手动映射导出卡死要素数量过大、内存不足按行政区/格网分块导出渲染闪烁重叠面未清理执行重叠消除与拓扑修复再检查三角面法线5.4 我对质量字段与功能字段的使用心得quality 字段是我最喜欢用的字段。做城市级可视化时我不可能对 3100 万栋楼逐一人工建模正确的打开方式是“按质量分层处理”高质量区域用精细建模参数低质量区域用低模占位把算力花在看得见的地方。这个过程靠 quality 字段做分层阈值几分钟就能完成配置而且效果比一刀切的均匀建模好得多。function 字段是做空间统计的利器。计算某个片区的居住/商业/公共服务配比直接按 function 分组汇总结果马上就能出来。比起拿着 CAD 图逐栋去核对效率提升是数量级的。做个简单 SQL 就能输出一张“片区功能构成表”再结合 QGIS 的图表功能就能给方案汇报配图。source 字段适合做数据治理。当我发现某个片区数据明显偏旧时通过 source 字段能快速定位到数据来源再去对应的渠道做增量更新。日常维护 CMAB 数据时这个字段省了我大量时间。6. 数据扩展与应用方向6.1 与 POI、路网数据结合的城市功能体检CMAB 提供的是建筑“形体基础属性”一旦与 POI 数据商铺、公司、公共服务和路网数据结合就能做城市功能体检某个片区建筑密集度高但 POI 密度低基本可以判断是“睡城”还是“产业空心化”。我把 CMAB 与本地 POI 数据做空间连接后做了几个城市片区的功能混合度分析结论很有说服力。具体做法是把 CMAB 建筑按function聚合出“居住面积”“商业面积”等指标同时把 POI 通过空间连接归到对应建筑上再以街区为单位汇总。最终得到每个街区的“功能混合指数”高低分区一目了然。这种分析在城市体检项目中非常受欢迎因为它直观地回答了“这个区域到底适不适合居住”的问题。6.2 时间序列与城市更新分析CMAB 的年份字段支持按年代筛选可以直观看到城市扩张轨迹从核心区向外围蔓延的路径、工业区改居住区的变迁、城中村改造的阶段性成果。我把这些按年份做分层设色渲染输出的图件在城市规划汇报里非常受欢迎。实际操作时按照year_built分桶1980 前、1980-1990、1990-2000、2000-2010、2010 以后分别设色渲染。这样一看城市不同年代的“生长带”非常清晰。再叠加道路网和轨道交通线就可以讨论城市扩张的驱动力问题。虽然这不算复杂分析但胜在直观、可解释性强非常适合用于汇报场景。6.3 更多扩展方向与倾斜摄影模型叠加用 CMAB 做“标准底座”快速定位倾斜模型的质量盲区。倾斜模型往往在屋顶细节上效果好但在建筑侧面纹理和高度精度上不稳定拿 CMAB 体块做对比就能快速找出问题区域。构建模拟仿真底座将 CMAB 建筑体块转换为仿真网格配合交通流、人口分布数据开展城市级应急疏散模拟或噪声传播分析。建筑高度是噪声传播和疏散路径计算的核心几何参数CMAB 的精度足够支撑这种初步仿真。结合人工智能方法先利用 CMAB 属性做预训练特征再对建筑形态进行自动分类或能耗估算。楼层数、高度、功能、年份组成的特征向量对建筑能耗回归模型来说是非常好的输入。这些方向里我最推荐从“数据体检可视化”入手因为这几乎是零门槛的只要会加载 shp 和调样式就能出成果但给人的直观冲击力远比一张普通统计图强得多。先把可视化做出来你自然会发现更多可以做分析的点。结尾花了很多篇幅把 CMAB 从数据内涵、字段设计、二维三维联动到扩展应用都过了一遍。回到开头那句话CMAB 是一份“会说话”的数据。关键在于你愿不愿意去听以及用正确的方法去听。我个人在实际操作中的最大体会是一份数据的好用程度取决于你对它的理解深度。刚开始我会把 CMAB 当成“带属性的建筑面”后来做多了发现它其实是“城市空间的信息骨架”——把它和任何其他数据叠加都会产生新的视角。后续如果你也准备拿 CMAB 做三维可视化、城市规划分析或者仿真模拟我的建议是先花半天时间做一份数据质量体检搞清楚每个字段的覆盖率和可信度再动手做任何复杂的分析这一步能帮你避开 80% 的返工。最后再分享一个小技巧做任何面向公众或客户的城市级可视化之前先把 CMAB 的数据来源、坐标系、精度等级写进元数据说明。这些看起来不起眼的细节往往决定了你的成果能不能被放心地用于决策。数据文档写得越清楚你的成果被采信的概率就越高。附录CMAB 字段字典字段名类型说明典型值示例bldg_idvarchar建筑唯一标识B230001provvarchar省级行政区北京市cityvarchar地级市北京市countyvarchar区县朝阳区longitudedouble中心点经度CGCS2000116.4864latitudedouble中心点纬度CGCS200039.9215heightdouble建筑高度米36.5floorsint建筑层数12functionvarchar主要功能类型居住year_builtint建成年份2008qualityvarchar数据精度等级高sourcevarchar数据来源标识测绘/遥感/OSMgeomgeometry建筑轮廓面Polygon/MultiPolygon-附录 ACMAB 通用建表 SQLPostgreSQL/PostGIS 版CREATE TABLE IF NOT EXISTS cmab_2024 ( bldg_id VARCHAR(32) PRIMARY KEY, prov VARCHAR(32), city VARCHAR(32), county VARCHAR(32), longitude NUMERIC(10, 6), latitude NUMERIC(10, 6), height NUMERIC(8, 2), floors INTEGER, function VARCHAR(32), year_built INTEGER, quality VARCHAR(16), source VARCHAR(64), geom GEOMETRY(Polygon, 4490) ); CREATE INDEX IF NOT EXISTS idx_cmab_geom ON cmab_2024 USING GIST (geom); CREATE INDEX IF NOT EXISTS idx_cmab_city ON cmab_2024 (city); CREATE INDEX IF NOT EXISTS idx_cmab_function ON cmab_2024 (function); CREATE INDEX IF NOT EXISTS idx_cmab_year ON cmab_2024 (year_built);建表后建议补充数据质量说明表用于记录字段覆盖率、采集时间、数据版本等元信息方便后续审计与增量更新。附录 BGeoJSON 数据导出参考如果你需要把 CMAB 的 PostGIS 表导出为 GeoJSON 供前端加载可以直接用 ogr2ogr 完成注意 GeoJSON 默认要求 WGS84EPSG 4326导出时加一次坐标转换即可ogr2ogr -f GeoJSON cmab_city.geojson \ PG:dbnamegis userpostgres passwordyourpassword \ -sql SELECT bldg_id, height, floors, function, year_built, quality, geom FROM cmab_2024 WHERE city 北京市 \ -t_srs EPSG:4326导出后的 GeoJSON 可以直接拖入 Leaflet、Mapbox GL 或 Cesium 做前端展示。注意大文件用 GeoJSON 会导致浏览器卡顿建议按城市或区县分块导出。
返回列表