Skip to content

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 一致),并行创建 BillboardCollectionLabelCollection,逐点 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 一致
}
参数类型默认值描述
positionsCartesian3[]点位列表,空数组构造抛错
imagestring图标地址,支持网络 URL / dataURL / Canvas 转 dataURL
width / heightnumber图标原始尺寸显式设置时写入 billboard,否则按图片原始尺寸(对齐源案例)
verticalOriginVerticalOriginBOTTOM对齐源案例 monitor.png 的底部对齐
scalenumber1整体缩放
showbooleantrue是否显示全部图标
labelsPointPrimitivesLabelOptions[]每点一个文字,长度必须与 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
}
参数类型默认值描述
textstring标注文字,为空抛错
fontstring'normal 24px sans-serif'字体
fillColorColorColor.WHITE填充色
outlineColorColorColor.BLACK描边色
outlineWidthnumber2描边宽度
pixelOffsetCartesian2(14, -4)文字偏移到图标右上(对齐源案例)
styleLabelStyleFILL_AND_OUTLINE文字样式
verticalOriginVerticalOriginBOTTOM垂直对齐
scalenumber1文字缩放

生命周期

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                // 整体显隐切换(同步图标与文字)
方法参数说明
onviewer重复调用为 no-op,不会重复创建集合
offviewer未启用时调用为 no-op;只移除自建集合,不触碰调用方 entities
destroyviewer委托 off,重复调用安全
setPositionspositions传非数组抛错;带 labels 时长度不匹配抛错;未启用时仅记录数据,on 后按新点位生效
setShowshow未启用时仅记录状态,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] 一一对应,构造时校验长度一致 (不一致抛错),防止文字错位;
  • 整批更新setPositionsremoveAll + 重建(图标与文字同步),适合低频整批替换; 高频增量增删点不在本效果目标内;
  • 资源所有权:集合由本效果创建并持有,off/destroyscene.primitives 移除并释放, 幂等安全;不触碰调用方 entities
  • 数据源:点位与文字由调用方提供,不内置数据、不依赖 turf 等第三方。

Cesium 版本限制

  • 依赖 BillboardCollection / LabelCollection / Label / Billboard / VerticalOrigin / LabelStyle,均为 Cesium 长期稳定公共 API;
  • 已验证目标版本:Cesium 1.133.1。

清理责任

  • on() 创建的 BillboardCollectionLabelCollection 统一由 destroy(viewer)(或 off(viewer))释放;
  • 不调用 destroy 会残留集合,务必在页面或场景退出时清理;
  • destroy 可重复调用,幂等安全;off 后可再次 on 重新启用。

与原生 Cesium API 的组合方式

  • positions 可直接复用 viewer.entities 中已有点位或绘制工具产出的 Cartesian3[]
  • 图标 image 可传任意静态资源 URL 或运行时 Canvas 生成的 dataURL;
  • 需要按距离缩放图标/文字时,可在 labels 之外叠加 LabelCollectionscaleByDistance/distanceDisplayCondition 配置(本效果保持最小封装,不覆盖)。