资讯动态

淮南市30m DEM裁剪处理:从坐标配准到质量检查全流程

发布时间:2026/9/10 14:08:25 来源:尧图企业网站定制
简介安徽省淮南市30米分辨率DEM数字高程数据包内含核心TIF栅格高程模型和淮南市行政范围SHP矢量边界面向GIS初学者、地理信息从业者及规划研究人员可支撑地形渲染、坡度坡向计算、流域分析、洪水淹没模拟与通视分析等常见任务。压缩包共12个文件以TIF栅格高程数据、SHP矢量范围文件为主配套PRJ投影、SBN/SBX空间索引、TFW坐标信息及XML元数据便于GIS软件直接读取、正确配准和高效显示包体仅10.67MB轻量易用。数据覆盖淮南市并包含周边部分区域为跨边界研究补充更完整的地理背景。目前已有412人学习或下载。借助该数据集用户可在ArcGIS或QGIS中快速加载结合范围图层进行裁剪、叠加与三维可视化深入理解DEM结构并完成定量地形分析是一份兼具教学与科研价值的高性价比地理信息数据。1. 拿到淮南市30m DEM数据包先别急着拖进ArcMap做淮河流域生态评价、采煤沉陷区地表分析或者县域规划的人经常会下载到这类压缩包一个命名为“安徽省淮南市DEM数字高程数据30m含区域范围shp文件.zip”的文件解开之后是30米分辨率的DEM栅格加一个边界shp。多数人的第一反应是把两个文件直接拖进ArcMap看一眼结果要么是屏幕上一片花白要么边界位置和影像对不上甚至裁剪出来的DEM带着一圈锯齿状的无效值。这个标题其实给出了三个关键信息区域限定在淮南市、分辨率是30米、附带区域范围shp。这三个信息决定了后续操作的正确顺序先想清楚30m在平原城市能表达什么再用shp作为裁剪边界做一次严格的地理配准最后才是渲染和出图。下面按这个顺序把完整流程走一遍。2. 30m DEM的分辨率与淮南地形适配先想清楚再动手2.1 30米像元这个精度级别适合做什么、不适合做什么30m DEM的一个像元对应地面上30米乘30米的范围。放到淮南市的地貌背景下这个尺度特别需要辩证看。淮南跨淮河两岸北部是淮河冲积平原地势平缓局部高差只有几米到十几米南部有舜耕山、上窑山等低山丘陵最高点两百米上下。同样是30m分辨率在平原区域一个像元可能完全落在同一高度带上两个相邻像元的高程差小于0.1米而在舜耕山南坡一个像元里可能包含从山脚到山坡的变化。这带来一个实用判断如果要做的是10米等深线级别的河漫滩精细分析或者采煤沉陷区小尺度积水边界提取30m数据会明显力不从心沉陷坑边缘和淮河滩地上的微小起伏会被平均掉。但如果做的是全市域的汇水区划分、坡度分级、或者地表粗糙度概算30m是性价比很高的选择它能把山体轮廓和主要沟谷形态表达出来同时文件体量又足够小。淮南市域面积约5500平方公里30m分辨率下栅格行列数大概在2500乘2200的量级单波段16位整型存下来只有十几MB处理起来非常轻。像元大小 30m x 30m 1个像元面积 900平方米 淮南市域约5500km²约合611万像元这个体量意味着后续所有操作包括裁剪、坡度计算、等高线提取在普通笔记本上都能秒级完成。30m数据真正要防的不是算不动而是用错了场景拿30m数据硬去做米级精度的淹没分析得到的结论会让人误判风险。2.2 ASTER GDEM、SRTM与ALOS 12.5m数据怎么判断你手里的是哪类市面上流通的30m DEM主要是两个家族。一个是NASA和METI合作的ASTER GDEM覆盖全球按1角秒网格采样标称垂直精度在十米级常见的是V2和V3版本。另一个是SRTM的1角秒重采样产品原始航天飞机雷达地形测绘任务在2000年采集后来发布过30m分辨率版本垂直精度在数米级相比ASTERSRTM在平坦区域的噪声更小但高纬度地区和陡峭峡谷会有雷达阴影空洞。还有一类是ALOS AW3D30它原始分辨率是30m但很多渠道把它标成12.5米DEM下载因为ALOS PALSAR的原始数据可以处理成12.5m分辨率重采样之后和30m混在一起流通。判断手里的文件属于哪一类不依赖文件名直接读文件元数据更靠谱。在QGIS里加载DEM图层后打开图层属性看“信息”页签里的栅格属性能找到数据来源和采集时间在ArcMap里则是在图层属性里的“源”页签。更直接的办法是用GDAL工具读文件头这个做法放到第3章详细展开。对于淮南这种以平原为主、地形起伏不大的区域SRTM类数据通常表现更稳定ASTER在某些河谷地带的条带噪声容易在渲染时显示出一楞一楞的纹理这不是真实地形是采集误差。2.3 高程基准与坐标系先知道它从哪里来才知道能不能直接算打开zip里的shp文件很多人只看是不是覆盖了淮南忽略了两个关键元数据坐标系和高程基准。淮南市的DEM产品常见两种坐标系WGS84经纬度坐标和UTM 50N投影坐标。如果shp是WGS84经纬度DEM也是WGS84经纬度两者可以直接叠加但如果shp被重投影到CGCS2000高斯投影DEM还停留在WGS84直接叠加就会看到边界整体偏移几十米到上百米。在平原上几十米偏移不容易肉眼识别只有把边界叠加到卫星影像或者和道路shp比照时才会暴露。高程基准同样影响计算结果。绝大多数30m DEM产品使用EGM96大地水准面参考椭球是WGS84。淮南市域内EGM96与WGS84椭球面的差距大约是负三十几米到负四十米这个垂向偏差在绝大多数地形分析里不会影响坡度、坡向、汇水区提取这类形态学分析但如果要用DEM做建筑物高度推算或者和GNSS测量的椭球高做差就必须先做高程基准转换。这个题目的原始需求如果只是裁切和可视化坐标系一致就够了高程基准差异可以暂时不管但如果要把DEM导入到已有三调数据的项目里务必先确认两个数据用的是不是同一个高程基准。3. 打开淮南市DEM和shp文件之前先用命令行做一次体检3.1 用gdalinfo读取栅格的尺寸、像元大小与NoData拿到解压后的tif和shp我一般先打开OSGeo4W Shell或者终端用一条gdalinfo命令把DEM的老底摸清楚。这条命令不依赖任何图形界面输出里包含判断数据可用性的全部关键参数。gdalinfo huainan_dem_30m.tif输出重点看以下几行Driver: GTiff/GeoTIFF Size is 2417, 1803 Coordinate System is: PROJCRS[WGS 84 / UTM zone 50N, BASEGEOGCRS[WGS 84] Pixel Size (30.000000000000000, -30.000000000000000) Metadata: AREA_OR_POINTArea Image Structure Metadata: INTERLEAVEBAND Band 1 Block256x256 TypeFloat32, ColorInterpGray NoData Value-9999 Minimum10.340 Maximum245.870 StdDev32.456逻辑说明Size后面是列数和行数2417列乘1803行乘上900平方米得到约5230平方公里和淮南市域面积对得上。Pixel Size为(30, -30)说明已经是投影坐标系的30m栅格如果是经纬度坐标会显示成(0.0002777778, -0.0002777778)。Band 1的Type是Float32高程范围10.34米到245.87米正好覆盖淮河河谷到舜耕山一带的高度这个范围符合淮南的地形认知。NoData Value是-9999这是DEM产品里很常见的无效值编码后续所有处理都要记得排除它否则高程统计会被污染。特别注意如果Pixel Size显示为经纬度说明数据还是地理坐标系后面的裁剪和测距都必须先做投影转换不转换就直接计算面积会得到完全错误的平方公里数。3.2 用Python读取shp文件的坐标系与边界范围和DEM对齐检查栅格检查完接下来检查shp。用geopandas读取代码比桌面软件操作更直接还能把两个文件放在同一个坐标系上下文里比对。import geopandas as gpd import rasterio # 读取DEM获取其坐标系与边界 with rasterio.open(huainan_dem_30m.tif) as src: dem_crs src.crs dem_bounds src.bounds print(DEM CRS:, dem_crs) print(DEM Bounds:, dem_bounds) # 读取区域边界shp shp_path huainan_area.shp gdf gpd.read_file(shp_path) print(Shp CRS:, gdf.crs) print(Shp Bounds:, gdf.total_bounds)参数说明dem_crs是rasterio从tif文件头解析出的坐标系对象gdf.crs是geopandas从shp的.prj文件里读出的坐标系。对比两个crs是否一致最严谨的方式是比较两者的权威代码比如EPSG:32650和EPSG:4528虽然都覆盖淮南附近但不是同一个坐标系。total_bounds返回的是四至边界(minx, miny, maxx, maxy)。如果shp的边界范围和DEM的边界范围对不上常见原因有两种一是shp本身是全市行政区划而DEM是分幅裁过的子集范围上会包含或包含于的关系二是两者坐标系不一致例如DEM是UTM 50Nshp是CGCS2000高斯投影那种情况下total_bounds会整体偏移数百米。对齐检查的意义就是提前发现这两个问题避免裁剪时裁出大片空白。3.3 把数据包内部对齐为什么矢量可以重投影而栅格要尽量少动检查之后如果发现坐标系不一致处理原则是重投影shp而不是重投影DEM。原因是栅格重投影会触发重采样重采样意味着每个像元的高程值要经过插值计算双线性插值或者三次卷积都会平滑掉一部分地形细节让原本30m的数据名义上还是30m实际信息量已经被修改过了。矢量shp重投影不会改变任何属性值只是把边界顶点坐标换算到新的坐标系是无损操作。# 将shp重投影到DEM的坐标系无损操作 if gdf.crs ! dem_crs: gdf gdf.to_crs(dem_crs) gdf.to_file(huainan_area_reprojected.shp)投影之后建议再打印一次total_bounds确认落位同时检查几何类型区域边界shp应该是Polygon或者MultiPolygon如果混入了LineString或Point在后续裁剪时需要先做几何过滤。另外留意属性表里是否含有区域名称字段这个字段在制图出图时会用来做注记缺失的话也没什么影响手工添加一列就行。提示如果DEM本身是经纬度坐标系而shp是投影坐标系建议反过来把DEM投影到合适的本地投影再做裁剪。因为30m的DEM在经纬度坐标下像元不是正方形坡度坡向计算会失真。4. 用淮南市shp边界裁剪DEM三条路线与参数对照4.1 ArcGIS里用Extract by Mask完成30m DEM裁剪ArcGIS的解决方案是Spatial Analyst工具集中的Extract by Mask这个工具用shp边界作为掩膜把边界内的像元保留边界外的像元替换为NoData。操作路径是ArcToolbox - Spatial Analyst Tools - Extraction - Extract by Mask。关键参数只有三个参数推荐值说明Input rasterhuainan_dem_30m.tif输入DEMInput raster or feature mask datahuainan_area.shp区域边界Output rasterhuainan_dem_clip.tif输出路径需要注意一个隐藏参数环境设置里的“Snap Raster”。如果不设置栅格捕捉Extract by Mask输出的像元范围可能和原始DEM错开半个像元导致裁剪结果和原图有细微错位。处理方法是在Environment Settings - Processing Extent里把Snap Raster指定为原始DEM。另外输出格式建议直接选TIFF不要用img或者默认的Esri Grid这样后续转到QGIS或者其他工具时兼容性更好。ArcGIS裁剪完成之后检查两件事第一图层属性里查看源页签的像元大小是否还是30米如果变成其他值说明重采样被意外触发第二用Identify工具点一下边界线附近的像元确认边界轮廓没有出现锯齿状断层。4.2 QGIS的栅格裁剪工具与NoData处理QGIS的裁剪逻辑比ArcGIS更直白栅格菜单下有两个容易混淆的工具Clip Raster by Extent和Clip Raster by Mask Layer。前者是矩形范围裁剪直接裁掉外接矩形之外的部分不会跟着shp的不规则边界走后者才支持矢量掩膜裁剪。要做淮南市边界精确裁剪必须选Clip Raster by Mask Layer。参数上核心选项是“Create an output alpha band”。勾选之后输出tif会额外生成一个透明波段让边界外区域显示为透明。对于进一步做专题图有用但会增大文件体量而且有些老版本GDAL在读取带alpha波段的tif时会把透明区域读成0值干扰高程统计。如果后续还要做数值分析建议不勾选alpha保持单波段让边界外保持NoData。另一个参数是“Match the extent of the clipped raster”保持默认即可它决定输出范围是否严格贴合shp的边界矩形。如果选No输出范围会沿用输入DEM的范围只是把边界外改成了NoData文件大小不变处理效率低选Yes才会真正把数据裁剪成紧凑的范围。4.3 Python方式rasterio.mask一步裁剪并重写投影参数对于要批量处理多期DEM或者要把裁剪流程写进自动化管线的场景rasterio.mask是最干净的方式。先读shp、再调mask、最后写盘完整脚本如下。import geopandas as gpd import rasterio from rasterio.mask import mask # 1. 读取DEM并取得其坐标系 dem_path huainan_dem_30m.tif shp_path huainan_area_reprojected.shp with rasterio.open(dem_path) as src: # 2. 将shp重投影到DEM的坐标系 gdf gpd.read_file(shp_path) if gdf.crs ! src.crs: gdf gdf.to_crs(src.crs) # 3. 执行掩膜裁剪 # cropTrue 表示让输出尺寸贴合shp范围 # nodata-9999 替代原NoData值保证有效像元统计不受影响 out_image, out_transform mask( src, gdf.geometry, cropTrue, nodata-9999 ) # 4. 更新元数据并写入新文件 out_meta src.meta.copy() out_meta.update({ driver: GTiff, height: out_image.shape[1], width: out_image.shape[2], transform: out_transform, nodata: -9999 }) with rasterio.open(huainan_dem_clip.tif, w, **out_meta) as dst: dst.write(out_image) print(裁剪完成)参数说明mask函数的第一个参数是打开的栅格数据集第二个是几何对象列表gdf.geometry传进来的是GeoSeriesrasterio会自动取每个要素的外边界。cropTrue的意义是让输出栅格的行列数适应shp的边界范围而不是保留原始DEM的全部范围不设crop的话文件不会变小裁剪意义减半。nodata-9999与原始数据保持一致避免后续坡度计算时把边界外的无效区域当成高程0。需要注意gdf.geometry里如果包含多个要素rasterio.mask默认会把所有要素合并成一个掩膜取并集。如果shp文件里有多个不相邻的面状要素并且只想要其中某个区县需要先用gdf[gdf[name] 田家庵区]之类的过滤语句筛出目标要素再做裁剪。提示rasterio.mask里还有一个all_touched参数默认False表示只保留中心点落在shp内部的像元True表示只要像元和边界有交集就保留。边界上差一圈像元对后续面积统计影响不大但对岸线边界定位有影响建议保持默认False。5. 裁剪后的DEM质量检查识别NoData洞、负高程与DSM残留5.1 用统计指标判断高程分布是否合理裁剪完成不等于数据可用。30m DEM的常见问题在裁剪后反而更容易暴露因为裁掉了一大片无效区域后统计指标会全部集中在淮南市域内。跑一遍numpy统计比肉眼看渲染图可靠得多。import numpy as np import rasterio with rasterio.open(huainan_dem_clip.tif) as src: arr src.read(1) nodata src.nodata valid arr[arr ! nodata] print(f有效像元总数: {valid.size}) print(f有效像元占比: {valid.size / arr.size:.2%}) print(f最小高程: {np.nanmin(valid):.2f} m) print(f最大高程: {np.nanmax(valid):.2f} m) print(f高程均值: {np.nanmean(valid):.2f} m) print(f高程标准差: {np.nanstd(valid):.2f} m)逻辑说明先用arr ! nodata清理无效值避免-9999参与统计把最小值拉到负一万。得到的有效像元占比如果低于95%说明DEM里存在大量空洞这种数据直接做坡度分析会在空洞边缘产生异常的高梯度。高程范围用来和淮南地形常识对照如果最大值超过400米而淮南最高的舜耕山只有两百多米就要怀疑是不是混入了粗差飞点如果最小值低于0米淮河河床在淮南段最低也在十几米以上低于0说明可能是NoData被错误转成了0值或者是数据源本身包含了水面高程异常。高程标准差是个好指标。淮南这种地形起伏从十几米到两百多米的区域标准差在30到50米之间属于正常。如果标准差超过80米通常意味着栅格里有极端异常值如果标准差小于10米说明数据可能被过度平滑过或者这个文件根本不是30m DEM而是重采样后的低精度插值结果。5.2 找出无效像元并修复而不是直接滤波抹平统计发现空洞之后常见的错误做法是直接套一个低通滤波把NoData区域填上这个操作会把本来没有数据的区域赋予一个平滑的伪造值如果这个区域恰好是淮河河面滤波后的水面会变成一个假的斜坡汇水区分析就全错了。正确做法是先定位空洞的分布特征再决定修复策略。import numpy as np from scipy.ndimage import binary_fill_holes import rasterio with rasterio.open(huainan_dem_clip.tif) as src: arr src.read(1) nodata src.nodata # 标记无效像元看它们是否连通成大块 invalid (arr nodata) print(f无效像元总数: {invalid.sum()}) print(f无效像元外围范围: 行 {invalid.any(axis1).argmin()}~{invalid.any(axis1).argmax()}) # 如果空洞是小块离散的用邻域插值修复 from scipy.ndimage import median_filter if invalid.sum() arr.size * 0.05: # 用3x3中值滤波填充无效值注意只替换无效位置的取值 filled median_filter(arr, size3, modenearest) arr[invalid] filled[invalid] print(已用中值滤波修复离散空洞)参数说明invalid.sum()小于总像元的5%时可以认为空洞是小概率离散事件这种用中值滤波修复风险低。中值滤波size3表示取每个像元周围3乘3邻域的中值相比均值滤波中值不会因为邻域里有另一个无效值而被拉偏。modenearest控制边界处的填充策略表示延伸边缘值防止计算到栅格边框时溢出。如果空洞占比超过5%或者空洞连成条带状比如SRTM在某些山区的雷达阴影带那就不建议修复了应该回到原始数据源重新下载缺口更少的数据比如ALOS的12.5m产品或者补充局部无人机测图数据。5.3 淮河平原这类缓坡区域哪些“细节”其实是要丢掉的淮南市域内有大面积平缓的淮河冲积平原30m DEM在这种地形上经常出现一种让新手困惑的现象看起来一片平坦的区域渲染后出现许多随机的高程噪点一个像元比周围高出0.5米下一个像元又低0.5米。这些不是真实微地形而是传感器的垂直噪声。判断要不要处理这些噪声看后续用途。如果只做全市尺度的坡度分级这些噪声会被坡度算法放大成一个一个的伪坡面尤其是坡度为0到1度之间的平地区域噪声会让坡度在0到5度之间跳变制图效果很差。我一般会用3乘3的均值滤波对平坦区域做一步平滑但关键是控制平滑范围只作用于坡度小于2度的区域避免把舜耕山的山脊线也抹圆了。import numpy as np from scipy.ndimage import uniform_filter # 计算简单坡度 gy, gx np.gradient(valid.astype(float)) slope np.degrees(np.arctan(np.sqrt(gx**2 gy**2))) # 平坦区域做均值平滑 flat_mask slope 2.0 smoothed uniform_filter(valid.astype(float), size3) valid[flat_mask] smoothed[flat_mask]另一个要主动丢弃的“细节”是DSM残留。如果这份DEM的原始数据源是光学立体像对生成的DSM淮南市区里的高楼、桥梁、煤矿井架都会被记录成一个高出地面的包块。在30m分辨率下一栋30米宽的楼房会占掉一个像元体现在渲染图上是城区位置出现许多小尖峰。识别方法是把高程渲染图叠上夜间灯光数据或者道路shp凡是亮灯区域对应的尖峰基本都是DSM残留。处理方式是把这类像元的高程替换为邻域中值替换范围控制在建筑密集区。6. 用裁剪结果生成等高线、山体阴影与DXF叠加6.1 一条命令生成等高线与山体阴影数据质量过关后最常用的产品化输出是等高线加山体阴影底图。gdal自带两个命令能直接完成不需要开ArcGIS。# 生成等高线-i表示等高距 gdal_contour -a ELEV -i 10 huainan_dem_clip.tif huainan_contour_10m.shp # 生成山体阴影-az方位角 -alt太阳高度角 -z垂直放大系数 gdaldem hillshade huainan_dem_clip.tif huainan_hillshade.tif -az 315 -alt 45 -z 1.2参数说明gdal_contour的-a ELEV指定等高线属性字段名后续在QGIS里用这个字段做注记。等高距选择要结合淮南地形平原区域用10m等高距会出现大量密集短小闭合等高线反而干扰判读如果出图比例尺是1:5万建议在平原区域用5m山区用20m分开两个图层承载。gdaldem的-az参数是315度即从西北方向打光这是制图标准习惯因为人眼对西北方向的光影最敏感-alt 45度是太阳高度角平原区用45度能突出微地形-z 1.2是垂直夸张系数淮南这种整体高差只有两百多米的区域不做垂直夸张山体阴影会非常平淡夸张到1.2到1.5之间比较合适。6.2 把DEM、道路shp与DXF图纸叠加做最终验证等高线和山体阴影生成之后最后一步是把它们和原始区域shp、已有道路shp叠加在一起做视觉验证。在QGIS里把山体阴影放到最底层DEM放在中间并调成半透明淮南市边界shp和等高线放在最上层这个配图既能看出地形起伏又能保持行政边界清晰。如果项目要求CAD环境下的三维分析可以用Python把等高线shp转成DXF格式直接导入AutoCAD或者中望CAD。转换路径是gdal_polygonize先取等值面再用shp2dxf工具转格式或者用ezdxf库直接写出dxf文件这一步在规划项目里经常用来给道路选线、管线走廊提供纵断面参考。叠加之后重点检查两个位置淮河河谷里的等高线是否和河道走向一致如果等高线横穿河道并在两岸出现明显落差说明原始DEM在河流区域的高程被水体表面污染这种情况在30m DEM里不少见另一个是舜耕山一带的等高线有没有闭合圈断裂或突然折角折角通常意味着数据空洞修复失败或者是坐标系统仍有细微偏移。验证通过后把裁剪后的tif、等高线shp、山体阴影tif三个文件用同样的命名前缀和数据字典归档后续任何基于这个数据集的坡度、坡向、汇水分析都从裁剪后的tif出发不再动原始文件。这样整条数据链路保持可追溯换人接手时只需要读一遍文档就能复现全部成果。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价