> **本文回答**：用 `vjmap.Draw` 编辑/绘制底座图形（线、面、点、圆弧等），导出 GeoJSON 后送入 Polyline / Polygon。

## 一、用途

底座图元（Polyline / Polygon）通常是"只读可视化"。如果需要**用户交互绘制 / 编辑**这些图元，有两条路：

1. **vjmap.Draw.Tool**（本文）：通用绘图控件（`vjmap.Draw` 是命名空间对象，可构造的是 `Draw.Tool`），输出 GeoJSON
2. **map.createDrawLayer / vjmap.Draw.actionDraw***：便捷创建 / 原子绘制命令（详见 [interaction/draw-tools](../interaction/draw-tools.md)）

本文聚焦：**用 `vjmap.Draw` 画完形状 → 拿到 GeoJSON → 用 Polyline / Polygon 重渲染到业务层**。

## 二、最小示例

```js
// 1) 在地图上挂 Draw 控件
const draw = new vjmap.Draw.Tool({
  displayControlsDefault: false,
  controls: { polygon: true, trash: true, line_string: true, point: true }
});
map.addControl(draw);

// 2) 切到绘面模式
draw.changeMode("draw_polygon");

// 3) 监听绘制完成
map.on("draw.create", e => {
  const featureCollection = draw.getAll();
  // 把最后一条 feature 作为业务图元
  const last = e.features[e.features.length - 1];
  console.log("新增几何", last);

  // 业务层渲染
  polygonLayer.setData(draw.getAll());
});
map.on("draw.update", ()  => polygonLayer.setData(draw.getAll()));
map.on("draw.delete", ()  => polygonLayer.setData(draw.getAll()));
```

## 三、核心模式

| mode | 说明 |
|---|---|
| `simple_select` | 默认：选中已存在要素 |
| `direct_select` | 选中单个 feature 并显示顶点，可拖顶点 |
| `draw_point` | 画点 |
| `draw_line_string` | 画线 |
| `draw_polygon` | 画面 |
| `static` | 禁用一切交互 |

```js
draw.changeMode("draw_polygon");
```

## 四、事件

| 事件 | 触发 |
|---|---|
| `draw.create` | 新要素产生（绘制完成） |
| `draw.update` | 已存在要素被拖 / 改变 |
| `draw.delete` | 删除 |
| `draw.selectionchange` | 选择集改变 |
| `draw.modechange` | 切换模式 |
| `draw.render` | 每帧渲染 |

## 五、API 摘要

```js
draw.getAll();               // { type: "FeatureCollection", features: [...] }
draw.get(id);                // 取单个
draw.getSelected();          // 当前选中
draw.getSelectedIds();       // 选中 id 数组
draw.getMode();              // 当前模式

draw.add(feature);           // 增
draw.set(featureCollection); // 全量替换
draw.delete(id);             // 删
draw.deleteAll();            // 清空
draw.changeMode(mode, opts); // 改模式

// 选中
draw.changeMode("simple_select", { featureIds: [id] });
```

## 六、把 Draw 的结果转 CAD 坐标

`vjmap.Draw` 以 **LngLat** 存 feature。要在 CAD 坐标系保存：

```js
const lnglatFc = draw.getAll();
const cadFc = map.fromLngLat(lnglatFc);   // 反投影回 CAD
saveToBackend(cadFc);
```

## 七、把 CAD 数据反灌进 Draw 进行二次编辑

```js
const cadFc = loadFromBackend();
draw.set(map.toLngLat(cadFc));
draw.changeMode("simple_select");
```

## 八、只想编辑（不允许新增）

```js
const draw = new vjmap.Draw.Tool({
  displayControlsDefault: false,
  controls: { trash: false }
});
map.addControl(draw);

draw.set(existingFc);
draw.changeMode("simple_select", { featureIds: existingFc.features.map(f => f.id) });
// 禁用用户新增：只监听 update / delete
```

## 九、吸附（snap）

结合 vjmapext 的 `SnapManager`（`mapcadLayer.snapManager`，见 vjmapext skill 的 drawing/snap），或对 Draw 自定义 snap：

```js
const draw = new vjmap.Draw.Tool({
  api: {
    getSnapFeatures: snapObj      // { features: [...] } 待吸附点集
  }
});
```

详见 [interaction/snap-ortho](../interaction/snap-ortho.md)。

## 十、与 Polyline / Polygon 的对接

**推荐流程**：

```
draw.create ──► draw.getAll() ──► setData 到 vjmap.Polygon / Polyline
                                    （业务图层，用真实样式）
draw.update ──► 同上
draw.delete ──► 同上
```

业务层和编辑层分开：

- Draw 图层：简单样式、可交互
- 业务图层：自己的色彩、filter、hoverPopup 等

```js
const businessLayer = new vjmap.Polygon({
  data: { type: "FeatureCollection", features: [] },
  fillColor: "#0af",
  fillOpacity: 0.6
});
businessLayer.addTo(map);

map.on("draw.create", () => businessLayer.setData(draw.getAll()));
map.on("draw.update", () => businessLayer.setData(draw.getAll()));
map.on("draw.delete", () => businessLayer.setData(draw.getAll()));
```

## 十一、常见坑

1. **fc 坐标混乱** → Draw 是 LngLat；业务可能要 CAD；记得 `fromLngLat` / `toLngLat` 转换。
2. **删除后图层不更新** → `draw.delete` 后要手动 `businessLayer.setData(draw.getAll())`。
3. **禁用某些控件** → `displayControlsDefault: false` + `controls: { ... }` 白名单。
4. **Vue/React 里挂两次** → Draw 是 IControl，热更时记得 `map.removeControl(draw)` 再 add。
5. **样式不好看** → Draw 有默认样式，可覆盖 `styles: [...]` 或直接用业务层展示，Draw 用 static 模式。
