唯杰地图 logo唯杰地图
VJMAP
EN

瓦片模式

vjcad/references/quickref/tile-mode.md 9.4 KB380 行
原文

大型图纸的瓦片方式打开和编辑指南。

概念

瓦片模式 vs 矢量模式

特性 矢量模式 瓦片模式
数据加载 完整加载到前端 按需加载可视区域
适用场景 中小型图纸(<50MB) 大型图纸(数GB)
初始状态 可直接编辑 只读,需选择编辑区域
渲染方式 实时矢量渲染 WMS 瓦片图层
内存占用 与图纸大小相关 固定较低

编辑模式

模式 命令 说明
区域编辑 TILEEDITAREA 选择矩形区域内的实体
图层编辑 TILEEDITLAYER 选择指定图层的所有实体

两种模式是「或」的关系,可以同时使用。


瓦片打开图纸

命令方式

// 打开图纸浏览器,选择「瓦片打开」
await Engine.editor.executerWithOp('OPENFROMSERVER');

API 方式

const { 
    DrawingManagerService, Engine, 
    GeoBounds, Point2D 
} = vjcad;

const drawingManager = new DrawingManagerService();
const service = drawingManager.getService();

const mapid = 'drawing-123';
const version = 'v1';

// 1. 获取图纸元数据
const metadata = await service.metadata(mapid, version);
const bounds = GeoBounds.fromString(metadata.bounds);

// 2. 创建空白文档
Engine.view.newDocument();
Engine.currentDoc.name = `${mapid}_${version}_tile`;

// 3. 配置瓦片图层
const pcanvas = Engine.pcanvas;
const tileConfig = {
    mapid: mapid,
    version: version,
    layers: metadata.styles?.[0]?.layername,
    tileSize: 256,
    maxZoom: 20,
    minZoom: 0,
    transparent: true,
    preloadBuffer: 1,     // 预加载缓冲区
    maxConcurrent: 6,     // 最大并发请求数
    cacheSize: 200        // 缓存大小
};

// 4. 启用 WMS 瓦片图层
pcanvas.enableWmsTileLayer(service, tileConfig);

// 5. 设置视口
const centerX = (bounds.min.x + bounds.max.x) / 2;
const centerY = (bounds.min.y + bounds.max.y) / 2;
const width = bounds.max.x - bounds.min.x;
const height = bounds.max.y - bounds.min.y;

const zoom = Math.min(
    pcanvas.div.clientWidth / width,
    pcanvas.div.clientHeight / height
) * 0.9;

Engine.currentSpace.setZoom(zoom);
Engine.currentSpace.lookPt = new Point2D(centerX * zoom, centerY * zoom);
pcanvas.setCenter(new Point2D(centerX, centerY), true);

// 6. 标记只读(与 OPENFROMSERVER 瓦片打开一致;isReadOnly 只是状态标记,本身不阻止编辑)
Engine.currentDoc.isReadOnly = true;

// 7. 保存来源信息
Engine.currentDoc.serverSource = {
    type: 'imports',
    mapid: mapid,
    version: version,
    branchName: 'main',
    lastPatchId: 'base'
};

区域编辑

选择矩形区域内的实体进行编辑。

命令方式

// 在瓦片模式下执行
await Engine.editor.executerWithOp('TILEEDITAREA');
// 操作:指定第一个角点 → 指定对角点 → 加载区域数据

API 方式

const { TileEditAreaCommand, DrawingManagerService, Engine } = vjcad;

const drawingManager = new DrawingManagerService();
const pcanvas = Engine.pcanvas;

// 定义编辑区域
const editArea = {
    minX: 1000,
    minY: 1000,
    maxX: 2000,
    maxY: 2000
};

// 加载编辑区域
const loadResult = await TileEditAreaCommand.loadEditArea(
    editArea,
    Engine.currentDoc.serverSource,
    pcanvas,
    Engine.currentDoc,
    drawingManager
);

if (loadResult.success) {
    Engine.currentDoc.isReadOnly = false;
    console.log(`加载完成: ${loadResult.loadedCount} 个可编辑实体`);
}

区域编辑特点

  • 支持多次选择不同区域(累积模式)
  • 添加遮盖层覆盖瓦片内容
  • 实体和块定义自动合并去重
  • 保存时只保存编辑区域的变更

图层编辑

选择指定图层的所有实体进行编辑。

命令方式

// 在瓦片模式下执行
await Engine.editor.executerWithOp('TILEEDITLAYER');
// 操作:在对话框中选择图层 → 加载图层数据

API 方式

const { TileEditLayerCommand, DrawingManagerService, Engine } = vjcad;

const drawingManager = new DrawingManagerService();
const pcanvas = Engine.pcanvas;

const mapid = Engine.currentDoc.serverSource.mapid;
const version = Engine.currentDoc.serverSource.version;

// 1. 获取图层列表
const layerInfos = await TileEditLayerCommand.getLayerListFromService(mapid, version);
const layerNames = layerInfos.map(l => l.name);
console.log('可用图层:', layerNames);

