概述
MapboxGL在2的版本之后通过地形服务开始支持三维的展示了,之前也有文章“mapboxGL2中Terrain的离线化应用”对该服务进行过说明与分析。前些天在翻公众号的时候翻到了dem2terrain
可以生成地形服务,同时做了一些优化,今天就给大家分享一下如何使用dem2terrain
生成MapboxGL地形服务。
效果
简介
- 仓库地址:https://github.com/FreeGIS/dem2terrain.git
根据 DEM 数据生成地形切片工具,使用 NodeJS + GDAL
(NodeBinding)开发制作。可用于用户自定义 DEM 高程数据源生产地形瓦片,以便局域网离线使用。
特点:
- 支持
mapbox
和terrarium
两种地形瓦片编码格式供mapboxgl使用,其中terrarium格式是tangram引擎的官方地形格式,tangram是另外一款开源的webgl二三维一体化的引擎; - 固定瓦片尺寸256,瓦片周围有1cell的buffer,即实际瓦片是258*258.
- 自动读取数据源的坐标系统,重编码输入的 DEM 栅格文件,并重投影至指定的坐标系4490、4326、3857,默认3857,然后生成瓦片;
- 支持适用于3857、4490、4326的地形切片生产;
- 内置了影像金字塔索引和多进程实现(暂未使用多线程),加速瓦片生成速度;
- 支持地形瓦片以文件目录或mbtiles两种格式存储;
- 命令行提供了瓦片生成的进图条提示,便于用户查看生成进度。
- 内置一些异常导致的临时文件清理工作。
使用
可以通过两种方式使用dem2terrain
:一种是下载源代码,直接使用源代码;一种是全局安装dem2terrain
使用。
源码使用
通过源码的方式使用需要先下载源码,再将当前目录定位至工程根目录,然后运行如下命令:
npm install && npm link
依赖使用
运行npm i dem2terrain -g
全局添加依赖,便可使用dem2terrain
进行地形切片了。
切片
通过命令dem2terrain --help
查看使用帮助,如下图。
执行命令dem2terrain -f ./config.json
即可开始切片,config.json
文件的内容如下:
{
"zoom": "5-14",
"epsg": 3857,
"size": 256,
"resampling": 3,
"encoding": "mapbox",
"input": "D:\\test\\dingxi.tif",
"output": "D:\\test\\terrain",
"clean": true
}
前端调用
完成切片后,可以将切片部署到如Nginx等web服务器中,部署完即可在前端调用地形服务了。示例代码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Query terrain elevation</title>
<meta
name="viewport"
content="initial-scale=1,maximum-scale=1,user-scalable=no"
/>
<link href="./mapbox-gl.css" rel="stylesheet" />
<script src="./mapbox-gl.js"></script>
<style>
body {
margin: 0;
padding: 0;
}
#map {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
}
</style>
</head>
<body>
<div id="map"></div>
<script>
const mapStyle = {
version: 8,
name: "Dark",
sources: {
"xyz-img": {
type: "raster",
tiles: [
"https://webst01.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}",
"https://webst02.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}",
"https://webst03.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}",
"https://webst04.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}",
],
tileSize: 256,
},
},
layers: [
{
id: "img",
type: "raster",
source: "xyz-img",
minzoom: 1,
maxzoom: 18,
},
],
};
const map = new mapboxgl.Map({
container: "map",
zoom: 12,
center: [104.61023753726323, 35.63101027697721],
pitch: 75,
bearing: 90,
style: mapStyle,
hash: true,
});
map.on("load", (e) => {
// Set custom fog
map.setFog({
range: [-0.5, 2],
color: "#def",
"high-color": "#def",
"space-color": "#def",
});
// Add terrain source, with slight exaggeration
map.addSource("mapbox-dem", {
type: "raster-dem",
tiles: ["./terrain/{z}/{x}/{y}.png"], // 此处是地形服务地址
tileSize: 256,
maxzoom: 14,
});
map.setTerrain({ source: "mapbox-dem", exaggeration: 2 });
});
</script>
</body>
</html>
注意:
- 在使用前需要配置配置
GDAL_DATA
环境变量,如果有安装过POSTGIS
的话已经配置过该环境变量了; - 在使用的过程中如提示错误
Error: PROJ: proj_create_from_database: D:\Program Files\PostgreSQL\12\share\contrib\postgis-3.1\proj\proj.db lacks DATABASE.LAYOUT.VERSION.MAJOR / DATABASE.LAYOUT.VERSION.MINOR metadata. It comes from another PROJ installation.
,这是由于内置的proj和proj.db冲突,最直接的方式就是将对应目录如D:\Program Files\PostgreSQL\12\share\contrib\postgis-3.1\proj\proj.db
文件直接替换。