SVG 导入
本文回答:把 SVG 图形导入为 CAD 实体 ——
svgToEntities/createBlockDefFromSvg/createBlockRefFromSvg/SvgParseOptions。
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 |
一步生成可插入的块引用 |
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
}
最小代码
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 栈)
块引用一步式(适合做图符库):
const ref = vjmapext.createBlockRefFromSvg(
svg, '灯具', mapcadLayer.blocks,
[300, 300], // insertionPoint
[0, 0], // basePoint:仅存为 BlockDef 元数据,不影响锚点(见坑 6)
1, 0, // scaleFactor, rotation
{ flipY: true }
);
mapcadLayer.addEntity(ref);
坑
flipY默认已是true:SVG 坐标系 y 向下、CAD 向上,解析器默认已做翻转(y → height - y);只有要保留 SVG 原始朝向时才显式传flipY: false。(tolerance默认 0.5、enableFill默认 true。)- 返回的是 CAD 坐标系像素值:
width/height是 SVG 原始尺寸,实体坐标也未按地图比例缩放——SVG 设计稿通常要自己再scale到 CAD 单位。 - 不支持的元素静默跳过:
image/foreignObject/渐变滤镜/defs/clipPath/mask等不产出实体,检查entities.length是否符合预期;非法输入(非 XML、无 svg 根)不抛错,返回{entities: [], width: 0, height: 0}。 svgToEntities不自动入图:只返回数组,必须逐个addEntity;createBlockRefFromSvg同理(返回 ref,仍需addEntity)。createBlockRefFromSvg的blockName是显示名:生成的BlockDef/ref.blockId是随机 id(如ruaoiion这类),查块引用别拿blockId === '灯具'判断。basePoint不会平移块内实体:createBlockDefFromSvg/createBlockRefFromSvg只把它存进BlockDef.basePoint,块内实体仍是 SVG 原坐标,BlockRefEnt渲染时也不减基点——插入点对齐的是解析后坐标的原点(默认flipY时即 SVG 画布左下角)。要以某点为锚:先svgToEntities,对每个实体e.move(基点, [0, 0]),再自建BlockDef逐个addEntity后blocks.add(见 block-reference 基点一节)。
相关
- 块体系 → block-reference
- 实体入图 / undo → lifecycle / drawing/undo-redo