CZML是一種基于JSON的數據格式,專門用于在Cesium中描述3D場景和時間動態數據。
本文將詳細介紹了CZML的特點(JSON格式、時間動態性、層次結構等)和基本組件,并給出了一個火箭發射的實例。通過搭建Cesium開發環境(使用vite)、配置vite插件、加載CZML數據源(space.czml)并設置相機跟蹤,實現了火箭從起飛到降落的完整動畫效果。最后還提供了保持相機跟蹤火箭位置的關鍵代碼實現。
前置知識點
知識點:CZML數據格式
CZML(Cesium Language)是一種用于描述3D場景和時間動態的數據格式,最初由Cesium開發團隊創建,用于在Cesium JavaScript庫中呈現虛擬地球和其他三維地理空間數據。它通常用于創建可視化地球表面上的物體、飛行軌跡、傳感器信息等。
CZML數據擁有以下特點:
JSON格式:CZML數據以JSON格式編寫,這使得它易于創建和解析,JSON是一種輕量級的數據交換格式,易于人類閱讀和編寫,同時也易于機器解析和生成。
時間動態性:CZML支持時間動態性,允許您描述物體隨時間變化的屬性。這使得您可以創建動態的3D場景,例如模擬飛行軌跡、天體運動等。
基本組件:CZML包含了一系列基本的組件來描述場景中的對象。這些組件包括點、線、多邊形、模型等。
層次結構:CZML允許您以層次結構的方式組織場景中的對象,例如可以創建父對象和子對象,這樣可以更好地管理和組織復雜的場景。
事件:CZML允許您指定事件,例如單擊事件、鼠標懸停事件等,這使得您可以創建與場景交互的用戶體驗。
插件支持: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是開箱即用的下一代打包工具, 原生支持模塊化開發
相比于webpack
Rollup
Parcel
更快, 更好用
將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");
代碼功能說明
導入模塊
import * as Cesium from "cesium"
?將整個 Cesium 庫導入,并通過?Cesium
?對象訪問其功能。設置訪問令牌
Cesium.Ion.defaultAccessToken = "xxx"
?用于設置 Cesium Ion 的訪問令牌,替換?"xxx"
?為實際令牌字符串。初始化 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
這樣你可以看到一個橢球
然后設置一下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 開始。