Appearance
Viewer 初始化与生命周期
CesiumViewer 是对 Cesium 原生 Viewer 的业务封装类,负责三维地球视图的创建、时钟管理、实体 CRUD 以及销毁生命周期。
构造函数
typescript
constructor(container: HTMLElement | string, options?: CesiumViewerOptions)| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
container | HTMLElement | string | 是 | DOM 元素或元素 ID。传入字符串时会通过 document.getElementById 查找 |
options | CesiumViewerOptions | 否 | 初始化选项,见下方参数表 |
CesiumViewerOptions
以下为所有可用选项及其默认值:
| 选项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
animation | boolean | false | 显示/隐藏动画控件 |
timeline | boolean | false | 显示/隐藏时间轴 |
baseLayerPicker | boolean | false | 显示/隐藏底图选择器 |
fullscreenButton | boolean | false | 显示/隐藏全屏按钮 |
vrButton | boolean | false | 显示/隐藏 VR 按钮 |
geocoder | boolean | false | 显示/隐藏地理编码搜索框 |
homeButton | boolean | false | 显示/隐藏 Home 按钮 |
infoBox | boolean | true | 显示/隐藏信息框 |
sceneModePicker | boolean | false | 显示/隐藏场景模式切换(2D/3D/哥伦布视图) |
selectionIndicator | boolean | false | 显示/隐藏选择指示器 |
navigationHelpButton | boolean | false | 显示/隐藏导航帮助按钮 |
navigationHelpVisible | boolean | false | 导航帮助面板初始可见性 |
sceneMode | SceneMode | SceneMode.SCENE3D | 初始场景模式 |
creditText | string | '🌍 AirGIS' | 左下角版权文字 |
baseLayerUrl | string | 内置单张底图 | 默认底图图片 URL |
defaultView | Rectangle | { west, south, east, north } | { west: 70, south: 10, east: 140, north: 55 } | 默认相机视角(覆盖东亚) |
viewFactor | number | 2 | 视角包围盒缩放因子,控制相机距包围盒的距离比例 |
contextOptions | WebGLContextAttributes | { preserveDrawingBuffer: true } | WebGL 上下文配置,默认启用 preserveDrawingBuffer 以支持截图 |
shouldAnimate | boolean | - | 是否自动播放时钟动画 |
terrainProvider | TerrainProvider | false | - | 地形 Provider |
enableTerrain | boolean | - | 是否启用地形 |
NOTE
animation、timeline、baseLayerPicker 等控件默认值均为 false,以保持界面简洁,适合战术仿真场景。若需要标准 Cesium 界面,可自行启用。
WARNING
preserveDrawingBuffer: true 默认开启,这会影响 WebGL 性能(增加内存占用)。若不需要截图功能,可通过 contextOptions 覆盖该设置。
示例
typescript
import { CesiumViewer } from '@space-air/gis-cesium'
import { SceneMode } from 'cesium'
const viewer = new CesiumViewer('map', {
animation: true,
timeline: true,
sceneMode: SceneMode.SCENE3D,
defaultView: {
west: 73,
south: 3,
east: 135,
north: 53,
},
viewFactor: 1.5,
creditText: 'SpaceAir GIS',
contextOptions: {
preserveDrawingBuffer: false,
alpha: true,
},
})默认底图
CesiumViewer 在初始化时会自动加载一幅内置的单张世界影像图作为底图,底图覆盖全球范围(经度 -180 ~ 180,纬度 -90 ~ 90),分辨率为 5400 x 2700 像素。
typescript
// 构造函数内部实现的等效逻辑
const baseLayer = new ImageryLayer(
new SingleTileImageryProvider({
url: baseLayerUrl, // 默认使用内置影像资源
rectangle: Rectangle.fromDegrees(-180, -90, 180, 90),
tileWidth: 5400,
tileHeight: 2700,
})
)运行时底图切换由 BaseMapManager 接管,参见底图与地形指南。
默认相机视角
构造函数内部会修改 全局静态属性 Camera.DEFAULT_VIEW_RECTANGLE 和 Camera.DEFAULT_VIEW_FACTOR:
typescript
Camera.DEFAULT_VIEW_RECTANGLE = rectangle // 默认覆盖东亚区域
Camera.DEFAULT_VIEW_FACTOR = viewFactor // 默认 2参数对照
| 选项 | 类型 | 默认值 |
|---|---|---|
defaultView.west | number | 70 |
defaultView.south | number | 10 |
defaultView.east | number | 140 |
defaultView.north | number | 55 |
viewFactor | number | 2 |
自定义视角
typescript
// 方式一:使用矩形对象
import { Rectangle } from 'cesium'
const viewer = new CesiumViewer('container', {
defaultView: Rectangle.fromDegrees(110, 20, 130, 40),
viewFactor: 3,
})
// 方式二:使用快捷对象
const viewer2 = new CesiumViewer('container', {
defaultView: { west: 110, south: 20, east: 130, north: 40 },
})CAUTION
Camera.DEFAULT_VIEW_RECTANGLE 是 Cesium 的全局静态属性,修改它会影响到同一页面中所有后续创建的 Camera 实例。如果你在同一页面中创建多个独立的 CesiumViewer,后创建的实例会覆盖前一个的默认视角。需要在创建前自行管理该副作用。
核心方法
getViewer()
返回原始 Cesium Viewer 实例,用于访问原生 API 或传给 Mixin:
typescript
const v = viewer.getViewer()
// v 的类型为 Cesium.ViewerClock 管理
setClock()
设置时钟参数:
typescript
interface ClockOptions {
startTime?: Date | string | number // 起始时间
stopTime?: Date | string | number // 结束时间
currentTime?: Date | string | number // 当前时间
clockRange?: ClockRange // 循环方式
multiplier?: number // 时间倍速
}
viewer.setClock({
startTime: '2024-01-01T00:00:00Z',
stopTime: '2024-01-02T00:00:00Z',
currentTime: '2024-01-01T06:00:00Z',
clockRange: ClockRange.LOOP_STOP, // 循环播放
multiplier: 60, // 60 倍速
})ClockOptions 中时间字段支持以下类型,内部会自动转换:
Date对象- ISO 8601 字符串(如
'2024-01-01T00:00:00Z') - Unix 时间戳(毫秒数)
getClock()
获取 Cesium Clock 实例,可直接操作:
typescript
const clock = viewer.getClock()
console.log(clock.currentTime) // JulianDate
console.log(clock.multiplier) // numbersetClockRange()
仅设置循环方式,不修改其他时钟参数:
typescript
import { ClockRange } from 'cesium'
viewer.setClockRange({ clockRange: ClockRange.CLAMPED })timelineZoomTo()
将时间轴视图缩放到指定区间(需要启用 timeline: true):
typescript
import { JulianDate } from 'cesium'
const start = JulianDate.fromIso8601('2024-01-01T00:00:00Z')
const stop = JulianDate.fromIso8601('2024-01-01T06:00:00Z')
viewer.timelineZoomTo(start, stop)Entity CRUD
CesiumViewer 提供了对 viewer.entities 的快捷封装方法:
| 方法 | 返回值 | 说明 |
|---|---|---|
addEntity(entity) | Entity | 添加一个 Entity 或普通对象 |
getEntity(id) | Entity | undefined | 根据 ID 获取 Entity |
getEntities() | EntityCollection | 获取完整的 Entity 集合 |
removeId(id) | boolean | 根据 ID 移除 Entity |
removeEntity(entity) | boolean | 移除指定的 Entity 实例 |
removeAllEntities() | void | 移除所有 Entity |
typescript
// 添加 Entity
const box = viewer.addEntity({
id: 'demo-box',
position: Cartesian3.fromDegrees(116.39, 39.91, 1000),
box: {
dimensions: new Cartesian3(4000, 4000, 4000),
material: Color.RED.withAlpha(0.5),
},
})
// 查找 Entity
const found = viewer.getEntity('demo-box')
// 遍历所有 Entity
const all = viewer.getEntities()
all.values.forEach(entity => console.log(entity.id))
// 移除 Entity
viewer.removeId('demo-box')
// 或 viewer.removeEntity(box)
// 清空所有
viewer.removeAllEntities()TIP
addEntity() 接受 Entity 实例或普通对象,底层实际调用 viewer.entities.add()。如果需要更丰富的实体创建能力(带组件体系),请安装 viewerEntityMixin 并使用 createEntity()。
销毁生命周期
当组件卸载或不再需要三维场景时,务必调用 destroy() 以释放 GPU 资源:
typescript
// 在 Vue 组件中
onBeforeUnmount(() => {
viewer.destroy()
})destroy() 内部会检查 viewer.isDestroyed(),避免重复销毁抛出异常:
typescript
destroy(): void {
if (this.viewer && !this.viewer.isDestroyed()) {
this.viewer.destroy()
}
}WARNING
调用 destroy() 后,CesiumViewer 实例及原始 Viewer 将不再可用。如需重新创建,请新建一个 CesiumViewer 实例。
完整示例
typescript
import { CesiumViewer } from '@space-air/gis-cesium'
import {
Cartesian3,
Color,
ClockRange,
JulianDate,
} from 'cesium'
import { onMounted, onBeforeUnmount } from 'vue'
let viewer: CesiumViewer
onMounted(() => {
// 初始化
viewer = new CesiumViewer('cesiumContainer', {
animation: false,
timeline: true,
creditText: 'My App',
defaultView: { west: 110, south: 20, east: 130, north: 40 },
})
// 设置时钟
viewer.setClock({
startTime: '2024-01-01T00:00:00Z',
stopTime: '2024-01-01T12:00:00Z',
currentTime: '2024-01-01T00:00:00Z',
clockRange: ClockRange.LOOP_STOP,
multiplier: 120,
})
// 添加 Entity
viewer.addEntity({
id: 'marker',
position: Cartesian3.fromDegrees(116.39, 39.91, 500),
point: {
pixelSize: 10,
color: Color.YELLOW,
},
label: {
text: '北京',
font: '14px sans-serif',
fillColor: Color.WHITE,
},
})
})
onBeforeUnmount(() => {
viewer?.destroy()
})相关指南
- 快速开始 — 从零搭建第一个三维场景
- 相机控制 — 飞行漫游与视角锁定
- 实体管理 — CombatEntity 组件体系
- 底图与地形 — BaseMapManager / TerrainManager