简介这份资源是湖南省湘潭市30米分辨率DEM数字高程数据包面向GIS初学者、地理信息专业学生及需要湘潭市地形数据的研究人员可用于坡度分析、洪水模拟、地质灾害评估及城市规划等场景。压缩包共12个文件约12.91MB核心为湘潭市dem.tif高程栅格辅以tfw、ovr、xml等影像配套文件同时提供湘潭市范围shp矢量边界并附带dbf、prj、shx、sbn、sbx等Shapefile属性与索引文件坐标系统与空间索引信息完整便于直接加载分析。目前已有464人学习下载。数据覆盖湘潭市行政区域并兼顾周边过渡地带读者可据此开展地形起伏研究、三维可视化与空间建模也可作为GIS课程中DEM读取、裁剪、坡度提取等实验的实操素材快速上手真实地理数据。1. 湘潭市30m DEM与shp边界从数据包到可分析底图拿到“湖南省湘潭市DEM数字高程数据30m含本市级范围shp文件.zip”这个包第一反应不该是解压看文件而是先想清楚它能干什么。湘潭地处湘中丘陵与洞庭湖平原过渡带湘江穿城而过地势西南高、东北低最高点与最低点落差超过千米。30m分辨率意味着每个栅格像元代表地面30米×30米的平均高程对市级尺度的坡度分析、汇水区划分、选址踏勘足够用但做小区级土方计算就偏粗。包里附带的市级行政边界shp文件价值在于能把DEM裁剪到湘潭市实际管辖范围避免周边地市数据干扰统计。这套组合适合做流域分析、洪水淹没模拟前期底图、风电光伏选址初筛以及GIS教学中的地形分析案例。如果你手头只有DEM没有边界裁剪时靠经纬度矩形框硬切边缘会混入株洲、娄底的地形统计结果直接失真。2. 湘潭市DEM数据包拆解30m栅格与市级shp的匹配逻辑2.1 30m分辨率DEM的坐标基准与高程基准30m DEM常见来源包括ASTER GDEM、SRTM以及国内测绘部门生产的格网数据。这个包里的数据大概率采用WGS84椭球基准或CGCS2000坐标系高程基准可能是EGM96大地水准面或1985国家高程基准。两者差异在湘潭地区可达十几米做淹没分析时这个量级足以改变结论。判断方法很简单用GIS软件加载后查看属性中的坐标系信息再找一个已知水准点比对。如果高程值明显偏大或偏小先别急着用查清楚基准再动手。栅格文件的命名通常包含行列号或经纬度范围湘潭市覆盖范围大致在东经111°58′至113°05′北纬27°20′至28°05′之间。30m分辨率下整个湘潭市约5000平方公里栅格数量在550万像元左右单波段Float32格式文件大小约22MB压缩后更小。这个体量在普通笔记本上用QGIS或ArcGIS打开毫无压力但做全市汇水分析时注意内存占用。2.2 市级行政边界shp文件的字段与拓扑检查shp文件是ESRI Shapefile格式至少包含.shp、.shx、.dbf三个文件缺一不可。市级边界通常是面要素字段里会有市名、代码、面积等信息。拿到后第一件事不是直接裁剪而是做拓扑检查有没有自相交、有没有缝隙、边界是否闭合。湘潭市边界与周边地市接壤如果从省级边界里提取接边处容易出现重复线或微小缝隙裁剪DEM时会产生空值条带。检查方法用QGIS的“几何有效性检查”工具或者用Python的geopandas读入后调用is_valid属性。发现无效几何用buffer(0)修复这是血泪经验比手动改节点快得多。import geopandas as gpd # 读入湘潭市边界shp xt_boundary gpd.read_file(xiangtan_boundary.shp) # 检查几何有效性 invalid xt_boundary[~xt_boundary.is_valid] print(f无效几何数量: {len(invalid)}) # 修复无效几何 xt_boundary[geometry] xt_boundary[geometry].buffer(0) # 检查修复后是否还有无效 print(f修复后无效几何数量: {len(xt_boundary[~xt_boundary.is_valid])}) # 查看坐标系 print(f当前坐标系: {xt_boundary.crs})这段代码先读入边界文件用is_valid筛出有问题的要素buffer(0)是GIS圈公认的几何修复偏方原理是把多边形向外扩0距离再收回过程中自动消除自相交和重复节点。最后打印坐标系如果显示EPSG:4326就是经纬度坐标裁剪前需要和DEM统一。2.3 DEM与shp的坐标系对齐操作坐标系不统一是新手翻车重灾区。DEM如果是WGS84地理坐标系EPSG:4326而shp是投影坐标系如EPSG:4547 CGCS2000 3度带直接裁剪会报错或结果错位。统一方法有两种把shp转到DEM的坐标系或者把两者都转到适合湘潭的投影坐标系。做面积和坡度统计时强烈建议用投影坐标系因为地理坐标系下像元大小随纬度变化30m×30m不是真实面积。湘潭市适用EPSG:4547CGCS2000 / 3-degree Gauss-Kruger CM 114E中央经线114°E覆盖湘潭全境。转换用geopandas的to_crs方法# 将边界转到CGCS2000 3度带投影 xt_boundary_proj xt_boundary.to_crs(EPSG:4547) # DEM如果是地理坐标系用rasterio读取后重投影 import rasterio from rasterio.warp import calculate_default_transform, reproject, Resampling with rasterio.open(xiangtan_dem.tif) as src: transform, width, height calculate_default_transform( src.crs, EPSG:4547, src.width, src.height, *src.bounds) kwargs src.meta.copy() kwargs.update({ crs: EPSG:4547, transform: transform, width: width, height: height }) with rasterio.open(xiangtan_dem_proj.tif, w, **kwargs) as dst: reproject( sourcerasterio.band(src, 1), destinationrasterio.band(dst, 1), src_transformsrc.transform, src_crssrc.crs, dst_transformtransform, dst_crsEPSG:4547, resamplingResampling.bilinear )calculate_default_transform自动计算重投影后的范围和像元大小Resampling.bilinear是双线性插值适合连续型高程数据。重采样方法别选最近邻那会造成高程值阶梯状失真。重投影后像元大小可能不是整30m这是正常的因为投影变换会引入微小形变。3. 用QGIS和Python裁剪湘潭市DEM从全市栅格到边界内地形3.1 QGIS按掩膜提取的图形化操作QGIS里裁剪DEM用“按掩膜图层裁剪栅格”工具路径在Processing Toolbox → GDAL → Raster extraction → Clip raster by mask layer。参数设置输入图层选DEM掩膜图层选湘潭市边界shp勾选“保持输入分辨率”输出格式选GeoTIFF。注意“掩膜图层”必须和DEM坐标系一致否则工具会报错或输出空白。如果边界有多个面要素工具默认合并所有要素作为掩膜湘潭市只有一个市级面没问题。裁剪后检查边缘用识别工具点几个边界附近的像元看值是否在合理高程范围内。如果出现-9999或极大值说明掩膜外区域被赋了NoData这是正常行为但要在后续分析中排除。3.2 Python rasterio掩膜裁剪的完整脚本批量处理或需要嵌入自动化流程时Python更可控。rasterio的mask函数配合geopandas读入的边界几何一行代码完成裁剪。import rasterio from rasterio.mask import mask import geopandas as gpd # 读入投影后的DEM和边界 with rasterio.open(xiangtan_dem_proj.tif) as src: xt_boundary gpd.read_file(xiangtan_boundary.shp).to_crs(src.crs) # 提取边界几何 geoms xt_boundary.geometry.values # 执行掩膜裁剪 out_image, out_transform mask(src, geoms, cropTrue, nodata-9999) # 更新元数据 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(xiangtan_dem_clipped.tif, w, **out_meta) as dst: dst.write(out_image)cropTrue表示裁剪后缩小栅格范围到边界外接矩形减少文件体积。nodata-9999是常用标记值后续统计时用out_image ! -9999过滤。注意geoms必须是GeoJSON-like的几何列表直接传GeoSeries可能报错用.values转成numpy数组更稳。3.3 裁剪后高程统计与异常值排查裁剪完别急着出图先做统计。用rasterio读入裁剪结果计算有效像元的高程均值、标准差、最小最大值。import numpy as np import rasterio with rasterio.open(xiangtan_dem_clipped.tif) as src: dem src.read(1) nodata src.nodata # 过滤NoData valid_dem dem[dem ! nodata] print(f有效像元数: {valid_dem.size}) print(f高程范围: {valid_dem.min():.1f} ~ {valid_dem.max():.1f} 米) print(f平均高程: {valid_dem.mean():.1f} 米) print(f标准差: {valid_dem.std():.1f} 米) # 检查异常值 outliers valid_dem[(valid_dem -100) | (valid_dem 3000)] print(f异常值数量: {outliers.size})湘潭市最高点约802米位于湘潭县西南部最低点约30米湘江沿岸。如果统计结果超出这个范围比如出现负值或超过1000米说明数据有问题。负值可能是水体或NoData未正确标记超过1000米可能是相邻地市的高山混入。排查方法用QGIS加载裁剪结果符号化时设置分级显示异常区域一眼就能看出来。4. 湘潭市DEM分析避坑坐标系、NoData与边界接边4.1 坑一裁剪后面积与统计口径不一致现象裁剪后的DEM像元数乘以900平方米和湘潭市官方面积5006平方公里对不上偏差超过5%。原因DEM覆盖范围是矩形裁剪后边界外像元被赋NoData但统计时如果没排除NoData面积会偏大。另外投影坐标系下像元面积不是精确900平方米CGCS2000 3度带在湘潭地区的尺度因子约0.9996实际像元面积约899.3平方米。解决统计前用dem ! nodata生成掩膜只计算有效像元。面积换算用像元数 × 像元宽度 × 像元高度像元宽高从src.transform里取别直接用30。4.2 坑二边界接边处出现空值条带现象裁剪结果在湘潭与株洲、娄底交界处出现宽约1-2个像元的空值条带。原因市级边界shp从省级边界提取时接边处可能有微小缝隙或重复线掩膜裁剪时缝隙处没有覆盖DEM像元被赋NoData。解决裁剪前对边界做buffer(0.0001)微小缓冲再收回或者用unary_union合并所有面要素后做buffer(0)。如果已经裁剪完用栅格填补工具如QGIS的“填充NoData”或rasterio的fillnodata补上但会引入插值误差不如从源头修复。4.3 坑三DEM高程基准与shp高程字段不匹配现象用DEM提取的某点高程与shp属性表里的已知高程点相差十几米。原因DEM用EGM96大地水准面shp里的高程是1985国家高程基准两者在湘潭地区差约0.5-1.5米但如果DEM是SRTM原始数据差可能更大。解决查清DEM元数据里的高程基准用GIS软件做基准转换或者找已知水准点做线性校正。做淹没分析时这个差异必须消除否则水位线画错。4.4 坑四大文件裁剪时内存溢出现象用Python裁剪全市DEM时进程被系统杀掉报MemoryError。原因rasterio的mask函数默认把整个DEM读入内存550万像元的Float32数组约22MB但加上中间变量和边界几何内存占用可能翻几倍。如果同时处理多个文件容易爆。解决用mask的indexes参数只读需要的波段或者分块处理。更稳妥的方法是用GDAL的gdalwarp命令行工具它流式处理内存占用低。gdalwarp -cutline xiangtan_boundary.shp -crop_to_cutline -dstnodata -9999 xiangtan_dem_proj.tif xiangtan_dem_clipped.tif-cutline指定裁剪边界-crop_to_cutline自动缩小范围-dstnodata设NoData值。这条命令在终端里跑不占Python内存适合大文件。4.5 坑五shp文件字段乱码导致属性丢失现象用geopandas读入shp后中文字段名变成乱码或者属性表里市名显示为问号。原因Shapefile的.dbf文件默认编码是Latin-1国内数据常用GBK或UTF-8编码不匹配就乱码。解决读入时指定编码gpd.read_file(file.shp, encodinggbk)或encodingutf-8。如果还是乱码用QGIS打开后重新导出导出时选UTF-8编码。这个坑不影响几何操作但做属性筛选时会出错。5. 从DEM到坡度与汇水分析湘潭市地形衍生数据实战5.1 坡度计算与分级配色坡度是DEM最常用的衍生数据。QGIS里用“坡度”工具Raster → Analysis → Slope输入裁剪后的DEM输出坡度栅格单位选度。湘潭市坡度分布湘江沿岸和东北部平原区0-5度中部丘陵5-15度西南部低山区15-35度。做农业规划时坡度大于25度区域建议退耕还林。Python计算坡度用richdem或gdaldemgdaldem slope xiangtan_dem_clipped.tif xiangtan_slope.tif -p -s 1.0-p表示输出百分比坡度-s 1.0是垂直单位与水平单位的比例DEM高程是米投影坐标也是米所以比例1.0。如果要输出度去掉-p。5.2 汇水区提取与河网分级汇水分析用QGIS的“汇水区”工具Processing Toolbox → SAGA → Hydrology → Catchment Area或者用WhiteboxTools。步骤先填洼Fill Sinks再计算流向Flow Direction然后汇流累积Flow Accumulation最后提取河网。湘潭市湘江干流汇水面积大支流如涓水、涟水汇入提取时注意设置汇流累积阈值一般取1000-5000个像元对应约0.9-4.5平方公里。import whitebox wbt whitebox.WhiteboxTools() wbt.fill_depressions(xiangtan_dem_clipped.tif, dem_filled.tif) wbt.d8_pointer(dem_filled.tif, flow_dir.tif) wbt.d8_flow_accumulation(flow_dir.tif, flow_accum.tif) wbt.extract_streams(flow_accum.tif, streams.tif, threshold2000)threshold2000表示汇流累积超过2000个像元的区域划为河网这个值需要根据湘潭市实际水系密度调整。阈值太小河网太密太大漏掉小支流。5.3 淹没模拟前期高程切片与水位线叠加做洪水淹没模拟时用DEM做高程切片叠加不同水位线。湘潭市湘江段警戒水位约38米吴淞高程用DEM提取38米以下区域就是潜在淹没范围。注意DEM高程基准要统一到吴淞高程否则水位线对不上。import rasterio import numpy as np with rasterio.open(xiangtan_dem_clipped.tif) as src: dem src.read(1) nodata src.nodata # 假设水位38米 water_level 38.0 # 生成淹没掩膜 flooded (dem water_level) (dem ! nodata) # 统计淹没面积 pixel_area src.transform[0] * abs(src.transform[4]) flooded_area flooded.sum() * pixel_area / 1e6 # 平方公里 print(f淹没面积: {flooded_area:.2f} 平方公里)src.transform[0]是像元宽度src.transform[4]是像元高度负值取绝对值相乘得像元面积。这个方法假设水位是平面实际洪水有水面比降但做初步评估够用。5.4 用DEM做风电光伏选址初筛风电选址关注海拔和坡度光伏选址关注坡向和坡度。湘潭市西南部海拔300-800米区域坡度15-25度适合风电东北部平原区坡度小于5度适合光伏。用QGIS的栅格计算器做多条件筛选# 假设已有坡度栅格和坡向栅格 import rasterio import numpy as np with rasterio.open(xiangtan_slope.tif) as src: slope src.read(1) profile src.profile with rasterio.open(xiangtan_aspect.tif) as src: aspect src.read(1) # 光伏适宜区坡度5度坡向朝南135-225度 pv_suitable (slope 5) (aspect 135) (aspect 225) # 写出结果 profile.update(dtyperasterio.uint8, nodata0) with rasterio.open(pv_suitable.tif, w, **profile) as dst: dst.write(pv_suitable.astype(rasterio.uint8), 1)坡向135-225度是南向坡接收太阳辐射最多。这个筛选结果还要叠加土地利用、电网距离等数据但DEM衍生数据是第一道筛子。6. 湘潭市DEM进阶用GDAL命令行批量处理与质量验证6.1 GDAL命令行批量裁剪与重投影手头如果有湖南省多个市的DEM和边界用GDAL命令行批量处理比Python脚本更省事。写一个bash循环#!/bin/bash for city in xiangtan zhuzhou louxia; do gdalwarp -cutline ${city}_boundary.shp \ -crop_to_cutline \ -dstnodata -9999 \ -t_srs EPSG:4547 \ hunan_dem.tif \ ${city}_dem_clipped.tif done-t_srs EPSG:4547在裁剪同时重投影一步到位。注意-cutline的shp坐标系可以是任意GDAL会自动转换但DEM的坐标系要和-t_srs一致或能被转换。6.2 用gdaldem生成山体阴影与地形纹理山体阴影图能直观检查DEM质量。命令gdaldem hillshade xiangtan_dem_clipped.tif xiangtan_hillshade.tif -z 2 -az 315 -alt 45-z 2是垂直 exaggeration放大2倍让地形更明显-az 315是光源方位角315度是西北方向符合制图习惯-alt 45是光源高度角。生成的山体阴影图如果出现条纹或块状伪影说明DEM有接边误差或噪声。6.3 DEM质量验证与已知高程点比对找湘潭市几个已知高程点如水文站、三角点用QGIS的“识别”工具读取DEM值和已知值比对。误差在±5米内算合格超过10米要查数据源。如果没有已知点用Google Earth读取几个地标高程做粗略验证但精度有限。import rasterio from pyproj import Transformer # 已知点经纬度 points [(112.944, 27.829), (112.985, 27.756)] # 示例坐标 transformer Transformer.from_crs(EPSG:4326, EPSG:4547, always_xyTrue) with rasterio.open(xiangtan_dem_clipped.tif) as src: for lon, lat in points: x, y transformer.transform(lon, lat) row, col src.index(x, y) elev src.read(1)[row, col] print(f点({lon}, {lat}) 高程: {elev:.1f} 米)src.index把投影坐标转成行列号注意边界外的点会返回越界索引需要加判断。6.4 一个我常用的检查习惯每次拿到新DEM先做三件事看坐标系、看高程范围、看边缘有没有空值条带。这三步花不了五分钟但能避免后面几小时的返工。湘潭市这个包我一般会先用QGIS快速加载确认边界和DEM套合无误再用Python做批量统计。如果边界shp有多个面要素先dissolve合并别让内部行政界线干扰裁剪。做汇水分析前填洼步骤不能省湘潭市丘陵区有不少洼地不填洼流向会断。希望帮到你。本文还有配套的精品资源点击获取