Appearance
军事标绘编辑
MilitaryPlotEditor在自有CustomDataSource中提供军标绘制、选择、控制点拖动、整体平移和 GeoJSON 管理。
能力边界
编辑器复用 generateMilitarySymbol 的纯几何算法,不复制军标算法,也不改造通用 DrawManager。
DrawManager适合点、线、普通面和矩形的一次性绘制。MilitaryPlotEditor处理不同军标的固定/最少控制点规则、实时变形、选择柄和持久化。- 军标是地图注记,不是
ScenarioEntity装备。编辑器不会调用viewer.createEntity(),也不会创建或删除任何业务装备。 - 若军标需要关联装备,装备仍须通过
viewer.createEntity()创建,可在军标properties中保存装备 id。
快速开始
ts
import {
MilitaryPlotEditor,
MilitarySymbolType,
} from '@nexa/gis-cesium'
const editor = new MilitaryPlotEditor({
viewer,
onChange: ({ plot, source }) => {
console.log(plot.id, source)
},
})
editor.addPlot({
id: 'attack-01',
name: '进攻方向',
type: MilitarySymbolType.ATTACK_ARROW,
controlPoints: [
[116.39, 39.91],
[116.40, 39.90],
[116.42, 39.91],
],
})
editor.startDraw(MilitarySymbolType.CIRCLE)
// 页面卸载时释放一个 handler、全部编辑柄和自有数据源。
editor.destroy()绘制规则
固定点数类型达到点数后自动完成:
| 点数 | 类型 |
|---|---|
| 2 | 正圆、椭圆、矩形、直箭头、突击方向 |
| 3 | 扇形、集结地 |
| 4 | 钳击 |
可变点数类型使用右键完成:
| 最少点数 | 类型 |
|---|---|
| 2 | 折线、分队战斗、分队战斗尾 |
| 3 | 多边形、曲线面、进攻方向、进攻方向尾 |
右键在控制点不足时取消绘制。拖动过程中右键会回滚到拖动前控制点。
API
MilitaryPlotEditor
| API | 说明 |
|---|---|
plots | 当前编辑器管理的只读军标记录 |
selectedPlot | 当前选中军标 |
isDrawing / isDragging | 当前交互状态 |
addPlot(definition) | 添加军标注记 |
getPlot(id) | 查询军标 |
updatePlot(id, patch) | 原子更新控制点、高度、属性或样式 |
removePlot(id) | 移除一条自有军标 |
clear() | 只清理本编辑器军标 |
startDraw(type, draft?) | 开始绘制 |
cancelDraw() | 取消绘制并清理预览 |
select(id) | 选择军标;传 undefined 取消选择 |
importGeoJson(collection, options?) | 导入源案例兼容 GeoJSON |
exportGeoJson() | 导出控制点 GeoJSON |
enable() / disable() | 幂等启用或禁用交互 |
cancelDrag() | 回滚未提交拖动 |
destroy() | 释放交互和自有数据源 |
MilitaryPlotEditorOptions
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
viewer | Cesium.Viewer | - | Cesium Viewer |
enabled | boolean | true | 是否立即启用 |
dataSourceName | string | military-plot-editor | 自有数据源名称 |
style | MilitaryPlotStyle | 黄色/红色选中 | 默认样式 |
positionPicker | (screen) => Cartesian3 | undefined | 内置三级回退 | 自定义取点策略 |
onSelect | (plot) => void | - | 选择变化回调 |
onChange | (event) => void | - | 数据提交回调 |
默认取点依次使用:
scene.pickPositionSupported && scene.pickPosition();scene.globe.pick(camera.getPickRay());camera.pickEllipsoid()。
全程只使用 Cesium 公共 API。
数据定义
ts
interface MilitaryPlotDefinition {
id?: string
type: MilitarySymbolType
name?: string
controlPoints: readonly Point2D[]
height?: number
properties?: Readonly<Record<string, unknown>>
style?: MilitaryPlotStyle
}控制点统一为 WGS84 [经度, 纬度]。一个军标使用统一椭球高度;整体移动保持所有点之间的经纬差,并将经度归一到 [-180, 180)。
GeoJSON
导出数据保存原始控制点,而不是拟合后的数百个轮廓点,因此可继续编辑:
ts
const collection = editor.exportGeoJson()
const restored = new MilitaryPlotEditor({ viewer })
restored.importGeoJson(collection, { clearExisting: true })Polygon 军标使用 geometry.type = "Polygon",coordinates[0] 是控制点;折线使用 LineString。属性兼容源案例的 plotCode、plotBase、plotType、plotName 与 style.height。
导入会先校验完整集合,再按需清空已有数据;任一要素非法时不会产生部分导入或误清空。
选择与拖动
- 选中军标变为红色。
- 蓝色点编辑单个控制点。
- 红色点整体移动;正圆的红点是圆心,蓝点是半径控制点。
- 拖动时编辑器精确保存并恢复相机旋转、平移、倾斜开关和鼠标样式。
- 松开只触发一次
update;右键、禁用或销毁会回滚未提交拖动。
onChange.source 可为 draw、vertex-drag、move-drag、api 或 import。
所有权与清理
ts
const unrelated = viewer.entities.add({ /* 其他模块实体 */ })
const editor = new MilitaryPlotEditor({ viewer })
editor.clear()
// unrelated 仍存在
editor.destroy()
// 只移除 editor 的 CustomDataSource;Viewer 与业务装备仍存在不要用 viewer.entities.removeAll() 清理案例。编辑器自有数据源异步加入 Viewer 时也处理了立即销毁竞态,不会在卸载后残留数据源。
浏览器验收
- 打开“军事标绘编辑”,确认 6 个内联代表性军标出现,无外部 JSON、图片或远程 3D Tiles 请求。
- 单击黄色符号,确认变红并出现蓝色控制点与红色整体移动点。
- 拖动蓝点,确认轮廓实时重算;拖动红点,确认整体平移且不变形。
- 正圆只显示半径柄和圆心移动柄。
- 分别验证固定点数自动完成、可变点数右键完成、控制点不足右键取消。
- 拖动途中右键取消,确认控制点、相机控制和鼠标样式恢复。
- 导出 GeoJSON,确认控制点数量与当前军标一致。
- 清空后确认其他 Viewer 实体未被删除;离开案例再返回无重复 handler、编辑柄或数据源。
限制
- 逐帧编辑仅重算当前军标;超大
fittingCount仍可能增加拖动开销。 pickPosition可能落在 3D 模型表面。需要固定地面高度时应注入positionPicker。- bbox 中心平移适合一般区域;跨 180° 经线或极区的大跨度军标应由调用方提供更适合的编辑策略。
相关链接
- 军标纯几何生成
- 在示例中心搜索“军事标绘编辑”可直接运行完整案例。