ARTICLE DETAIL

资讯详情

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

云南30米DEM数据实战:解压、加载与地形分析全流程

云南30米DEM数据实战:解压、加载与地形分析全流程 简介云南省30米分辨率数字高程模型DEM数据以Shapefile格式提供面向GIS数据处理人员、城乡规划师及环境研究人员。30米分辨率对应地面30米×30米的栅格单元能够清楚呈现中宏观地形起伏支持坡度、坡向、流域分析、视线分析、地形剖面提取等常见地形分析任务。压缩包共17个文件核心为.shp几何文件同时包含.dbf属性表、.prj投影坐标定义、.sbn/.sbx空间索引、.aux辅助文件及.shp.xml元数据等文件体系完整可直接在ArcGIS、QGIS中打开并进行后续编辑与分析整个RAR包大小约43.66MB。数据采用明确的投影坐标系统便于与其他城市数据、土地利用数据叠加开展空间建模或城市规划相关工作。目前已有1178人学习下载适合需要快速获取云南高程基础数据、开展地形分析或项目前期调研的GIS使用者。1. 这份云南30米分辨率DEM解压后到底该怎么用从网上下载到“各省30米分辨率DEM数据-云南.rar”这类资源时解压后看到 .shp、.dbf、.adf、.aux 一长串后缀很多人的第一反应是不知道先打开哪个。其实这个压缩包并不只有一份数据而是两套东西打包在一起一套是云南的省级行政区划矢量边界也就是 .shp 那一组文件另一套是覆盖云南全境的30米分辨率数字高程模型栅格以 ArcGIS Grid 格式存放。所谓30米分辨率指的是像元在地面上对应的实际尺寸每个格网点代表30米乘30米的地表面积这个精度足以支撑坡度、坡向、山体阴影、流域提取等主流地形分析。对于做城市规划、交通选线、生态评估的人来说栅格DEM提供地表起伏矢量边界提供分析范围两者结合恰好是很多项目的底子。文章后面会把这套文件的内部结构、加载方式、地形因子计算和裁剪统计逐一拆开。2. Shapefile组件与ArcGrid文件从后缀识别数据角色2.1 每个后缀对应哪一层信息拿到压缩包后先按文件后缀分组别急着双击 .shp。这个包里的矢量部分采用的是 Esri Shapefile 格式它天生是“多文件共生”的结构。列表中的 云南.shp 存几何坐标云南.dbf 存属性云南.shx 是几何索引云南.prj 记录坐标系云南.sbn 和 .sbx 是空间索引云南.shp.xml 是元数据。平时加载时软件只认 .shp但实际读取会连带调用其余几个文件任何一个缺失都可能导致加载失败或属性丢失。下表把每个文件的角色列清楚便于对照检查文件类型作用缺失后果云南.shp矢量主体存储面要素的几何坐标无法显示图形云南.shx索引记录几何要素的偏移位置打开极慢或报错云南.dbf属性表存储每块区域的属性字段属性信息全部丢失云南.prj投影定义声明坐标系与投影方式经纬度偏移或自动定位失败云南.sbn / .sbx空间索引加速空间查询与显示不影响查看影响检索速度云南.shp.xml元数据记录数据来源等描述信息不影响加载仅供查阅云南.aux辅助文件保存栅格统计与色彩映射重新计算统计值即可.dbf 文件可以用 Excel 或任意文本编辑器打开里面通常带有行政区名称、类别代码等字段。如果后续要做属性关联要用字段名精确匹配。.prj 文件里包含坐标系描述文本例如“GCS_WGS_1984”或“Albers_Conic_Equal_Area”这决定了数据叠加时会不会偏位。2.2 栅格部分的adf与aux是什么来头真正承载DEM高程值的是那些没有扩展名的文件夹和一串 .adf 文件。ArcGIS Grid 格式的特色是一个栅格数据集存放在一个独立目录中内部由 .adf 文件分段存储数据。w001001.adf 是主体数据块存放高程值矩阵dblbnd.adf 记录栅格的空间范围sta.adf 存储最大值、最小值、均值、标准差等统计信息hdr.adf 保存了行列数、像元大小、NoData值等头信息prj.adf 则是投影信息文件。vvat.adf 和 w001001x.adf 是附加值表与扩展索引属于辅助结构。使用 QGIS 时不能直接双击任意一个 .adf而是要在打开栅格数据的对话框中选择包含这些文件的目录软件会自动识别为 ArcInfo Binary Grid。ArcGIS 的做法类似通过 ArcToolbox 或目录面板直接指向那个文件夹。手动修改 .adf 文件是高风险操作尤其不要用普通编辑器改动 header 里的行列数和像元尺寸一旦改错整个栅格就废了。2.3 解压后必须做的一次完整度检查拿到压缩包后最该做的第一件事不是打开软件而是核对文件清单。用命令行进入解压目录执行下面的命令查看所有文件ls -lh 云南/ file 云南/云南.shp 云南/云南.prjfile命令能识别出 Shapefile 和投影文本的真实格式。对于栅格部分可以查看 w001001.adf 的文件头信息od -c 云南/w001001.adf | head -n 20od 命令按字节显示文件开头内容能粗略判断文件是否为空或者损坏。更专业的做法是用 GDAL 工具读取元数据gdalinfo 云南/w001001.adfgdalinfo 会输出栅格的行列数、坐标系、像元大小和 NoData 值它的存在意味着完整的 DEM 数据已经就位。需要注意如果 gdalinfo 无法识别文件格式大概率是解压过程中丢失了目录结构或者杀毒软件误删了部分辅助文件重新解压并关闭实时防护后再试。压缩包内文件多不代表数据完整重点确认 .shp 相关五个文件和 .adf 系列文件都齐全。3. 加载、投影统一与可视化让DEM正常显示在地图上3.1 QGIS中加载矢量与栅格打开 QGIS选择“图层”菜单下的“添加矢量图层”定位到 云南.shp再从“添加栅格图层”中选择包含 w001001.adf 的文件夹。之所以强调用文件夹加载是因为 QGIS 的栅格对话框在选中 .adf 时能自动识别 Grid 格式如果只拖入单个 .adf 也可能成功但部分版本会把文件当成普通二进制数据导致黑屏。加载完成后先看图层顺序DEM 栅格放底部云南.shp 矢量边界放顶部这样后续做坡度提取或裁剪能直观对照。此时按 CtrlShiftB 可以调整渲染方式将单波段灰度拉伸为彩色# QGIS Python控制台示例 from qgis.core import QgsRasterLayer, QgsSingleBandPseudoColorRenderer from qgis.PyQt.QtGui import QColor layer QgsProject.instance().mapLayersByName(w001001)[0] ramp_item_list [ QgsColorRampShader.ColorRampItem(-100, QColor(51, 160, 44)), QgsColorRampShader.ColorRampItem(1000, QColor(255, 255, 51)), QgsColorRampShader.ColorRampItem(3000, QColor(255, 128, 0)), QgsColorRampShader.ColorRampItem(5000, QColor(178, 34, 34)) ] shader QgsColorRampShader(layer.extent().yMinimum(), layer.extent().yMaximum()) shader.setColorRampItemList(ramp_item_list) shader.setColorRampType(QgsColorRampShader.Interpolated) renderer QgsSingleBandPseudoColorRenderer(layer, 1, shader) layer.setRenderer(renderer) layer.triggerRepaint()这段代码通过 QgsColorRampShader 把高程值映射为从绿色到红色的渐变第一个参数是颜色渐变的起始高程第二个是终止高程中间可以任意增加节点数值范围要参考实际 DEM 的最小值和最大值否则颜色会被拉偏。setColorRampType参数选择插值模式Interpolated 表示颜色在节点之间平滑过渡。3.2 坐标系一致性检查与投影转换把两个数据叠加后如果发现边界线有明显偏移问题基本出在坐标系不一致。先分别查看两个图层的坐标系信息ogrinfo -al -so 云南/云南.shp | grep -i Data Source\|Geometry\|EXTENT输出中会包含图层范围和空间参考。如果 DEM 是 WGS84 经纬度而 Shapefile 是 Albers 等积投影必须统一到同一坐标系再进行分析。推荐用 QGIS 的“重投影”工具将矢量转换到栅格的坐标系下ogr2ogr -t_srs EPSG:4326 云南_albers.shp 云南/云南.shp-t_srs指定目标坐标系这里写的是 WGS84 经纬度的 EPSG 编码。如果 DEM 本身是投影坐标比如 UTM 48N就把 EPSG:4326 换成对应的 EPSG:32648。转换成功后用 QGIS 重新加载目视检查边界与 DEM 地形是否对齐山地阴影走向是否与河谷线条吻合。3.3 渲染效果与高程单位的坑DEM 的高程单位一般是米但部分数据用了厘米或英尺。可以通过 gdalinfo 输出的 “TypeFloat32” 和统计信息中的Minimum、Maximum值判断如果云南区域的最大高差在 6000 左右是正常的如果算出来是 600000 那多半是单位问题。遇到这种情况用 GDAL 做一次简单的数值缩放gdal_calc.py -A w001001.adf --outfiledem_meter.tif --calcA/100 --NoDataValue-9999gdal_calc 的--calc参数接受简单的算术表达式A/100将厘米值转换回米。NoData 值要保持原样否则会在坡度计算时出现数值飞点。完成缩放后再用可视化工具检查低海拔区域是否出现负数负值通常来自填洼或插值边界需要视情况剔除或保留。4. 地形因子提取坡度、坡向与山体阴影的工程参数4.1 坡度计算的窗口算法与输出选择有了坐标系正确的 DEM下一步是提取坡度。QGIS 的“坡度”工具基于 Horn 算法在 3x3 窗口内计算中心像元与周围像元的高差梯度。关键参数有两个Z factor和“坡度以度或百分数表示”。Z factor 在高纬度地区用于补偿经纬度与真实距离的差异如果数据已经投影为等面积或等距坐标系此值保持 1.0 即可。输出格式建议选择“度”方便后续按坡度等级分类。命令行方式用 GDAL 同样能完成gdaldem slope w001001.adf slope_deg.tif -p -s 111120-p表示输出以百分数表示的坡度不写则默认输出度数-s是垂直夸大因子当输入数据为经纬度坐标系时设置为 111120 可以补偿度与米之间的比例关系投影坐标则设置成 1 或省略。坡度结果中平地是 0悬崖接近 90生成后加载进 QGIS 按自然间断点分类渲染平原、丘陵、山地分界明显可见。4.2 坡向与山体阴影的数值含义坡向的角度范围是0到360度0表示北90表示东270表示西。这个字段对光伏选址和农业种植规划特别有意义南坡光照条件好北坡相对阴冷。用 gdaldem 提取坡向gdaldem aspect w001001.adf aspect.tif输出值 0 代表平地-9999 是边缘无效值。分析的时候要把 -9999 排除在统计范围之外否则会严重拉低平均坡向的参考价值。山体阴影用于模拟太阳光照下的地形起伏感。需要设定太阳高度角和方位角两个核心参数gdaldem hillshade w001001.adf hillshade.tif -az 315 -alt 45 -z 1.0-az指定光线方位角315度代表西北方向来光-alt是太阳高度角45度适合突出中等地形起伏。z 因子的作用与坡度工具相同若地形起伏平缓可以把 z 调到 2 至 3 增强立体感但不要超过 5否则会产生过曝的塑料感。4.3 从等高线到流域分析的联动流程等高线是最直观的地形可视化产物提取命令如下gdal_contour -a elev -i 50 dem_meter.tif contour_50m.shp-a elev定义属性字段名-i 50指定等高线间距。云南省内高差大50 米间距的线条密度适合省域尺度观察如果只想做某个县城片区用-i 10能得到更细的地形细节。流域分水岭提取需要先填洼再计算流向、流量、河网分级。核心命令链如下gdaldem fill dem_meter.tif dem_fill.tif python -c from osgeo import gdal, gdalalg # 使用Python调用gdal算法模块计算流向 填洼的意义在于抹平 DEM 中的凹陷区域保证水流能连续向下游推导。没有填洼的 DEM 会把水流困在坑洞中导致河网断裂。填洼后还要计算流量累积量通常设定一个阈值来提取河网阈值越大河网越稀疏具体数值需要反复试验常见范围是 1000 到 10000 像元。这套流程在云南崎岖山区做水资源分析或地质灾害评估时非常常用。5. 进阶栅格与矢量联动按行政区裁剪与分区统计5.1 用行政区边界裁剪DEM避免跨区域计算溢出分析过程中常常不需要整个云南省的范围比如只关注昆明周边或某个流域的DEM数据。裁剪有矢量裁剪和栅格裁剪两种路线。矢量裁剪能够保留不规则行政边界栅格裁剪则适合按矩形范围切块。用 QGIS 的“裁剪栅格”工具或直接用 GDAL 命令gdalwarp -cutline 云南.shp -crop_to_cutline -dstnodata -9999 dem_meter.tif dem_clip.tif-cutline指定矢量边界作为裁剪模板-crop_to_cutline让输出范围与矢量边界完全贴合-dstnodata设置边缘外区域的无效值。执行后加载检查地块边界的锯齿状像元是否合理如果边缘有明显毛刺说明矢量边界与栅格配准存在半个像元的偏差建议先重投影对齐再裁剪。5.2 分区统计每个区县的平均高程与坡度行政区Shapefile的属性表里通常带有“市”“县”名称字段。要统计每个区域内部的平均海拔或平均坡度用 QGIS 的“分区统计”功能或者 Python 脚本批量计算# 使用PyQGIS进行分区统计 from qgis.core import QgsZonalStatistics dem_layer QgsProject.instance().mapLayersByName(dem_clip)[0] vector_layer QgsProject.instance().mapLayersByName(云南)[0] zone_stat QgsZonalStatistics(vector_layer, dem_layer, 统计_, QgsZonalStatistics.Mean) zone_stat.calculateStatistics(None)QgsZonalStatistics构造函数中第一个参数是分区矢量图层第二个是栅格数据层第三个是输出字段前缀第四个是统计类型。Mean 代表平均值也可以改为 QgsZonalStatistics.Median 或 QgsZonalStatistics.Maximum。执行后矢量图层的属性表会多出名为“统计_平均值”的字段直接用表达式筛选就能找出平均海拔最高的区县。5.3 裁剪后的小技巧计算实际地形起伏与可适建设面积裁剪出的局部 DEM 还能用于快速评估地形起伏度。方法是先计算坡度再按坡度分级重分类然后结合面积统计。用 QGIS 的“栅格计算器”将坡度小于 5 度的区域作为适宜建设用地的候选区代码如下# QGIS栅格计算器表达式 CASE WHEN slope_deg1 5 THEN 1 ELSE 0 END运算结果会生成值为0或1的新栅格其中1代表平缓区域。打开“栅格图层唯一值统计”即可得到像元数量乘以像元面积就能换算成平方公里。这种方法在城市规划前期摸底时相当实用把 DEM、坡度和行政区边界叠加短时间内就能粗略估算出可用土地总量。配合夜间灯光数据或人口分布数据还能解锁更多分析场景是一份基础DEM数据最常见的延伸用法。本文还有配套的精品资源点击获取
返回列表