// 2. 选择要编辑的图层
const selectedLayers = ['0', '标注层'];

// 3. 加载编辑图层
const loadResult = await TileEditLayerCommand.loadEditLayers(
    selectedLayers,
    Engine.currentDoc.serverSource,
    pcanvas,
    Engine.currentDoc,
    drawingManager
);

if (loadResult.success) {
    Engine.currentDoc.isReadOnly = false;
    console.log(`加载完成: ${loadResult.layersCount} 个图层,共 ${loadResult.totalLoadedCount} 个实体`);
}

图层编辑特点

  • 支持多选图层
  • 图层范围不固定,不添加遮盖层
  • 实体和块定义自动合并去重

透明度设置

瓦片图层透明度

// 命令方式
await Engine.editor.executerWithOp('TILEALPHA');

// API 方式
const pcanvas = Engine.pcanvas;

// 获取当前透明度
const currentAlpha = pcanvas.getWmsTileAlpha();
console.log(`当前透明度: ${Math.round(currentAlpha * 100)}%`);

// 设置透明度(0-1)
pcanvas.setWmsTileAlpha(0.5);  // 50%
pcanvas.redraw();
值 效果
0 完全透明
0.5 半透明
1 完全不透明(默认)

遮盖层透明度

// 命令方式
await Engine.editor.executerWithOp('TILEMASKALPHA');

// API 方式
const pcanvas = Engine.pcanvas;

// 设置遮盖层透明度
pcanvas.tileMaskContainer.alpha = 0.8;   // PixiJS Container 透明度
pcanvas.redraw();

使用场景:

  • 对比编辑区域与底图的差异
  • 降低底图干扰,专注编辑区域
  • 检查编辑内容与原图的对齐

相关命令

命令 说明
OPENFROMSERVER 打开图纸(可选瓦片模式)
TILEEDITAREA 选择矩形区域编辑
TILEEDITLAYER 选择图层编辑
TILEALPHA 设置瓦片图层透明度
TILEMASKALPHA 设置遮盖层透明度
SAVESERVER 保存(只保存编辑区域的变更)

瓦片配置参数

参数 说明 默认值
mapid 图纸 ID -
version 版本号 -
layers 图层名称 全部图层
tileSize 瓦片大小(像素) 256
maxZoom 最大缩放级别 20
minZoom 最小缩放级别 0
transparent 是否透明 true
preloadBuffer 预加载缓冲区 1
maxConcurrent 最大并发请求数 6
cacheSize 缓存大小 200

完整示例

const { 
    MainView, initCadContainer, Engine,
    DrawingManagerService, TileEditAreaCommand, TileEditLayerCommand,
    GeoBounds, Point2D, LineEnt, message
} = vjcad;

// 初始化
const cadView = new MainView({
    appname: "唯杰CAD",
    version: "v1.0.0",
    serviceUrl: env.serviceUrl,
    accessToken: env.accessToken,
    sidebarStyle: "none"
});

initCadContainer("map", cadView);
await cadView.onLoad();

const drawingManager = new DrawingManagerService();
const service = drawingManager.getService();

const mapid = 'large-drawing';
const version = 'v1';

// === 1. 瓦片打开图纸 ===
const metadata = await service.metadata(mapid, version);
const bounds = GeoBounds.fromString(metadata.bounds);

Engine.view.newDocument();
Engine.currentDoc.name = `${mapid}_tile`;

const pcanvas = Engine.pcanvas;
pcanvas.enableWmsTileLayer(service, {
    mapid, version,
    tileSize: 256,
    transparent: true
});

const centerX = (bounds.min.x + bounds.max.x) / 2;
const centerY = (bounds.min.y + bounds.max.y) / 2;
pcanvas.setCenter(new Point2D(centerX, centerY), true);

Engine.currentDoc.isReadOnly = true;
Engine.currentDoc.serverSource = {
    type: 'imports', mapid, version,
    branchName: 'main', lastPatchId: 'base'
};

message.info('瓦片模式已启用');

// === 2. 加载编辑区域 ===
const width = bounds.max.x - bounds.min.x;
const height = bounds.max.y - bounds.min.y;

const editArea = {
    minX: centerX - width * 0.1,
    minY: centerY - height * 0.1,
    maxX: centerX + width * 0.1,
    maxY: centerY + height * 0.1
};

const loadResult = await TileEditAreaCommand.loadEditArea(
    editArea,
    Engine.currentDoc.serverSource,
    pcanvas,
    Engine.currentDoc,
    drawingManager
);

if (loadResult.success) {
    Engine.currentDoc.isReadOnly = false;
    message.info(`已加载 ${loadResult.loadedCount} 个实体`);
}

// === 3. 编辑图纸 ===
const line = new LineEnt([centerX - 50, centerY], [centerX + 50, centerY]);
line.setDefaults();
line.color = 1;
Engine.addEntities(line);

// === 4. 设置透明度便于对比 ===
pcanvas.setWmsTileAlpha(0.5);
pcanvas.redraw();

// === 5. 保存(只保存编辑区域的变更)===
// await Engine.editor.executerWithOp('SAVESERVER');