唯杰地图 logo唯杰地图
VJMAP
EN

查询与选择

vjcad/references/autodraw/query-selection.md 4.4 KB158 行
原文

实体查询、过滤、选择集操作、边界框。


获取所有实体

const { Engine } = vjcad;
// getEntities() 不带过滤 = [...currentSpace.items],含已删除(isAlive=false)实体
const allEntities = Engine.getEntities(e => e.isAlive);   // 或 Engine.currentSpace.aliveItems

按类型获取

const { Engine } = vjcad;

const lines   = Engine.getEntitiesByType('LINE');
const circles = Engine.getEntitiesByType('CIRCLE');
const arcs    = Engine.getEntitiesByType('ARC');
const plines  = Engine.getEntitiesByType('PLINE');
const texts   = Engine.getEntitiesByType('TEXT');
const mtexts  = Engine.getEntitiesByType('MTEXT');
const inserts = Engine.getEntitiesByType('INSERT');
const hatches = Engine.getEntitiesByType('HATCH');

getEntitiesByType / getEntities(filter) 同样不过滤已删除实体;需要时在条件里加 e.isAlive,如 Engine.getEntities(e => e.isAlive && e.type === 'LINE')。


按条件过滤

const { Engine } = vjcad;

// 按颜色
const redEntities = Engine.getEntities(ent => ent.color === 1);

// 按图层
const layerA = Engine.getEntities(ent => ent.layer === "图层A");

// 组合条件
const redLines = Engine.getEntities(ent =>
    ent.type === "LINE" && ent.color === 1
);

// 自定义复杂条件
const largeCircles = Engine.getEntities(ent =>
    ent.type === "CIRCLE" && ent.radius > 50
);

// 排除某些实体
const visible = Engine.getEntities(ent =>
    ent.layer !== "隐藏图层"
);

// 带扩展数据的实体
const withXData = Engine.getEntities(ent =>
    ent.hasExtData?.() && ent.extDataAppName === "MY_APP"
);

选择集操作

const { Engine } = vjcad;

// 设置选择集
Engine.ssSetFirst([entity1, entity2]);

// 获取当前选择集
const selected = Engine.ssGetFirst();
console.log(`选中 ${selected.length} 个实体`);

// 清空选择集
Engine.ssSetFirst([]);

// 选择所有存活实体(不过滤会把已删除实体也塞进选择集)
Engine.ssSetFirst(Engine.getEntities(e => e.isAlive));

边界框

单个实体

const bbox = entity.boundingBox();
// 返回 BoundingBox 类实例:{ pt1, pt2, minX, minY, maxX, maxY, width, height, center, ... }
// (返回纯 {minX,minY,maxX,maxY} 字面量的是 GLine/GArc/GCircle/GEllipse 几何原语,不是实体)

const w = bbox.width, h = bbox.height;
console.log(`宽度: ${w}, 高度: ${h}`);
console.log(`中心: (${bbox.center.x}, ${bbox.center.y})`);

多实体组合范围

const { Engine } = vjcad;

// 方式1:Engine API
const combined = Engine.getBoundsByEntities([ent1, ent2], "WCS");

// 方式2:mergeBoundingBoxes(返回 BoundingBox 类实例)
const { mergeBoundingBoxes } = vjcad;
const merged = mergeBoundingBoxes([
    entity1.boundingBox(),   // 实体 boundingBox() 本就返回 BoundingBox 实例,可直接传
    entity2.boundingBox()
]);

判断相交与包含

⚠️ BoundingBox 的 pt1/pt2 是纯数据字段:minX/minY/maxX/maxY 仅在构造时从 pt1/pt2 快照一次,事后赋 bb.pt1 = pt 不会重算 min/max——isPointInBox/width/center 等仍按旧值返回。事后调整请用 minPoint/maxPoint setter 或直接写 minX..maxY 字段(new BoundingBox() + 赋 pt1/pt2 后 isPointInBox(中点)=false)。

// 判断两个边界框是否相交
function bboxIntersects(bbox1, bbox2) {
    return !(
        bbox1.pt2.x < bbox2.pt1.x ||
        bbox1.pt1.x > bbox2.pt2.x ||
        bbox1.pt2.y < bbox2.pt1.y ||
        bbox1.pt1.y > bbox2.pt2.y
    );
}

// 判断点是否在边界框内
function pointInBbox(point, bbox) {
    return point.x >= bbox.pt1.x && point.x <= bbox.pt2.x &&
           point.y >= bbox.pt1.y && point.y <= bbox.pt2.y;
}

屏幕范围内的实体

const { Engine } = vjcad;

// 获取屏幕边界(世界坐标系)
const bounds = Engine.getScreenBoundsWcs();
// 返回: BoundingBox 类实例——{ pt1, pt2, minX, minY, maxX, maxY, width, height, center, ... }

// 获取屏幕内的实体
const screenEntities = Engine.getScreenEntities();
const expandedEntities = Engine.getScreenEntities(1.5);  // 扩展 1.5 倍范围