Code Monkey home page Code Monkey logo

dem2terrain's Introduction

简介

根据 DEM 数据生成地形切片工具,使用 NodeJS + GDAL(NodeBinding)开发制作。可用于用户自定义 DEM 高程数据源生产地形瓦片,以便局域网离线使用。

特点:

  • 支持 mapboxterrarium 两种地形瓦片编码格式供mapboxgl使用,其中terrarium格式是tangram引擎的官方地形格式,tangram是另外一款开源的webgl二三维一体化的引擎;
  • 固定瓦片尺寸256,瓦片周围有1cell的buffer,即实际瓦片是258*258.
  • 自动读取数据源的坐标系统,重编码输入的 DEM 栅格文件,并重投影至指定的坐标系4490、4326、3857,默认3857,然后生成瓦片;
  • 支持适用于3857、4490、4326的地形切片生产;
  • 内置了影像金字塔索引和多进程实现(暂未使用多线程),加速瓦片生成速度;
  • 支持地形瓦片以文件目录或mbtiles两种格式存储;
  • 命令行提供了瓦片生成的进图条提示,便于用户查看生成进度。
  • 内置一些异常导致的临时文件清理工作。

生成进度条

1. 安装与配置

1.1. 配置 GDAL_DATA

由于使用了 GDAL,用户需要 下载 gdal-data.zip 数据包,并配置 GDAL_DATA 环境变量为解压缩的目录。

以 Windows 操作系统为例(此例直接使用 PostgreSQL 附带的资源,若用户有安装 PostgreSQL,也可以直接使用对应目录):

配置环境变量

1.2. 安装

从网络全局安装,成为命令行工具:

npm i dem2terrain -g
yarn add dem2terrain -g
pnpm add dem2terrain -g

源码安装(先将当前目录定位至工程根目录,且明白什么是 link 命令):

npm install && npm link
#
yarn && yarn link
#
pnpm install && pnpm link --global

安装完毕后就可以当普通命令行程序使用了。

1.3. 测试

测试地形数据生产:

npm run test

基于maplibregl地形预览:

npm run server

浏览器输入地址进行预览:http://[ip]:[port]/terrain.html

效果图如下:

地形测试可视化

2. 用法与说明

当前支持作为命令行使用:

> dem2terrain --help
Usage: dem2terrain [options]

使用 GDAL 制作地形瓦片,支持 mapbox 和 terrarium 两种编码输出格式,当前仅输出 PNG 容器格式。

Options:
  -v, --version               当前版本
  -i, --input <string>        <必填> 输入 tif 格式的 DEM 文件路径,支持相对路径
  -o, --output <string>       <必填> 输出目录,支持相对路径
  -f, --configFile <File>     <可选> 通过配置文件执行任务,输入绝对路径,可参考配置模板
  -g, --epsg <number>         <可选> Tile适用坐标系,3857 | 4490 | 4326 (default: 3857)
  -r, --resampling <number>,  <可选> 构建影像金字塔或重投影时设置重采样策略,默认3,1:AVERAGE|2:BILINEAR|3:CUBIC|4:CUBICSPLINE|5:LANCZOS|6:MODE|7:NEAREST
  -c, --clean <number>        <可选> 是否清空输出目录,0 | 1 (default: 0)
  -z, --zoom <number-number>  <可选> 指定瓦片的等级生成范围。例如,想生成 7 ~ 12 级的瓦片,则输入 -z 7-12 (default: "5-14")
  -e, --encoding <string>     <可选> 指定瓦片的数据编码规则(mapbox 或 terrarium) (default: "mapbox")
  -h, --help                  帮助

可选参数说明:

  • -i: 输入 tif 格式的 DEM 文件路径,支持相对路径;
  • -o: 输出目录,支持相对路径;
  • -g: 指定地形Tile适用坐标系,默认是适用3857坐标系;
  • -r: 构建影像金字塔或重投影时设置重采样策略,默认3 CUBIC 采样;
  • -z: 由于地形栅格数据通常是 90m、30m 的空间分辨率,等级太大意义不大,等级太低时起伏辨识也不高,所以默认生成中间的 5-14 级;
  • -c: 指定是否预先清理输出瓦片的存储目录,默认0,不清理;
  • -e: 指定切片编码规则,默认 mapbox,用户可指定 terrarium 规则输出。
  • -f: 以上参数可以都放到一个配置json文件里,使用-f执行切片任务,简化操作;

