🚀 如何在内网中运行 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 文件上传接口,实现地图服务在线发布管理
相关推荐
快乐肚皮10 小时前
一文了解XSS攻击:分类、原理与全方位防御方案
java·前端·xss
保护我方头发丶10 小时前
ESP-wifi-蓝牙
前端·javascript·数据库
想学后端的前端工程师10 小时前
【Flutter跨平台开发实战指南:从零到上线-web技术栈】
前端·flutter
老王Bingo10 小时前
Qwen Code + Chrome DevTools MCP,让爬虫、数据采集、自动化测试效率提升 100 倍
前端·爬虫·chrome devtools
董世昌4111 小时前
什么是扩展运算符?有什么使用场景?
开发语言·前端·javascript
来杯三花豆奶11 小时前
Vue 3.0 Mixins 详解:从基础到迁移的全面指南
前端·javascript·vue.js
想学后端的前端工程师11 小时前
【React性能优化实战指南:从入门到精通-web技术栈】
前端·react.js·性能优化
白兰地空瓶12 小时前
React Hooks 深度理解:useState / useEffect 如何管理副作用与内存
前端·react.js
cike_y12 小时前
JSP内置对象及作用域&双亲委派机制
java·前端·网络安全·jsp·安全开发
巴拉巴拉~~12 小时前
KMP 算法通用进度条组件:KmpProgressWidget 多维度 + 匹配进度联动 + 平滑动画
java·服务器·前端