Skip to content

多字段自适应监控弹窗

该组合案例演示统一装备接口、Viewer 内建选择事件和 PopupManager.addFields 的协作方式:监控装备拥有业务身份,PopupManager 只负责安全展示与屏幕定位。

能力分层

职责API
创建、查询和销毁监控装备viewerEntityMixinviewer.createEntityviewer.entityManager
点击后的实体选择状态viewer.selectedEntityChanged
结构化字段安全渲染PopupManager.addFields
屏幕跟随、遮挡和高度显隐PopupManager
页面退出清理Viewer 销毁钩子、PopupManager.destroy()

创建监控装备

typescript
import {
  CesiumViewer,
  PopupManager,
  viewerEntityMixin,
} from '@nexa/gis-cesium'

const nexaGis = new CesiumViewer('container', { infoBox: false })
const viewer = nexaGis.viewer
nexaGis.extend(viewerEntityMixin)

const monitor = viewer.createEntity({
  id: 'monitor-01',
  name: '路口监控',
  entityType: 'other',
  components: [
    { id: 'position', type: 'PositionComponent', lon: 106.4569, lat: 29.5049, alt: 10 },
    { id: 'billboard', type: 'BillboardComponent', url: '/monitor.svg', scale: 0.6 },
  ],
  modules: [],
})

不要绕过装备入口直接 viewer.entities.add 创建具有业务身份的监控点。场景装饰或无业务身份的夹具才由案例自行创建和精确清理。

选中后显示字段

业务数据放在应用状态中,以公开 Entity ID 关联;无需给 raw Entity 写入私有 info 字段。

typescript
const popupManager = new PopupManager(viewer)
const monitorData = new Map([
  ['monitor-01', {
    name: '路口监控',
    ip: '42.23.33.23',
    type: '固定枪机',
    state: '在线',
  }],
])

let activePopup
const removeSelectedListener = viewer.selectedEntityChanged.addEventListener(entity => {
  activePopup?.close()
  const data = entity ? monitorData.get(entity.id) : undefined
  const position = entity?.position?.getValue(viewer.clock.currentTime)
  if (!data || !position) return

  activePopup = popupManager.addFields({
    position,
    title: '监控信息',
    fields: [
      { label: '监控名称', value: data.name },
      { label: 'IP 地址', value: data.ip },
      { label: '监控类型', value: data.type },
      { label: '监控状态', value: data.state },
    ],
    anchor: 'top',
    cameraHeightRange: { maximum: 4000 },
  })
})

addFields 使用 textContent 写入字段名和值,即使接口返回 <img onerror=...> 也只会作为普通文本显示。它适合字段数量、标签长度和值长度均不固定的设备信息。

完整清理

typescript
nexaGis.extend(() => () => {
  removeSelectedListener()
  activePopup?.close()
  popupManager.destroy()
})

viewerEntityMixin 的销毁钩子负责回收监控装备;案例自己的钩子负责选择监听和 Popup DOM。不要调用 viewer.entities.removeAll() 清理不属于当前功能的实体,也不要直接销毁由外层托管的 raw Viewer。