唯杰地图 logo唯杰地图
VJMAP
EN

entity-bulk-add

vjmapext/references/batch/entity-bulk-add.md 2.5 KB73 行
原文

本文回答:MapCadLayer 批量 addEntity 的正确姿势 —— 渲染合并、undo 事务、性能。

一、直接循环即可

for (let i = 0; i < 10000; i++) {
  const line = new vjmapext.LineEnt([0, i], [100, i]);
  mapcadLayer.addEntity(line);
}

不需要手动 bulk 接口。addEntity 内部只标记 dirty,真正的重绘由 requestAnimationFrame 合并到下一帧——循环 1 万次也只会调度一次重绘。包内没有 beginBulk/endBulk/bulkRun 这类 API。

二、undo 事务:批量操作算一步撤销

mapcadLayer.undoManager.beginTransaction();
try {
  for (const feat of features) {
    const ent = toEntity(feat);
    mapcadLayer.addEntity(ent);
  }
} finally {
  mapcadLayer.undoManager.endTransaction();
}

用户按一次 Ctrl+Z 会一次撤销整批。beginTransaction/endTransaction 支持嵌套,只有最外层 endTransaction 才入栈。

三、并行构造(Web Worker)

实体对象自身在主线程创建(访问 SDK),但数据准备可以放 worker:

const raw = await workerPool.run('buildCoords', bigData);
raw.forEach(({ pts, color }) => {
  const poly = new vjmapext.PolylineEnt(pts);
  poly.color = color;
  mapcadLayer.addEntity(poly);
});

四、混合 GeoJSON + 实体

当"只看不交互"量大(几万 ~ 几十万),走 primitive/geojson-source;"要交互 / 编辑"的小量(< 1 万)走实体:

// 展示层:50 万线
map.addGeoJSONSource('roads-bg', fcRoads);
map.addLineLayer('roads-bg', 'roads-bg', { lineColor: '#ccc', lineWidth: 1 });

// 业务层:10 条重点线,走实体便于编辑
importantRoads.forEach(r => mapcadLayer.addEntity(toLineEnt(r)));

五、样式批量

变更大量实体的颜色 → 单独有快路径:ent.styleChanged()(而不是 ent.changed()),见 bulk-style-update。

六、删除批量

idsToDelete.forEach(id => mapcadLayer.deleteEntity(id));

同样由帧调度自动合并重绘;要一步撤销就包在 beginTransaction/endTransaction 里。

七、常见坑

  1. 创建实体时同步做网络请求 → 主线程卡;数据先拉齐,再循环 addEntity。
  2. undo 记录没包事务 → 用户要按 N 次 Ctrl+Z;批量操作用 beginTransaction/endTransaction。
  3. 循环里 await 异步操作 → 把 addEntity 摊到多个帧、拉长总耗时;先同步构造完再一次性加。