cesium学习(一)-基本概念

地图/影像服务

Cesium 的地球本质是:

  • 一个 WGS84 椭球
  • 上面可以贴各种影像

地图服务 = 影像贴图 + 瓦片规则

常见地理数据服务

类型 作用 典型 在 Cesium 中的位置
影像瓦片 贴在地球表面的图片 天地图影像、高德影像 imageryLayers
地形瓦片 提供地表高程起伏 Cesium World Terrain terrainProvider
3D Tiles 加载大规模三维数据 倾斜摄影、城市模型 scene.primitives
矢量瓦片 道路、文字、面数据 MVT、高德矢量 需要额外处理

注意:二维地图里的"矢量瓦片"并不是 Cesium 最核心的加载方式。Cesium 更常见的是影像、地形、Entity、Primitive 和 3D Tiles。

坐标体系

分为:地理坐标系(经纬度)、投影坐标系(Web Mercator)、渲染坐标系(Cartesian)

系统 特点
WGS84 全球通用、GPS 坐标
GCJ02 火星坐标、高德 / 腾讯、在国内强制加密偏移
BD09(百度) 百度二次加密、更偏
Web Mercator(EPSG:3857) 瓦片地图用、平面坐标
Cartesian(笛卡尔) Cesium 内部计算用、几乎不用用户手算

经纬度 ↔ Cartesian

业务里几乎所有"加东西到场景"都要先把经纬度转成 Cartesian3

ini 复制代码
const cartesian = Cesium.Cartesian3.fromDegrees(116.39, 39.9, 100)

反过来:

ini 复制代码
const cartographic = Cesium.Cartographic.fromCartesian(cartesian)
​
const lon = Cesium.Math.toDegrees(cartographic.longitude)
const lat = Cesium.Math.toDegrees(cartographic.latitude)
const height = cartographic.height

注意:

  • fromDegrees 顺序是 (经度, 纬度, 高度),和很多前端库相反。
  • Cartographic 内部存的是弧度,取出来需要用 Math.toDegrees 转。
  • 批量造点:Cartesian3.fromDegreesArray([lon, lat, lon, lat, ...])
  • 批量带高度:Cartesian3.fromDegreesArrayHeights([lon, lat, h, ...])

各类影像

数据 坐标系统 是否偏移
GPS / 卫星 WGS84
天地图 WGS84
高德 / 腾讯 GCJ02
百度 BD09
Cesium WGS84

接入 Cesium

Cesium 可以通过 npm 安装,也可以直接走 CDN。

npm 安装

复制代码
npm install cesium

新版 Cesium(1.99 之后)实际上拆成了多个包:

内容
cesium 入口包,重新导出 engine 和 widgets
@cesium/engine 渲染、几何、3D Tiles 等核心能力
@cesium/widgets Viewer / Timeline / Animation 等内置 UI

一般直接装 cesium 就够。只用核心能力(自己实现 UI)可以只装 @cesium/engine

CESIUM_BASE_URL

Cesium 运行时会去加载 Workers、Assets、Widgets 等资源。打包项目(Vite / Webpack)里需要:

javascript 复制代码
import * as Cesium from 'cesium'
import 'cesium/Build/Cesium/Widgets/widgets.css'
​
window.CESIUM_BASE_URL = '/cesium/'

同时把 node_modules/cesium/Build/Cesium/{Assets,Workers,Widgets,ThirdParty} 拷到 public/cesium/。漏掉这一步常见症状:worker 报错、地球白屏、卫星图加载失败。

Vite 项目可以直接用 vite-plugin-cesium 自动处理。

Cesium Ion Token

用 Cesium 官方的卫星图、地形、OSM 建筑等数据需要 token:

ini 复制代码
Cesium.Ion.defaultAccessToken = 'YOUR_ION_TOKEN'

不设置时会用一个有频次限制的默认 token,开发可以凑合,生产环境必须替换。

Hello World