2.1 任务执行

有两种形式执行命令行任务

  • 方式1:通过命令行参数执行任务
dem2terrain -z 4-15 -e terrarium -i ./ZONE.tiff -o ./output -c 1 -g 3857
  • 方式2:通过配置文件执行任务

1)配置参数

{
    "zoom":"5-13",
    "epsg": 3857,
    "encoding": "mapbox",
    "input": "./data/xxx.tif",
    "output": "./data/tile",
    "clean": true
}

2)执行任务

dem2terrain -f d://config.json

2.2 数据输出

支持地形切片生成以文件或mbtiles目录两种形式存储。

  • 以文件存储

-o参数为文件目录,则以文件形式存储:

dem2terrain -z 4-15 -e terrarium -i ./ZONE.tiff -o ./output -c 1 -g 3857
  • 以mbtiles存储

-o参数带.mbtiles扩展名,则以mbtiles形式存储:

dem2terrain -z 4-15 -e terrarium -i ./ZONE.tiff -o ./output/tile.mbtiles -c 1 -g 3857

3. 使用输出成果

使用 HTTP(S) 协议的 Web 服务器(例如 nginxIIS)将生成的地形瓦片作为静态资源发布,即可使用。

举例:根据 MapboxGL 地形示例 简单修改,将在线数据源换成本地 Web 服务器发布的地址即可,注意编码格式要与生成时输入的编码格式一致。

// 数据编码,'mapbox'或'terrarium'
const encoding = 'mapbox';
const maxZoom = 14;
map.addSource('my-custom-terrain', {
  type: 'raster-dem',
  encoding:encoding,
  // 使用tiles方式替换本地发布的地形切片服务
  tiles: ['./mapbox/{z}/{x}/{y}.png'],
  // 注释掉官方的服务url,替换自己的
	//'url': 'mapbox://mapbox.mapbox-terrain-dem-v1',
  tileSize: 256,
  maxzoom: maxZoom,
})

如下图所示:

本地离线切片可视化

4. TODO

当前版本足够 MapboxGL.js 使用,但仍然有新功能未开发,留待以后扩展功能,初步拟定待扩展功能如下:

  • 大数据量的dem tif改用分块读取分块处理
  • 扩展 gdal 驱动,使其支持 webp,直接生成 webp 格式的切片
  • 重构核心模块,解耦,扩展使其支持生成 CesiumJS 支持的地形切片格式

欢迎参与贡献,包括但不限于文档、功能扩展、性能优化!

5. 安装问题

5.1 c++编译环境问题

由于node-gdal、node-gdal-next或node-gdal-async都会内置编译安装一个gdal,编译是需要依赖c++环境的,在win上常出现问题如下:

npm ERR! gyp ERR! stack Error: Could not find any Visual Studio installation to use

如果用户未安装vs c++环境,请最好安装下vs c++编译环境。 如果用户已经安装了vs,例如vs2022仍提示找不到,配置如下:

# 配置npm的msvs版本号,例如安装了vs 2022
npm config set msvs_version 2022
# 更新下node-gyp
npm install node-gyp@latest -g

5.2 环境变量冲突

在node-gdal系列相关包npm安装成功后,使用过程中遇到投影操作定义就会报各种错误,典型错误如下:

const srs= gdal.SpatialReference.fromProj4('+init=epsg:4326'); ^ Error: Corrupt Data

主要原因是win上各种软件包都会内置安装,环境变量冲突导致。

例如,用户安装了PostGIS,会内置安装proj,geos,gdal并自动生成proj_lib的环境变量。

PROJ_LIB=C:\Program Files\PostgreSQL\14\share\contrib\postgis-3.1\proj

