Skip to content

ReverseMaskEffect 反选遮罩(区域聚焦高亮)

把「除指定区域(边界内)外的全球表面」用半透明遮罩覆盖,边界处绘制一条青色高亮轮廓线 —— 反选遮罩 / 区域聚焦高亮。对齐源案例 Scene/BoundarysetBoundary 支持运行时切换高亮区域。


能力定位

ReverseMaskEffect 适合:

  • 态势聚焦:在地图上高亮某个行政/业务区域,其余全部压暗;
  • 规划示意:展示范围/边界时把范围外区域做遮罩强调;
  • 数据质量排查:只关注某个区域,屏蔽无关区域视觉干扰。

与同类能力的分工:

能力API行为
反选遮罩(本类)ReverseMaskEffect全球 4 分块遮罩 polygon + 边界洞 + 可选边界线,区域外全部压暗
3D Tiles 裁剪TilesMultClip对 3D Tileset 挂载垂直裁剪平面挖洞(模型体切割),非地表遮罩

SDK 全库 PolygonHierarchy 此前仅以无 holes 形式使用(militaryPlot/BufferAnalysis/measure 等), 本类是「多边形带洞遮罩 / 反选遮罩 / 区域聚焦高亮」这一垂直能力。

构造函数

ts
constructor(options: ReverseMaskEffectOptions)
ts
interface ReverseMaskEffectOptions {
  boundary: Cartesian3[]          // 高亮区域边界(世界坐标,至少 3 点),必填
  maskColor?: Color               // 遮罩颜色,默认 BLUE.withAlpha(0.5)
  boundaryColor?: Color           // 边界高亮线颜色,默认 AQUA.withAlpha(0.7)
  boundaryWidth?: number          // 边界高亮线宽度(像素),默认 3
  showBoundary?: boolean          // 是否绘制边界高亮线,默认 true
  show?: boolean                  // 是否立即显示遮罩,默认 true
}
参数类型默认值描述
boundaryCartesian3[](必填)高亮区域边界(≥3 点;不允许跨反子午线,跨度 > 180° 抛错)
maskColorColorBLUE.withAlpha(0.5)遮罩颜色
boundaryColorColorAQUA.withAlpha(0.7)边界高亮线颜色
boundaryWidthnumber3边界高亮线宽度(像素)
showBoundarybooleantrue是否绘制边界高亮线
showbooleantrue是否立即显示遮罩

生命周期与操作

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

ts
on(viewer: Viewer): void        // 创建 4 个分块遮罩 polygon(边界所在分块挖洞)+ 可选边界线
setBoundary(boundary: Cartesian3[]): void // 运行时切换高亮区域(重建遮罩洞与边界线)
setShow(show: boolean): void    // 整体显隐遮罩与边界线
off(viewer: Viewer): void       // 移除全部自建实体并释放
destroy(viewer: Viewer): void   // 等价于 off(幂等)

清理完整性:效果只管理自建 entities(4 个遮罩 polygon + 1 条边界 polyline),off/destroyviewer.entities.remove 逐个移除,绝不 removeAll 触碰调用方实体。

基础示例

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

// 高亮区域边界(世界坐标,至少 3 点)
const boundary = [
  Cesium.Cartesian3.fromDegrees(108.5, 31.6),
  Cesium.Cartesian3.fromDegrees(108.5, 28.2),
  Cesium.Cartesian3.fromDegrees(110.2, 28.2),
  Cesium.Cartesian3.fromDegrees(110.2, 31.6),
]

const effect = new ReverseMaskEffect({ boundary })
effect.on(viewer)
// 全球除该矩形区域外全部被蓝色半透明遮罩覆盖,边界一圈青色高亮线

// 运行时切换高亮区域
effect.setBoundary([
  Cesium.Cartesian3.fromDegrees(103.5, 30.2),
  Cesium.Cartesian3.fromDegrees(104.5, 30.2),
  Cesium.Cartesian3.fromDegrees(104.5, 31.1),
  Cesium.Cartesian3.fromDegrees(103.5, 31.1),
])

// 整体隐藏 / 恢复
effect.setShow(false)
effect.setShow(true)

// 页面或场景退出时由创建方负责清理(幂等)
effect.destroy(viewer)

进阶示例

  • 完全关闭边界线new ReverseMaskEffect({ boundary, showBoundary: false }) → 只建 4 个遮罩、0 条线;
  • 自定义配色maskColor: Color.RED.withAlpha(0.4)boundaryColor: Color.YELLOWboundaryWidth: 5
  • 预置显示状态show: false 先隐藏,后续 setShow(true) 再展示。

实现说明

  • 4 分块外环(Cesium 1.133 实测约束):经度跨度 ≥180° 或包围极点(lat ±85)的 polygon 外环 不渲染;因此全球按经度切成 4 个跨度 ≤90° 的分块外环(-180..-90 / -90..0 / 0..90 / 90..180, 纬度 ±60,不包围极点),任一分块都不跨越反子午线;
  • 显式 height: 0 / perPositionHeight: false:Cesium 1.133 默认 ground-clamp 的 polygon 会 破坏洞的渲染(洞区域被填充),强制 height:0 平面后洞正确切出;
  • 分块裁剪挖洞:边界在经度空间表示后,按分块经度区间用 Sutherland-Hodgman 单趟裁剪出洞 (_clipToSlab);边界完全在东 → 仅东侧分块挖洞,完全在西 → 仅西侧,跨本初子午线/±90° → 各分块分别挖段洞;
  • 相邻重复点去重:源码重庆边界含零长边(相邻同坐标),会令洞三角化失败,构造/setBoundary 时自动去重;
  • 边界线抬升 10mBOUNDARY_LINE_HEIGHT = 10,保证描线始终位于 height:0 遮罩面之上;
  • 资源所有权:只管理自建 entities,off/destroy 逐个移除并释放,绝不 removeAll 触碰调用方实体。

清理责任

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

重复调用 destroy/off 安全(未 on 时为空操作)。销毁后重新 on 可再次启用遮罩。 setBoundary/setShow 在未 on 时只记录数据,on 后按最新状态生效。

限制与组合

  • 边界不允许跨反子午线(经度跨度 > 180° 抛错);跨 ±180 的边界请先切分;
  • 跨本初子午线(0°)或 ±90° 分块边界的边界会自动在对应经线切分;
  • 边界相邻点间距需远小于分块跨度(90°):单条边至多跨越一条分块经线;若传入相邻点跨整块 (≥90° 经度差)的异常边界,裁剪结果可能不完整 —— 属超出现实区域边界的边界情况;
  • 遮罩是地表 polygon(height:0 平面),与 TilesMultClip(3D Tiles 模型体裁剪)互不重叠, 可叠加使用;
  • DrawManager 组合可实现鼠标绘制区域后聚焦:drawManager.onDrawComplete(({ positions }) => effect.setBoundary(positions))

Cesium 版本限制

  • 依赖 Cesium 公共 PolygonHierarchy / Cartesian3 / Cartographic / Color
  • 已验证目标版本:Cesium 1.133.1。