Appearance
图层管理
图层系统是三维场景组织地理数据的核心机制。本章介绍 LayerManager、GeoJsonLayer、HeatmapLayer 和 HexGrid 四个图层相关的模块。
LayerManager
概述
LayerManager 是一个泛图层管理器,统一管理四种图层类型:影像图层(Imagery)、数据源(DataSource)、实体(Entity)和图元(Primitive)。支持增删改查、显隐切换、透明度调节、层级排序和事件监听。
构造函数
ts
constructor(options: LayerManagerOptions)ts
interface LayerManagerOptions {
viewer: Cesium.Viewer
}图层类型
ts
type LayerType = 'imagery' | 'dataSource' | 'entity' | 'primitive'各类型对应的运行时条目:
| 类型 | 条目接口 | 底层 Cesium 对象 |
|---|---|---|
'imagery' | ImageryLayerItem | ImageryLayer |
'dataSource' | DataSourceLayerItem | DataSource |
'entity' | EntityLayerItem | Entity |
'primitive' | PrimitiveLayerItem | Primitive | Cesium3DTileset |
BaseLayerItem 基础接口
ts
interface BaseLayerItem {
id: string
name: string
type: LayerType
show: boolean
opacity: number // 0-1
index: number // z-order
}方法
添加图层
| 方法 | 返回 | 说明 |
|---|---|---|
addImageryLayer(provider, name, options?) | ImageryLayerItem | 添加影像图层。options.index 指定层级,options.opacity 指定透明度 |
addDataSource(dataSource, name) | Promise<DataSourceLayerItem> | 添加数据源(支持 Promise) |
addEntity(entity, name) | EntityLayerItem | 添加实体 |
addPrimitive(primitive, name) | PrimitiveLayerItem | 添加图元或 3D Tileset |
删除图层
| 方法 | 返回 | 说明 |
|---|---|---|
removeLayer(id) | boolean | 删除指定图层 |
removeAllLayers() | void | 删除所有图层 |
显示 / 隐藏
| 方法 | 返回 | 说明 |
|---|---|---|
showLayer(id) | void | 显示图层 |
hideLayer(id) | void | 隐藏图层 |
toggleLayer(id) | void | 切换显隐 |
透明度
| 方法 | 返回 | 说明 |
|---|---|---|
setLayerOpacity(id, opacity) | void | 设置透明度 (0-1)。imagery 类型设置 alpha,primitive 类型设置 Cesium3DTileStyle 颜色透明度 |
层级排序
| 方法 | 返回 | 说明 |
|---|---|---|
raiseLayer(id) | void | 上移一层(imagery / primitive 支持) |
lowerLayer(id) | void | 下移一层 |
raiseLayerToTop(id) | void | 移至顶层 |
lowerLayerToBottom(id) | void | 移到底层 |
查询
| 方法 | 返回 | 说明 |
|---|---|---|
getLayer(id) | LayerItem | undefined | 获取指定图层 |
getAllLayers() | LayerItem[] | 获取所有图层 |
getLayersByType(type) | LayerItem[] | 按类型过滤图层 |
事件
ts
on(callback: (event: LayerEvent) => void): () => voidts
type LayerEventType = 'add' | 'remove' | 'show' | 'hide' | 'move' | 'opacity'
interface LayerEvent {
type: LayerEventType
layer: LayerItem
}on() 返回取消订阅函数。也可使用 off(callback) 手动移除监听。
完整示例
ts
import * as Cesium from 'cesium'
import { LayerManager } from '@space-air/gis-cesium'
const lm = new LayerManager({ viewer })
// ---- 添加影像图层 ----
const imageryLayer = lm.addImageryLayer(
new Cesium.UrlTemplateImageryProvider({
url: 'https://example.com/{z}/{x}/{y}.png',
}),
'自定义影像',
{ index: 0, opacity: 0.8 }
)
// ---- 添加数据源 ----
const dataSource = await Cesium.GeoJsonDataSource.load('./data.geojson')
const dsLayer = await lm.addDataSource(dataSource, 'GeoJSON 数据源')
// ---- 添加实体 ----
const entity = new Cesium.Entity({
position: Cesium.Cartesian3.fromDegrees(116.4, 39.9),
point: { pixelSize: 10, color: Cesium.Color.RED },
})
const entityLayer = lm.addEntity(entity, '标记点')
// ---- 添加图元 ----
const primitive = new Cesium.Primitive({
geometryInstances: new Cesium.GeometryInstance({
geometry: new Cesium.BoxGeometry({
dimensions: new Cesium.Cartesian3(1000, 1000, 1000),
}),
}),
appearance: new Cesium.MaterialAppearance(),
})
const primLayer = lm.addPrimitive(primitive, '立方体')
// ---- 显隐控制 ----
lm.hideLayer(entityLayer.id)
lm.showLayer(entityLayer.id)
lm.toggleLayer(imageryLayer.id)
// ---- 透明度 ----
lm.setLayerOpacity(imageryLayer.id, 0.5)
// ---- 排序 ----
lm.raiseLayerToTop(primLayer.id)
// ---- 事件监听 ----
const unsubscribe = lm.on((e) => {
console.log(`图层事件: ${e.type}, 图层: ${e.layer.name}`)
})
// ---- 查询 ----
const allImagery = lm.getLayersByType('imagery')
const layer = lm.getLayer(imageryLayer.id)
// ---- 删除 ----
lm.removeLayer(entityLayer.id)
lm.removeAllLayers()GeoJsonLayer
概述
GeoJsonLayer 封装了 GeoJsonDataSource 的加载和管理,支持多数据源同时管理,提供样式定制、高亮聚焦、显隐控制等功能。
构造函数
ts
constructor(viewer: Cesium.Viewer)方法
数据加载
| 方法 | 返回 | 说明 |
|---|---|---|
loadFromUrl(url, options?, name?) | Promise<string> | 从 URL 加载 GeoJSON 文件,返回数据源 ID |
loadFromData(data, options?, name?) | Promise<string> | 从 GeoJSON 对象加载,返回数据源 ID |
GeoJsonLoadOptions
ts
interface GeoJsonLoadOptions {
stroke?: Color | string // 描边颜色,默认 WHITE
fill?: Color | string // 填充颜色,默认 TRANSPARENT
strokeWidth?: number // 描边宽度,默认 2
clampToGround?: boolean // 是否贴地,默认 true
markerSymbol?: string // 标记符号,默认 '?'
}颜色支持 Cesium.Color 对象或 CSS 颜色字符串(如 '#ff0000'、'red')。
显示控制
| 方法 | 返回 | 说明 |
|---|---|---|
setVisible(sourceId, visible) | boolean | 设置数据源显隐 |
isVisible(sourceId) | boolean | undefined | 查询显隐状态 |
setOpacity(sourceId, opacity) | boolean | 设置不透明度 (0-1) |
getOpacity(sourceId) | number | undefined | 获取不透明度 |
高亮与聚焦
| 方法 | 返回 | 说明 |
|---|---|---|
highlight(sourceId, color?) | boolean | 高亮数据源(默认黄色),设置描边宽度 4px |
unhighlight() | void | 取消高亮 |
zoomTo(sourceId) | Promise<boolean> | 聚焦到数据源范围 |
数据源管理
| 方法 | 返回 | 说明 |
|---|---|---|
clear() | void | 清除所有数据源 |
remove(sourceId) | boolean | 移除指定数据源 |
getSourceIds() | string[] | 获取所有数据源 ID |
getAllSourceInfo() | SourceInfo[] | 获取所有数据源信息(id / name / visible / opacity) |
getDataSource(sourceId) | GeoJsonDataSource | undefined | 获取原生 Cesium 数据源 |
getSourceName(sourceId) | string | undefined | 获取数据源名称 |
完整示例
ts
import { GeoJsonLayer } from '@space-air/gis-cesium'
import * as Cesium from 'cesium'
const layer = new GeoJsonLayer(viewer)
// ---- 加载 GeoJSON 文件 ----
const id1 = await layer.loadFromUrl(
'/data/china.geo.json',
{
stroke: Cesium.Color.WHITE,
fill: Cesium.Color.fromCssColorString('rgba(0, 100, 200, 0.3)'),
strokeWidth: 2,
clampToGround: true,
},
'中国国界线'
)
// ---- 加载 GeoJSON 对象 ----
const geoJsonData = {
type: 'FeatureCollection',
features: [
{
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [116.4, 39.9],
},
properties: { name: '北京' },
},
],
}
const id2 = await layer.loadFromData(
geoJsonData,
{
markerSymbol: '●',
clampToGround: true,
},
'标记点'
)
// ---- 显隐与透明度 ----
layer.setVisible(id1, false)
layer.setVisible(id1, true)
layer.setOpacity(id1, 0.6)
// ---- 高亮与聚焦 ----
layer.highlight(id2, Cesium.Color.YELLOW)
await layer.zoomTo(id1)
// ---- 查询信息 ----
const allInfo = layer.getAllSourceInfo()
console.log(allInfo)
// [
// { id: 'geojson_0', name: '中国国界线', visible: true, opacity: 0.6 },
// { id: 'geojson_1', name: '标记点', visible: true, opacity: 1.0 },
// ]
// ---- 删除 ----
layer.remove(id2)
layer.clear() // 清除所有HeatmapLayer
概述
HeatmapLayer 基于 cesium-heatmap-es6 实现热力图渲染,支持三种渲染方式:Entity(实体)、Primitive(图元)和 Imagery(影像图层)。提供数据更新、样式修改、半径调节和自动重绘能力。
构造函数
ts
constructor(viewer: Cesium.Viewer)类型定义
HeatmapLayerOptions
ts
interface HeatmapLayerOptions {
points: HeatmapPoint[] // 热力图数据点
renderType?: HeatmapRenderType // 渲染方式,默认 'entity'
dataRange?: HeatmapDataRange // 数据值域范围
style?: HeatmapStyleOptions // 样式配置
zoomToLayer?: boolean // 是否自动定位到热力图范围
disableAutoRedraw?: boolean // 是否禁用相机高度自动重绘
cameraHeightDistance?: number // 触发重绘的相机高度阈值(米),默认 1000
onRadiusChange?: (radius: number) => void // 半径变化回调
}HeatmapPoint
ts
interface HeatmapPoint {
x: number // 经度
y: number // 纬度
value?: number // 权重值
}HeatmapRenderType
ts
type HeatmapRenderType = 'entity' | 'primitive' | 'imagery''entity':使用 Entity 矩形实体渲染,有三维效果,可贴模型'primitive':使用 Primitive 图元,性能较好'imagery':使用SingleTileImageryProvider作为影像图层
HeatmapStyleOptions
ts
interface HeatmapStyleOptions {
backgroundColor?: string // 背景颜色
blur?: number // 模糊因子 (0-1),默认 0.85
gradient?: Record<string, string> // 颜色渐变映射
maxOpacity?: number // 最大不透明度,默认 0.6
minOpacity?: number // 最小不透明度,默认 0.1
opacity?: number // 全局不透明度
radius?: number // 数据点半径(像素),默认 15
}HeatmapDataRange
ts
interface HeatmapDataRange {
max?: number
min?: number
}方法
| 方法 | 返回 | 说明 |
|---|---|---|
add(options) | void | 添加热力图图层。如已添加则先移除再重建 |
remove() | void | 移除热力图图层 |
updatePoints(points) | void | 更新数据点(重建热力图) |
updateStyle(style) | void | 更新样式配置(实时生效) |
updateDataRange(dataRange) | void | 更新数据值域范围 |
updateRadius(radius) | void | 更新数据点半径 |
show() | void | 显示热力图 |
hide() | void | 隐藏热力图 |
toggle() | void | 切换显隐 |
getState() | HeatmapLayerState | 获取当前状态 |
getOptions() | HeatmapLayerOptions | 获取当前配置 |
完整示例
ts
import { HeatmapLayer } from '@space-air/gis-cesium'
const heatmap = new HeatmapLayer(viewer)
// ---- 基本用法 ----
heatmap.add({
points: [
{ x: 116.4, y: 39.9, value: 80 }, // 北京
{ x: 121.5, y: 31.2, value: 95 }, // 上海
{ x: 113.3, y: 23.1, value: 70 }, // 广州
{ x: 114.1, y: 22.5, value: 65 }, // 深圳
{ x: 120.2, y: 30.2, value: 60 }, // 杭州
],
renderType: 'entity',
style: {
radius: 20,
gradient: {
'.3': 'blue',
'.5': 'green',
'.7': 'yellow',
'.95': 'red',
},
},
zoomToLayer: true,
})
// ---- 更新数据 ----
heatmap.updatePoints([
{ x: 116.4, y: 39.9, value: 90 },
{ x: 121.5, y: 31.2, value: 50 },
])
// ---- 更新样式 ----
heatmap.updateStyle({ radius: 25, maxOpacity: 0.8 })
// ---- 更新值域 ----
heatmap.updateDataRange({ min: 0, max: 200 })
// ---- 更新半径 ----
heatmap.updateRadius(30)
// ---- 显隐控制 ----
heatmap.hide()
heatmap.show()
heatmap.toggle()
// ---- 查询状态 ----
const state = heatmap.getState()
console.log(state) // { added: true, visible: true, pointCount: 5 }
// ---- 不同渲染方式对比 ----
// 方式一:Entity 渲染(有三维效果)
heatmap.add({
points: data,
renderType: 'entity',
style: { radius: 15 },
})
// 方式二:Primitive 渲染(性能较好)
heatmap.add({
points: data,
renderType: 'primitive',
style: { radius: 15 },
})
// 方式三:Imagery 渲染(影像图层方式)
heatmap.add({
points: data,
renderType: 'imagery',
style: { radius: 15 },
})
// ---- 移除 ----
heatmap.remove()HexGrid
概述
HexGrid 基于 Turf.js 实现六边形格网生成,支持矩形范围和圆形范围两种边界模式,可自定义格网大小、颜色、透明度等样式。
构造函数
ts
constructor(viewer: Cesium.Viewer, options?: HexGridOptions)HexGridOptions
ts
interface HexGridOptions {
cellSize?: number // 六边形边长,默认 1
unit?: 'degrees' | 'kilometers' // 单位,默认 'degrees'
fillColor?: string // 填充颜色,默认 '#4A90D9'
fillOpacity?: number // 填充透明度 (0-1),默认 0.5
strokeColor?: string // 描边颜色,默认 '#FFFFFF'
strokeWidth?: number // 描边宽度,默认 1
clampToGround?: boolean // 是否贴地,默认 true
height?: number // 高度(clampToGround=false 时有效),默认 0
}HexGridBounds
ts
type HexGridBounds = RectangleBounds | CircleBoundsRectangleBounds
ts
interface RectangleBounds {
type: 'rectangle'
west: number // 西经(-180 ~ 180)
south: number // 南纬(-90 ~ 90)
east: number // 东经(-180 ~ 180)
north: number // 北纬(-90 ~ 90)
}CircleBounds
ts
interface CircleBounds {
type: 'circle'
center: [number, number] // [经度, 纬度]
radius: number // 半径
}实例属性
| 属性 | 类型 | 说明 |
|---|---|---|
viewer | Viewer | Cesium Viewer 实例 |
options | Required<HexGridOptions> | 当前配置(含默认值填充) |
entities | HexGridEntityCollection | 生成的六边形实体集合 |
show | boolean | 当前显隐状态 |
方法
| 方法 | 返回 | 说明 |
|---|---|---|
generate(bounds) | Promise<void> | 根据边界生成六边形格网。自动校验参数,超出 10000 个时会报错 |
clear() | void | 清除所有六边形 |
updateOptions(options) | void | 更新配置(下次 generate 时生效) |
toggle() | void | 切换全部六边形显隐 |
校验规则
cellSize必须大于 0fillOpacity必须在[0, 1]范围内strokeWidth不能为负数degrees单位下cellSize不超过 50,半径不超过 90kilometers单位下cellSize不超过 5000,半径不超过 20000- 矩形边界需要
west < east、south < north,坐标在有效范围内 - 预计生成超过 10000 个六边形时会抛出错误
完整示例
ts
import { HexGrid } from '@space-air/gis-cesium'
// ---- 矩形范围六边形格网 ----
const grid = new HexGrid(viewer, {
cellSize: 2,
unit: 'degrees',
fillColor: '#4A90D9',
fillOpacity: 0.4,
strokeColor: '#FFFFFF',
strokeWidth: 1,
clampToGround: true,
})
await grid.generate({
type: 'rectangle',
west: 110,
south: 20,
east: 122,
north: 42,
})
// ---- 圆形范围六边形格网 ----
const circleGrid = new HexGrid(viewer, {
cellSize: 5,
unit: 'kilometers',
fillColor: '#FF6B6B',
fillOpacity: 0.3,
})
await circleGrid.generate({
type: 'circle',
center: [116.4, 39.9],
radius: 50,
})
// ---- 切换显隐 ----
grid.toggle()
// ---- 更新配置 ----
grid.updateOptions({
cellSize: 1,
fillOpacity: 0.6,
})
// 重新应用配置生成
await grid.generate({
type: 'rectangle',
west: 110,
south: 20,
east: 122,
north: 42,
})
// ---- 清理 ----
grid.clear()
// ---- 错误处理 ----
try {
await grid.generate({
type: 'rectangle',
west: 110,
south: 20,
east: 111,
north: 21,
})
} catch (e) {
console.error('格网生成失败:', e.message)
}