三维GIS开发实战!Cesium + CZML 实现火箭飞行与分离的 3D 动态模拟

发布于:2025-09-13 ⋅ 阅读:(17) ⋅ 点赞:(0)

CZML是一种基于JSON的数据格式,专门用于在Cesium中描述3D场景和时间动态数据。

本文将详细介绍了CZML的特点(JSON格式、时间动态性、层次结构等)和基本组件,并给出了一个火箭发射的实例。通过搭建Cesium开发环境(使用vite)、配置vite插件、加载CZML数据源(space.czml)并设置相机跟踪,实现了火箭从起飞到降落的完整动画效果。最后还提供了保持相机跟踪火箭位置的关键代码实现。

前置知识点

知识点:CZML数据格式

CZML(Cesium Language)是一种用于描述3D场景和时间动态的数据格式,最初由Cesium开发团队创建,用于在Cesium JavaScript库中呈现虚拟地球和其他三维地理空间数据。它通常用于创建可视化地球表面上的物体、飞行轨迹、传感器信息等。

CZML数据拥有以下特点:

  1. JSON格式:CZML数据以JSON格式编写,这使得它易于创建和解析,JSON是一种轻量级的数据交换格式,易于人类阅读和编写,同时也易于机器解析和生成。

  2. 时间动态性:CZML支持时间动态性,允许您描述物体随时间变化的属性。这使得您可以创建动态的3D场景,例如模拟飞行轨迹、天体运动等。

  3. 基本组件:CZML包含了一系列基本的组件来描述场景中的对象。这些组件包括点、线、多边形、模型等。

  4. 层次结构:CZML允许您以层次结构的方式组织场景中的对象,例如可以创建父对象和子对象,这样可以更好地管理和组织复杂的场景。

  5. 事件:CZML允许您指定事件,例如单击事件、鼠标悬停事件等,这使得您可以创建与场景交互的用户体验。

  6. 插件支持:CZML可以与Cesium JavaScript库的插件集成,从而扩展其功能,例如添加地形、天气数据等。

CZML数据示例

关于czml数据规范,可以查看官方文档:

https://github.com/AnalyticalGraphicsInc/czml-writer/wiki/CZML-Structure

CZML数据是一个数组,可以看到,数组中的每一项其实都是一个实体对象的描述,这种对象,成为一个包:CZML

  • id:固定值

  • name:可自定义设置值

  • version:CZML版本,CZL目前只有1.0版本,固定值

完整的CZML至少包合两个packet,第一个用于标识CZML,第二个packet对应一个场景中的对象,例如一个盒子。

可以看到,box中的属性和Cesium实体中boxGraphic的属性是一致的

box.czml

{
  "document": {
    "id": "document",
    "name": "box",
    "version": "1.0"
  },
  "shape1": {
    "id": "shape1",
    "name": "Blue box",
    "position": {
      "cartographicDegrees": [
        -114.0,
        40.0,
        300000.0
      ]
    },
    "box": {
      "dimensions": {
        "cartesian": [
          400000.0,
          300000.0,
          500000.0
        ]
      },
      "material": {
        "solidColor": {
          "color": {
            "rgba": [
              0,
              0,
              255,
              255
            ]
          }
        }
      }
    }
  }
}
 

所以这里我们就知道Cesium是如何实现火箭起飞到分体到降落的过程了,通过加载czml数据,可以快速的实现这个效果

使用到的火箭升空数据源----数据来源(火星科技)

space.czml

实现全过程

首先搭建Cesium开发环境

新建一个cesium_basic的目录,并初始化

npm init -y

安装cesium与vite的cesium插件,本教程使用的版本为1.97

npm i cesium@1.97 vite-plugin-cesium

安装vite

vite是开箱即用的下一代打包工具, 原生支持模块化开发

相比于webpackRollupParcel更快, 更好用

将vite安装成开发时依赖, 使用vite启动开发服务

"vite": "^5.4.9"
npm i vite -D

配置vite.config.js,主要是配置cesium插件,这样才能正常引入cesium

import { defineConfig } from'vite';
import cesium from'vite-plugin-cesium';
// https://vitejs.dev/config/
export defaultdefineConfig({
	plugins: [cesium()]
});

创建入口文件index.html, 在入口文件中引入

  • 初始化样式reset.css

  • 主入口文件main.js

  • 编辑package.json脚本脚本,使用vite会自动编辑index.html

  • 启动开发服务

ndex.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <!-- 引入初始化样式 -->
    <link rel="stylesheet" href="./src/assets/styles/reset.css" />
  </head>
  <body>
    <div id="cesiumContainer"></div>
    <!-- 使用模块化方式引入入口文件 -->
    <script src="./src/main.js" type="module"></script>
  </body>
</html>
 
功能说明
  • 该代码为Cesium.js等WebGL库的基础HTML模板
  • reset.css用于清除浏览器默认样式
  • cesiumContainer作为三维渲染的DOM容器
  • 模块化引入的main.js为应用入口文件