当安装node-gdal-next或noe-gdal-async时,内置的proj和proj.db由于冲突不能生效,就会在使用过程中报各种错误。 依此类推,如果用户安装了独立的GDAL,又有内置的proj,geos和环境变量也会有这种问题。 解决办法:从系统环境变量中删除这些冲突的环境变量重启机器即可。

5.3 最好的办法

使用本机已编译好的gdal编译binding下node的gdal环境:

npm install gdal-next --build-from-source --shared_gdal

npm install gdal-async --build-from-source --shared_gdal

这样,node的gdal环境可以和本机的gdal环境一致,能使用更多的驱动例如webp,内置驱动是没有的。 这种操作可以让公用软件装一次,不会产生更多的冲突,linux上很方便。但由于windows上都不是源码编译,从.exe安装,因此不太适用。该操作适合c++编译环境熟悉的高级用户可定制安装多项扩展。

6. 知识补充

6.1. 参考资料

6.2. 编解码差异

mapboxterrarium 都将高程值编码成 RGB 数组存储,下面以简单的编解码函数说明两种编码格式的差异。

MapboxGL:

function mapboxEncode(height: number) {
  const value = Math.floor((height + 10000) * 10);
  const r = value >> 16;
  const g = value >> 8 & 0x0000FF;
  const b = value & 0x0000FF;
  return [r, g, b];
}

function mapboxDecode(
  color: [number, number, number]
) {
  return -10000 + ((color[0] * 256 * 256 + color[1] * 256 + color[2]) * 0.1);
}

terrarium:

function terrariumEncode(height: number) {
  height += 32768;
  const r = Math.floor(height / 256.0);
  const g = Math.floor(height % 256);
  const b = Math.floor((height - Math.floor(height)) * 256.0);
  return [r, g, b];
}

function terrariumDecode(
  color: [number, number, number]
) {
  return (color[0] * 256 + color[1] + color[2] / 256.0) - 32768;
}

对于 cesium 的地形编码和解码:

// 每个点像素值是 int16
function cesiumEncode(height: number) {
  return Math.floor((height + 1000) / 0.2);
}

function cesiumDecode(pixel: number){
  return (pixel * 0.2) - 1000;
}

dem2terrain's People

Contributors

deyihu avatar freegis avatar onsummer avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

dem2terrain's Issues

类似dem越界导致的异常现象

您好,我在使用90m的dem切地形,生成的是5-13级的地形 ,原数据dem最大值为4000左右最小值为-8000左右,在生成的瓦片中出现了这样的现象。靠近一些的高层级瓦片正常,缩小后的底层级瓦片有类似尖刺的情况,我怀疑是不是存储的数据类型越界了导致的,请问地形是short类型的所有以高程限制吗

Uploading 地形异常.png…

dem 插值

image
拉近后,阶梯层叠状,这是由于dem精度低导致的吗,用的30m高程数据。 可以自动插值,使之平滑吗?

Array length must be greater than or equal to -281759359

大佬你好,出现这个问题难道是我没有C++环境造成的么?

D:\>cd dem2terrain

