Cesium离线使用和部署地图影像

今天来聊一下cesium的离线使用。某些情况下,我们的服务是部署在内网的,所以无法使用cesium官方提供的一些服务。

离线引入Cesium

Cesium-1.128下载 2025年4月发布的

为什么要下载呢?官网确实提供cdn引入:

html 复制代码
<script src="https://cesium.com/downloads/cesiumjs/releases/1.128/Build/Cesium/Cesium.js"></script> 
<link href="https://cesium.com/downloads/cesiumjs/releases/1.128/Build/Cesium/Widgets/widgets.css" rel="stylesheet">

哪有人就想直接把这个两个文件下载下来不就可以了嘛,下载下来然后本地引入,发现报错:

bash 复制代码
Cesium.js:1 Uncaught SyntaxError: Invalid regular expression: /[א-ת؀-ۿݐ-ݿࢠ-ࣿ]/: Range out of order in character class (at Cesium.js:1:1711082)
    at new RegExp (<anonymous>)

其实Cesium.js中还引用很多js文件的。

正确引用: 将下载好压缩包解压:

我是直接在html文件测试的,所以只要关注Build文件夹,我猜测packages文件夹应该是npm包,使用框架的话应该关注这个文件夹。

点开Build文件夹:

Cesium文件夹是压缩后的代码,CesiumUnminifed文件夹是未压缩代码的。这个两个文件都是完整的cesium。 然后直接引入,跟官方cdn引入是一样的,只需要改变基础地址就行了,我的引入:

html 复制代码
  <script src="./assets/cesium-1.128/Build/CesiumUnminified/Cesium.js"></script>
   <link
      href="./assets/cesium-1.128/Build/CesiumUnminified/Widgets/widgets.css"
      rel="stylesheet"
    />

到此为止,引入计算结束了。接下来就是代码层面的了,先看我的案列代码:

html 复制代码
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title></title>
    <script src="./assets/cesium-1.128/Build/CesiumUnminified/Cesium.js"></script>
    <link
      href="./assets/cesium-1.128/Build/CesiumUnminified/Widgets/widgets.css"
      rel="stylesheet"
    />
  </head>
  <style>
    * {
      padding: 0;
      margin: 0;
    }
    #cesiumContainer {
      width: 100%;
      height: 100vh;
    }
  </style>
  <body>
    <div id="cesiumContainer"></div>
    <script type="module">
      // 禁用Ion服务
      Cesium.Ion.defaultAccessToken = undefined;

      let viewer;
      async function initCesium() {
        viewer = new Cesium.Viewer('cesiumContainer', {
          animation: false,
          baseLayerPicker: false,
          fullscreenButton: false,
          vrButton: false,
          geocoder: false,
          homeButton: false,
          infoBox: false,
          sceneModePicker: false,
          selectionIndicator: false,
          timeline: false,
          navigationHelpButton: false,
          skyBox: false,
          skyAtmosphere: false,
          contextOptions: {
            webgl: {
              alpha: true,
              failIfMajorPerformanceCaveat: false,
            },
          },
          imageryProvider: false, //让控制台不报错 默认状态会加载cesium的底图
        });

        viewer.cesiumWidget.creditContainer.style.display = 'none';
        // 添加底图
        // const provider = await Cesium.SingleTileImageryProvider.fromUrl(
        //  'http://127.0.0.1:8004/blue.jpg'
        // );
        // viewer.scene.imageryLayers.addImageryProvider(provider);
        viewer.scene.imageryLayers.addImageryProvider(
          new Cesium.TileMapServiceImageryProvider({
            url: 'http://127.0.0.1:8004/map/{z}/{x}/{reverseY}.jpg',
            fileExtension: 'jpg',
            tilingScheme: new Cesium.GeographicTilingScheme(),
          })
          // new Cesium.UrlTemplateImageryProvider({
          //   url: 'http://192.168.5.228:8004/map/{z}/{x}/{reverseY}.jpg',
          //   fileExtension: 'jpg',
          //   tilingScheme: new Cesium.GeographicTilingScheme(),
          // })
        );
      }
      initCesium();
    </script>
  </body>
</html>

代码解读:

  • Cesium.Ion.defaultAccessToken:既然是离线使用那么Cesium.Ion.defaultAccessToken就没有用了,我们设置undefined,设置undefined,是为了避免一些请求,而在内网环境下的话就会报错,为了避免报错设置undefined。
  • 那些官方的组件就不要用了设置为false,具体的可以看Cesium.Viewer.ConstructorOptions
  • baseLayerPicker设置false,也是避免不必要的报错。
  • imageryProvider设置false,重点说一下这个配置项,其实这个配置项在新版本中已经移除了。如果ts的话大概率会报错,首先是还可以正常用,为什么移除了还要使用呢,主要原因就是如果不在配置项中设置的话,cesium就会默认加载cesium的地图服务,然后导致控制台报错