reset.css

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  background-color: skyblue;
  overflow: hidden;
}

#cesiumContainer {
  width: 100vw;
  height: 100vh;
  position: relative;
}
 
代码说明
  • box-sizing: border-box 确保元素尺寸计算包含边框和内边距
  • overflow: hidden 防止页面出现滚动条
  • position: relative 为容器内的绝对定位元素建立定位上下文
功能增强
  • 添加了视口单位(vw/vh)确保容器始终填满屏幕
  • 重置了所有元素的盒模型计算方式
  • 优化了背景色显示效果

main.js

import * as Cesium from "cesium";

// 注册token
Cesium.Ion.defaultAccessToken = "xxx";

// 使用cesium默认配置初始化viewer
const viewer = new Cesium.Viewer("cesiumContainer");
 
代码功能说明
  1. 导入模块
    import * as Cesium from "cesium" 将整个 Cesium 库导入,并通过 Cesium 对象访问其功能。

  2. 设置访问令牌
    Cesium.Ion.defaultAccessToken = "xxx" 用于设置 Cesium Ion 的访问令牌,替换 "xxx" 为实际令牌字符串。

  3. 初始化 Viewer
    const viewer = new Cesium.Viewer("cesiumContainer") 创建一个 Cesium 地图实例,绑定到 HTML 中 ID 为 "cesiumContainer" 的元素。

package.json

{
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "preview": "vite preview"
  }
}
 
功能说明
  • dev 命令启动开发服务器,支持热模块替换(HMR)
  • build 命令执行生产环境构建
  • preview 命令本地预览生产构建结果

然后开启终端运行项目

terminal

npm run dev

这样你可以看到一个椭球

image.png

然后设置一下viewer,将不需要的控件隐藏起来,并去Cesium ion注册一个token(具体流程可以自行百度),然后将token写入到Cesium.Ion.defaultAccessToken上。

这里需要注意将shouldAnimate设置为true,这样才会有动画效果

import * as Cesium from "cesium";
import * as dat from "dat.gui";

const gui = new dat.GUI();
Cesium.Ion.defaultAccessToken = import.meta.env.VITE_CESIUM_TOKEN;

// 使用cesium默认配置初始化viewer
const viewer = new Cesium.Viewer("cesiumContainer", {
    timeline: true,              // 设置默认的时间轴不显示
    animation: false,            // 隐藏动画控件
    baseLayerPicker: false,      // 隐藏底图切换
    geocoder: false,             // 隐藏导航功能
    homeButton: false,           // 复位按钮
    sceneModePicker: false,      // 二三维切换按钮
    navigationHelpButton: false, // 隐藏帮助按钮
    scene3DOnly: true,          // 如果是三维的系统,最好加上这个配置
    shouldAnimate: true         // 最好设置动画为true,这样火箭才能有动画效果
});
 
代码说明
  • 代码格式已调整为标准的JavaScript语法,包含适当的缩进和换行
  • 注释保持原样,但增加了与代码的对齐
  • 配置项使用一致的缩进方式,便于阅读
  • 对象字面量的属性使用逗号分隔,最后一个属性不加逗号(符合ESLint推荐风格)
  • 保留了原有的功能实现,未做逻辑修改

接着调用Cesium中加载Czml数据的方法,将space.czml接入,就可以让火箭起飞了,在加载完成的回调函数中,还可以调用viewer.trackedEntity,让相机一直锁定火箭的位置

// CZML 是 Cesium 的数据源格式,用于快速加载动态实体场景
new Cesium.CzmlDataSource()
    .load('/src/assets/dataSource/space.czml')
    .then(dataSource => {
        // 添加数据源到场景
        viewer.dataSources.add(dataSource);
        
        // 自动缩放到数据源范围
        viewer.zoomTo(dataSource);
        
        // 设置相机跟踪数据源中的第二个实体(索引为1)
        viewer.trackedEntity = dataSource.entities.values[1];
    });
 
代码说明
  • CZML 加载:通过 CzmlDataSource.load() 方法异步加载指定的 CZML 文件(路径为 /src/assets/dataSource/space.czml)。
  • 数据源处理:加载完成后,将数据源添加到 viewer 的 dataSources 集合中,并通过 zoomTo 自动调整视角至数据范围。
  • 实体跟踪:将相机的跟踪目标设为数据源中的第二个实体(values[1]),通常用于跟踪动态对象如火箭。
注意事项
  • 确保 Cesium 库已正确引入,且 viewer 为有效的 Cesium.Viewer 实例。
  • CZML 文件路径需根据实际项目结构调整。
  • 实体索引(如 values[1])需根据具体 CZML 内容确认,通常索引 0 为文档定义,实体从索引 1 开始。

该系列持续更新,手把手教你玩转GIS开发!

一键关注不迷路👇👇