绘图命令主题 (vjmapext)
本文回答:vjmapext 命令系统总览 —— CommandRegistry / CommandContext、40+ 内置命令、自定义命令、预览 / 快捷键 / Undo。
vjmapext 用命令模式封装所有交互式绘图 / 编辑操作。每条命令是一个独立的异步流程,通过 CommandRegistry 注册、通过 executeCommand(name) 执行。
架构
UI / 快捷键 / 右键菜单
│ mapcadLayer.executeCommand('LINE')
▼
CommandRegistry.execute → CommandClass.main(ctx)
│
┌────────────────────────┼─────────────────────────┐
▼ ▼ ▼ ▼ ▼ ▼
store inputManager eventBus preview gripMgr undoMgr
(实体集) (点/选/数字) (广播) (橡皮筋) (夹点) (撤销)
子项索引
| 文件 | 主题 |
|---|---|
| execute-command | executeCommand / repeatLastCommand / getLastCommandName(commandRegistry 上为 repeatLast/lastCommandName) |
| builtin-draw | LINE/PLINE/POINT/CIRCLE/ARC/ELLIPSE/SPLINE/FREEHAND/RECTPOLY/DLINE/REVCLOUD |
| builtin-edit | MOVE/COPY/ERASE/MIRROR/OFFSET/SCALE/STRETCH/BREAK/TRIM/EXTEND/FILLET/ARRAY/EXPLODE/DRAWORDER |
| input-manager | getPoint / getSelections / getReal / getInteger / getKeyword / getString |
| snap | SnapManager + 10 种捕捉模式(END/MID/CEN/NOD/QUA/INT/INS/PER/TAN/NEA 位标志) |
| grip | 夹点编辑:GripManager / GripPointDef / GripType |
| preview | PreviewManager.setPreviewEntities 橡皮筋实时预览 |
| undo-redo | undoManager.beginTransaction / undo / redo |
| serialize | mapcadLayer.toJSON / fromJSON / DrawingDefaults |
| custom-command | commandRegistry.register:完整自定义命令 |
| shortcuts | setShortcuts / getShortcuts / setModeToggleShortcut(动作→键位映射) |
| mode | setMode('edit'|'browse') / toggleMode |
最小代码
// 打开地图 + 挂 MapCadLayer(官方示例与模板写法)
const map = new vjmap.Map({ container: 'map', ... });
map.attach(svc, prj); // 必须:CoordMapper 靠 map.getMapProjection() 做 CAD↔经纬度
await map.onLoad();
const mapcadLayer = new vjmapext.MapCadLayer();
map.addControl(mapcadLayer); // addControl 即触发 onAdd,无需再等 ready
// 顺序说明:onAdd 内部是 `map.loaded() ? doConnect() : map.on('load', doConnect)`,
// 所以 onLoad 前挂、onLoad 后紧接着挂都可以。⚠️ 风险窗口:onLoad 之后又 await 了别的异步、
// 地图正在加载新瓦片时才 addControl,`map.loaded()` 可能为 false 而 'load' 不会再发
// → doConnect 两路落空,mapcad-* 渲染桶永远不建,实体进 store 但**画面静默不渲染**。
// 已错过时可 `map.fire('load')` 重发事件触发补连(或 removeControl+addControl 重挂)。
// 启动一条 LINE 命令(等用户点击两点后自动落实)
mapcadLayer.executeCommand('LINE');
// 键入其他命令
mapcadLayer.executeCommand('CIRCLE'); // 6 种绘制模式(圆心半径 / 两点 / 三点 / TTR / TTT / 圆心直径)
mapcadLayer.executeCommand('MOVE'); // 选集 → 基点 → 目标点
主题级 Top 5 陷阱
- 多命令互斥:一次只有一条命令在跑;启动新命令会取消旧命令。
- 忘记
ctx.inputManager.cancelCurrentInput:UI 切换时要主动取消,否则留下"半死"命令。 - 以为自定义命令要手动包 undo 事务:不必——
commandRegistry.execute已在main(ctx,opts)外层自动beginTransaction/endTransaction,命令内所有store.add/delete/recordModify天然合并成一条 undo;手动再包只是无害嵌套。 getPoint的message不写关键字提示:用户看不到C/U等可用命令字母(提示字段是message不是prompt)。- 预览完没
clear():预览实体残留在画面上(方法名pm.clear(),不存在clearPreview)。
相关主题
- 事件(command:started/ended / input:started/ended)→ event/bus-command-mode
- 实体写入 → entity/lifecycle
- 右键菜单触发命令 → interaction/context-menu