唯杰地图 logo唯杰地图
VJMAP
EN

mapdata-hider

vjmapext/references/batch/mapdata-hider.md 4.9 KB140 行
原文

本文回答:createMapDataHider / MapEntityHider —— 把 DWG 原图里的实体"用样式隐藏",避免 SDK 接管后双重显示;栅格 / 矢量底图双模式。

一、为什么需要

查出实体 → 加动画 → 但原图还在 → 画面上有两份 → 需要隐藏原图那份。

但不是 "删除",是"样式级隐藏",可逆,也不影响底图其它内容。

二、创建

const hider = mapcadLayer.createMapDataHider();
// 等价 new vjmapext.MapEntityHider(map)

它会自动识别当前底图模式:

底图 机制
栅格(svc.rasterStyle()) `map.updateStyle(svc, { expression: "if(gInObjectId in 'id1
矢量(svc.vectorStyle()) map.setFilterEx(layers, ['!', ['match', ['id'], ids, true, false]]),前端过滤

三、核心 API

type HideItem =
  | string                                    // 栅格 objectid
  | number                                    // 矢量 feature.id
  | { id?, objectid? }
  | GeoJSON.Feature;                          // 推荐,两种 id 自动抽取

hider.hide(items): Promise<void>
hider.show(items): Promise<void>
hider.clear(): Promise<void>
hider.getHiddenIds(): string[]                // 栅格 objectid
hider.getHiddenFeatureIds(): number[]         // 矢量 feature.id
hider.isHidden(id): boolean
hider.refresh(): Promise<void>
hider.mode: 'raster' | 'vector'

四、基本使用

// 1. 查
const fc = await mapcadLayer.queryMapEntities({ entTypes: ['AcDbText'] });

// 2. 隐藏(直接传 Feature,兼容两种底图)
const hider = mapcadLayer.createMapDataHider();
await hider.hide(fc.features);

// 3. 用 SDK 实体重绘
mapcadLayer.featuresToEntities(fc).forEach(e => mapcadLayer.addEntity(e));

// 4. 恢复原图
await hider.clear();

五、栅格 vs 矢量的关键差异

模式 过滤字段 类型 来源
栅格 gInObjectId 字符串 '9BE_2' feature.properties.objectid
矢量 ['id'] 数字 1234 feature.id(DB 主键)

警告:只传 objectid 数组给 hide():

  • 栅格下生效
  • 矢量下命中不到(['match', ['id'], ['9BE_2'], ...] 永远 false)→ 看起来"没效果"

解决:传 Feature 对象,两种 id 都带着。

六、多个 hider 独立管理

const textHider = mapcadLayer.createMapDataHider();
const roadHider = mapcadLayer.createMapDataHider();

await textHider.hide(textFeatures);
await roadHider.hide(roadFeatures);

// 导出时分别传:
await mapcadLayer.exportDwg({ hider: textHider });   // 只删文字
await mapcadLayer.exportDwg({ hider: roadHider });   // 只删道路

注意:多 hider 是"后写覆盖"不是合并。栅格模式下所有 hider 默认写同一个 styleName(myCustomStyle_temp)的样式,矢量模式下 setFilterEx 也是整体替换——最后一次 refresh() 生效,之前 hider 的隐藏会被顶掉。要并存请给每个 hider 传不同 styleName(栅格)或干脆只用一个 hider 管理所有隐藏 id。

七、配合 exportDwg(导出时删除)

await mapcadLayer.exportDwg({ hider });              // 自动删除源图中被 hider 隐藏的实体
await mapcadLayer.exportDwg({ hider, deleteFromSource: false }); // 仅导出,不删源

见 backend/export-dwg 的 deleteObjectIds / onBeforeUpdate 钩子。

八、栅格底图耗时

栅格模式下 hide 会触发后端瓦片重拉(瓦片里少了被隐藏的实体),通常 300 ~ 800 ms;期间画面会有一次闪。

想避免闪烁:

const canvas = map.getCanvas();
canvas.style.opacity = 0.3;
await hider.hide(fc.features);
canvas.style.opacity = 1;

九、矢量底图瞬时

矢量模式是前端 filter 表达式,1 万 id 内基本瞬时;更大量级(10+ 万 id)时 filter 本身可能慢。

超大量级时可考虑:

  • 分组 hide:一次 1 万
  • 改用 CSS opacity 方案
  • 用 feature-state + 样式表达式把实体变透明:
fc.features.forEach(f => map.setFeatureState({ source: 'vec', id: f.id }, { hidden: true }));
// layer 样式里:
// lineOpacity: ['case', ['boolean', ['feature-state', 'hidden'], false], 0, 1]

十、常见坑

  1. 只传 objectid → 矢量不生效:务必传 Feature 对象。
  2. 栅格模式 hide 后画面闪一下:瓦片重拉;上面 opacity 技巧或用矢量底图。
  3. 连续 hide 多次:每次都会触发样式刷新;收集好 features 再一次 hide。
  4. hider 丢失引用:GC 后无法 clear;用全局 Map 持有。
  5. 导出时忘了 hider:导出的 DWG 里既有原实体又有 SDK 实体 → 双份。

相关