这里说一下其中有段注释的代码:

js 复制代码
const provider = await Cesium.SingleTileImageryProvider.fromUrl(
          'http://127.0.0.1:8004/blue.jpg'
        );
        viewer.scene.imageryLayers.addImageryProvider(provider);

为什么要说一下呢,就是这个SingleTileImageryProvider使用问ai和网上搜的都是错的 问ai回答我的是这样的:

js 复制代码
  function initCesium() {
        viewer = new Cesium.Viewer('cesiumContainer', {
          // ... existing code ...
          imageryProvider: new Cesium.SingleTileImageryProvider({
            url: './assets/img/blue.jpg',
            rectangle: Cesium.Rectangle.fromDegrees(-180.0, -90.0, 180.0, 90.0)  // 添加地理范围
          })
        });
        // ... existing code ...
      }

使用ai的发现 页面一片空白。

新版的使用方式改成异步的了 await Cesium.SingleTileImageryProvider.fromUrl()加载图片。

部署地图影像服务

其实部署很简单,最麻烦的就是地图影像数据。这里感谢xingke提供的地图影像数据,

夸克网盘「地图影像」 链接:pan.quark.cn/s/5ac3d143e... 提取码:DrTh

两个压缩包一个是地图影像的,一个是地形的

下载好之后就可以选择服务类型,我这边使用nest.js部署一个本地测试的,很简单,去官网直接使用命令创建一个nest项目,然后在项目根目录创建一个public目录,然后将压缩包直接解压到public目录下,然后在项目根目录下的src/mian.ts中设置一下public的路径和跨域

ts 复制代码
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { join } from 'path';
import { NestExpressApplication } from '@nestjs/platform-express';
import { TransformInterceptor } from './core/interceptor/transform.interceptor';
async function bootstrap() {
  const app = await NestFactory.create<NestExpressApplication>(AppModule);
  // 配置 CORS
  app.enableCors({
    origin: true, // 允许所有来源访问,生产环境建议设置具体的域名
    methods: 'GET,HEAD,PUT,PATCH,POST,DELETE,OPTIONS',
    credentials: true,
  });
  app.useStaticAssets(join(__dirname, '..', 'public'));
  app.useGlobalInterceptors(new TransformInterceptor());
  await app.listen(8004, '127.0.0.1');
}
bootstrap();

替换成你的地址就可以了

这里说一下TileMapServiceImageryProvider中的tilingScheme:

GeographicTilingScheme (地理坐标切片方案):

diff 复制代码
-   基于地理坐标系(经纬度)
-   适用于全球范围的数据展示
-   经度范围:-180° 到 180°
-   纬度范围:-90° 到 90°
-   在高纬度地区变形较小

WebMercatorTilingScheme (墨卡托投影切片方案):

diff 复制代码
-   基于墨卡托投影
-   是最常用的网络地图切片方案
-   适用于 Google Maps、OpenStreetMap 等常见地图服务
-   在高纬度地区会产生较大变形
-   不能完全显示极地区域 这两种切片方案的主要区别:

Cesium-1.128版本目前是只有这两种tilingScheme

相关推荐
Danta28 分钟前
百度网盘一面值得look:我有点难受🤧🤧
前端·javascript·面试
OpenTiny社区39 分钟前
TinyVue v3.22.0 正式发布:深色模式上线!集成 UnoCSS 图标库!TypeScript 类型支持全面升级!
前端·vue.js·开源
dwqqw1 小时前
opencv图像库编程
前端·webpack·node.js
Captaincc2 小时前
为什么MCP火爆技术圈,普通用户却感觉不到?
前端·ai编程
阿虎儿2 小时前
MCP
前端
毕小宝2 小时前
编写一个网页版的音频播放器,AI 加持,So easy!
前端·javascript
万水千山走遍TML2 小时前
JavaScript性能优化
开发语言·前端·javascript·性能优化·js·js性能
Aphasia3112 小时前
react必备JS知识点(一)——判断this指向👆🏻
前端·javascript·react.js
会飞的鱼先生3 小时前
vue3中slot(插槽)的详细使用
前端·javascript·vue.js
小小小小宇3 小时前
一文搞定CSS Grid布局
前端