🚀 如何在内网中运行 Cesium?基于 NestJS 构建离线地形与影像服务

在构建内网三维 GIS 系统或工业级可视化平台时,很多开发者都会遇到 CesiumJS 依赖网络地图服务的问题,比如默认使用 Bing、Ion 提供的在线地形与影像服务。但在无网络、私有化部署或内网安全环境下,我们就必须提供离线的地图和地形服务。

本文将基于 NestJS + CesiumJS ,手把手实现一个离线地图瓦片服务 + 离线地形服务的完整方案。


🧰 技术选型

技术 用途
NestJS 后端服务框架,提供地图/地形文件
CesiumJS 前端三维可视化引擎
地图瓦片(TMS) 提供离线影像,如天地图、谷歌等
地形数据(QuantizedMesh) 提供离线地形数据支持
@nestjs/serve-static 提供静态文件服务

目录结构预览

bash 复制代码
cesium-offline-server/
├── src/
├── public/
│   ├── tiles/           # 离线影像瓦片(z/x/y.png)
│   └── terrain/         # 地形数据(layer.json + .terrain)
├── package.json
└── ...

一、准备地图和地形数据

1.1 离线地图瓦片(TMS)

你可以使用:

  • Global Mapper、QGIS 等工具裁剪下载地图
  • 参考天地图、谷歌影像瓦片命名规则(z/x/y.png)

最终结构:

arduino 复制代码
public/tiles/
├── 0/0/0.png
├── 1/0/0.png
├── 1/0/1.png
└── ...

1.2 离线地形数据(QuantizedMesh)

推荐使用以下工具生成:

地形目录结构如下:

arduino 复制代码
public/terrain/
├── layer.json
├── 0/0/0.terrain
├── 1/0/0.terrain
├── 1/0/1.terrain
└── ...

二、NestJS 项目搭建

2.1 创建 Nest 项目

bash 复制代码
nest new cesium-offline-server

2.2 安装静态资源模块

bash 复制代码
npm install @nestjs/serve-static

2.3 配置静态资源服务

编辑 app.module.ts:

ts 复制代码
import { Module } from '@nestjs/common';
import { ServeStaticModule } from '@nestjs/serve-static';
import { join } from 'path';

@Module({
  imports: [
    // 映射 tiles 到 /tiles 路由
    ServeStaticModule.forRoot({
      rootPath: join(__dirname, '..', 'public/tiles'),
      serveRoot: '/tiles',
    }),
    // 映射 terrain 到 /terrain 路由
    ServeStaticModule.forRoot({
      rootPath: join(__dirname, '..', 'public/terrain'),
      serveRoot: '/terrain',
    }),
  ],
})
export class AppModule {}

2.4 开启跨域

修改 main.ts:

ts 复制代码
async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.enableCors(); // 必须开启
  await app.listen(3000);
}

三、前端 Cesium 接入离线地图和地形

3.1 离线地图瓦片加载

js 复制代码
const viewer = new Cesium.Viewer("cesiumContainer", {
  imageryProvider: new Cesium.UrlTemplateImageryProvider({
    url: "http://localhost:3000/tiles/{z}/{x}/{y}.png",
    tilingScheme: new Cesium.GeographicTilingScheme(), // WGS84
    maximumLevel: 18,
  }),
  baseLayerPicker: false,
  terrainProvider: new Cesium.EllipsoidTerrainProvider(), // 暂不加载地形
});

3.2 离线地形加载

js 复制代码
viewer.terrainProvider = new Cesium.CesiumTerrainProvider({
  url: "http://localhost:3000/terrain",
  requestVertexNormals: true,
  requestWaterMask: true,
});

四、测试验证与排查建议

✅ 检查资源访问

确保能访问:

  • http://localhost:3000/tiles/0/0/0.png
  • http://localhost:3000/terrain/layer.json
  • http://localhost:3000/terrain/1/0/0.terrain

✅ layer.json 示例:

json 复制代码
{
  "tilejson": "2.1.0",
  "format": "quantized-mesh-1.0",
  "version": "1.0.0",
  "scheme": "tms",
  "tiles": ["{z}/{x}/{y}.terrain"],
  "attribution": "Offline Terrain",
  "bounds": [-180, -90, 180, 90],
  "minzoom": 0,
  "maxzoom": 14
}

✅ 浏览器调试工具 Network 查看请求是否 200


五、总结

通过本文我们完成了:

  • 使用 NestJS 快速部署离线地图和地形服务
  • 结构清晰地管理 tiles 和 terrain 资源
  • 在 Cesium 前端正确加载离线资源

✅ 优势

  • 📡 完全离线:适用于内网、矿井、无人区等环境
  • 🛡️ 私有数据保护:不暴露给外部 API
  • ⚡ 性能更优:局域网传输,加载快无延迟

🔗 后续拓展

  • 支持多地图图层(如天地图、谷歌、OpenStreetMap 切换)
  • 加入图层控制 API,动态切换瓦片
  • 加入 NestJS 文件上传接口,实现地图服务在线发布管理
相关推荐
用户461169657287 分钟前
网站 HTTPS 不稳定?证书排查指南
前端
n876519 分钟前
Playwright Java WEB UI 自动化实现框架与逻辑
java·前端·ui
keyipatience21 分钟前
TypeScript学习(1)
前端·javascript·学习·typescript·html·css3
xifangge20251 小时前
基于 JavaScript 实现 CNC 数控切削参数与螺纹公差纯前端核算引擎
开发语言·前端·javascript
wangruofeng1 小时前
2026 Web 技术选型指南,AI 时代如何选择适合项目的技术栈
前端·aigc·ai编程
honkun61 小时前
vue 表格组件 vxe-table 修改滚动条样式,修改滚动条样式,统一宽度、颜色与自动隐藏
前端·javascript·vue.js
爱勇宝2 小时前
研究数字孪生的这半年,做了个 Demo,也有了一些新想法
前端·程序员
不可能片场2 小时前
工程实践 一个缓存把选片从十分钟压到一分钟
前端·electron
前端小万2 小时前
探索副业五个月,最终以放弃告终
前端·后端·面试
FRing032 小时前
JavaScript入门到精通二十四(正则表达式、元字符、修饰符)
开发语言·前端·javascript·正则表达式