D:\dem2terrain>cnpm install && cnpm link
√ Installed 6 packages on D:\dem2terrain
√ Linked 136 latest versions fallback to D:\dem2terrain\node_modules\.store\node_modules
[1/3] scripts.postinstall [email protected] › es5-ext@^0.10.61 run " node -e \"try{require('./_postinstall')}catch(e){}\" || exit 0", root: "D:\\dem2terrain\\node_modules\\.store\\[email protected]\\node_modules\\es5-ext"
[1/3] scripts.postinstall [email protected] › es5-ext@^0.10.61 finished in 317ms
[2/3] scripts.install @mapbox/[email protected] › sqlite3@^5.0.0 run "node-pre-gyp install --fallback-to-build", root: "D:\\dem2terrain\\node_modules\\.store\\[email protected]\\node_modules\\sqlite3"
node-pre-gyp http GET https://cdn.npmmirror.com/binaries/sqlite3/v5.1.4/napi-v6-win32-unknown-x64.tar.gz
[sqlite3] Success: "D:\dem2terrain\node_modules\.store\[email protected]\node_modules\sqlite3\lib\binding\napi-v6-win32-unknown-x64\node_sqlite3.node" is installed via remote
[2/3] scripts.install @mapbox/[email protected] › sqlite3@^5.0.0 finished in 722ms
[3/3] scripts.install gdal-async@^3.5.1 run "node-pre-gyp install --fallback-to-build -j max && echo 'I am currently unemployed and looking for work. Please, consider hiring me if you like and use gdal-async. Check https://github.com/mmomtchev to what I do and what is my current situation.'", root: "D:\\dem2terrain\\node_modules\\.store\\[email protected]\\node_modules\\gdal-async"
node-pre-gyp http GET https://cdn.npmmirror.com/binaries/node-gdal-async/v3.6.2/node-v93-win32-x64.tar.gz
[gdal-async] Success: "D:\dem2terrain\node_modules\.store\[email protected]\node_modules\gdal-async\lib\binding\node-v93-win32-x64\gdal.node" is installed via remote
'I am currently unemployed and looking for work. Please, consider hiring me if you like and use gdal-async. Check https://github.com/mmomtchev to what I do and what is my current situation.'
[3/3] scripts.install gdal-async@^3.5.1 finished in 2s
√ Run 3 scripts
deprecate @mapbox/[email protected][email protected][email protected][email protected][email protected] › @npmcli/move-file@^1.0.1 This functionality has been moved to @npmcli/fs
Recently updated (since 2023-01-29): 3 packages (detail see file D:\dem2terrain\node_modules\.recently_updates.txt)
  Today:
    → [email protected][email protected] › @types/node@*(18.11.19) (07:02:40)
√ All packages installed (147 packages installed from npm registry, used 21s(network 19s), speed 2.22MB/s, json 87(821.23KB), tarball 40.74MB, manifests cache hit 49, etag hit 49 / miss 4)


added 1 package in 905ms

D:\dem2terrain>dem2terrain -f d://dem2terrain/config.json

>> 开始转换...
- 输入文件: D:\dem2terrain\广东省.tif
- 输出路径: D:\dem2terrain\data\tile
- Tile适用坐标系: EPSG:3857
- 瓦片编码: mapbox(raster-dem)
- 瓦片尺寸: 256 px
- 瓦片等级: 5 至 13 级

>> 步骤1: 清空输出文件夹 - 完成
D:\dem2terrain\node_modules\.store\[email protected]\node_modules\gdal-async\lib\gdal.js:712
    return read.apply(this, mangleRead(arguments))
                ^

Error: Array length must be greater than or equal to -281759359
    at RasterBandPixels.read (D:\dem2terrain\node_modules\.store\[email protected]\node_modules\gdal-async\lib\gdal.js:712:17)
    at encodeDataset (D:\dem2terrain\src\index.js:111:24)
    at main (D:\dem2terrain\src\index.js:275:19)
    at Object.<anonymous> (D:\dem2terrain\bin\dem2terrain.js:70:1)
    at Module._compile (node:internal/modules/cjs/loader:1103:14)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1155:10)
    at Module.load (node:internal/modules/cjs/loader:981:32)
    at Function.Module._load (node:internal/modules/cjs/loader:822:12)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:77:12)
    at node:internal/main/run_main_module:17:47

config.json文件:

{
    "zoom":"5-13",
    "epsg": 3857,
    "size": 256,
    "encoding": "mapbox",
    "input": "./广东省.tif",
    "output": "./data/tile",
    "clean": true
}

npm ERR! path /dem2terrain/node_modules/gdal-async

npm install出现以下错误是什么原因:

npm WARN deprecated @npmcli/[email protected]: This functionality has been moved to @npmcli/fs
npm ERR! code 2
npm ERR! path /dem2terrain/node_modules/gdal-async
npm ERR! command failed
npm ERR! command sh -c -- node-pre-gyp install --fallback-to-build -j max && echo 'If you are using gdal-async, please do not forget that I am living below the poverty line because of the extortion.
npm ERR! sh: 1: Syntax error: Unterminated quoted string

环境:Ubuntu 20.04 | Node 16 | GDAL 3.5.2

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.