Skip to content

CameraBoundary 相机边界约束

以球心 + 半径定义相机可视边界:每次相机移动结束检查与球心的距离,越界自动 flyTo 回拉至 最后一次合法视角(默认同步绘制半透明边界椭球作可视化提示)。


能力定位

CameraBoundary 适合:

  • 视域约束:限定用户在某区域(雷达站 / 监测点 / 项目地)内观察,防止视角漂移到界外;
  • 导览模式:演示、巡览场景下把相机锁定在一个范围里;
  • 越界观测:通过 onOutOfBounds 回调感知越界距离,做提示或记录。

cameraControl 插件的定位不同:viewer.cameraControl 负责飞行、跟随、锁定视角等主动 操控;CameraBoundary 负责被动约束——不干预用户操作,仅在越界时把相机拉回。二者可组合使用。

构造函数

ts
constructor(options: CameraBoundaryOptions)
ts
interface CameraBoundaryOptions {
  center: Cartesian3                        // 必填:边界球心(建议 fromDegrees(lon, lat, height))
  radius: number                            // 必填:边界半径(米)
  showBoundary?: boolean                    // 是否绘制边界椭球,默认 true
  boundaryColor?: Color                     // 填充色,默认 半透明红(对齐源案例)
  outlineColor?: Color                      // 描边色,默认 水蓝(对齐源案例)
  flyDuration?: number                      // 越界回拉飞行时长(秒),默认 1
  initialView?: { destination; orientation }// 初始/回拉目标视角;缺省取 on() 时相机当前状态
  onOutOfBounds?: (distance: number) => void// 越界回调,distance 为越界时相机到球心距离(米)
}
参数类型默认值描述
centerCartesian3(必填)边界球心
radiusnumber(必填)边界半径(米),超过即判定越界
showBoundarybooleantrue是否绘制半透明边界椭球
boundaryColorColorRED.withAlpha(0.1)边界椭球填充色
outlineColorColorAQUA边界椭球描边色
flyDurationnumber1越界回拉飞行时长(秒)
initialViewCameraBoundaryView当前相机状态初始/回拉目标视角,须在界内
onOutOfBounds(distance) => void越界回调

注意:若 initialView 缺省,取 on() 时的相机当前状态作为首次回拉目标——此时相机须已在 界内,否则首次越界会回拉到界外视角。建议明确传入一个界内 initialView

生命周期

实现 Lifecycle<Viewer> 契约,on/off/destroy 均幂等:

ts
on(viewer: Viewer): void      // 记录初始视角 + 绘制边界椭球 + 订阅 camera.moveEnd
off(viewer: Viewer): void     // 移除 moveEnd 监听 + 移除自有边界椭球
destroy(viewer: Viewer): void // 等价于 off

清理完整性:本类只拥有自身创建的边界椭球实体与 moveEnd 监听器,off/destroy 一并移除, 不触碰调用方其他实体(对齐 ClusterLayer 的资源所有权约定)。

基础示例

ts
import { CameraBoundary } from '@nexa/gis-cesium'

const boundary = new CameraBoundary({
  center: Cesium.Cartesian3.fromDegrees(108, 25, 0),
  radius: 2000, // 米
  initialView: {
    destination: Cesium.Cartesian3.fromDegrees(108, 25, 500),
    orientation: { heading: 0, pitch: Cesium.Math.toRadians(-35), roll: 0 },
  },
})
boundary.on(viewer)

// 页面或场景退出时统一销毁(幂等)
boundary.destroy(viewer)

进阶示例

越界观测 + 关闭边界可视化 + 自定义回拉时长:

ts
import { CameraBoundary } from '@nexa/gis-cesium'

const boundary = new CameraBoundary({
  center: Cesium.Cartesian3.fromDegrees(116.4, 39.9, 0),
  radius: 5000,
  flyDuration: 2, // 更柔和的回拉
  showBoundary: false, // 只约束,不画边界球
  onOutOfBounds: (distance) => {
    console.warn(`越界 ${Math.round(distance)}m,正在回拉`)
  },
})
boundary.on(viewer)

实现说明

  • 越界判定camera.moveEnd 事件触发时计算 Cartesian3.distance(camera.position, center), 超过 radius 即回拉至 lastValidView(最近一次界内的相机位置 + 姿态角);界内移动则更新 lastValidView,保证回拉目标是用户最后一次合法视角。
  • 边界可视化EllipsoidGraphics 半透明椭球(maximumCone 90°,subdivisions 128, 对齐源案例边界样式),资源由本类创建与移除。
  • 资源所有权:本类只拥有自身创建的边界椭球实体与 moveEnd 监听器,不触碰调用方实体。
  • 无外部依赖:源案例的底图 URL(appConfig.imageryProvider)与 pickCamera 调试按钮 (非核心行为)迁移时剥离。

清理责任

ts
boundary.destroy(viewer) // 或 boundary.off(viewer),等价且幂等

重复调用 destroy/off 安全(未 on 时为空操作)。销毁后重新 on 可再次启用约束。

Cesium 版本限制

  • 依赖 Cesium 公共 Camera.moveEnd 事件与 Camera.flyTo
  • 已验证目标版本:Cesium 1.133.1。