背景:

内网环境下使用mapboxgl开发需要加载本地部署的离线地形切片

mapbox支持的地形瓦片规范

  1. Mapbox 地形 RGB 瓦片。更多信息参见 https://www.mapbox.com/help/access-elevation-data/#mapbox-terrain-rgb。

  2. Terrarium 格式的 PNG 瓦片。更多信息参见 https://aws.amazon.com/es/public-datasets/terrain/。

实践步骤:

1.DEM下载

使用QGIS插件STRM-Downloader可以下载全球任意经纬度范围的DEM切片

注意:使用该插件需要科学上网,如果没有科学上网没有下载成功也不会报错,这个比较坑,我科学上网以后就能正常下载了

image-20250731105638143

下载完成后,在qgis中打开vrt索引文件,长这样

image-20250731110502625

2.地形切片

有了DEM数据后,就可以开始地形切片了,这里使用了国内大佬开发的开源地形切片工具:https://github.com/FreeGIS/dem2terrain

根据readme文档一步步操作:

1.工具下载

先使用npm全局安装dem2terrain工具

1
npm i dem2terrain -g

2.数据预处理

将上面在QGIS中下载的DEM数据,右键另存为,选择格式为geotiff保存为.tif后缀的文件

3.切片

使用下面的命令开始执行1到15级地形切片任务

1
dem2terrain -i your/data_dir.tif -o your/output_dir -z 1-15

切片完成后的界面显示

7336422f930edd868582b4757f4dbbc

⚠️可能遇到的问题

运行dem2terrain命令时遇到报错:

1
2
3
4
5
Error: PROJ: proj_create_from_database: D:\Program Files\PostgreSQL\17\share\contrib\postgis-3.5\proj\proj.db contains DATABASE.LAYOUT.VERSION.MINOR = 2 whereas a number >= 4 is expected. It comes from another PROJ installation.
at reprojectImage (D:\ProgramFiles\nvm\v20.18.0\node_modules\dem2terrain\src\gdal-util.js:80:39)
at project (D:\ProgramFiles\nvm\v20.18.0\node_modules\dem2terrain\src\index.js:110:3)
at main (D:\ProgramFiles\nvm\v20.18.0\node_modules\dem2terrain\src\index.js:203:19)
at Object.<anonymous> (D:\ProgramFiles\nvm\v20.18.0\node_modules\dem2terrain\bin\dem2terrain.js:84:1)

结合工具的readme文档定位到是环境变量冲突问题,于是按照建议在系统变量中删除了PROJ_LIB变量,重启cmd后得以解决

3.在mapboxgl中加载离线地形

将地形瓦片目录使用nginx代理后,即可使用mapboxgl加载:

1
2
3
4
5
6
7
8
9
10
//加载地形
map.addSource('terrain_rgb_source', {
type: 'raster-dem',
maxzoom: 9,
tileSize: 256,
tiles: [
'http://localhost:80/mapbox_terrain/{z}/{x}/{y}.png'
]
})
map.setTerrain({ source: 'terrain_rgb_source', exaggeration: 1 })

效果展示:

image-20250731170517328

优化建议:

地形放大会呈现出马赛克,推测为目前14级地形切片分辨率较低,不知道切到16级会不会好一些,或者有其他可以控制地形插值平滑的配置来解决?有大佬知道的也可以在评论区留言解惑一下,感激!

image-20250731170650181

参考文章:

Mapbox Terrain-DEM地形切片原理浅析 - Douglas_0