ARTICLE DETAIL

资讯详情

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

建筑面shp数据如何助攻SWMM建模:从GIS预处理到产流参数

建筑面shp数据如何助攻SWMM建模:从GIS预处理到产流参数 简介面向城市规划、地理信息、应急管理与环境工程等领域的从业者和学生这份2020年上海建筑物面数据含城市与农村可补足下垫面信息缺失、矢量化成本高的痛点以标准shp格式封装能直接在ArcGIS、QGIS中加载使用适用于下垫面分析、SWMM建模、建筑能耗模拟及城乡发展评价。压缩包共6个文件总大小约108.78MB核心为shp建筑面要素层配套dbf属性表记录面积与人口信息shx提供空间索引prj定义坐标系cpg与xml则负责字符集和元数据说明结构简洁但字段基本满足建模需要。浏览/学习人数已有621人108.78MB的体量也侧面反映建筑轮廓细化程度可用作数据精度参考。借助该数据使用者无需重新采集即可获得覆盖上海城乡的建筑面要素可按区县、格网裁剪合并快速构建SWMM汇水区参数、分析屋顶可用潜力、推算人口空间分布也可结合面积字段提取不透水率并评估内涝风险暴露程度为规划决策节省大量前期处理时间。1. 把建筑轮廓shp送进SWMM之前这份数据到底帮你省了什么做SWMM项目的人大概都有同感管网模型调参再玄学好歹有套路真正让人翻车的反而是建模第一步——下垫面数据。你要给汇水区赋不透水率得知道每一块建筑屋顶、院子、道路到底占多少面积你要做溢流节点检查得知道这片汇水区里的人口和建筑密度。没有可靠的面状数据整个模型的产流参数就是空中楼阁。这份2020年上海建筑物面数据城市农村正好补齐这块拼图。它是一份shp格式的矢量数据要素是建筑物面属性里带着面积和人口信息覆盖上海全域城市和农村的建筑都在里面。对SWMM建模来说它的直接价值是你不用再靠目估或者手工描建筑轮廓来推算不透水面积直接把建筑面叠进汇水区按属性统计就行。适合三类人一是做上海片区SWMM模型的工程师二是需要给排水模型提供下垫面底图的规划人员三是做洪涝风险评估、需要快速估算建筑密度和人口分布的研究者。数字一个都不用你自己编矢量面套上去该有的都有了。2. 建筑面shp和SWMM的产流参数为什么它能顶替半天的外业测量2.1 不透水率的底层逻辑面积统计不是目的产流参数才是SWMM的径流模拟质量很大程度上取决于子汇水区不透水率设得准不准。不透水率不是拍脑袋拍出来的它来自“屋顶道路停车场”这类真正不透水的表面积占总面积的比例。建筑面shp给你的就是其中最大的一块——屋顶。剩下还有道路、广场这些但建筑通常占了城市建成区不透水面的绝对大头。拿到这份shp你可以在GIS里把每个汇水区内的建筑面面积累加出来除以汇水区总面积得到“建筑不透水贡献率”。实际建模时我一般会在这个基础上再叠道路中心线或者用地分类把道路比例补进去得到一个更完整的子汇水区不透水率。这里有一个经常被忽略的细节SWMM的Subcatchment属性里%Imperv填的是整个汇水区的不透水比例不是建筑占汇水区面积的比例。如果你直接把建筑覆盖率填进去产流量会偏小因为道路和广场没算进去。这份shp的价值就在于“建筑底数”这一层是可靠的。农村区域尤其明显——农村房屋尺度小、形状不规则手工描一遍轮廓动辄大半天有些房顶还是彩钢瓦、阳光棚这类半透水材料目估误差很大。有了矢量面数据你至少能把“建筑轮廓”这一项钉死剩下的误差来源就只有“材料透水性”这个经验参数了。2.2 面积字段和人口字段一个用于产流一个用于水质和旱季流量属性表里如果带面积字段那你不用自己计算几何省了一步人口字段则能撑起两个用途一是SWMM水质模拟里的污染物累积和冲刷——人口密度直接关联生活垃圾和污水产量二是旱季流量DWF的估算——你把人口字段落到各个汇水区乘以人均排水量系数能算出基础污水量这部分很实用。常见做法是用空间连接Spatial Join把建筑面的面积和人口字段按汇水区边界聚合产出两个统计量——建筑总面积和总人口。需要说明的是shp属性表里的“人口”大概率是按建筑属性比如住宅楼层数、建筑面积估算出来的不是普查口径的实住人口。用它做区域间对比、估算量级没问题但要落到具体社区人数建议还是用街道/居委的人口统计去做校验。2.3 坐标系陷阱WGS84还是CGCS2000直接影响面积量算打开shp第一件事不是看属性表而是看投影坐标系。如果数据是WGS84地理坐标系经纬度直接算面积会得到一个离谱的数字因为经纬度坐标没有投影变形校正。正确做法是先投影到适合上海的区域投影坐标系——常见用CGCS2000 / 高斯-克吕格投影上海一般落在119E或121E分带附近也可以直接用WGS 1984 UTM Zone 51N。这一步别偷懒。我见过有人在ArcGIS里直接算面积出了几百万平方米的“建筑”——误差放大十倍以上原因是几何计算用decimal degrees直接跑。正确的操作路径是先定义投影再用Project工具转投影最后用Calculate Geometry算面积。如果你的属性表已经带了面积字段不代表它一定是用投影坐标算出来的建一个临时字段用投影后几何复核一遍是最稳妥的。3. 把shp喂给SWMM从GIS预处理到inp文件的完整操作流3.1 GIS端的预处理清洗、投影、字段规整拿到原始shp先做三件事检查要素类类型、确认坐标系、看属性表结构。建筑面一般是Polygon要素字段里通常有建筑ID、面积、人口这几列。运行以下PyQGIS脚本可以快速规整字段并导出备用# 在QGIS Python控制台或PyQGIS脚本中运行 # 目的检查字段名、坐标系并生成一个仅保留关键字段的副本 layer iface.activeLayer() # 当前图层必须是建筑面shp print(layer.crs().authid()) # 输出坐标系比如EPSG:4326代表WGS84经纬度 # 新建字段用投影后的几何计算面积平方米 from qgis.core import QgsField, QgsVectorFileWriter from PyQt5.QtCore import QVariant # 给图层添加area字段 layer.dataProvider().addAttributes([QgsField(area_m2, QVariant.Double)]) layer.updateFields() # 逐要素计算几何面积 with edit(layer): for feat in layer.getFeatures(): geom feat.geometry() feat.setAttribute(area_m2, geom.area()) # geom.area()返回的是投影后的面积 layer.updateFeature(feat) # 导出为新的shp只保留字段OBJECTID、area_m2、POPU如果有 options QgsVectorFileWriter.SaveVectorOptions() options.driverName ESRI Shapefile transform_context QgsProject.instance().transformContext() QgsVectorFileWriter.writeAsVectorFormat( layer, /path/to/output/building_clean.shp, transform_context, options)这段脚本的逻辑分三层先打印坐标系确认数据是经纬度还是投影坐标然后给每个建筑要素新增一个面积字段按当前几何计算面积——注意如果图层还是WGS84地理坐标系这一步算出来的面积依然是错的必须先做Project变换最后只导出需要的字段去掉冗余列避免后面空间连接时字段名冲突。实际处理时我会把“投影变换”放在添加字段计算之前执行。之前遇到一份数据坐标系定义是CGCS2000但实际坐标数值是经纬度项目文件里却标成了投影坐标——这是shp常见病.prj文件内容和实际几何不符。遇到这种情况先看坐标值范围如果经度在120左右、纬度在31左右即使.prj写着投影坐标也要手动按WGS84定义再转投影。3.2 空间连接汇水区面积和人口按区聚合SWMM建模的下一步是给每个子汇水区算建筑覆盖率。你需要一个汇水区边界shp然后用空间连接把建筑面的面积、人口聚合到汇水区上。ArcGIS的Spatial Join可以选聚合规则为SUM——即统计每个汇水区内建筑的面积总和与人口总和。下面用QGIS表达式引擎做同样的工作-- 在QGIS的“按位置汇总”工具中执行 -- 目的对每个汇水区多边形汇总落入该区内的建筑面积和人口 -- 输入subcatchment目标图层、building_clean连接图层 -- 聚合方式sum(area_m2)、sum(POPU) SELECT sub.id AS sub_id, SUM(b.area_m2) AS bldg_area, SUM(b.POPU) AS bldg_popu, COUNT(b.id) AS bldg_count FROM subcatchment sub LEFT JOIN building_clean b ON ST_Within(ST_PointOnSurface(b.geometry), sub.geometry) GROUP BY sub.id这段SQL的逻辑核心是ST_PointOnSurface——取建筑面的质心点判断是否落在汇水区内。为什么不用ST_Intersects因为建筑边界和汇水区边界常常共享一段线用面-面相交会重复计数一栋建筑骑在两个汇水区边界上会被算了两次。用质心则保证每栋建筑只归入一个汇水区这个细节能避免后续SWMM模型里出现面积重复计入的问题。这里还要强调一个计数陷阱shp的字段名最长10个字符如果原始字段叫AREA_M2已经超了就需要改短。Spatial Join成功后检查结果表如果出现大量建筑总面积为0的汇水区多半是建筑层和汇水区边界在空间上没有完全套合比如建筑超出了汇水区边界线。这时用“按位置选择”里的“与源图层相交”做一次诊断性选择看是不是有几十栋建筑悬空在汇水区外面。3.3 生成SWMM的inp文件把统计结果变成Subcatchment属性建筑覆盖率算好后手动在SWMM里一个一个填Subcatchment属性太累了尤其是有几十上百个子汇水区的时候。常见做法是先把属性表整理成CSV用Python生成inp文件片段或者直接操作swmm-api这类库来写。下面是生成Subcatchment段落的基础代码框架# 读取汇水区统计CSV生成SWMM .inp文件的[SUBCATCHMENTS]段 # CSV字段SubName,Outlet,Area_ha,%Imperv,Width,Slope import csv # inp文件的subcatchment段格式 # Name Outlet Area %Imperv Width Slope # 注意面积单位是公顷%Imperv是百分数 rows [] with open(subcatch_stats.csv, r) as f: reader csv.DictReader(f) for r in reader: # 建筑覆盖率转不透水率这里按建筑占汇水区面积比例作为不透水率下限 imp float(r[bldg_area_ha]) / float(r[area_ha]) * 100 # 实际建模时再加道路不透水比例 imp_total min(imp 10.0, 95.0) # 道路/广场按10%估算 rows.append(f{r[sub_id]} {r[outlet_id]} {r[area_ha]} {imp_total:.1f} {r[width]} {r[slope]}) with open(subcatchments.inp, w) as f: f.write([SUBCATCHMENTS]\n) f.write(;;Subcatchment Outlet Area %Imperv Width Slope\n) f.write(\n.join(rows))这段代码干的事很简单把CSV里每行的建筑覆盖率换算成SWMM要的%Imperv——注意这里做了一件事就是加了一个10%的道路/广场估算值上限卡在95%。原因是不透水率超过95%在物理上不太可信而且SWMM对超100%的值会直接报错。宽度Width和坡度Slope这两个参数代码里直接从CSV读实际项目中它们通常来自汇水区几何计算或地形数据。用这个办法几十个汇水区的inp段落几秒钟就能拼出来。生成后直接用SWMM打开inp文件检查有没有“Node not found”或“Subcatchment outside of study area”这类报错。特别提醒inp文件里的单元编号不能重复Outlet名称必须和节点表里的ID完全一致包括大小写——SWMM的ID匹配是区分大小写的这个坑我至少踩过三次。4. 避坑指南shp建筑面数据的六个常见炸点4.1 坐标系定义错了算出来的面积和人口密度全是错的现象在GIS里打开shp建筑图形位置和底图对不上歪了几百米或者直接用工具算面积出来的数值大得离谱。原因shp的.prj文件缺失或标注错误实际坐标是GCJ02或BD09偏移坐标系而软件按WGS84去理解或者坐标是经纬度但被当成了投影坐标。解决先看坐标数值范围判断真实坐标系再检查.prj。如果图形偏移量是固定的几百米多半是GCJ02偏移——这种国内测绘数据很常见。处理方式是识别出真实坐标系用已知控制点做校正或者直接放弃原坐标用底图上的地标做视觉配准。上海地区我一般统一转到CGCS2000 高斯投影。4.2 字段名截断导致后续脚本报错现象Python脚本读字段报KeyError或者明明CSV里有Column叫POPULATION程序却说找不到。原因shp的dBASE格式硬性限制字段名最长10字符ArcGIS/QGIS在保存时会自动截断或重命名原始长字段名不保留。解决拿到shp后先看属性表列名凡是超过10字符的字段在导出前手动改成短名。如果已经截断了用QGIS的Refactor Fields工具批量重命名字段再导出。我习惯在一开始就用“code_10”这样的短字段规划属性结构避免后面所有脚本都要跟着改名。4.3 建筑面和汇水区边界不对齐统计值系统性偏小现象Spatial Join之后沿主干道的汇水区建筑覆盖率异常低明显和航拍图不符。原因建筑shp和汇水区shp来源不同边界线存在几米到几十米不等的套合误差导致靠近边界的建筑被分到了相邻汇水区或者干脆悬在外面没被统计到。解决先做拓扑检查看建筑要素是否完整落在汇水区边界内。对于骑行误差不大的数据可以用缓冲带Buffer处理后重新切割汇水区——我一般给建筑面设定0.5到1米的负缓冲向内收缩消除边界贴合误差对误差大的数据直接以建筑层为基准重新描绘沿街汇水区边界。这套操作虽然繁琐但面积统计的准确性能上一个台阶。4.4 面积字段不是平方米单位不一导致SWMM报错现象SWMM运行时提示Subcatchment面积过大或者总径流量异常偏大。原因原始shp里AREAFIELD的单位可能是平方公里或公顷直接导入后没换算。解决在代码里统一单位换算面积全部转成公顷hectare再进inp。SWMM的Area单位是公顷acres也可看项目设置如果你按平方米填进去数值放大一万倍水文过程线会像山洪暴发。检查方法很简单把所有子汇水区面积加起来和整个研究区面积对比如果差十倍以上基本是单位问题。4.5 人口字段口径不清DWF估算失真现象用人口字段估算旱季流量结果比污水处理厂进水量大了好几倍。原因shp的属性表里“人口”可能是住户数×户均人数粗算出来的也可能是建筑面积除以人均住房面积得到的和实际常住人口是两回事。上海中心城区和老旧小区这种偏差尤其明显。解决用分区人口统计校准。拿到shp后先按街道或行政区汇总人口去和统计年鉴的常住人口比对——通常需要乘以一个0.6~0.85的修正系数抵消“一房多人多户但shp只算一套”导致的高估。做SWMM模型的旱季流量输入时建议单独建一个人口修正字段不要直接用原始字段。4.6 数据版本和现状不符新建小区建筑缺失现象模型里某一片汇水区建筑覆盖率特别低但实地看已经建成了新楼盘。原因数据是2020年的但现在已经是好几年后新建建筑自然不包含在里面。解决叠加最新卫星影像或路网数据做增量更新。在GIS里把项目区的现状影像作为底图新建建筑手动补充画边界再合并进原图层。上海这种城市更新速度快的地方数据新鲜度的影响比坐标系还大。SWMM模型率定完之后如果监测流量长期低于模拟值不妨先怀疑是不是下垫面数据缺了新建建筑而不是急着调参数。5. 进阶用法用建筑面数据反推不透水率子区划分和产流参数5.1 按建筑密度聚类划分子汇水区SWMM建模时子汇水区怎么划直接影响率定成本。城市片区常见的做法是按用地性质或道路边界切分汇水区但如果你手里只有建筑面这份数据也可以直接用建筑密度做聚类划分“高密度建筑区、中密度建筑区、低密度建筑区、农村散居区”四种类型每类赋一套产流参数。和按道路切割的方法相比按密度聚类的优势是每一类汇水区的产流参数物理意义更明确率定时调整参数也更好解释。具体实现可以用GIS里的核密度分析工具提取建筑面中心点做KDE核密度估计然后重分类成四级。带宽参数一般用100米左右——太密了全是马赛克太疏了又看不出老街区和新建区的差异。然后用重分类后的栅格转面再和汇水区边界做裁剪。每一类区域给一个初始%Imperv高密度建成区80~90%中密度建成区65~80%低密度区40~60%农村散居区20~40%。有一个经验值得记上海老城厢那种密集低层建筑区建筑密度高但屋顶面积小和老式花园洋房区的产流特征完全不同——前者虽然建筑覆盖率高但巷道窄、绿化少汇流时间短后者建筑覆盖率不高但有大面积庭院绿地和透水铺装汇流时间反而长。所以建筑密度分区不能替代汇流时间参数的分组两套参数要分别率定。5.2 人口数据在SWMM水质模拟里的落地SWMM水质模块里的污染物累积曲线通常用人口密度作为关键驱动参数——生活垃圾、污水管道溢流污染都和人口直接相关。建筑面shp里的人口字段可以按汇水区聚合成人口密度然后映射到Land Use类型的污染物累积参数上。具体操作是把每个子汇水区的人口密度算出来分成低、中、高三档分别对应SWMM里Land Use的不同堆积速率参数。常见做法是给每个Land Use类型设置不同的最大累积量Max. Buildup和半饱和常数Half Saturation Constant。人口密度高的区域最大累积量要调大清扫频率相应也要调整。这里有个细节SWMM里的清扫参数是按街道清扫频率设置的而街道清扫频率往往和人口密度正相关——高密度商业区一周扫三次低密度居住区可能一周才一次。用人口字段推导清扫参数比拍脑袋设一个固定值要靠谱很多。5.3 建筑层数和面积字段联合推导屋顶径流污染初始浓度如果你那份shp属性表里恰好有建筑层数或建筑高度字段那还能再进一步。屋顶径流的污染物初始浓度和屋面材料、老化程度关系很大但层数是“屋顶面积建筑占地面积×层数”这个关系里不可或缺的因子——总屋面面积越大初期冲刷效应越明显。SWMM的洗涤Washoff模块里的Coefficient和Exponent参数对于高层住宅和低层厂房应该分别设置高层住宅屋顶面积大、坡度缓污染物冲刷速率低厂房坡度大冲刷快、浓度峰值高。用建筑面shp的方式也很直接按建筑占地面积乘楼层数算出总屋面面积汇总到汇水区后把汇水区按“屋面面积占比”分档——屋面面积占比超过35%的区洗涤速率系数取低值低于15%的取高值。这一个分类能让水质模拟里的SS和COD曲线和实际监测更贴近。6. 验证方法用三张图和一组数确认这份建筑面数据能不能用数据拿手里先别急着建模花半小时做四道验证工序值回票价。第一道图形检验。把建筑面shp叠到卫星影像或百度底图上随机抽三个区域中心城区、近郊城镇、远郊农村。中心城区建筑轮廓应当和影像基本贴合轮廓线偏差不超过两三个像素近郊能看到成片的老式农民房轮廓小而密远郊应该是零散分布的独栋农宅。如果某个区域建筑密度异常稀疏或异常密集这一片数据大概率有问题直接跳过或另找数据补齐。这一步有个细节影像底图时间要尽量接近数据年份拿最新的影像去核对2020年的数据新建筑自然会显示为空缺。第二道面积量算复核。用QGIS或ArcGIS对全图层计算一次总面积和上海市统计年鉴里的“城镇建设用地面积”做量级对比。建筑占地面积一般占建设用地面积的两到四成如果超出这个范围检查是不是有“多部件要素”被重复计数。有人拿到shp后直接算Geometry面积结果发现汇总面积是实际的两倍——因为数据里有大量MultiPolygon要素的环inner ring被当成独立面算了。正确的检查方式是Attribute Table里看每个要素的几何类型确认是Polygon还是MultiPolygon在统计时用ST_Area(geom)而不是ST_Area(ST_ExteriorRing(geom))。第三道人口总量校准。把属性表里的人口字段汇总和2020年上海常住人口2487万比较。如果shp的“人口”是建筑容量口径和实际值偏差20%以内都能接受如果偏差超过50%别直接用需要按区县做线性校偏。操作方法按行政区字段分组汇总shp人口把每个区的汇总值和七普数据相除得到每个区的修正系数再乘回去。这个修正系数表之后做DWF估算和污染负荷计算都能复用建议存成CSV放在项目目录里。第四道SWMM冷启动测试。挑一个片区先建好简化管网和三个子汇水区把不透水率设为用这份数据算出来的值跑一场5年一遇的设计暴雨。看输出的径流总量是不是落在合理区间——上海短历时暴雨径流系数一般在0.4~0.75之间如果总径流系数小于0.3或大于0.9说明不透水率参数或者汇水区面积设置有比较大的误差。冷启动测试不追求和监测数据拟合只求量级合理这一步能拦住后期率定阶段的大量无效劳动。从那以后我拿到任何一份下垫面shp第一件事就是先做上面四道工序再谈建模。校验数据本身花的半小时只要能在率定阶段省下一周就非常划算。希望这份上海建筑物面数据的验证思路也能帮你少走点弯路——毕竟SWWM的参数调起来够玄学了数据底子咱尽量别给它添乱。本文还有配套的精品资源点击获取
返回列表