php 复制代码
import * as Cesium from 'cesium'
import 'cesium/Build/Cesium/Widgets/widgets.css'
​
Cesium.Ion.defaultAccessToken = 'YOUR_ION_TOKEN'
​
const viewer = new Cesium.Viewer('cesiumContainer', {
  terrain: Cesium.Terrain.fromWorldTerrain()
})
​
viewer.entities.add({
  position: Cesium.Cartesian3.fromDegrees(116.39, 39.9, 100),
  point: {
    pixelSize: 10,
    color: Cesium.Color.YELLOW
  }
})
​
viewer.camera.flyTo({
  destination: Cesium.Cartesian3.fromDegrees(116.39, 39.9, 5000)
})

什么是 Viewer

Viewer 是 Cesium 对外暴露的最高层应用封装,整合了 Scene、Camera、Entity、时间系统和默认 UI,是 Cesium 应用的根对象。

当执行:

arduino 复制代码
const viewer = new Cesium.Viewer('cesiumContainer')

Cesium 内部实际上做了以下这些事:

创建渲染系统

  • Scene(真正渲染的地方)
  • Camera(相机)
  • Globe(地球)
  • WebGL Context

创建数据 & 实体管理系统

这就是你平时加点、线、模型的地方。

  • EntityCollection
  • DataSourceCollection

创建时间系统

所有动态效果、轨迹、仿真,最终都依赖这个

  • Clock
  • Timeline
  • Animation

创建事件 & 交互系统

  • 鼠标事件
  • 拾取(pick)
  • 相机交互

创建一堆默认 UI(可关)

  • 图层按钮
  • 时间轴
  • 动画控件
  • 地名搜索

Viewer 的核心结构

css 复制代码
Viewer
 ├─ scene
 │   ├─ camera
 │   ├─ globe
 │   ├─ primitives
 │   └─ postProcessStages
 ├─ entities
 ├─ dataSources
 ├─ clock
 ├─ timeline
 ├─ animation
 ├─ imageryLayers
 └─ terrainProvider

什么是 Entity

entities 是 Cesium 提供的高层业务对象系统,用于以"数据 + 时间"的方式描述场景中的对象,由 Cesium 自动完成渲染与更新。

Entity 可以表示什么

属性 表现
point
polyline 线
polygon
billboard 常用于:图标、标记点
label 文字
model glTF 模型
path 轨迹

Entity 本身不渲染,真实渲染链路是:

复制代码
Entity
↓
Visualizer
↓
Primitive
↓
Scene
↓
GPU

Cesium 内部有很多 Visualizer

  • BillboardVisualizer
  • ModelVisualizer
  • PolylineVisualizer

它们负责把 Entity 转成 Primitive。

什么是 Primitive

Primitive 是 Cesium 的底层渲染单元,直接对应 GPU 绘制对象,性能高但抽象低,是 Entity 最终转换的目标。

Primitive 可以表示什么

Primitive 用途
Primitive 通用几何
ClassificationPrimitive 贴地 / 分类
GroundPrimitive 贴地几何
Model glTF 模型
Cesium3DTileset 3D Tiles

为什么 Primitive 表现更好?

因为它:

  • ❌ 没有 Property 系统
  • ❌ 没有时间系统
  • ❌ 没有自动插值
  • ❌ 没有 Entity 管理

但换来的是:

  • ✅ 极少对象创建
  • ✅ 批量提交 GPU
  • ✅ 更少 CPU 开销

什么时候必须用 Primitive?

  • 十万 / 百万条线
  • 海量点云
  • 大规模静态几何
  • 自定义渲染效果
  • 强性能约束(大屏、信创)

什么是 Scene

Scene 是 Cesium 的核心渲染上下文,负责管理相机、地球和所有 Primitive,并驱动每一帧的 GPU 渲染。

复制代码
Scene
 ├─ camera          ← 你看世界的方式
 ├─ globe           ← 地球 & 地形
 ├─ primitives      ← 所有真实绘制对象
 ├─ postProcess     ← 后处理
 ├─ fog / sky / sun ← 环境
 └─ context         ← WebGL 上下文

Scene 的行为

每一帧,Scene 都在干这件事:

复制代码
更新时间(Clock)
 ↓
更新相机(Camera)
 ↓
更新 Primitive
 ↓
裁剪 / LOD
 ↓
提交 GPU
 ↓
渲染一帧

常见使用场景

  • 相机控制
  • 加 3D Tiles
  • 高度计算
  • 性能优化

