> **本文回答**：把 SVG 图形导入为 CAD 实体 —— `svgToEntities` / `createBlockDefFromSvg` / `createBlockRefFromSvg` / `SvgParseOptions`。

# SVG 导入

vjmapext 内置 SVG → CAD 实体解析器，三个导出函数（`vjmapext` 顶层，非 `MapCadLayer` 方法）：

| 函数 | 返回 | 用途 |
|---|---|---|
| `svgToEntities(svgString, options?)` | `SvgParseResult` | 解析为散实体数组，自行 `addEntity` |
| `createBlockDefFromSvg(svgString, blockName, basePoint, blocks, options?)` | `BlockDef` | 直接生成块定义 |
| `createBlockRefFromSvg(svgString, blockName, blocks, insertionPoint, basePoint?, scaleFactor?, rotation?, options?)` | `BlockRefEnt` | 一步生成可插入的块引用 |

```ts
interface SvgParseResult {
  entities: EntityBase[];   // 已实例化的实体（LineEnt/PolylineEnt/...）
  width: number;            // SVG 画布宽（px 单位原值）
  height: number;
}
interface SvgParseOptions {
  flipY?: boolean;          // 默认 true：SVG 的 y 轴向下 → CAD 向上翻转
  tolerance?: number;       // 曲线离散容差，默认 0.5
  enableFill?: boolean;     // 默认 true：填充区转 Hatch
  defaultColor?: number;    // 无 stroke/fill 元素的颜色，默认 0xffffff
}
```

## 最小代码

```js
const svg = '<svg xmlns="http://www.w3.org/2000/svg" width="100" height="80">' +
            '<line x1="0" y1="0" x2="100" y2="80" stroke="#f00"/></svg>';

const { entities, width, height } = vjmapext.svgToEntities(svg, { flipY: true });
entities.forEach(e => mapcadLayer.addEntity(e));   // 逐实体入图（进 undo 栈）
```

块引用一步式（适合做图符库）：

```js
const ref = vjmapext.createBlockRefFromSvg(
  svg, '灯具', mapcadLayer.blocks,
  [300, 300],   // insertionPoint
  [0, 0],       // basePoint：仅存为 BlockDef 元数据，不影响锚点（见坑 6）
  1, 0,         // scaleFactor, rotation
  { flipY: true }
);
mapcadLayer.addEntity(ref);
```

## 坑

1. **`flipY` 默认已是 `true`**：SVG 坐标系 y 向下、CAD 向上，解析器默认已做翻转（`y → height - y`）；只有要保留 SVG 原始朝向时才显式传 `flipY: false`。（`tolerance` 默认 0.5、`enableFill` 默认 true。）
2. **返回的是 CAD 坐标系像素值**：`width/height` 是 SVG 原始尺寸，实体坐标也未按地图比例缩放——SVG 设计稿通常要自己再 `scale` 到 CAD 单位。
3. **不支持的元素静默跳过**：`image`/`foreignObject`/渐变滤镜/`defs`/`clipPath`/`mask` 等不产出实体，检查 `entities.length` 是否符合预期；**非法输入（非 XML、无 svg 根）不抛错**，返回 `{entities: [], width: 0, height: 0}`。
4. **`svgToEntities` 不自动入图**：只返回数组，必须逐个 `addEntity`；`createBlockRefFromSvg` 同理（返回 ref，仍需 `addEntity`）。
5. **`createBlockRefFromSvg` 的 `blockName` 是显示名**：生成的 `BlockDef`/`ref.blockId` 是随机 id（如 `ruaoiion` 这类），查块引用别拿 `blockId === '灯具'` 判断。
6. **`basePoint` 不会平移块内实体**：`createBlockDefFromSvg`/`createBlockRefFromSvg` 只把它存进 `BlockDef.basePoint`，块内实体仍是 SVG 原坐标，`BlockRefEnt` 渲染时也不减基点——插入点对齐的是解析后坐标的原点（默认 `flipY` 时即 SVG 画布左下角）。要以某点为锚：先 `svgToEntities`，对每个实体 `e.move(基点, [0, 0])`，再自建 `BlockDef` 逐个 `addEntity` 后 `blocks.add`（见 [block-reference](block-reference.md) 基点一节）。

## 相关

- 块体系 → [block-reference](block-reference.md)
- 实体入图 / undo → [lifecycle](lifecycle.md) / [drawing/undo-redo](../drawing/undo-redo.md)
