Appearance
底图与地形管理
底图(BaseMap)和地形(Terrain)是三维地理场景的两大基础设施。BaseMapManager 管理 Cesium 的 ImageryLayerCollection,支持多底图叠加、排序、透明度调节和场景持久化;TerrainManager 管理 terrainProvider,支持预设地形和自定义地形服务切换。
BaseMapManager
概述
BaseMapManager 封装了对 viewer.imageryLayers 的操作,提供底图的增删改查、显示隐藏、透明度调节、层级排序以及事件通知能力。
构造函数
ts
constructor(viewer: Cesium.Viewer, options?: BaseMapManagerOptions)| 参数 | 类型 | 说明 |
|---|---|---|
viewer | Cesium.Viewer | Cesium Viewer 实例 |
options.initialBaseMap | BaseMapAddConfig | (可选)初始化时自动添加的默认底图 |
类型定义
BaseMapAddConfig
ts
interface BaseMapAddConfig {
name: string // 底图名称
config: BaseLayerConfig // 底图配置
token?: string // API Token(天地图等需要)
opacity?: number // 初始透明度 (0-1)
index?: number // 插入层级位置
}BaseLayerConfig 可以是预设类型字符串或自定义配置对象:
- 预设类型:
'osm'|'openstreetmap'|'gaode'|'gaode-img'|'gaode-vec'|'none' - 自定义类型对象:
ts
interface CustomBaseLayerConfig {
type: 'xyz' | 'wms' | 'arcgis' | 'single'
url: string
layers?: string // WMS 图层名称
maximumLevel?: number
minimumLevel?: number
tileWidth?: number
tileHeight?: number
subdomains?: string[]
credit?: string
[key: string]: any
}BaseMapItem(运行时状态)
ts
interface BaseMapItem {
id: string
name: string
type: 'preset' | 'custom'
config: PresetBaseLayerType | CustomBaseLayerConfig
opacity: number // 透明度 (0-1)
visible: boolean // 是否可见
index: number // 层级位置
imageryLayer: ImageryLayer // 原生 Cesium 图层
provider: ImageryProvider // 原生 Cesium Provider
}BaseMapSnapshot(可序列化快照)
ts
interface BaseMapSnapshot {
id: string
name: string
type: 'preset' | 'custom'
config: PresetBaseLayerType | CustomBaseLayerConfig
opacity: number
visible: boolean
index: number
}方法
底图操作
| 方法 | 返回 | 说明 |
|---|---|---|
addBaseMap(config) | Promise<BaseMapItem> | 添加底图 |
removeBaseMap(id) | boolean | 删除指定底图 |
removeAll() | void | 删除所有底图 |
查询
| 方法 | 返回 | 说明 |
|---|---|---|
getBaseMap(id) | BaseMapItem | undefined | 获取指定底图 |
getAllBaseMaps() | BaseMapItem[] | 获取所有底图(按层级排序) |
显示 / 隐藏
| 方法 | 返回 | 说明 |
|---|---|---|
show(id) | void | 显示底图 |
hide(id) | void | 隐藏底图 |
toggle(id) | void | 切换显隐 |
透明度
| 方法 | 返回 | 说明 |
|---|---|---|
setOpacity(id, alpha) | void | 设置透明度 (0-1) |
层级排序
| 方法 | 返回 | 说明 |
|---|---|---|
raise(id) | void | 上移一层 |
lower(id) | void | 下移一层 |
raiseToTop(id) | void | 移至顶层 |
lowerToBottom(id) | void | 移到底层 |
moveTo(id, targetIndex) | void | 移动到指定索引 |
场景持久化
| 方法 | 返回 | 说明 |
|---|---|---|
takeSnapshot() | BaseMapSnapshot[] | 导出当前全部底图为可序列化快照 |
restoreFromSnapshot(snapshots) | Promise<void> | 从快照恢复底图(清除现有后重建) |
事件
ts
on(event: 'add' | 'remove' | 'visibility' | 'opacity' | 'order', callback): () => void返回取消订阅函数。回调接收 BaseMapEvent:
ts
interface BaseMapEvent {
type: BaseMapEventType
item: BaseMapItem
previousIndex?: number // type 为 'order' 时携带
}销毁
| 方法 | 返回 | 说明 |
|---|---|---|
destroy() | void | 销毁管理器,移除所有底图并清理事件监听 |
完整示例
ts
import { BaseMapManager } from '@space-air/gis-cesium'
const bm = new BaseMapManager(viewer)
// ---- 添加底图 ----
// 预设底图:OSM
const osm = await bm.addBaseMap({
name: 'OpenStreetMap',
config: 'osm',
opacity: 1.0,
})
// 预设底图:高德影像
const gaode = await bm.addBaseMap({
name: '高德影像',
config: 'gaode-img',
})
// 自定义 XYZ 瓦片
const custom = await bm.addBaseMap({
name: '自定义瓦片',
config: {
type: 'xyz',
url: 'https://example.com/{z}/{x}/{y}.png',
},
})
// 自定义 WMS
const wms = await bm.addBaseMap({
name: 'WMS 服务',
config: {
type: 'wms',
url: 'https://example.com/wms',
layers: 'layer_name',
},
})
// ---- 切换显示 ----
bm.hide(osm.id)
bm.show(osm.id)
bm.toggle(osm.id)
// ---- 透明度 ----
bm.setOpacity(osm.id, 0.5)
// ---- 排序 ----
bm.raiseToTop(gaode.id)
bm.lowerToBottom(osm.id)
bm.moveTo(custom.id, 1) // 移动到索引 1
// ---- 事件监听 ----
const unsubscribe = bm.on('visibility', (e) => {
console.log(`底图 ${e.item.name} 可见性: ${e.item.visible}`)
})
// ---- 场景持久化 ----
// 保存
const snapshot = bm.takeSnapshot()
// 恢复
await bm.restoreFromSnapshot(snapshot)
// ---- 清理 ----
bm.removeAll() // 移除所有底图
bm.destroy() // 销毁管理器TerrainManager
概述
TerrainManager 管理 Cesium Viewer 的 terrainProvider。由于 Cesium 同一时间只能有一个活跃地形,管理器维护地形列表,通过 show(id) 切换不同地形。销毁时恢复默认地形 provider。
构造函数
ts
constructor(viewer: Cesium.Viewer, options?: TerrainManagerOptions)| 参数 | 类型 | 说明 |
|---|---|---|
viewer | Cesium.Viewer | Cesium Viewer 实例 |
options.initialTerrain | TerrainAddConfig | (可选)初始化时自动添加的默认地形 |
类型定义
预设地形类型
ts
type PresetTerrainType = 'cesium-world' | 'none''cesium-world':Cesium World Terrain(基于 Ion Asset ID 1,含地形光照和水面遮罩)'none':使用EllipsoidTerrainProvider(无地形,平滑椭球面)
自定义地形配置
ts
interface CustomTerrainConfig {
type: 'custom-url'
url: string // terrain tileset URL
requestVertexNormals?: boolean // 请求地形光照,默认 true
requestWaterMask?: boolean // 请求水面遮罩,默认 false
}TerrainAddConfig
ts
interface TerrainAddConfig {
name: string
config: PresetTerrainType | CustomTerrainConfig
}TerrainItem
ts
interface TerrainItem {
id: string
name: string
type: 'preset' | 'custom'
config: PresetTerrainType | CustomTerrainConfig
visible: boolean
provider: TerrainProvider
}TerrainSnapshot
ts
interface TerrainSnapshot {
id: string
name: string
type: 'preset' | 'custom'
config: PresetTerrainType | CustomTerrainConfig
visible: boolean
}方法
地形操作
| 方法 | 返回 | 说明 |
|---|---|---|
addTerrain(config, name?) | Promise<TerrainItem> | 添加地形配置。config 可以是 TerrainAddConfig、预设字符串或 CustomTerrainConfig |
removeTerrain(id) | boolean | 删除指定地形。若为当前活跃地形,自动切换到下一个可用地形或回退到默认 provider |
removeAll() | void | 删除所有地形 |
查询
| 方法 | 返回 | 说明 |
|---|---|---|
getTerrain(id) | TerrainItem | undefined | 获取指定地形 |
getAllTerrains() | TerrainItem[] | 获取所有地形 |
getActiveTerrain() | TerrainItem | undefined | 获取当前活跃地形 |
激活 / 切换
| 方法 | 返回 | 说明 |
|---|---|---|
show(id) | void | 激活指定地形(切换 terrainProvider),触发 'switch' 事件 |
场景持久化
| 方法 | 返回 | 说明 |
|---|---|---|
takeSnapshot() | TerrainSnapshot[] | 导出所有地形为可序列化快照 |
restoreFromSnapshot(snapshots) | Promise<void> | 从快照恢复地形 |
事件
ts
on(event: 'add' | 'remove' | 'switch', callback): () => void回调接收 TerrainEvent:
ts
interface TerrainEvent {
type: TerrainEventType
item: TerrainItem
previousItem?: TerrainItem // 'switch' 事件时携带前一个活跃地形
}销毁
| 方法 | 返回 | 说明 |
|---|---|---|
destroy() | void | 销毁管理器,恢复默认 terrain provider,清理所有状态 |
完整示例
ts
import { TerrainManager } from '@space-air/gis-cesium'
const tm = new TerrainManager(viewer)
// ---- 添加地形 ----
// 预设:Cesium World Terrain
const world = await tm.addTerrain({
name: 'Cesium World',
config: 'cesium-world',
})
// 预设:无地形
const none = await tm.addTerrain({
name: '无地形',
config: 'none',
})
// 自定义地形服务
const custom = await tm.addTerrain({
name: '自建地形',
config: {
type: 'custom-url',
url: 'https://example.com/terrain/{z}/{x}/{y}.terrain',
requestVertexNormals: true,
requestWaterMask: true,
},
})
// 快捷方式:传入 config + name 参数
await tm.addTerrain('cesium-world', 'Cesium World Terrain')
await tm.addTerrain({
url: 'https://example.com/terrain/{z}/{x}/{y}.terrain',
requestVertexNormals: true,
})
// ---- 切换地形 ----
tm.show(world.id) // 激活 Cesium World Terrain
// 查询活跃地形
const active = tm.getActiveTerrain()
console.log(active?.name) // "Cesium World"
// ---- 事件监听 ----
const unsubscribe = tm.on('switch', (e) => {
console.log(`地形切换: ${e.previousItem?.name} -> ${e.item.name}`)
})
// ---- 场景持久化 ----
const snapshot = tm.takeSnapshot() // 保存
await tm.restoreFromSnapshot(snapshot) // 恢复
// ---- 清理 ----
tm.removeAll()
tm.destroy()快照 / 恢复模式
BaseMapManager 和 TerrainManager 都支持 takeSnapshot() + restoreFromSnapshot() 模式,方便将场景状态序列化存入文件,之后完整恢复。
ts
// 保存场景
const scene = {
basemaps: bm.takeSnapshot(),
terrains: tm.takeSnapshot(),
}
// 将场景序列化为 JSON 持久化
localStorage.setItem('scene', JSON.stringify(scene))
// 恢复场景
const saved = JSON.parse(localStorage.getItem('scene')!)
await bm.restoreFromSnapshot(saved.basemaps)
await tm.restoreFromSnapshot(saved.terrains)注意:
restoreFromSnapshot会先调用removeAll()清除当前状态,再根据快照重建。TerrainManager恢复时会根据visible字段自动激活地形。