features-to-entities
本文回答:
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) |
0alpha===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 处理:
- 有块定义(
mapcadLayer.blocks里能找到blockname)→ 真正的BlockRefEnt - 无块定义 + 回退 → 从
feature.geometry生成一组展开的基础实体(视觉在,语义丢) - 无块定义 + 不回退 → 忽略
保 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
十、常见坑
- 转换后颜色变黑:
color=0被判成 ByLayer,SDK 不写入;原实体设了颜色但没跟上。 - 缺 blocks 导致 Block 变一堆线:
BlockRefEnt回退到 geometry;先mapcadLayer.blocks.add(blockDef)。 - 对齐字段缺失:AcDbText 侧由
horzMode/vertMode/alignMode推导TextEnt.textAlignment(1-9 锚点值);AcDbMText 侧由attachment/attachmentPoint(1-9 直用)或horzMode/vertMode推导MTextEnt.attachmentPoint;源属性缺这些值时对齐回退默认。 - location 字符串解析失败:后端偶尔返回非标准
"x,y;z";SDK 做了容错,仍异常可手动location.split(/[,;]/)。 - metaPrefix 和业务属性冲突:默认
__md_;若业务也有这个前缀要改metaPrefix。
相关
- 查询入口 → mapdata-query
- 隐藏原图 → mapdata-hider
- 实体公共属性 → entity/style-props