Appearance
PointPrimitivesEffect 批量图标点(可选文字标注)
用
BillboardCollection(Primitive)批量渲染大量图标点(数千~数万级),对齐源案例 PointObject/PointPrimitives。传入labels时并行创建LabelCollection,同一批位置上 渲染「图标点 + 文字标注」组合,对齐源案例 PointObject/LabelBillboardCol。单集合单次 绘制调用,性能远优于逐 Entity 挂载。
能力定位
PointPrimitivesEffect 适合:
- 海量点位展示:态势显示、传感器轨迹、设备/点位标注等需要同时呈现数千以上图标点的场景;
- 图标 + 文字组合:点位同时需要文字标注时(地图 POI、设备清单),
labels让文字与图标 在同一批位置上 1:1 对齐渲染,无需逐 Entity 挂载; - 整批动态更新:
setPositions一次替换全部点位、setShow整体显隐,不逐点操作; - 性能敏感图层:Entity 语义(
AnimatePointEffect单点、ClusterLayer聚合)不覆盖 「Primitive 批量渲染」这一面,本效果按 SDK「大量同类目标优先使用 Primitive」约定封装。
与 点位聚合 的区别:聚合是 Entity 语义的分组聚类;本效果是 Primitive 集合的批量渲染,图标独立、不做聚类,性能目标不同。
纯图标 vs 图标+文字
- 纯图标:不传
labels,只创建BillboardCollection(原行为,向后兼容); - 图标 + 文字:传
labels(长度与positions一致),并行创建BillboardCollection与LabelCollection,逐点 1:1 对齐。setPositions/setShow/off同步管理两个集合。
构造函数
ts
constructor(options: PointPrimitivesEffectOptions)ts
interface PointPrimitivesEffectOptions {
positions: Cartesian3[]; // 点位置(世界坐标),至少 1 个点,必填
image: string; // 图标(URL / DataURL / Canvas),必填
width?: number; // 图标宽度(像素),默认取图标原始宽度
height?: number; // 图标高度(像素),默认取图标原始宽度
verticalOrigin?: VerticalOrigin; // 垂直对齐,默认 VerticalOrigin.BOTTOM
scale?: number; // 图标缩放比例,默认 1
show?: boolean; // 是否显示全部图标,默认 true
labels?: PointPrimitivesLabelOptions[]; // 可选文字标注,长度与 positions 一致
}| 参数 | 类型 | 默认值 | 描述 |
|---|---|---|---|
positions | Cartesian3[] | — | 点位列表,空数组构造抛错 |
image | string | — | 图标地址,支持网络 URL / dataURL / Canvas 转 dataURL |
width / height | number | 图标原始尺寸 | 显式设置时写入 billboard,否则按图片原始尺寸(对齐源案例) |
verticalOrigin | VerticalOrigin | BOTTOM | 对齐源案例 monitor.png 的底部对齐 |
scale | number | 1 | 整体缩放 |
show | boolean | true | 是否显示全部图标 |
labels | PointPrimitivesLabelOptions[] | 无 | 每点一个文字,长度必须与 positions 一致(不一致抛错) |
ts
interface PointPrimitivesLabelOptions {
text: string; // 标注文字,必填
font?: string; // 字体,默认 'normal 24px sans-serif'
fillColor?: Color; // 填充色,默认 Color.WHITE
outlineColor?: Color; // 描边色,默认 Color.BLACK
outlineWidth?: number; // 描边宽度,默认 2
pixelOffset?: Cartesian2; // 文字相对图标的像素偏移,默认 (14, -4)(对齐源案例)
style?: LabelStyle; // 文字样式,默认 LabelStyle.FILL_AND_OUTLINE
verticalOrigin?: VerticalOrigin; // 垂直对齐,默认 BOTTOM
scale?: number; // 文字缩放,默认 1
}| 参数 | 类型 | 默认值 | 描述 |
|---|---|---|---|
text | string | — | 标注文字,为空抛错 |
font | string | 'normal 24px sans-serif' | 字体 |
fillColor | Color | Color.WHITE | 填充色 |
outlineColor | Color | Color.BLACK | 描边色 |
outlineWidth | number | 2 | 描边宽度 |
pixelOffset | Cartesian2 | (14, -4) | 文字偏移到图标右上(对齐源案例) |
style | LabelStyle | FILL_AND_OUTLINE | 文字样式 |
verticalOrigin | VerticalOrigin | BOTTOM | 垂直对齐 |
scale | number | 1 | 文字缩放 |
生命周期
ts
on(viewer: Viewer): void // 启用:创建 BillboardCollection(与可选 LabelCollection)并批量添加(幂等)
off(viewer: Viewer): void // 停用:从 scene.primitives 移除自建集合(图标/文字)并释放(幂等)
destroy(viewer: Viewer): void // 销毁,委托 off(可重复调用)
setPositions(positions: Cartesian3[]): void // 运行时整批替换点位(图标+文字同步重建;长度须与 labels 一致)
setShow(show: boolean): void // 整体显隐切换(同步图标与文字)| 方法 | 参数 | 说明 |
|---|---|---|
on | viewer | 重复调用为 no-op,不会重复创建集合 |
off | viewer | 未启用时调用为 no-op;只移除自建集合,不触碰调用方 entities |
destroy | viewer | 委托 off,重复调用安全 |
setPositions | positions | 传非数组抛错;带 labels 时长度不匹配抛错;未启用时仅记录数据,on 后按新点位生效 |
setShow | show | 未启用时仅记录状态,on 后生效 |
基础示例
ts
import { PointPrimitivesEffect } from '@nexa/gis-cesium'
import { Cartesian3, VerticalOrigin } from 'cesium'
// 2 万个点位(示例用确定性随机生成,不依赖 turf)
const positions = Array.from({ length: 20000 }, () =>
Cartesian3.fromDegrees(73 + Math.random() * 62, 20 + Math.random() * 20, 0)
)
const effect = new PointPrimitivesEffect({
positions,
image: '/static/images/effects/monitor.png',
width: 24,
height: 24,
verticalOrigin: VerticalOrigin.BOTTOM,
})
effect.on(viewer)
// 页面或场景退出时由创建方负责清理
effect.destroy(viewer)进阶示例
图标 + 文字组合、整批替换 + 整体显隐:
ts
import { PointPrimitivesEffect } from '@nexa/gis-cesium'
import { Cartesian2, Cartesian3, Color, LabelStyle, VerticalOrigin } from 'cesium'
// 点位与其文字标注一一对应(长度必须一致)
const positions = [/* ...Cartesian3[] 点位 */]
const labels = positions.map((_, i) => ({
text: `POI-${i}`,
font: 'normal 20px sans-serif',
fillColor: Color.WHITE,
outlineColor: Color.BLACK,
outlineWidth: 3,
pixelOffset: new Cartesian2(14, -4), // 文字偏移到图标右上,对齐源案例
style: LabelStyle.FILL_AND_OUTLINE,
verticalOrigin: VerticalOrigin.BOTTOM,
}))
const effect = new PointPrimitivesEffect({
positions,
image: '/static/images/effects/monitor.png',
width: 24,
height: 24,
labels,
})
effect.on(viewer)
// 8 秒后整批替换点位(图标+文字同步重建;数量需与 labels 一致,否则抛错)
setTimeout(() => effect.setPositions(nextPositions), 8000)
// 12 秒后整体隐藏,14 秒后恢复
setTimeout(() => effect.setShow(false), 12000)
setTimeout(() => effect.setShow(true), 14000)
// 场景退出时统一清理
effect.destroy(viewer)实现与性能说明
- Primitive 集合渲染:所有图标挂到同一个
BillboardCollection(加入scene.primitives), 传入labels时文字挂到并行LabelCollection,单次绘制调用提交整批,避免逐 Entity 的 渲染状态开销; - 图标与文字逐点对齐:
labels[i]与positions[i]一一对应,构造时校验长度一致 (不一致抛错),防止文字错位; - 整批更新:
setPositions走removeAll+ 重建(图标与文字同步),适合低频整批替换; 高频增量增删点不在本效果目标内; - 资源所有权:集合由本效果创建并持有,
off/destroy从scene.primitives移除并释放, 幂等安全;不触碰调用方entities; - 数据源:点位与文字由调用方提供,不内置数据、不依赖 turf 等第三方。
Cesium 版本限制
- 依赖
BillboardCollection/LabelCollection/Label/Billboard/VerticalOrigin/LabelStyle,均为 Cesium 长期稳定公共 API; - 已验证目标版本:Cesium 1.133.1。
清理责任
on()创建的BillboardCollection与LabelCollection统一由destroy(viewer)(或off(viewer))释放;- 不调用
destroy会残留集合,务必在页面或场景退出时清理; destroy可重复调用,幂等安全;off后可再次on重新启用。
与原生 Cesium API 的组合方式
positions可直接复用viewer.entities中已有点位或绘制工具产出的Cartesian3[];- 图标
image可传任意静态资源 URL 或运行时 Canvas 生成的 dataURL; - 需要按距离缩放图标/文字时,可在
labels之外叠加LabelCollection的scaleByDistance/distanceDisplayCondition配置(本效果保持最小封装,不覆盖)。