资讯动态

DEM与SHP数据实战:从解压裁剪到3D Tiles全流程解析

发布时间:2026/9/12 22:19:53 来源:尧图企业网站定制
简介澄迈县30米分辨率DEM数字高程模型数据包覆盖海南省澄迈县并附带市级范围Shapefile边界适合GIS初学者、城乡规划、地质与环境专业学生进行地形分析、坡度坡向计算、水文模拟等练习。数据包共12个文件核心为TIFF高程栅格含ovr与aux辅助文件可直接读取海拔信息澄迈县范围shp及其dbf、prj、shp.xml配套文件则提供边界属性、坐标投影与元数据另有tfw地理配准文件和sbn/sbx空间索引整体约4.89MB压缩包结构简洁可导入ArcGIS、QGIS等主流GIS平台。目前已有264人学习下载作为理解DEM数据结构的学习范例也可用于生成等高线、制作三维地形、提取流域特征等基础研究。需注意该数据集标注为学习练习用途若用于商业项目应事先确认授权许可。1. 拿到的是数据包不是现成答案海南省澄迈县 DEM 数字高程数据 30m含市级范围 shp 文件.zip光看名字容易误判成“下载完解压就能用”。实际打开后你会发现里面往往是两部分一是覆盖澄迈县及周边范围的 30 米分辨率 DEM 栅格二是用来限定工作区的市级行政区划 SHP 文件zip 只是外层打包。这个组合的常见用途是用 SHP 做掩膜去裁剪 DEM、把高程转成坡度坡向、或者统一坐标系后做地形分析。对 GIS 从业者来说坑不在下载而在解压后的投影不一致、边界有缝隙、栅格出现 NoData 黑边。本文按“先搞清数据形态、再从命令行和可视化两个路径处理、最后做质检”的顺序直接把可复现的命令和参数写出来。2. 从 zip 到可用数据文件结构、坐标参照和常见误判2.1 先别急着解压zip 内部结构决定了后续操作路径拿到这个 zip我一般会先看一眼压缩包内部布局而不是双击直接全部解压。原因是这类数据包经常出现“嵌套文件夹”或“重复文件名”问题如果里面同时存在dem.tif和dem.tfw解压顺序错了会导致栅格配准信息丢失。常见做法是用命令行工具列出 zip 内容比图形界面更可控。在 Windows 上可以用 PowerShell 的Expand-Archive但它不支持只查看内容所以我通常用tar或unzip来预览结构。Windows 10 1803 之后的系统自带了tar.exe可以直接用tar -tf 海南省澄迈县DEM数字高程数据30m含市级范围shp文件.zip-t表示列出内容-f指定文件名。这一步能让你看到 zip 内部是否有顶层文件夹以及 SHP 文件的三个伴生文件.shp、.shx、.dbf是否齐全。缺少.shx时 SHP 仍可能在多数软件中打开但缺少.dbf时属性表会变成空壳这点在后续按行政区裁切时非常关键。解压时建议保留目录结构避免把栅格和矢量混在同一个扁平目录里tar -xf 海南省澄迈县DEM数字高程数据30m含市级范围shp文件.zip -C ./chengmai_dem-C指定解压目标目录。注意如果 zip 内本身有一个顶层文件夹解压后会变成./chengmai_dem/xxx/...后续脚本里引用路径时要多注意一层。2.2 这是不是“真正的 30 米 DEM”先看像素分辨率再谈精度很多用户拿到“30m DEM”就直接用但这里的 30m 通常有两种含义一是分辨率约等于 30 米二是数据源来自 ASTER GDEM 或 ALOS AW3D30 这类全球产品。ASTER GDEM 的标称分辨率是 30 米1 弧秒但实际地面分辨率并非严格 30 米尤其在地形起伏大的区域会出现条带噪声。ALOS 12.5 米 DEM 数据本身比 30 米更细但如果被重采样到 30 米精度不一定优于原生 30 米产品。打开 DEM 后第一步不是看颜色而是用gdalinfo确认以下四个值Size像元数量不能直接反映地面分辨率Origin左上角坐标Pixel Size像元尺寸单位通常为度或米EPSG坐标系代码在命令行里执行gdalinfo chengmai_dem/dem.tif如果输出里Pixel Size显示为(0.00027777778, -0.00027777778)这表示约 1 弧秒接近 30 米但单位是度。如果你的 SHP 是投影坐标系比如 EPSG:32649WGS 84 / UTM zone 49N而 DEM 是地理坐标系EPSG:4326必须做统一处理。一个容易踩的坑用 ArcMap 直接加载时软件会自动做动态投影看起来两者重合得很好但一旦做Extract by Mask或Zonal Statistics就会因为空间参考不完全一致而报错或产生偏移。我一般会在处理前先写个小函数检查一致性from osgeo import gdal, ogr dem gdal.Open(chengmai_dem/dem.tif) shp ogr.Open(chengmai_data/city_boundary.shp) dem_srs dem.GetProjection() lyr shp.GetLayer() shp_srs lyr.GetSpatialRef().ExportToWkt() print(DEM SRS matches SHP SRS:, dem_srs shp_srs)这段代码如果输出False不要试着强行叠加而是先把 SHP 投影到 DEM 的坐标系或者反过来重采样 DEM 到 SHP 的坐标系。决策依据是如果你后续要提取等高线或计算坡度建议以 DEM 的坐标系为准因为重采样栅格会改变高程值而矢量投影不会改变几何精度。2.3 一个 zip 里两种格式是顺手打包还是有意组织压缩包名里特意写“含市级范围 shp 文件”说明数据提供方的意图是让用户借 SHP 来限定分析范围。这里有个细节打包者可能用的是海南省级或海口市级的行政边界但文件名写澄迈县内部 SHP 的范围却覆盖了周边市县。这不算错误但你必须先看 SHP 的要素范围再决定是原样使用还是重新裁剪你真正需要的区域。查看 SHP 范围的最快方式是用 OGR 信息ogrinfo -so -al chengmai_data/city_boundary.shp-so表示只输出摘要-al表示列出所有图层。输出中的Extent字段就是要素的实际边界如果这个范围远大于澄迈县你要么是用它做掩膜去裁剪 DEM 到局部区域要么是把 SHP 里不需要的行政区要素删掉导出新文件。考虑到澄迈县本身的面积并不大30 米分辨率下完全可以直接保留全幅 DEM再用 SHP 做掩膜提取避免反复裁剪造成边缘锯齿。3. 用 SHP 裁剪 DEM从 QGIS 界面到 GDAL 命令行3.1 SHP 不是拿来“画范围”的它是裁切模板在处理 DEM 和 SHP 的组合时最常见的需求是用行政区边界把 DEM 裁成研究区。有人在 ArcMap 里用Extract by Mask工具做这件事但参数选项较少也有人直接在 QGIS 里用Clip Raster by Mask Layer这两个工具底层逻辑一致SHP 的几何被转换成栅格掩膜然后参与裁剪。我需要提醒的是掩膜分辨率默认与 DEM 一致但如果 SHP 边界很小且 DEM 像元很大掩膜边缘会出现台阶状锯齿。解决办法是先对 SHP 做一点点缓冲通常半个像元即 15 米再做裁剪。在 QGIS 中的操作路径是栅格→提取→按掩膜层裁剪栅格。参数设置如下输入图层dem.tif掩膜图层city_boundary.shp裁剪模式掩膜层区别于扩展和像素输出裁剪栅格chengmai_dem_clip.tif勾选为输出栅格创建 VRT可选调试时用裁剪完成后打开属性查看 NoData 值QGIS 默认通常保留 DEM 原有的 NoData。如果裁剪后图像边缘出现黑色块多半是 NoData 没有正确继承需要在后续处理里手动指定。3.2 更可控的 GDAL 命令行裁剪一次跑完参数全握在手里QGIS 适合交互式操作但在批量处理或需要复现的场景中我倾向用gdalwarp。它裁剪栅格的同时可以做重投影、重采样和 NoData 设置一个命令干完 ArcGIS 里两三个工具的活。对一个 30 米分辨率的县域 DEM 来说以下命令足够用gdalwarp -cutline chengmai_data/city_boundary.shp -crop_to_cutline -dstnodata -9999 -of GTiff chengmai_dem/dem.tif chengmai_dem_clip.tif参数拆开看-cutline指定矢量裁剪边界支持 SHP、GeoJSON 等格式-crop_to_cutline让输出范围恰好等于裁剪区的边界框不加这个参数输出范围仍是原 DEM 的范围只是多出来的部分变成 NoData-dstnodata -9999设置输出栅格的 NoData 值避免默认的 0 被误认为真实高程-of GTiff输出格式为 GeoTIFF保证地理信息不丢失如果 SHP 和 DEM 坐标系不一致gdalwarp会自动做重投影但我在实际项目里不推荐依赖这种隐式行为。先手动统一坐标系是一种美德因为你无法控制源数据里的参数是否精确。统一坐标系时可以这样做ogr2ogr -t_srs EPSG:32649 chengmai_data/city_boundary_utm49.shp chengmai_data/city_boundary.shp gdalwarp -t_srs EPSG:32649 -cutline chengmai_data/city_boundary_utm49.shp -crop_to_cutline -dstnodata -9999 -of GTiff chengmai_dem/dem.tif chengmai_dem_clip_utm49.tifogr2ogr用-t_srs转换坐标参考输出新 SHP。gdalwarp中的-t_srs会把 DEM 重采样到目标坐标系此时输出像素尺寸单位变成米可以直接量算坡度坡向。3.3 裁完检查像素尺寸和边界对齐不做这一步等于白裁裁剪成功的栅格并不代表能用。我在处理海南区域数据时发现一个常见问题裁剪后的 DEM 边缘会有一圈高程值异常偏低的像元这通常是 SHP 边界穿过了低质量的 SRTM 空洞裁切后把空洞区的 0 值或 32767 值当作真实高程带进来了。因此裁剪后的下一步是检查最小值最大值gdalinfo -stats chengmai_dem_clip_utm49.tif查看Minimum和Maximum值如果最小值是 -9999 或 0而你确定研究区最高点比这高得多说明 NoData 与有效高程值混合了。解决办法是重新执行裁剪并显式声明-srcnodata和-dstnodatagdalwarp -srcnodata -9999 -dstnodata -9999 -cutline chengmai_data/city_boundary_utm49.shp -crop_to_cutline -of GTiff chengmai_dem/dem.tif chengmai_dem_clip_clean.tif-srcnodata告诉 GDAL 输入里哪些值是无数据-dstnodata则定义输出里的无数据值。两者分开设置比混用好理解输入来自原始 DEM输出是重采样后的结果重采样过程会因为插值产生新的像元值组合不显式指定就会出现边缘渐晕效应。4. SHP 转 TXT、批量压缩和 zip 加密数据交付的 3 个高频后续动作4.1 从 DEM 或 SHP 里提取坐标到 TXT写脚本比手动导出靠谱很多人搜“shp转txt”实际要的是把 SHP 里的点要素坐标导出成文本或者把 DEM 采样成 XYZ 格式。前者在导入测量仪器或做简单可视化时常用后者则多见于建模软件输入。把 SHP 的点坐标导出成 TXT 有现成工具但直接用 GDAL 脚本更灵活from osgeo import ogr ds ogr.Open(chengmai_data/points.shp) lyr ds.GetLayer() with open(points_xy.txt, w) as f: for feat in lyr: geom feat.GetGeometryRef() if geom is not None: x, y, _ geom.GetPoint() if geom.GetGeometryName() POINT else (0, 0, 0) f.write(f{x},{y}\n)如果你的 SHP 是面状或线状GetPoint()会返回错误这时需要用geom.GetGeometryRef(0).GetPoint()绕一层。这个逻辑很容易被忽略因为实际传给你的 SHP 里可能既有面又有线先打印geom.GetGeometryName()是安全的做法。另一个更直接的工具是ogr2ogr但很多人不知道它能写出 CSV/TXT 格式ogr2ogr -f CSV points_xy.csv chengmai_data/points.shp -lco GEOMETRYAS_XYZ-lco GEOMETRYAS_XYZ会把几何坐标转成 X、Y、Z 三列输出-lco是 layer creation option 的缩写。若所有要素都是二维点则 Z 列恒为 0。CSV 用文本编辑器打开另存为 TXT 就是纯文本格式不需要额外转码。4.2 单个 SHP 如何批量压缩写循环比逐个右键压缩省一半时间项目里如果有很多县域 SHP逐个右键压缩费时且容易漏。用 zip 命令配合 shell 循环可以批量打包还可以把每个 SHP 连同投影文件.prj和索引文件.shx一起打包方便交付for shp in *.shp; do base${shp%.shp} zip ${base}.zip ${base}.shp ${base}.shx ${base}.dbf ${base}.prj done${shp%.shp}是 shell 参数扩展去掉扩展名后作为压缩包名。.dbf里存的是属性表.prj里存的是投影信息很多人只压缩.shp文件导致对方打不开属性。若原始数据没有.prj后续在 GIS 软件里会被强制指定坐标系这是数据交接时最常见的纠纷之一。如果要对整个目录统一压缩且排除临时文件可以用zip -r dem_shp_package.zip chengmai_data/ -x *.tmp -x *~-r递归压缩子目录-x指定排除规则。这个命令适合交付前打包但注意 zip 格式对中文文件名支持一般文件名内部如果用中文解压到部分 Linux 环境可能乱码。这种情况下我建议先重命名成拼音或英文再压缩。4.3 zip 加密是交付保护不是安全手段相关热搜词里出现过“zip压缩包密码破解工具”和“zip密码移除”这里必须把话讲清楚zip 的加密本质是防君子不防小人标准 ZipCrypto 加密很容易被已知明文攻击破解AES-256 加密要安全得多。如果你要给客户或同事发一个带敏感边界数据的 zip用 7-Zip 或 WinRAR 的 AES 加密比传统 zip 密码靠谱7z a -tzip -pyour_password -memAES256 chengmai_dem_encrypted.zip chengmai_dem/-memAES256指定加密算法-p设置密码。注意普通zip命令行不支持 AESWindows 自带的Compress-Archive也不支持。用7z才能输出 AES 加密的 zip。如果收到的是加密 zip 并且密码丢失合法路径只有两条一是问对方要密码二是用字典攻击碰运气效率取决于密码强度。网上流传的所谓“zip密码移除”对 AES 加密几乎无效别指望。4.4 遇到 “failed to copy spatial iop zip” 或 “invalid zip archive” 怎么办这两个报错在 GIS 圈子里很常见。failed to copy spatial iop zip通常出现在 GDAL 安装不完整或环境变量冲突时它和你的 DEM zip 无关而是 GDAL 在初始化时找不到内部数据包。解决办法是重新安装对应版本的 GDAL或者在 Windows 上使用 OSGeo4W 环境并确保GDAL_DATA指向正确的gdal-data目录。invalid zip archive: could not find eocd则说明 zip 文件损坏或下载不完整。EOCD 是 End of Central Directory 记录位于 zip 文件末尾如果下载工具断了导致文件被截断就会出现这个错。这时候不要再试解压直接重新下载或改用支持断点续传的下载工具。如果你需要从命令行验证 zip 完整性zip -T chengmai_dem.zip-T会逐个测试压缩包内的文件 CRC 校验值输出OK才代表完整。这个命令对判断“文件能打开但解压报错”非常有效值得在数据处理流水线里加一步。5. DEM 和 SHP 坐标系不一致时到底该信谁一个校准流程跑通5.1 优先以 DEM 原始坐标系为基准还是以 SHP 投影为基准讨论坐标系一致性时必须先明确 DEM 的用途。如果目标是做坡度坡向或水文分析栅格像元的几何属性必须真实反映地面距离这种情况下建议把数据投影到 UTM 或高斯-克吕格投影得到单位为米的像元尺寸。如果只是做简单的可视化展示地理坐标系也未尝不可。但澄迈县位于低纬度地区经度 1 度对应的距离在 110 公里上下纬度方向约 111 公里如果直接用经纬度单位计算坡度得出的数值是错的。所以我的做法是第一步用ogrinfo查看 SHP 的坐标系第二步用gdalinfo查看 DEM 的坐标系第三步看两者 EPSG 是否一致。不一致时优先将 DEM 重投影到 CGCS2000 / 3-degree Gauss-Kruger zone 23海南常用投影大多数收集来的 SHP 也在这个坐标系里。命令如下gdalwarp -t_srs EPSG:4548 -r bilinear -of GTiff dem.tif dem_cgcs2000_3deg_23.tifEPSG:4548 是 CGCS2000 / 3-degree Gauss-Kruger zone 23对应海南区域。-r bilinear是重采样方法高程数据用双线性插值即可不要用最邻近法会丢失细节。如果 DEM 里有少量空洞可以考虑先填洞再用cubic重采样但这是后话。5.2 校准后的三层质检边界、直方图和剖面线重投影完成后用gdalinfo -stats再看一遍 Min/Max 和均值确认高程范围符合澄迈县实际地形。澄迈县北临琼州海峡南部有丘陵山地海拔从接近海平面到数百米。如果最小值是负几十甚至负几百且位置不在海岸线附近就要怀疑 NoData 混入或像元值有系统偏差。第二层质检是把 DEM 加载到 QGIS叠加 SHP 边界检查边界线是否与地形起伏吻合。如果 SHP 边界穿过山谷但 DEM 边缘出现明显的矩形裁切痕迹说明-crop_to_cutline没生效或输出范围不对。第三层更定量随机抽取 5 到 10 个已知高程点比如道路交叉点、山顶用gdallocationinfo查询 DEM 上的高程值再与参考值比较echo 110.2046 19.7501 | gdallocationinfo -valonly dem_cgcs2000_3deg_23.tif-valonly只输出像元值输入坐标格式为 “经度 纬度”如果 DEM 已是投影坐标系这里就要输入对应投影下的坐标。误差在 ±10 米内正常30 米 DEM 的垂直精度本来就谈不上厘米级。5.3 高程转等高线野外踏勘前生成辅助文件有了裁剪好的 DEM生成等高线在野外验证时很实用。GDAL 有个配套工具gdal_contour30 米分辨率 DEM 生成 10 米间隔的等高线会有大量锯齿20 米或 25 米间隔更合理gdal_contour -a elev -i 25.0 dem_cgcs2000_3deg_23.tif contour_25m.shp-a elev给等高线属性字段取名为elev-i 25.0设定等高距。生成后的 SHP 可以直接与原始 SHP 叠加检查高程分布合理性。若等高线在某个区域密集到完全粘连说明该区域坡度很大DEM 在此处的噪声会被放大后续做坡度分级时需要考虑平滑处理。6. 把 DEM 转成 3D Tiles轻量预览和共享的实用技巧处理完 DEM 裁剪、坐标统一和数据交付后另一个高频需求是把 DEM 转成 Cesium 能直接加载的 3D Tiles也就是相关热搜词里的“shp转3dtiles”和“dem转3dtiles”。用 Cesium 预览 DEM 比在桌面 GIS 里分享更轻对方不需要安装任何软件浏览器打开就能看地形和边界。从 DEM 生成 3D Tiles 的常用工具是 Cesium ion 的在线上传但它要注册所以更可控的做法是用开源工具py3dtilespy3dtiles convert dem_cgcs2000_3deg_23.tif -o tiles_outputpy3dtiles convert会读取 DEM 栅格按地形起伏生成瓦片金字塔输出目录里包含tileset.json和分块文件。这里有一个重要参数原始 DEM 如果像元尺寸是 30 米直接转换会生成大量瓦片建议先重采样到 60 米或 90 米再转换预览效果差别不大但文件体积和加载速度差距明显。重采样命令gdalwarp -tr 60 60 -r bilinear dem_cgcs2000_3deg_23.tif dem_60m.tif-tr 60 60是指定输出像元大小为 60 米。如果原始 DEM 已经是投影坐标系-tr的单位是米如果还是经纬度-tr单位是度需要自己换算。这一步顺带解决了网络加载性能问题。如果你需要把 SHP 边界也叠加到 3D Tiles 场景里可以用shp转 GeoJSON 再转 3D Tiles或者直接在 Cesium 里加载 GeoJSON 图层不需要做 3D Tiles。常见错误是用shp2tiles之类的工具把矢量压成 3D Tiles 时忽略了属性字段结果场景里能看到边界但无法高亮或查询属性分享价值大打折扣。最后给一个验证 3D Tiles 是否成功的命令用 Python 的json模块检查 tileset 结构python -c import json; djson.load(open(tiles_output/tileset.json)); print(d[root][boundingVolume].keys()); print(len(d[root][children]))如果输出里boundingVolume包含box或region且 children 数量大于 0说明瓦片生成基本正确。若报 KeyError说明 tileset JSON 结构异常通常是因为输入 DEM 范围太小导致瓦片金字塔层数不够回到gdalinfo检查Size如果宽高像素数少于 256要么扩大范围要么降低-tr值。本文还有配套的精品资源点击获取

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

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

免费获取报价