简介:这份资源是四川省自贡市30米分辨率的DEM数字高程数据包,面向地理信息系统学习者、测绘与城市规划从业者及高校师生,可用于地形分析、洪水模拟、地质灾害评估与地图制作等教学实践场景。压缩包共12个文件,约14.72MB,核心为自贡市dem.tif高程栅格,辅以ovr金字塔与tfw坐标文件便于快速浏览定位;自贡市范围.shp、shx、dbf、prj、sbn、sbx等Shapefile组件提供行政边界与投影信息,多个xml元数据文件则记录数据结构与像元参数。数据覆盖自贡市全域并延伸至部分邻近区域,便于考虑边界效应或开展更大范围研究。目前已有421人学习下载,适合需要完整、可直接加载的市级DEM与边界矢量数据,用于GIS软件实操、地形起伏分析与空间建模练习。
1. 自贡市30m DEM数据到手后:从zip包到能用的地形底图,中间隔着什么
拿到一个标注“四川省自贡市DEM数字高程数据30m(含本市级范围shp文件).zip”的压缩包,很多人第一反应是解压、拖进GIS软件、出图。但真正做过地形分析的人知道,从zip到可用的地形底图,中间至少隔着坐标系确认、无效值处理、范围裁剪、分辨率匹配这四道工序。自贡地处四川盆地南部,地形以低山丘陵为主,海拔跨度大约在250米到900米之间,沱江及其支流切割出大量宽谷和缓坡。30m分辨率意味着每个像素代表地面30米×30米的区域,对市级尺度的坡度分析、汇水区划分、选址评估来说,这个精度刚好够用,又不会让数据量失控。这篇文章面向需要用自贡DEM做地形分析、水文建模或工程选址的从业者,把从数据检查到成果输出的完整链路拆开讲清楚,每一步都给出可复现的操作和参数依据。
2. 先搞清楚手里这份数据到底是什么:30m DEM与市级shp的配套逻辑
2.1 DEM栅格与行政边界shp的关系
DEM是栅格数据,每个像素存一个高程值;shp是矢量数据,用多边形描述自贡市的行政边界。两者配套使用,核心目的是把分析范围严格限定在自贡市辖区内,避免邻市地形干扰统计结果。常见做法是:先用shp裁剪DEM,再在裁剪后的栅格上做坡度、坡向、汇流等派生计算。如果不裁剪,直接对整幅DEM做分析,边界外的像元会被计入统计,导致坡度均值、高程分布等指标偏离真实情况。
这份数据里,DEM通常是GeoTIFF格式,shp一般包含至少一个面要素,属性表里可能有行政区名称或代码字段。打开后第一件事不是急着裁剪,而是确认两者的坐标系是否一致。如果DEM是WGS84地理坐标系(EPSG:4326),而shp是投影坐标系(比如CGCS2000 3度带),直接裁剪会报错或结果错位。
2.2 30m分辨率的实际含义与适用边界
30m分辨率来自ASTER GDEM或类似数据源,水平精度约±30米,高程精度约±10到15米。对自贡这种丘陵区,30m能识别出主要的山脊、沟谷和台地,但无法刻画小于60米的微地形。如果你的目标是分析农田坡度、选址建厂、做小流域水文模拟,30m够用;如果要分析单栋建筑周边的排水,需要更高分辨率数据。
数据量方面,自贡市面积约4381平方公里,30m分辨率下,整幅DEM大约有4800×4800个像素,GeoTIFF文件通常在50到100MB之间。这个体量在普通笔记本上用QGIS或Python处理完全可行,不需要服务器。
2.3 用Python快速检查数据完整性
解压后,我一般先用Python做一次体检,确认栅格和矢量的基本信息。以下代码读取DEM和shp,输出坐标系、范围、像素尺寸和无效值统计。
import rasterio import geopandas as gpd import numpy as np # 读取DEM dem_path = "自贡市_DEM_30m.tif" with rasterio.open(dem_path) as src: print("DEM坐标系:", src.crs) print("DEM范围:", src.bounds) print("像素尺寸:", src.res) print("行列数:", src.height, src.width) dem = src.read(1) nodata = src.nodata print("无效值标记:", nodata) # 统计无效值占比 if nodata is not None: invalid_ratio = np.sum(dem == nodata) / dem.size print(f"无效值占比: {invalid_ratio:.2%}") print(f"高程范围: {np.nanmin(dem)} ~ {np.nanmax(dem)} 米") # 读取市级边界shp shp_path = "自贡市边界.shp" gdf = gpd.read_file(shp_path) print("\nshp坐标系:", gdf.crs) print("要素数量:", len(gdf)) print("边界范围:", gdf.total_bounds)这段代码的关键参数说明:src.res返回像素的x和y方向尺寸,30m数据应显示(30.0, 30.0);src.nodata是无效值标记,常见为-9999或-32768;gdf.total_bounds返回shp的[minx, miny, maxx, maxy]。如果DEM和shp的坐标系不一致,gdf.total_bounds的数值范围会与src.bounds明显不同,比如一个是经纬度(约104°E, 29°N),另一个是投影坐标(百万级数值)。
提示:如果发现坐标系不一致,不要直接裁剪。先用
gdf.to_crs(src.crs)把shp转到DEM的坐标系,再执行后续操作。
3. 把DEM裁到自贡市范围内:shp裁剪栅格的三种做法与参数选择
3.1 用QGIS图形界面完成裁剪
对不常写代码的人,QGIS是最快的路径。操作步骤:打开QGIS,拖入DEM和shp;确认两者坐标系一致(右下角状态栏可看);菜单栏选择“栅格”→“提取”→“按掩膜图层裁剪”;在对话框中,输入图层选DEM,掩膜图层选shp,输出文件指定路径;勾选“将输入图层的分辨率保持为输出分辨率”,避免重采样改变像素尺寸;点击运行。
裁剪完成后,用“识别要素”工具点击边界外区域,应显示无数据。如果边界外仍有高程值,说明掩膜没生效,检查shp是否有面要素、坐标系是否一致。
3.2 用rasterio做精确裁剪
需要批量处理或嵌入自动化流程时,用Python更可控。以下代码用rasterio的mask功能,按shp几何裁剪DEM,并输出为新的GeoTIFF。
import rasterio from rasterio.mask import mask import geopandas as gpd dem_path = "自贡市_DEM_30m.tif" shp_path = "自贡市边界.shp" out_path = "自贡市_DEM_30m_clipped.tif" # 读取shp并统一坐标系 gdf = gpd.read_file(shp_path) with rasterio.open(dem_path) as src: if gdf.crs != src.crs: gdf = gdf.to_crs(src.crs) # 提取几何对象 geoms = gdf.geometry.values # 执行裁剪,crop=True表示裁剪后缩小栅格范围 out_image, out_transform = mask(src, geoms, crop=True, nodata=src.nodata) out_meta = src.meta.copy() out_meta.update({ "height": out_image.shape[1], "width": out_image.shape[2], "transform": out_transform }) # 写出裁剪结果 with rasterio.open(out_path, "w", **out_meta) as dest: dest.write(out_image) print("裁剪完成,输出:", out_path)参数说明:crop=True会把输出栅格的范围收缩到shp的外包矩形,减少文件体积;nodata=src.nodata保持无效值标记一致;out_meta继承原DEM的坐标系、数据类型等信息。如果shp有多个面要素(比如自贡下辖的区县),mask会合并所有几何进行裁剪。裁剪后建议再用3.1节的方法检查边界外是否为空。
3.3 裁剪后必做的两项验证
第一项:像素数量对比。裁剪前DEM有约2300万像素,裁剪后应减少到约1900万左右(自贡市面积占整幅的比例)。如果裁剪后像素数几乎没变,说明掩膜没起作用。
第二项:高程范围对比。裁剪前后高程最小值和最大值不应有剧烈变化,因为自贡市边界内包含了主要地形单元。如果裁剪后最大值突然降到500米以下,可能是shp只覆盖了部分区域,或者坐标系转换出错导致掩膜位置偏移。
注意:有些shp文件的面要素可能存在自相交或缝隙,导致裁剪后出现零星空洞。用
gdf.is_valid检查几何有效性,无效的用gdf.buffer(0)修复。
4. 从DEM到地形因子:坡度、坡向、汇流累积量的计算与参数设置
4.1 坡度计算:单位选择与Z因子
坡度是DEM最常用的派生因子。在QGIS中,用“栅格”→“分析”→“坡度”工具,输入裁剪后的DEM,输出坡度栅格。关键参数是“Z因子”:如果DEM的坐标系是投影坐标系(单位米),Z因子设为1;如果是地理坐标系(单位度),需要设Z因子为约111320(赤道处1度约111.32公里),否则坡度会被严重低估。
用Python计算坡度,GDAL的gdaldem命令行更直接:
gdaldem slope 自贡市_DEM_30m_clipped.tif 自贡市_坡度.tif -p -s 1.0-p表示输出为百分比坡度,-s 1.0是Z因子。如果输出角度制坡度,去掉-p。计算完成后,用QGIS打开坡度图,自贡市大部分区域坡度应在0到25度之间,沱江沿岸有局部陡坡超过35度。如果整幅图坡度都在5度以下,检查Z因子是否设错。
4.2 坡向与汇流累积量
坡向计算类似,用gdaldem aspect命令,输出0到360度的方向值。坡向对农业选址和光伏板布置有直接参考价值。
汇流累积量需要先做洼地填充,再计算流向,最后统计汇流。用WhiteboxTools或SAGA GIS的“Fill Sinks”和“Flow Accumulation”工具。参数上,填充阈值一般设为0.01米,避免过度填充改变地形。汇流累积量输出后,高值区域对应沟谷和河道,可用于提取自贡市的水系网络。
4.3 参数设置的三个经验值
第一,坡度计算的Z因子:投影坐标系用1,地理坐标系用111320。第二,洼地填充阈值:自贡丘陵区建议0.01到0.1米,太大填平真实洼地,太小留下伪洼地。第三,汇流累积量阈值:提取水系时,阈值设为500到1000个像素,对应约0.45到0.9平方公里集水面积,能过滤掉细小沟壑,保留主要河道。
5. 避坑与排查:自贡DEM处理中最容易翻车的五个地方
5.1 裁剪后边界外仍有数据
现象:用shp裁剪DEM后,边界外区域显示为正常高程值,不是无数据。原因:shp的坐标系与DEM不一致,掩膜位置偏移;或者shp只有线要素没有面要素。解决:用gdf.geom_type检查要素类型,确保是Polygon;用gdf.to_crs(src.crs)统一坐标系后重新裁剪。
5.2 坡度计算结果整体偏小
现象:自贡市坡度图显示大部分区域坡度小于3度,与实际丘陵地形不符。原因:DEM是地理坐标系,坡度计算时Z因子未设置或设为1。解决:确认DEM的CRS,如果是EPSG:4326,在QGIS坡度工具中把Z因子改为111320,或用gdaldem slope -s 111320重新计算。
5.3 汇流累积量出现大量平行线
现象:汇流累积量图上出现密集的平行线条,而不是自然的沟谷网络。原因:DEM中存在条带状噪声或洼地填充不充分。解决:先做一次中值滤波(3×3窗口)平滑DEM,再执行洼地填充和流向计算。滤波会轻微改变高程,但对水文分析影响可接受。
5.4 裁剪后文件体积异常大
现象:裁剪后的GeoTIFF比原始DEM还大。原因:输出时未设置压缩,或者crop=True未生效,保留了整幅范围但边界外为无数据。解决:写出时添加compress="LZW"参数,并确认crop=True。用gdalinfo查看裁剪后文件的范围是否与shp外包矩形一致。
5.5 shp属性表乱码
现象:打开shp属性表,行政区名称显示为乱码。原因:shp的DBF文件编码与GIS软件默认编码不匹配,常见于GBK与UTF-8冲突。解决:在QGIS中右键图层→属性→源,把编码改为GBK或UTF-8逐个尝试;或用Python的gpd.read_file(shp_path, encoding="gbk")指定编码读取。
6. 让这份DEM数据真正可复用的两个进阶技巧
6.1 建立自贡市地形因子数据库
单次分析做完就丢,下次用又要重新处理。我习惯把裁剪后的DEM、坡度、坡向、汇流累积量统一导出为GeoTIFF,放在同一个文件夹,用QGIS的“图层组”管理。更进一步,用GeoPackage格式把栅格和矢量打包成一个文件,方便传输和归档。以下代码把多个栅格写入一个GeoPackage:
import rasterio from osgeo import gdal # 用gdal_translate把栅格转为GeoPackage import subprocess layers = { "dem": "自贡市_DEM_30m_clipped.tif", "slope": "自贡市_坡度.tif", "aspect": "自贡市_坡向.tif" } for name, path in layers.items(): subprocess.run([ "gdal_translate", "-of", "GPKG", path, f"自贡市地形.gpkg", name ]) print("GeoPackage构建完成")这样一份自贡市地形.gpkg就包含了所有地形因子,下次直接加载即可。
6.2 用地形因子做选址筛选的实操思路
假设要在自贡市选一块适合建厂的区域,条件:坡度小于5度、不在汇流累积量高值区(避免洪水)、海拔在300到500米之间。在QGIS中用“栅格计算器”逐步筛选:坡度<5 → 输出1/0;汇流累积量<500 → 输出1/0;高程在300到500之间 → 输出1/0;三者相乘,得到候选区域。最后用“栅格转矢量”导出候选地块,再叠加交通和用地数据做进一步筛选。
这套流程我用了三年,从自贡的DEM数据到最终选址图,熟练后大约40分钟能跑完一轮。最深的教训是:永远先检查坐标系,再动手裁剪。有一次帮同事处理川南某市的DEM,跳过检查直接裁剪,结果整个市的坡度图偏移了十几公里,白跑了一下午。后来我养成了一个习惯:任何DEM到手,第一行代码永远是打印CRS和bounds。希望帮到你。
本文还有配套的精品资源,点击获取