> **本文回答**：在 OpenLayers 项目里叠加 vjmap CAD。

## 一、OL 上叠 CAD WMS

```js
import "ol/ol.css";
import Map from "ol/Map";
import View from "ol/View";
import TileLayer from "ol/layer/Tile";
import TileImage from "ol/source/TileImage";
import TileWMS from "ol/source/TileWMS";

const svc = new vjmap.Service(URL, TOKEN);
await svc.openMap({ mapid: "sys_cad2000", mapopenway: vjmap.MapOpenWay.GeomRender });

const wmsUrl = svc.wmsTileUrl({
  mapid: "sys_cad2000",
  layers: "默认图层名",
  bbox: "",                // ⚠️ 必传空串：默认 "{bbox-epsg-3857}" 只有 vjmap 引擎会填，OL 不认
  srs: "EPSG:3857",
  crs: "EPSG:4548"          // sys_cad2000 是 CGCS2000 3° 带 117°E（无带号）
});

// 用 TileWMS（由它追加 BBOX）；TileImage 会把 {bbox-epsg-3857} 原样发给后端
const cadLayer = new TileLayer({
  source: new TileWMS({ url: wmsUrl, params: { TILED: true } })
});

const olMap = new Map({
  target: "map",
  layers: [cadLayer],
  view: new View({ center: [13000000, 3100000], zoom: 16 })
});
```

## 二、以 CAD 为底图，加互联网瓦片

`webMapUrl` 返回的瓦片按 vjmap 的 **CAD 瓦片网格**切，OL 的 View 必须用以 CAD 范围为 extent 的自定义投影 + 匹配的 resolutions（官方示例 `12olwebCad.js`），CAD 本身用 `svc.rasterTileUrl()` 作底图；在默认 EPSG:3857 的 View 上叠不齐：

```js
import Projection from "ol/proj/Projection";
import { addProjection } from "ol/proj";

const mapBounds = vjmap.GeoBounds.fromString(res.bounds);
const cadProjection = new Projection({ code: "cad", extent: mapBounds.toArray(), units: "m" });
addProjection(cadProjection);
const resolutions = [];
for (let i = 0; i < 25; i++) resolutions.push(mapBounds.width() / (512 * Math.pow(2, i - 1)));
const olMap = new Map({
  target: "map",
  layers: [new TileLayer({ source: new TileImage({ url: svc.rasterTileUrl() }) })],   // CAD 底图
  view: new View({ projection: cadProjection, resolutions, center: mapBounds.center().toArray(), zoom: 9 })
});
```

再叠互联网瓦片：

```js
const tileUrl = svc.webMapUrl({
  tileCrs: "gcj02",
  tileUrl: ["https://webrd0{s}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}"],
  tileSize: 256,
  tileShards: "1,2,3,4",
  mapbounds: res.bounds,
  srs: "EPSG:4527",
  fourParameterBefore: "39000000,0,1,0"
});

const gdLayer = new TileLayer({
  source: new TileImage({ url: tileUrl }),
  zIndex: -1
});
olMap.addLayer(gdLayer);
```

## 三、坐标系配置

OL 默认 EPSG:3857。如果 CAD 是 WMS-based 叠加，已经由 WMS 服务做坐标转换，不需动 OL 投影。

如果想让 OL 直接用 CAD 坐标系（EPSG:4544 等）：

```js
import proj4 from "proj4";
import { register } from "ol/proj/proj4";
import { get as getProjection } from "ol/proj";

proj4.defs("EPSG:4544", "+proj=tmerc +lat_0=0 +lon_0=105 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m +no_defs");   // 4544 = CGCS2000 3° 带 105°E；117°E 是 EPSG:4548
register(proj4);

const view = new View({
  projection: getProjection("EPSG:4544"),
  center: [100000, 3000000],
  zoom: 14
});
```

## 四、点击查询

```js
olMap.on("click", async (evt) => {
  const [lng, lat] = evt.coordinate;     // EPSG:3857 坐标（默认）
  // 转 CAD
  // 目标 EPSG 必须与 WMS 的 crs 一致（sys_cad2000 → EPSG:4548）
  const r = await svc.cmdTransform("EPSG:3857", "EPSG:4548", vjmap.geoPoint([lng, lat])); // 必须 geoPoint 包装，裸数组会序列化成 undefined,undefined
  const [x, y] = r[0];
  // 查询附近实体：zoom 参数按 vjmap 的缩放级别换算像素容差，OL 的 zoom 不是同一套——改传每像素地理长度
  const q = await svc.pointQueryFeature({
    x, y, pixelsize: 5,
    pixelToGeoLength: olMap.getView().getResolution()   // 3857 米/像素，近似 CAD 米（纬度 φ 处偏大 1/cosφ），作拾取容差够用
  });
  console.log(q);
});
```

## 五、常见坑

1. **OL 默认 tileSize 256** → 没问题；vjmap WMS 动态生成瓦片会按请求 size 渲染。
2. **图像旋转**：WMS `useImageRotate` 默认自动；若底图与 CAD 有夹角会自动旋转。
3. **OL 不支持 `{s}` subdomain** → 用 tileUrls 数组自己做负载均衡：

   ```js
   source: new TileImage({ urls: [url1, url2, url3] })
   ```
