唯杰地图 logo唯杰地图
VJMAP
EN

区域编辑 / 图层编辑

vjcad/references/tile/edit-area-layer.md 7.5 KB172 行
原文

文档:vjcad/doc/tile/tile-mode.md 示例:

  • vjcad/example/tile/02editarea.js — 区域编辑
  • vjcad/example/tile/03editlayer.js — 图层编辑

进入瓦片模式后,默认只读。要修改图纸有两种方式:

  1. 区域编辑:拉一个矩形(editArea),把范围内实体加载进矢量层
  2. 图层编辑:选定若干图层,意图只加载这些图层的实体——但 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] 数组也不是 Point2D
  • loadEditLayers 在 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 — 图层编辑