相机 Camera

scene.camera 决定我们怎么看这个三维世界。最常用的三种操作:

带动画飞行:

yaml 复制代码
viewer.camera.flyTo({
  destination: Cesium.Cartesian3.fromDegrees(116.39, 39.9, 5000),
  orientation: {
    heading: Cesium.Math.toRadians(0),
    pitch: Cesium.Math.toRadians(-30),
    roll: 0
  }
})

无动画直接定位:

css 复制代码
viewer.camera.setView({
  destination: Cesium.Cartesian3.fromDegrees(116.39, 39.9, 5000)
})

锁定看向某个目标:

less 复制代码
viewer.camera.lookAt(
  Cesium.Cartesian3.fromDegrees(116.39, 39.9, 0),
  new Cesium.HeadingPitchRange(0, -Cesium.Math.PI_OVER_FOUR, 1000)
)

详细用法见(四)相机。

时间系统 Clock

Cesium 内置了一套时间系统,Entity 的动态属性、轨迹、回放都依赖它。

arduino 复制代码
viewer.clock.startTime       // 起始时间
viewer.clock.stopTime        // 结束时间
viewer.clock.currentTime     // 当前时间
viewer.clock.multiplier      // 倍速
viewer.clock.shouldAnimate   // 是否在播放

时间在 Cesium 里是 JulianDate,不是普通 Date

vbscript 复制代码
const now = Cesium.JulianDate.now()
const later = Cesium.JulianDate.addSeconds(now, 60, new Cesium.JulianDate())

JulianDateDate 精度高、能直接做时间区间运算,适合仿真和轨迹场景。

业务上经常需要和原生 Date 互转:

vbscript 复制代码
const julian = Cesium.JulianDate.fromDate(new Date())
const date = Cesium.JulianDate.toDate(julian)

什么是 3D Tiles

3D Tiles 是一种为大规模三维地理数据设计的分块、分级、流式加载规范,是 Cesium 支撑城市级三维场景的核心技术。

如果用普通 glTF,一次性加载会使内存爆炸,首屏会非常慢

3D Tiles 是 Primitive 层的数据,不是 Entity ,所以是加到 scene.primitives,不是 viewer.entities

csharp 复制代码
const tileset = await Cesium.Cesium3DTileset.fromUrl('/tileset/tileset.json')
viewer.scene.primitives.add(tileset)
viewer.flyTo(tileset)

Entity、Primitive、3D Tiles 怎么选?

场景 推荐
少量点、线、面、图标、文字 Entity
需要时间动态、轨迹、插值 Entity + Property
海量静态点线面 Primitive
城市模型、倾斜摄影、点云 3D Tiles
相机飞行、拾取、后处理 Scene / Camera
地形高度、贴地、离地高度 Terrain + HeightReference

高度模式

在无人机(Drone)和 GIS 场景里,高度最容易混淆。关键是先分清楚:高度到底是相对于哪个基准面

1. HAE(Height Above Ellipsoid)- 椭球高

HAE 是相对于 WGS84 椭球体的高度。

  • 基准面:WGS84 椭球体,一个数学上定义的地球椭球模型。
  • 特点:不考虑真实海平面起伏,也不考虑地形起伏。
  • 在 Cesium 中:Cartographic.heightCartesian3.fromDegrees(lon, lat, height) 里的 height 默认就是相对 WGS84 椭球体的高度,通常可以理解为 HAE。

这是 Cesium 里最底层、最直接的高度概念。

2. ASL(Above Sea Level)- 海拔高

ASL 是相对于平均海平面或大地水准面(Geoid)的高度,也就是日常说的"海拔"。

  • 基准面:平均海平面 / 大地水准面。
  • 特点:不随当前位置地形起伏变化,但它的基准面不是 WGS84 椭球体。
  • 应用场景:跨区域飞行、气压高度计参考、需要和传统海拔数据对齐的场景。

HAE 和 ASL 的关系大致是:

ini 复制代码
HAE = ASL + Geoid Undulation(大地水准面差距)

在不同地区,大地水准面和 WGS84 椭球体可能相差几十米,所以不能简单认为 Cesium 的 height 就是严格的海拔 ASL。

