Appearance
ReverseMaskEffect 反选遮罩(区域聚焦高亮)
把「除指定区域(边界内)外的全球表面」用半透明遮罩覆盖,边界处绘制一条青色高亮轮廓线 —— 反选遮罩 / 区域聚焦高亮。对齐源案例
Scene/Boundary;setBoundary支持运行时切换高亮区域。
能力定位
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
}| 参数 | 类型 | 默认值 | 描述 |
|---|---|---|---|
boundary | Cartesian3[] | (必填) | 高亮区域边界(≥3 点;不允许跨反子午线,跨度 > 180° 抛错) |
maskColor | Color | BLUE.withAlpha(0.5) | 遮罩颜色 |
boundaryColor | Color | AQUA.withAlpha(0.7) | 边界高亮线颜色 |
boundaryWidth | number | 3 | 边界高亮线宽度(像素) |
showBoundary | boolean | true | 是否绘制边界高亮线 |
show | boolean | true | 是否立即显示遮罩 |
生命周期与操作
实现 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/destroy 用 viewer.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.YELLOW、boundaryWidth: 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时自动去重; - 边界线抬升 10m:
BOUNDARY_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。