Appearance
glTF 模型绘制
组合
DrawManager与实体管理插件,在场景中交互选点,并通过viewer.createEntity()创建带 glTF/GLB 模型的装备。
概述
模型绘制不是一套独立的模型 Entity 工厂,而是两项既有公共能力的组合:
DrawManager负责鼠标取点、提示、取消和交互资源清理;viewer.createEntity()负责装备身份、模型组件和生命周期管理。
这种职责分离确保模型装备始终进入 EntityManager,后续可以统一查询、更新、显隐和删除。DrawManager 完成点只是绘图结果,不应作为最终装备保留。
基础用法
typescript
import {
CesiumViewer,
DrawManager,
viewerEntityMixin,
} from '@nexa/gis-cesium'
import { Cartographic, Math as CesiumMath } from 'cesium'
const nexaGis = new CesiumViewer('container')
nexaGis.extend(viewerEntityMixin)
const { viewer } = nexaGis
const drawManager = new DrawManager(viewer)
drawManager.onDrawComplete(({ mode, entity: marker, positions }) => {
// DrawManager 返回的完成点不是装备,由调用方移除。
viewer.entities.remove(marker)
if (mode !== 'point' || !positions[0]) return
const position = Cartographic.fromCartesian(positions[0])
viewer.createEntity({
id: `vehicle-${Date.now()}`,
name: '地面车辆',
entityType: 'vehicle',
components: [
{
id: 'position',
type: 'PositionComponent',
lon: CesiumMath.toDegrees(position.longitude),
lat: CesiumMath.toDegrees(position.latitude),
alt: position.height,
},
{
id: 'model',
type: 'ModelComponent',
url: '/static/GroundVehicle.glb',
scale: 1,
},
],
modules: [],
})
})
drawManager.startDraw('point')多种装备预设
预设只保存装备数据,不直接创建 Cesium Entity。用户选点后,将预设转换为 ScenarioEntity 并交给 createEntity():
typescript
const presets = {
operator: {
name: '操作员',
entityType: 'other',
modelUrl: '/static/Cesium_Man.glb',
scale: 2,
},
vehicle: {
name: '地面车辆',
entityType: 'vehicle',
modelUrl: '/static/GroundVehicle.glb',
scale: 1,
},
}
let selectedPreset = presets.operator
function startPlacement(preset: keyof typeof presets): void {
selectedPreset = presets[preset]
drawManager.cancelDraw()
drawManager.startDraw('point')
}完整案例还演示了四种人员/车辆预设、模型选中轮廓、只清理自身装备,以及把当前部署结果导出为 GeoJSON FeatureCollection。
资源所有权
| 资源 | 所有者 | 清理方式 |
|---|---|---|
| 鼠标事件、Tooltip、临时预览 | DrawManager | drawManager.destroy() |
| 绘制完成点 | 调用方 | 回调中 viewer.entities.remove(marker) |
| 模型装备 | EntityManager | viewer.entityManager.remove(id) 或 Viewer 销毁钩子 |
| 选中事件 | 注册事件的调用方 | 执行 addEventListener() 返回的移除函数 |
| 下载 Object URL | 导出逻辑调用方 | URL.revokeObjectURL(url) |
页面退出时不要调用 viewer.entities.removeAll() 清理装备,因为它可能误删其他模块创建的实体。应保存本功能创建的装备 ID,并逐个交给 EntityManager 删除。
清理
typescript
const removeSelectionListener = viewer.selectedEntityChanged.addEventListener(() => {
// 更新本功能拥有的模型选中状态
})
function destroy(): void {
drawManager.destroy()
removeSelectionListener()
for (const id of ownedEquipmentIds) {
viewer.entityManager.remove(id)
}
ownedEquipmentIds.clear()
}托管式 CesiumViewer 示例应把以上清理接入 Viewer 销毁钩子,确保切换案例或重置场景时不会残留 handler、Tooltip、事件监听或装备。
限制
- 当前组合案例在地球/地形表面取点,不包含 3D Tiles 建筑表面贴附。
- 模型上传、资源库管理以及平移、旋转、缩放编辑属于独立能力,不在模型绘制范围内。
- 模型 URL 的可用性、跨域策略和授权由调用方负责。