> **本文回答**：通用 XYZ / WMTS 栅格瓦片叠加方式，适用于任何厂家（国内国外均可）。

## 一、通用 addSource 方式

```js
map.addSource("any-tile", {
  type: "raster",
  tileSize: 256,
  tiles: ["https://host/{z}/{x}/{y}.png"]
});
map.addLayer({ id: "any-tile", type: "raster", source: "any-tile" });
```

关键字段：

| 字段 | 说明 |
|---|---|
| `tileSize` | 瓦片像素，256 / 512，默认 512；必须写服务的真实尺寸。互联网地图多为 256；vjmap CAD 栅格（`svc.rasterStyle()`）也是 256 |
| `tiles[]` | URL 模板数组（多个 = 负载均衡，按 `tiles[(x + y) % n]` 固定分配，不是随机） |
| `scheme` | `"xyz"` (默认) 或 `"tms"`（Y 轴反转） |
| `bounds` | `[minLng, minLat, maxLng, maxLat]` 仅在这个范围内请求瓦片 |
| `minzoom` / `maxzoom` | 瓦片源的 zoom 上下限 |

## 二、WMTS 模板

WMTS 风格 URL 通常包含 `{TileMatrix}/{TileCol}/{TileRow}`：

```js
tiles: [
  "https://host/wmts/xxx/tile/{z}/{y}/{x}"   // 注意：ArcGIS WMTS 常是 z/y/x
]
```

## 三、WMS 模板（BBOX 占位）

WMS 需要把 `{bbox-epsg-3857}` 填入：

```js
tiles: [
  "https://host/wms?SERVICE=WMS&VERSION=1.3.0&REQUEST=GetMap" +
  "&LAYERS=public:xxx" +
  "&STYLES=&FORMAT=image/png" +
  "&TRANSPARENT=true&CRS=EPSG:3857&WIDTH=256&HEIGHT=256" +
  "&BBOX={bbox-epsg-3857}"
]
```

## 四、通过 vjmap `webMapUrl` 走后端代理

用于以下场景：

- 厂家要求 key，不能放前端
- Y 轴需要反转（`tileFlipY`）
- 多 token 负载均衡 / 降级容灾
- CAD 为底图时把互联网瓦片转 WMS 对齐到 CAD 坐标

```js
const url = svc.webMapUrl({
  tileCrs: "gcj02",                 // 瓦片坐标系：wgs84 / gcj02
  tileUrl: [urlTemplate1, urlTemplate2],
  tileSize: 256,
  tileRetina: 1,
  tileMaxZoom: 18,
  tileShards: "1,2,3,4",
  tileToken: ["tk1", "tk2"],
  tileFlipY: false,
  mapbounds: res.bounds,            // CAD 范围（若 CAD 为底）
  srs: "EPSG:4527",                 // CAD 的 EPSG
  fourParameterBefore: "...",        // 可选：转换前四参数
  fourParameterAfter: "..."          // 可选：转换后四参数（⚠️ 字段名是 After，不是 fourParameter）
});

map.addSource("tile", { type: "raster", tiles: [url], tileSize: 256 });
```

## 五、tile URL 占位符

vjmap 引擎的 `tiles` 模板只替换这几个占位符：

- `{x} {y} {z}` — XYZ 坐标（`scheme: "tms"` 时 `{y}` 自动翻转）
- `{quadkey}` — Bing 风格 quadkey
- `{prefix}` — `x % 16` 与 `y % 16` 的十六进制拼接
- `{bbox-epsg-3857}` — WMS 的 BBOX

**不支持 `{s}`、`{ratio}`**（原样发出）：多子域要展开成多个 URL 放进 `tiles` 数组（引擎按 `(x + y) % n` 选用）。

后端 `svc.webMapUrl` 则会把 `{s}` 换成 `tileShards` 里的 shard、`{t}` 换成 `tileToken`、`{x}{y}{z}` 换成实际值——这是 `{s}` / `{t}` 唯一被替换的地方。

## 六、最小 zoom 的手动限定

某些瓦片源 zoom 范围窄：

```js
map.addSource("my-tile", {
  type: "raster",
  tileSize: 256,
  tiles: [...],
  minzoom: 4,                    // zoom < 4 不请求
  maxzoom: 18,
  bounds: [116.0, 39.0, 117.0, 40.0]  // 仅北京范围
});
```

## 七、常见坑

1. **瓦片 404 大量出现** → 检查 URL 模板、token、坐标系、`tileSize` 是否和服务一致。
2. **tile 显示错位** → 投影不匹配；必须是 EPSG:3857 或通过 `webMapUrl` 做中间层。
3. **`tile-boundaries` 出现方块边** → 栅格的 tileSize 与引擎默认 (512) 不一致时一定要显式写 256。
4. **跨域**：公开瓦片通常有 CORS 头，商业服务未必；走后端代理更稳。
