唯杰地图 logo唯杰地图
VJMAP
EN

features-to-entities

vjmapext/references/batch/features-to-entities.md 6.7 KB172 行
原文

本文回答:featuresToEntities(fc) —— 把后端 FeatureCollection 转成 EntityBase[] 的映射规则、回退策略、meta 属性、色值转换。

一、基础用法

const ents = mapcadLayer.featuresToEntities(fc);
ents.forEach(e => mapcadLayer.addEntity(e));

返回 EntityBase[],类型按 feature.properties.name 自动匹配。

二、类型映射表

AcDb 类型 SDK 实体 关键字段
AcDbLine LineEnt points → startPoint / endPoint
AcDbPolyline / AcDb2dPolyline / AcDb3dPolyline PolylineEnt points + bulge + isclosed
AcDbCircle CircleEnt center + radius
AcDbArc ArcEnt center + radius + startAngle + endAngle
AcDbEllipse EllipseEnt center + majorRadius/major + minorRadius/minor/ratio + rotate/rotation + startAngle + endAngle
AcDbSpline SplineEnt points(geometry 顶点)+ degree + isclosed
AcDbText TextEnt location + text + height + rotate + horzMode
AcDbMText MTextEnt location + contents + textHeight + width + rotate
AcDbAttributeDefinition / AcDbAttribute TextEnt 同 AcDbText
AcDbHatch HatchEnt geometry(Polygon/MultiPolygon)→loops + patternName(; 前段)+ patternScale + patternAngle + origin/patternOrigin
AcDbSolid / AcDbTrace / AcDbFace HatchEnt (SOLID) geometry→loops,patternName 强制 SOLID
AcDbBlockReference / AcDbMInsertBlock BlockRefEnt blockname/blockName + insertionPoint/location/position + scale/scaleFactor + rotate/rotation(⚠️ 1.0.1 把弧度 ×180/π 后写进了本应是弧度的 BlockRefEnt.rotation,带旋转的块引用角度错误,见下方修正)
AcDbPoint PointEnt position / location

未识别类型按 fallbackToGeometry 兜底(见下)。

块引用旋转修正(BlockRefEnt.rotation 是弧度,1.0.1 转换时多乘了 180/π):

const ents = mapcadLayer.featuresToEntities(fc);
ents.forEach(e => {
  if (e.type === 'INSERT' && e.rotation) { e.rotation *= Math.PI / 180; e.changed(); }  // 还原为原始弧度
});

三、通用字段映射

GeoJSON property SDK 字段 备注
color (int32,可能负) ent.color 经 dwgColorToInt 转 0xRRGGBB;0 / 0xFFFFFF 视为 ByLayer
alpha ent.opacity(无则 borderOpacity;HatchEnt 用 fillOpacity + fillColor) 0255 → 归一化 01;alpha===0 时 visible=false。不写 effectOpacity;非 Hatch 实体若带 fillOpacity 字段会被重置为 0(不继承后端填充)
linetype(非 BYLAYER/BYBLOCK) ent.lineType
linetypeScale / lineTypeScale ent.ltScale
lineWidth ent.lineWidth ≥ 0
layerindex ent.layerId = 'layer_' + n 与 DwgExporter 一致
layer(字符串) ent.layerId layerindex 缺失时用
visible === false ent.visible = false
xdata(JSON 对象字符串) 逐 key → setCustomProperty(key, val)(不带 meta 前缀) 非对象/解析失败 → __md_raw_xdata(带前缀)

四、meta 属性(追踪用)

每个实体自动附加(默认前缀 __md_):

key 内容
__md_source 'mapdata'
__md_objectid 原 DWG 实体 objectid
__md_typename 原 AcDb 类型名
__md_layerindex 原图层索引

自定义前缀:

mapcadLayer.featuresToEntities(fc, { metaPrefix: '__src_' });

五、fallbackToGeometry 回退策略

未实现或找不到块定义时:

geometry.type 兜底实体
Point / MultiPoint PointEnt(MultiPoint 逐点生成)
LineString PolylineEnt(isclosed 为真时闭合)
MultiLineString 每条线一个 PolylineEnt(非闭合)
Polygon / MultiPolygon HatchEnt(patternName 默认 SOLID,内环作 inner loop)
GeometryCollection 递归展开为多个子实体

禁用回退:

mapcadLayer.featuresToEntities(fc, { fallbackToGeometry: false });
// 未识别 feature 被忽略

六、BlockRefEnt 两条路径

AcDbBlockReference 处理:

  1. 有块定义(mapcadLayer.blocks 里能找到 blockname)→ 真正的 BlockRefEnt
  2. 无块定义 + 回退 → 从 feature.geometry 生成一组展开的基础实体(视觉在,语义丢)
  3. 无块定义 + 不回退 → 忽略

保 100% 块信息:

// 先注册块定义(BlockDef 可来自 createBlockDefFromSvg / fromJSON 的 doc.blocks)
mapcadLayer.blocks.add(blockDef);
const ents = mapcadLayer.featuresToEntities(fc);

或显式传 blocks:

const ents = mapcadLayer.featuresToEntities(fc, { blocks: mapcadLayer.blocks });

七、dwgColorToInt 色值转换

后端 color 是 int32(负值常见),SDK 用 0xRRGGBB。手动转:

import { dwgColorToInt } from 'vjmapext';

dwgColorToInt(-65536);   // 0xFF0000 = 16711680
dwgColorToInt(0);        // -1(ByLayer)
dwgColorToInt(0xFFFFFF); // -1(ByBlock)

八、脱离 MapCadLayer 独立使用

featuresToEntities 是纯函数:

import { featuresToEntities } from 'vjmapext';

const ents = featuresToEntities(fc, {
  blocks: myBlocks,
  fallbackToGeometry: true,
  metaPrefix: '__src_'
});

九、典型场景

把查到的文字全部染红并加动画

const ents = mapcadLayer.featuresToEntities(fc);
ents.forEach(e => {
  e.color = 0xff0000;
  e.setCustomProperty('hl', true);
  mapcadLayer.addEntity(e);
});

按 custom property 反查 objectid

const ent = mapcadLayer.getEntities().find(e => e.getCustomProperty('__md_objectid')?.value === '9BE_2');
// getCustomProperty 返回 {type, value} 包装对象,比较要取 .value

十、常见坑

  1. 转换后颜色变黑:color=0 被判成 ByLayer,SDK 不写入;原实体设了颜色但没跟上。
  2. 缺 blocks 导致 Block 变一堆线:BlockRefEnt 回退到 geometry;先 mapcadLayer.blocks.add(blockDef)。
  3. 对齐字段缺失:AcDbText 侧由 horzMode/vertMode/alignMode 推导 TextEnt.textAlignment(1-9 锚点值);AcDbMText 侧由 attachment/attachmentPoint(1-9 直用)或 horzMode/vertMode 推导 MTextEnt.attachmentPoint;源属性缺这些值时对齐回退默认。
  4. location 字符串解析失败:后端偶尔返回非标准 "x,y;z";SDK 做了容错,仍异常可手动 location.split(/[,;]/)。
  5. metaPrefix 和业务属性冲突:默认 __md_;若业务也有这个前缀要改 metaPrefix。

相关