Skip to content

图层管理

图层系统是三维场景组织地理数据的核心机制。本章介绍 LayerManagerGeoJsonLayerHeatmapLayerHexGrid 四个图层相关的模块。


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'ImageryLayerItemImageryLayer
'dataSource'DataSourceLayerItemDataSource
'entity'EntityLayerItemEntity
'primitive'PrimitiveLayerItemPrimitive | 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): () => void
ts
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 | CircleBounds
RectangleBounds
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             // 半径
}

实例属性

属性类型说明
viewerViewerCesium Viewer 实例
optionsRequired<HexGridOptions>当前配置(含默认值填充)
entitiesHexGridEntityCollection生成的六边形实体集合
showboolean当前显隐状态

方法

方法返回说明
generate(bounds)Promise<void>根据边界生成六边形格网。自动校验参数,超出 10000 个时会报错
clear()void清除所有六边形
updateOptions(options)void更新配置(下次 generate 时生效)
toggle()void切换全部六边形显隐

校验规则

  • cellSize 必须大于 0
  • fillOpacity 必须在 [0, 1] 范围内
  • strokeWidth 不能为负数
  • degrees 单位下 cellSize 不超过 50,半径不超过 90
  • kilometers 单位下 cellSize 不超过 5000,半径不超过 20000
  • 矩形边界需要 west < eastsouth < 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)
}