区域编辑 / 图层编辑
文档:
vjcad/doc/tile/tile-mode.md示例:
vjcad/example/tile/02editarea.js— 区域编辑vjcad/example/tile/03editlayer.js— 图层编辑
进入瓦片模式后,默认只读。要修改图纸有两种方式:
- 区域编辑:拉一个矩形(
editArea),把范围内实体加载进矢量层 - 图层编辑:选定若干图层,意图只加载这些图层的实体——但 vjcad@1.0.16 的
Service.getWebcadData不发送editLayers(只发 clipbounds/editAreas),服务端收不到图层过滤,实际载入的是 整图实体(见第 5 节)
isReadOnly不拦截命令(库内只用于只读标记和QSAVE走另存为),所谓"默认只读"只是瓦片里没有矢量可编辑。
底层接口分别是 TileEditAreaCommand 与 TileEditLayerCommand。
1. 区域编辑
命令方式
await Engine.editor.executerWithOp('TILEEDITAREA');
// 提示用户拉框;确认后自动调 TileEditAreaCommand.loadEditArea
API 方式
class EditTileAreaCommand {
async main() {
// 1. 用户拉框(Engine.getRectangle 不存在;getPoint + getCorner 两点成框)
const p1 = await Engine.getPoint(new PointInputOptions('指定第一角点:'));
if (p1.status !== InputStatusEnum.OK) return;
const p2 = await Engine.getCorner(new CornerInputOptions('指定对角点:', p1.value));
if (p2.status !== InputStatusEnum.OK) return;
const editArea = { // IEditAreaBounds 是 {minX,minY,maxX,maxY} 对象,不是数组
minX: Math.min(p1.value.x, p2.value.x),
minY: Math.min(p1.value.y, p2.value.y),
maxX: Math.max(p1.value.x, p2.value.x),
maxY: Math.max(p1.value.y, p2.value.y)
};
// 2. 调入矢量层
const drawingManager = new DrawingManagerService();
const loadResult = await TileEditAreaCommand.loadEditArea(
editArea,
Engine.currentDoc.serverSource, // 来自 open 阶段
Engine.pcanvas,
Engine.currentDoc,
drawingManager
);
if (loadResult.success) {
Engine.currentDoc.isReadOnly = false;
message.success(`加载 ${loadResult.loadedCount} 个实体到编辑区`);
} else {
message.error('加载失败:' + loadResult.error);
}
}
}
完整代码:
vjcad/example/tile/02editarea.js
loadEditArea 之后:
- 矩形内的实体进入
Engine.currentDoc,可正常MOVE / COPY / ERASE等 - 矩形外仍是瓦片图,且 该矩形对应的瓦片会自动被 mask 挡住,避免和矢量重合
- 编辑结束用
SAVESERVER把改动作为新 patch 保存到服务端(QSAVE只下载本地.vcad;无 TILESAVE 命令,见第 4 节)
2. 图层编辑
命令方式
await Engine.editor.executerWithOp('TILEEDITLAYER');
// 弹出图层多选框,选定后自动加载
API 方式
class EditTileLayerCommand {
async main() {
const drawingManager = new DrawingManagerService();
// 1. 拿图层列表(签名是 (mapid, version?),不是 serverSource 对象)
const src = Engine.currentDoc.serverSource;
const layerList = await TileEditLayerCommand.getLayerListFromService(
src.mapid, src.version
);
// layerList: ILayerInfo[] = [{ name, color?, selected? }] —— 注意是 selected 不是 on
// 2. 让用户选 / 你自定义筛选
const selected = layerList.filter(l => l.name.includes('管线'))
.map(l => l.name);
// 3. 加载图层实体
const result = await TileEditLayerCommand.loadEditLayers(
selected,
Engine.currentDoc.serverSource,
Engine.pcanvas,
Engine.currentDoc,
drawingManager
);
if (result.success) {
Engine.currentDoc.isReadOnly = false;
message.success(`加载图层:${selected.join(', ')}`);
}
}
}
完整代码:
vjcad/example/tile/03editlayer.js
3. 加载结果(loadResult)
两个 API 的返回类型不同,不要混用字段:
// TileEditAreaCommand.loadEditArea → ILoadEditAreaResult
{ success: boolean; error?: string; loadedCount?: number; }
// TileEditAreaCommand.loadEditAreas(批量)→ ILoadEditAreasResult
{ success: boolean; error?: string; totalLoadedCount: number; areasCount: number;
viewInfo?: { lookPt?: [number, number]; zoom?: number }; }
// TileEditLayerCommand.loadEditLayers → ILoadEditLayersResult
{ success: boolean; error?: string; totalLoadedCount: number; layersCount: number;
viewInfo?: { lookPt?: [number, number]; zoom?: number }; }
没有 entityCount / layerNames 字段——取实体数用 loadedCount / totalLoadedCount,图层数用 layersCount。
4. 保存与退出
⚠️ 没有 TILESAVE/TILEEXIT 命令(CommandRegistry 无注册)。瓦片模式下的编辑改动走普通保存/关闭路径:
await Engine.editor.executerWithOp('SAVESERVER'); // 存服务端:生成 patch,serverSource.lastPatchId 更新
// QSAVE 只把当前文档下载为本地 .vcad(只读时转另存为),不会写服务端补丁
// 退出即关闭图纸(如 OPENFROMSERVER 打开的图)
SAVESERVER 会把 editAreas 与瓦片透明度 tileAlpha 随补丁一起记录;之后用 OPENFROMSERVER 的"瓦片打开"重开该补丁时,会自动恢复瓦片透明度,并按记录的编辑区重新载入矢量、加回遮罩(OpenFromServerCommand)。SAVELOCAL / OPENFROMLOCAL 在本地存储里做同样的记录与恢复。OPENFROMSERVER 的图纸浏览器本身还带分支创建/删除、合并(含冲突对话框)、删补丁、删图纸等版本管理入口。
5. 区域 vs 图层 对比
| 维度 | 区域编辑 | 图层编辑 |
|---|---|---|
| 范围 | 用户拉框 | 设计上限于选中图层(1.0.16 实际整图,见下行) |
| 适合场景 | 局部改造(车位、施工细节) | 跨范围属性变更(颜色、可见性) |
| 加载量 | 小 | 大:1.0.16 不发送 editLayers,实际载入整图实体 |
| 是否加遮罩 | 是(背景色矩形挡住该区瓦片) | 否:不遮罩也不替换瓦片,瓦片与矢量会重复显示(可调 setWmsTileAlpha 淡化瓦片) |
红旗
- API 方式加载完毕后建议把
isReadOnly设回false(与命令行为一致)——它不拦截编辑命令,但为true时文档标签显示只读、QSAVE走另存为 editArea是IEditAreaBounds对象{minX, minY, maxX, maxY},不是[x1,y1,x2,y2]数组也不是Point2DloadEditLayers在 1.0.16 不管选了哪些图层都会载入整图实体(editLayers未发往服务端),大图 UI 要加 loading;只想动局部时优先用区域编辑- 多次区域 / 图层编辑是 累积加载:
fromDbPartial追加模式按实体 id 去重,已加载的实体(含未保存的修改)保留不被覆盖,切换区域不会丢改动 TileEditLayerCommand.getLayerListFromService是网络请求,不要在循环里调用
参考(官方文档 MCP)
- 文档:
vjcad/doc/tile/tile-mode.md - 示例:
vjcad/example/tile/02editarea.js— 区域编辑vjcad/example/tile/03editlayer.js— 图层编辑