# 瓦片打开（Tile Open Mode）

> 文档：`vjcad/doc/tile/tile-mode.md`
> 示例：`vjcad/example/tile/01opentile.js`

## 1. URL 参数方式（最简单）

```text
http://your-host/?vcad_mapid=test&vcad_version=v1&vcad_branch=main&vcad_patch=base&vcad_tile=true
```

带上以上参数后，`MainView` 初始化完成时会自动以 **瓦片模式** 打开图纸；无需手写代码（`MainView.URL_PARAMS`，源码 `MainView.openDrawingFromUrlParams`）：

- 参数名 **必须带 `vcad_` 前缀**（`vcad_mapid` 必填；`vcad_version` 缺省取最新版本，`vcad_branch` 缺省 `main`，`vcad_patch` 缺省 `base`）；`?mapid=…&type=…&lastPatchId=…` 这类无前缀参数会被忽略
- 只有 `vcad_tile=true` 才走瓦片打开，否则按矢量打开（`vcad_readonly=true` 为只读矢量打开）
- 类型固定为 `imports`（不支持 designs）；必须配置了 `serviceUrl`，否则直接跳过

## 2. API 方式（需要自定义 UI / 多图切换）

完整流程：拿元数据 → 创建文档 → 启用 WMS 瓦片层 → 标记只读 → 设置视口。

```js
class OpenTileApiCommand {
    async main() {
        const mapid = "test";
        const version = "v1";
        const drawingManager = new DrawingManagerService();
        const service = drawingManager.getService();

        // 1. 获取图纸元数据（Service.metadata，返回 bounds 字符串 / styles 等）
        const metadata = await service.metadata(mapid, version);
        const bounds = GeoBounds.fromString(metadata.bounds);

        // 2. 创建空白文档承载瓦片信息
        Engine.view.newDocument();
        Engine.currentDoc.name = `${mapid}_${version}_tile`;

        // 3. 启用 WMS 瓦片图层（同步调用）
        const pcanvas = Engine.pcanvas;
        pcanvas.enableWmsTileLayer(service, {
            mapid,
            version,
            layers: metadata.styles?.[0]?.layername,
            tileSize: 256,
            maxZoom: 20,
            minZoom: 0,
            transparent: true,
            preloadBuffer: 1,
            maxConcurrent: 6,
            cacheSize: 200,
        });

        // 4. 视口对齐图纸范围（setZoom + lookPt + setCenter）
        const centerX = (bounds.min.x + bounds.max.x) / 2;
        const centerY = (bounds.min.y + bounds.max.y) / 2;
        // GeoBounds 无 width()/height()，用 max-min 计算
        const bw = bounds.max.x - bounds.min.x;
        const bh = bounds.max.y - bounds.min.y;
        const zoom = Math.min(
            pcanvas.div.clientWidth / bw,
            pcanvas.div.clientHeight / bh
        ) * 0.9;
        Engine.currentSpace.setZoom(zoom);
        Engine.currentSpace.lookPt = new Point2D(centerX * zoom, centerY * zoom);
        pcanvas.setCenter(new Point2D(centerX, centerY), true);

        // 5. 标记只读 + 设置 serverSource（保存 / 切版本依赖它）
        Engine.currentDoc.isReadOnly = true;
        Engine.currentDoc.serverSource = {
            type: 'imports',
            mapid, version,
            branchName: 'main',
            lastPatchId: 'base',
        };

        message.success("已进入瓦片模式（只读）");
    }
}
CommandRegistry.regist(new CommandDefinition(
    'OPENTILEAPI', '打开瓦片图（API）', OpenTileApiCommand, new CommandOptions()
));
```

> 完整代码：`vjcad/example/tile/01opentile.js`

## 3. 元数据结构（meta）

`service.metadata(mapid, version)` 返回（字段节选）：

```ts
{
    bounds:       string;              // "x1,y1,x2,y2"，用 GeoBounds.fromString 解析
    styles:       Array<{ layername: string; ... }>; // 首项 layername 即瓦片图层名
    // ... 其他业务字段（分支/补丁链等依服务端返回）
}
```

## 4. enableWmsTileLayer 关键参数

| 参数 | 含义 |
|---|---|
| `mapid` | 服务端图纸 ID |
| `version` | 版本号 |
| `layers` | 瓦片图层名（取 `metadata.styles[0].layername`） |
| `tileSize` | 单个瓦片像素（默认 256） |
| `maxZoom` / `minZoom` | 瓦片缩放级别范围 |
| `transparent` | 瓦片背景透明 |
| `preloadBuffer` / `maxConcurrent` / `cacheSize` | 预取缓冲 / 并发 / 缓存数 |

## 5. 切换 / 退出

```js
// 切到另一个版本（均为同步调用）
pcanvas.disableWmsTileLayer();
pcanvas.enableWmsTileLayer(service, { /* 新参数 */ });

// 退回矢量图：重新 openDrawing + openDbDoc 即可（见 file/server.md）
```

## 红旗

- 瓦片按每块的 WCS bbox 向服务端请求、按 WCS 坐标定位（`WmsTileConfig` 没有 viewBox 字段），`metadata.bounds` 只用来算初始视口，不会让瓦片偏位
- `Engine.currentDoc.isReadOnly = true` **不拦截任何编辑命令**：库内只用它显示文档标签的只读标记、让 `QSAVE` 改走另存为
- 瓦片恒为该 `mapid`/`version` 的 **base** 渲染（`WmsTileLayer` 建 URL 只带 mapid/version）；`lastPatchId` 只决定区域/图层编辑时载入哪个补丁的矢量、以及保存时的 `parentId`
- 多个图同时叠加时只能开一层 WMS；要再叠就得用 `webmap` 或自行扩展 canvas 层
- URL 参数模式会自动处理 `serverSource`，但 API 模式必须手动赋值

## 参考（官方文档 MCP）

- 文档：`vjcad/doc/tile/tile-mode.md`
- 示例：`vjcad/example/tile/01opentile.js`