3. AGL(Above Ground Level)- 离地高

AGL 是相对于当前位置正下方地面的高度。

  • 基准面:当前地形表面。
  • 特点:参考面会随山地、谷地、建筑或地形数据变化。
  • 例子:AGL 为 50 米,表示始终距离脚下地面 50 米。
  • 应用场景:地形跟随飞行、植保喷洒、电力巡检、低空航线规划。

4. ALT(Relative to Takeoff)- 相对起飞点高度

ALT 在无人机项目里经常表示相对于起飞点的高度。

  • 基准面:起飞点高度。
  • 特点:起飞时高度记为 0。飞向山谷时,AGL 可能变大,但相对起飞点高度可能不变甚至为负。
  • 项目对应项:相对起飞点高度(relativeToTakeoff)。

Cesium 高度模式对应关系

Cesium 高度引用 含义 更接近的高度概念
HeightReference.NONE 使用坐标里传入的高度,不自动贴地 HAE / 绝对椭球高
HeightReference.CLAMP_TO_GROUND 贴到地表或地形上 贴地
HeightReference.RELATIVE_TO_GROUND 在地表或地形基础上增加一个高度 AGL / 离地高

如果项目里区分得更细,比如:

项目选项 含义 需要注意
海拔高度 通常指 ASL 如果直接传给 Cesium,可能需要做 ASL -> HAE 转换
相对地形高度 相对当前地形高度 通常对应 AGL
相对起飞点高度 相对起飞位置高度 需要记录起飞点基准高度

总结对比

缩写 全称 参考基准 是否随地形变化 在 Cesium 中的注意点
HAE Height Above Ellipsoid WGS84 椭球体 Cesium 默认高度更接近 HAE
ASL Above Sea Level 平均海平面 / 大地水准面 不能直接等同于 Cesium 的 height
AGL Above Ground Level 当前地面 / 地形 通常需要地形数据支持
ALT Relative to Takeoff 起飞点 取决于起飞点和当前位置 无人机项目中常见

学习路线

本篇是入口,覆盖最核心的概念和最少的接入代码。后续按主题展开:

主题 对应笔记
地图、地形、影像图层 (二)地图地形
3D Tiles、倾斜摄影、点云 (三)3D Tiles
相机、视角控制 (四)相机
Primitive、底层渲染对象 (五)Primitive
Entity、业务对象 (六)Entity
Shader 基础 (七)Shader
自定义材质 (八)自定义材质
渲染管线 (九)Render Pipeline

一句话指引:

复制代码
新手期:先把 Viewer / Entity / 影像 / 地形 跑通 → 看(一)(二)(六)
进阶期:理解 Primitive 性能差异、3D Tiles 数据 → 看(三)(五)
深入期:自定义材质、渲染管线、Shader      → 看(七)(八)(九)
相关推荐
LinDaiDai_霖呆呆1 小时前
大白话介绍大模型的一些底层原理,看完终于能跟人聊两句了
前端·人工智能·面试
悠哉摸鱼大王1 小时前
cesium学习(二)-地图地形
前端·cesium
青山师1 小时前
【AI热点资讯】5月10日AI热点:Cloudflare裁员1100人、Musk庭审第二周回顾、OpenAI发布Codex Chrome插件
前端·人工智能·chrome·ai·ai热点
阿赛工作室2 小时前
AI时代WEB开发人员生存与发展报告
前端·人工智能·node.js
ZC跨境爬虫2 小时前
跟着 MDN 学 HTML day_36:(深入理解 Comment 接口与 DOM 注释节点)
前端·javascript·ui·html·音视频·视频编解码
石小石Orz3 小时前
Harness Engineering 到底是什么?概念、实战与争议,一次全部讲清楚
前端·后端
悠哉摸鱼大王3 小时前
cesium学习(三)-3d tiles
前端·cesium
前端那点事3 小时前
Vue3自定义Hooks保姆级教程!从原理到企业级实战,告别混乱代码
前端·vue.js
前端那点事3 小时前
别再乱用Vue3响应式!ref、reactive、toRef、toRefs完整区别+企业级落地实战
前端·vue.js