ARTICLE DETAIL

资讯详情

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

青海省30米DEM处理全流程:从拼接裁剪到地形分析

青海省30米DEM处理全流程:从拼接裁剪到地形分析 简介青海省30米分辨率DEM数据基于ASTER GDEM V3版本构建采用WGS84坐标系可支撑地形特征提取、坡度坡向计算、流域划分、地质灾害评估等典型应用适合GIS研究人员、城乡规划与地质勘测人员直接调用。压缩包内共10个文件以GeoTIFF栅格数据QingHai_DEM_30m_ASTGTMV003.tif为核心配套TFW坐标世界文件、XML元数据及DBF属性表同时附带青海省Shapefile完整矢量边界shp、shx、dbf、prj、sbn、sbx便于限定研究范围后进行裁剪、镶嵌与空间叠加分析。资源整体约944.59MB30米格网精度在区域级地形研究中具有足够细节。依托开放ASTER GDEM源数据文件结构规范载入ArcGIS、QGIS或GlobalMapper后可直接提取高程点、生成等高线、制作坡度坡向图并结合卫星影像分析地形对植被分布、河流走向及气候变化的作用。目前已有495人下载学习能为青海高原地区环境演化、灾害防治与国土空间规划提供可靠的基础数据。1. 青海省DEM 30米先搞清楚它在GIS工作流里到底扮演什么角色做青海省境内的项目无论你是搞水电选址、光伏并网、地质灾害评估还是交通选线第一步几乎都是同一件事把地形底图铺好。青海省DEM30米分辨率就是这片区域最常用到的数字高程模型产品每个像元对应地面30米×30米的方格格子里存的是该处的高程值。它不像卫星影像那样能看出地物纹理但它是所有地形分析的地基——坡度、坡向、山体阴影、汇水区、视域分析全都从它身上派生。很多人拿到数据后第一反应是“这不就一张灰图吗”然后直接拖进ArcMap看颜色。真正的问题是30米这个精度在青海意味着什么它能不能分辨出沟壑裁剪之后为什么会有黑边拼接之后为什么会有接缝这篇文章我按自己实际做项目的顺序把获取、拼接、裁剪、质检、地形分析这五件事捋一遍顺便把那些不翻一次车就记不住的坑标出来。适合正在做青海区域分析、或者手里有西北地区DEM但不知道从哪下手的从业者。新手能跟着命令跑通老手可以跳过基础直接看第4章的坑和第6章的分块技巧。2. 从哪儿拿青海省30米DEM数据源对比与选型三原则2.1 三个常见数据源ASTER、SRTM、ALOS选哪个当底图青海省有72万多平方公里面积大意味着需要拼接大量分幅数据。目前能拿到30米左右分辨率的公开DEM主流的就三类ASTER GDEM30米、SRTM原30米国内常见的是经过处理的版本、ALOS AW3D30约30米。我三个都用过说下直观感受。ASTER GDEM覆盖全球从83°N到83°S都有青海全境覆盖没问题。它的优势是几乎无空洞但噪声偏大尤其在高山峡谷区会出现一些“麻点”——单个像元的高程突变看着像山脊碎裂其实不一定真实。SRTM覆盖到60°N青海在海西、玉树、果洛这些南部区域全覆盖它的特点是平坦地区表现稳定但在高山峡谷区会有大量的NoData空洞因为雷达信号在陡峭地形回波不好。ALOS AW3D30是JAXA发布的基于PRISM立体像对整体平滑度好视觉上最干净但对云遮挡敏感局部区域有数据缺失。选型三原则我个人的习惯是第一项目如果只做宏观分析比如全省的坡度分级三个都行优先用ALOS因为视觉干净、后续处理少第二项目涉及沟谷、矿山、深切河谷这种局部精细地形用ASTER因为30米下它保留的细节和噪声其实是一体两面细节多意味着你能看出沟但要有后续滤波的心理准备第三项目需要和已有高程控制点比对、且希望误差分布均匀用SRTM的30米版本它的误差均匀性最好。注意这里说的都是公开数据源的典型特征不是绝对结论同一个区域不同版本可能表现不一样。2.2 30米分辨率到底意味着什么像元尺寸、精度指标与适用尺度30米分辨率这个概念很多人在用但没细想。在青海这种尺度下一个30米像元差不多是一块标准足球场的四分之一。这意味着一个宽度小于30米的冲沟在DEM上可能只有一两个像元表现出高程异常如果做汇水分析这条沟的上游集水区可能根本连不出来。所以30米这个精度适合做的分析是区域地形趋势、坡度坡向宏观统计、流域划分与河网提取提取到的河网是“模拟水系”而不是精确的小沟、灾评中的地形因子计算。不适合做的是单条沟道断面设计、滑坡体边界圈定、精密土方量计算。精度指标上公开的30米DEM产品的标称垂直误差在5到10米量级水平位置误差在10到30米不等。这不是说每个点都差这么多而是统计上90%置信区间内可能达到的水平。你在青海做项目尤其是柴达木盆地这种平坦区域垂直误差通常小于水平误差看起来“很平”但高程值本身可能有几米的偏差。这一点在做土方平衡时特别危险——如果工期要求土方量精确到千分位30米DEM只能用来估算不能用来结算。另外一个容易忽略的细节是大地水准面。青海区域海拔变化剧烈格尔木附近海拔2800米唐古拉山口接近5000米不同数据源采用的高程基准可能略有差异。拼数据之前先确认所有分幅的坐标系和垂直基准一致否则拼接处会出现条带状的系统性偏差而不是随机噪声。3. 把碎片拼成一张图拼接、裁剪与投影转换的实操命令3.1 预处理第一步用GDAL批量拼接分幅DEM拿到青海全省的DEM通常不会是单独一个tif而是一堆分幅文件按经纬度网格切的。常见的有1度×1度分幅一个文件覆盖一个经纬度方格。青海省大约跨越5个经度带E90°~E101°左右、6个纬度带N31°~N39°左右如果你按1度×1度切理论上要拼几十个文件。我习惯用GDAL的命令行做拼接因为可以写批处理、可以留日志而且不需要打开ArcMap那种重型软件。最基础的命令是gdal_merge.py# 将当前目录下所有tif按顺序拼接成一个大的vrt文件 gdalbuildvrt -resolution highest -r nearest -srcnodata -32768 qinghai_dem.vrt *.tif # 将vrt转为正式tif并压缩存储 gdal_translate -co COMPRESSDEFLATE -co BIGTIFFIF_SAFER -co TILEDYES qinghai_dem.vrt qinghai_dem_raw.tif第一行gdalbuildvrt是建立虚拟栅格它不真正拷贝像元数据只是记录每个分幅文件的位置和空间范围。这里参数-resolution highest的意思是如果多个分幅的重叠区域分辨率不一致以分辨率最高的为准。-r nearest是重采样方法选最近邻对DEM这种浮点高程数据来说最近邻不会插值出虚假的高程值。-srcnodata -32768很关键因为很多DEM产品的无效值用-32768标记不指定的话这些无效区域会被当作真实高程参与后续计算。第二行gdal_translate把vrt变成独立的tif文件压缩成DEFLATE能大幅减小体积青海全省30米DEM的原始浮点tif可能有十几个GB压缩后可能降到一半以内。3.2 按省界裁剪矢量边界裁剪栅格的两种方式及取舍有了全省大tif之后很多项目不需要全省范围只需要某个市、某个流域或者自己画的研究区。这时候就要裁剪。ArcMap里大家习惯用的方式是“按掩膜提取”但命令行方式更可控。GDAL的裁剪有两种本质区别在于一种是用矢量边界创建掩膜一种是直接把超出矢量范围的像元置为无效值。# 方式一用矢量边界裁剪并保留边界外的NoData gdalwarp -cutline qinghai_province.shp -crop_to_cutline -of GTiff -co COMPRESSDEFLATE qinghai_dem_raw.tif qinghai_dem_clip.tif # 方式二先转成与矢量对齐的网格再按掩膜提取类似ArcMap的按掩膜提取 gdalwarp -cutline qinghai_province.shp -crop_to_cutline -dstnodata -9999 -of GTiff qinghai_dem_raw.tif qinghai_dem_clip_nodata.tif方式一直接按矢量边界裁剪输出栅格的范围刚好是矢量的外接矩形边界外的区域完全没有像元。方式二和ArcMap的“按掩膜提取”更像它会保留外接矩形范围内的像元但把矢量边界外的像元赋为指定的NoData值。两者在后续分析中差别很大如果你要做全省坡度统计方式一更合适因为NoData区域根本不存在如果你要做某个县域的分析、但希望保留周边一小圈地形作为缓冲方式二更合适因为NoData区域虽然在边界外但空间范围还在后续做视域分析时不会因为边缘缺失导致意外的断崖。再说一下gdalwarp裁剪时的重采样问题。如果裁剪后发现边界处的像元和原始DEM对不上多半是因为原始tif的像元边界和省界矢量不完全对齐默认重采样会把边界处的像元值重算一遍。想要严格保留原始像元值加-r nearest参数这样输出栅格在边界处的像元值直接取原始值不做插值。3.3 投影转换与坐标系统一WGS84还是CGCS2000青海省的范围横跨多个UTM分带如果做面积量算或者距离量算直接用经纬度的WGS84坐标会不准。常见做法是转成Albers等积投影或者UTM投影。我的建议是如果做面积统计比如不同类型地形区的面积占比用Albers等面积投影如果做距离和坡度相关的分析用UTM投影。青海省整体推荐UTM 47N对应东经99度中央经线附近或者根据项目区微调。# 从WGS84经纬度转到UTM 47N gdalwarp -t_srs EPSG:32647 -r cubic -co COMPRESSDEFLATE qinghai_dem_clip.tif qinghai_dem_utm47.tif # 从WGS84经纬度转到Albers等积投影类似全国标准 gdalwarp -t_srs projaea lat_125 lat_247 lat_00 lon_0105 x_00 y_00 ellpsGRS80 unitsm no_defs -r cubic qinghai_dem_clip.tif qinghai_dem_albers.tif投影转换时-r cubic是三次卷积重采样比最近邻平滑适合DEM这种连续表面数据。注意不要用-r bilinear以下的低阶方法否则地形细节会被磨掉一层。转换完成后一定要用gdalinfo检查输出文件的分辨率和范围比如UTM 47N下分辨率应该是30米左右如果变成29.99米说明原始数据本身有轻微变形不影响使用但要做到心里有数。4. 拿到手先别信质量检查与四个高频翻车现场4.1 现象拼接缝处出现明显的“撕裂”或错位第一次处理青海全省DEM时拼接完我直接用gdalbuildvrt生成了vrt然后在ArcGIS里加载放大到某两个分幅交接处看到一条南北走向的台阶——东边高程明显比西边低几十米。这不是地形突变是两个分幅数据的处理版本不一致。原因青海省内不同分幅数据的原始获取时间、来源版本不同导致相邻分幅在重叠区的高程系统性偏差。我查了下具体文件有几幅是旧版本SRTM有几幅是新的重处理版本两者在山区差异较大。解决拼接前先用gdalinfo逐个检查所有分幅的元数据确认它们的版本一致如果已经拼了就在拼接时用gdalbuildvrt的-overwrite重新来过或者在gdalwarp里加-wo SAMPLE_STEPSall做边缘羽化。注意拼接缝问题最好的解决是不要让它发生检查文件版本的时间一定不能省。4.2 现象裁剪后边缘出现黑边或NoData区域用省界裁剪后山地区域边界处经常出现大块的0值或黑洞。表现形式是和省界重叠的山脊线周围栅格像元显示为黑色或者极度暗色。放大看是很多像元值为0或NoData。原因原始DEM在高山区本身就有数据空洞比如SRTM在陡峭山地的雷达阴影区域以及ASTER在云遮挡区域的空洞。裁剪操作本身不会制造空洞只是把空洞暴露出来了。解决先用gdal_fillnodata.py填补原始DEM的空洞再用裁剪命令。填补空洞的常见做法是用周围有效像元的插值来填充脚本如下gdal_fillnodata.py -md 10 -si 2 qinghai_dem_raw.tif qinghai_dem_filled.tif-md 10意思是最大搜索距离10个像元超过这个距离的空间洞不填避免在区域大面积缺测时硬插值。-si 2是平滑迭代次数建议设小一点2次足够设大了会把真实地形磨掉。填充之后再做裁剪边缘问题基本消失。4.3 现象负值异常——湖泊与盐湖区域的真实高程被抹平柴达木盆地的盐湖区域比如察尔汗盐湖周边高程非常平坦有些地方接近海平面以下。有次我拿到一份处理过的数据在ArcMap里看盐湖区域的高程全是0和周围几百米的落差完全对不上。检查后发现是数据提供方在预处理时把0值当NoData统一置成了0。原因湖面区域可能是平坦的、接近海拔0米也可能因为水体反射导致原始数据反演失败被处理成0值或NoData。解决不要一刀切把0值当NoData先用直方图看高程分布盐湖区域如果出现大量完全相等的0或某个恒定值用掩膜单独重新获取该区域高精度高程并替换而不是全局填洞。4.4 现象在ArcMap里裁剪和用GDAL裁剪结果不一致有同行问过我为什么同一个边界ArcMap的“按掩膜提取”和GDAL裁剪出来的像元值不一样。这个问题的根源不是软件本身而是两个工具在裁剪时的重采样默认值不一样。ArcMap的按掩膜提取默认用双线性插值GDAL的gdalwarp默认用最近邻两者的边界像元值自然不同。解决如果希望结果和ArcMap一致GDAL命令里加-r bilinear如果希望保留原始DEM的像元值在ArcMap里把环境设置里的重采样方法从双线性改成最近邻。这个坑看着小但在两个团队协作、互相校验结果时会造成无谓的返工。5. 让30米DEM干活坡度坡向提取与地形因子的参数调校5.1 坡度提取度数还是百分比输出类型怎么选坡度是DEM最常用的派生数据。青海这种高原地区坡度分布跨度很大柴达木盆地几乎0度祁连山和唐古拉山地区可达40度以上。ArcGIS的坡度工具会问你要输出“度”还是“百分比”我一般选“度”因为后续做分级统计时更直观。注意一个细节如果原始DEM是经纬度坐标系直接用ArcGIS的坡度工具会得到错误的坡度值——因为经纬度下X和Y方向的单位不是米计算出来的坡度要么被夸大要么被压缩。正确做法是先把DEM投影到UTM或Albers投影然后计算坡度。用GDAL的命令行也能算坡度核心是使用gdaldem工具# 从UTM投影的DEM生成坡度单位度 gdaldem slope qinghai_dem_utm47.tif qinghai_slope_deg.tif -p -s 111120 # 从经纬度DEM生成坡度不推荐但如果你手头只有经纬度数据需要指定scale gdaldem slope qinghai_dem_wgs84.tif qinghai_slope_wgs84.tif -p -s 111120-p表示输出百分比坡度如果去掉这个参数默认输出度数。-s 111120比较关键当输入数据是经纬度时这个值表示水平比例尺111120是一度大约对应的米数。如果输入数据已经是投影坐标系米制这个参数可以省略否则坡度值会被严重放大。我遇到过有人拿着经纬度DEM直接算坡度输出的坡度全是80度以上就是没设这个参数。5.2 坡向与山体阴影把光照模型加进分析坡向在很多项目中不是主角但在光伏选址、农业种植、雪灾评估里非常关键。青海的光伏项目多在海西、海南一带场址选择时要避开朝北坡面因为日照不足会直接拉低发电量。ArcGIS的坡向工具输出0到360度0度正北90度正东需要自己写重分类把坡向分成9类8个方位加平地。GDAL的命令行同样可以算坡向和山体阴影# 坡向输出为0-360度 gdaldem aspect qinghai_dem_utm47.tif qinghai_aspect.tif # 山体阴影默认方位角315度、高度角45度 gdaldem hillshade qinghai_dem_utm47.tif qinghai_hillshade.tif -az 315 -alt 45 -z 2.0山体阴影的两个参数-az方位角和-alt太阳高度角需要按项目定制。青海冬季太阳高度角低如果模拟冬季光照把-alt调低到25~30度如果模拟夏季35~45度合理。-z是垂直放大系数当研究区地形平缓时不放大山体阴影会灰蒙蒙一片调到2到3倍能把沟谷层次显出来。山体阴影一般不直接用于定量分析而是作为底图叠加在其他图层下面做可视化让地形立体感出来方便判断地质构造走向。5.3 地形起伏度与粗糙度两个容易被忽略的衍生指标坡度坡向是常用指标但在青海的宏观评估中起伏度和粗糙度往往更有说服力。起伏度定义是分析窗口内最大高程减最小高程反映地形破碎程度粗糙度是表面积与投影面积的比值反映地表的褶皱情况。这两个指标对窗口大小非常敏感窗口太小看不出区域差异窗口太大把细节全平均掉。青海省做灾评时我一般用5×5像元窗口即150米×150米算起伏度这个尺度既不会漏掉冲沟也不会被单个像元噪声干扰。ArcGIS里有焦点统计工具Focal Statistics直接设置矩形5×5、统计类型选RANGE就能得到起伏度。注意边界处会有一圈NoData这是正常的裁剪到省界后去掉边缘一个窗口宽度的区域再统计。粗糙度用gdaldem roughness# 计算粗糙度输出范围1~无穷值越大表面越粗糙 gdaldem roughness qinghai_dem_utm47.tif qinghai_roughness.tif粗糙度值在平坦盐湖区域接近1山区可达2以上。做土地利用规划时粗糙度超过1.3的区域基本不适合铺设管网因为土方量会失控。这些衍生指标算完之后记得统一做一次一致性检查用目视和统计直方图确认最大值、最小值、均值在合理范围内不要出现负数坡度和0度坡向错乱。6. 用20行Python把青海省30米DEM的分块处理与批处理跑起来6.1 分块处理把大tif拆成瓦片避免内存溢出青海全省的30米DEM转成投影坐标系后整个范围大约有数万个像元行和列在普通电脑上直接做全区域坡度会非常卡。我一般会把大tif拆成若干个5000×5000像元的瓦片分别处理最后再拼回去。GDAL的gdal_retile.py可以干这个# 拆成512x512像元的瓦片输出到tiles目录 gdal_retile.py -ps 512 512 -targetdir tiles -co COMPRESSDEFLATE qinghai_dem_utm47.tif拆完之后逐瓦片算坡度处理速度提升明显因为每个瓦片都小到能读入内存。算完坡度再把瓦片拼回整幅# 先拼vrt再转tif gdalbuildvrt qinghai_slope_tiles.vrt tiles/slope_*.tif gdal_translate -co COMPRESSDEFLATE -co BIGTIFFIF_SAFER qinghai_slope_tiles.vrt qinghai_slope_final.tif注意拆片后不要直接拼回tif先建vrt再做一次translate这样能避免瓦片之间出现接缝错位。6.2 用Python脚本批量填洞、批量转投影、批量做统计如果你的项目需要经常更新数据或者要对多期DEM做对比写一个Python脚本把这些步骤串起来是值得的。下面是一个最小可用的批处理骨架import subprocess import glob dem_files glob.glob(raw/*.tif) for dem in dem_files: out dem.replace(raw/, processed/).replace(.tif, _fill.tif) # 第一步填补NoData空洞 subprocess.run([ gdal_fillnodata.py, -md, 10, -si, 2, dem, out ], checkTrue) # 第二步转UTM 47N投影 out_utm out.replace(_fill.tif, _utm47.tif) subprocess.run([ gdalwarp, -t_srs, EPSG:32647, -r, cubic, out, out_utm ], checkTrue) # 第三步输出基本统计信息 subprocess.run([gdalinfo, -stats, out_utm])subprocess.run加checkTrue会在命令报错时直接抛出异常不会继续处理下一幅避免把坏数据留到后面。批处理最怕的其实是文件命名混乱建议在脚本开头统一做一轮重命名检查用正则把文件名里的空格和中文替换掉否则gdalwarp容易因为路径问题翻车。6.3 用实测点交叉验证30米DEM的信任边界到底在哪处理完整套数据之后我会做一次验证找项目区内的实测高程点比如水准点、GPS实测点、已有的高精度LiDAR断面点用gdallocationinfo在DEM上取样和实测值做差统计均方根误差。如果误差在5米以内说明这套30米DEM在这个区域可以用于宏观地形分析如果误差超过10米说明原始数据在这个区域失真可能需要换数据源。gdallocationinfo -valonly -wgs84 qinghai_dem_utm47.tif 96.5 34.5-valonly表示只输出该点的像元值不输出其他冗余信息。注意点位坐标必须和DEM的空间参考一致如果DEM是UTM 47N而点位是经纬度要用-wgs84参数让GDAL临时把输入坐标当作经纬度做转换。这个检验我每次做新区域DEM都会跑一遍算是给自己的数据建立一套信任档案。验证结果如果可用后续做坡度分级、地形区划时心里就有底了。三十米分辨率不是万能的但它能帮你把青海的地形骨架搭出来。希望这份实践能让你在下一个项目里少走几段弯路——至少在看到那些莫名其妙的黑边和陡坡时你能第一反应想起数据源、重采样和坐标系这三件事。本文还有配套的精品资源点击获取
返回列表