唯杰地图 logo唯杰地图
VJMAP
EN

recognizer

vjmap/references/backend/recognizer.md 5.4 KB161 行
原文

本文回答:实体智能识别(块参照批量查询 + 模式匹配相似实体)。

一、两个能力

  1. 批量获取所有块参照:自动列出图中所有 AcDbBlockReference。
  2. 相似实体识别:基于用户选的参考实体,找出图中几何形态相似(含缩放/旋转)的实体。

二、获取所有块参照

优先从 metadata

const meta = await svc.metadata();
if (meta.blockReferences) {
  const blocks = JSON.parse(meta.blockReferences);
  // blocks = [{ objectId, blockName, layerName, position:[x,y], rotate, scale:[x,y,z], bounds }, ...]
}

没有则走表达式查询

const q = await svc.exprQueryFeature({
  expr: `return gInFeatureType == 'AcDbBlockReference'`,
  fields: "",           // 空表示所有字段
  geom: false,
  useCache: true,
  limit: 1_000_000
});
const blocks = q.result.map(r => ({
  objectId: r.objectid,
  blockName: r.blockname,
  layerName: r.layername,
  bounds: r.bounds,
  position: r.positon,
  ...r
}));

可视化

const polygons = blocks.map(b => ({
  points: map.toLngLat(vjmap.GeoBounds.fromString(b.bounds).toPointArray()),
  properties: { blockName: b.blockName, layerName: b.layerName, objectId: b.objectId }
}));
const layer = new vjmap.Polygon({
  data: polygons,
  fillColor: ["case", ["to-boolean", ["feature-state", "hover"]], "#0ff", "#f00"],
  fillOpacity: ["case", ["to-boolean", ["feature-state", "hover"]], 0.1, 0.0],
  fillOutlineColor: ["get", "color"],
  isHoverPointer: true,
  isHoverFeatureState: true
});
layer.addTo(map);
layer.hoverPopup((f, popup) => {
  return `<h3>${f.properties.blockName}</h3>objectId: ${f.properties.objectId}`;
}, { anchor: "bottom" });

三、相似实体识别

配置

const patternConfig = {
  name: "",
  sameColor: true,           // 必须同色
  sameLayer: false,          // 是否必须同图层
  global: {
    match: {
      all: { equalMatchProperty: ["color"] },
      AcDbCircle: { scaleMatchProperty: ["radius"] },
      AcDbArc:    { scaleMatchProperty: ["radius"] },
      AcDbLine:   { scaleMatchProperty: ["length"] },
      AcDbText:   { scaleMatchProperty: ["height"] }
    }
  },
  rules: [{
    tolerance: 1e-5,
    translateTolerance: 0.015,
    transform: {
      scale:    { min: 0.5, max: 2.0 },
      rotation: { min: 0,   max: 360 }
    },
    referenceObjectIds: []       // 用户选的参考实体 feature[]
  }]
};

选择参考实体 + 识别

// 1) 让用户框选或点选(selectFeatures 是自定义助手函数,非包导出——
//    实现见 interaction/draw-action.md「CAD 实体框选/点选」一节)
const sel = await selectFeatures(map, /* isPointSel */ false);
patternConfig.rules[0].referenceObjectIds = sel.features;

// 2) 执行后端识别
const res = await svc.execCommand("objectDetection", {
  mapid:  svc.currentMapParam().mapid,
  version: svc.currentMapParam().version,
  pattern: JSON.stringify(patternConfig),
  detailedLog: false,
  bounds: undefined
}, "_null", "v1");

// 3) 结果高亮
const geoData = res.result.map(r => {
  const pts = vjmap.GeoBounds.fromString(r.bounds).toPointArray();
  pts.push(pts[0]);
  return { points: map.toLngLat(pts), properties: { color: "#f00" } };
});
vjmap.createAntPathAnimateLineLayer(map, geoData, {
  fillColor1: "#f00", fillColor2: "#0ff", lineWidth: 2, lineOpacity: 0.8
});

四、保存 / 加载配置

// 保存
await svc.httpPost(svc.serviceUrl("recognizer/add"), patternConfig);

// 获取列表
const list = (await svc.httpGet(svc.serviceUrl("recognizer/list"))).data;   // httpGet 返回 {status,response,data,xhr},取 .data

// 获取详情
const detail = (await svc.httpGet(svc.serviceUrl(`recognizer/detail?filenames=${filePrefix}`))).data;

// 删除
await svc.httpDel(svc.serviceUrl(`recognizer/delete?filename=${filePrefix}`));

五、生成缩略图

getObjectsThumbnail(map, objectIds, bounds, width, height) 返回 base64 缩略图,可以和 pattern 配合保存。它是官方 vjmap-vue3/packages/map-manage 包中的辅助函数(非 vjmap 核心导出;内部用 svc.createStyle 按 objectid 过滤 + wmsTileUrl 出图 + cmdDeleteStyle 清理,可按需复制实现)。

const objectIds = sel.features.map(f => f.properties.objectid);
const bounds = sel.features
  .map(f => vjmap.GeoBounds.fromString(f.properties.bounds))
  .reduce((a, b) => a.updateByBounds(b));
const thumb = await getObjectsThumbnail(map, objectIds, bounds, 120, 80);
patternConfig.thumbnail = thumb;

六、适用场景

  • 块实体统计 / 定位 / 属性查看。
  • 重复元素检测 / 设计模式分析。
  • 工程标准化检查(查找违规的图例)。

七、常见坑

  1. metadata.blockReferences 为空:是旧版本的图;走表达式查询作为 fallback。
  2. 选参考实体数量不足 → 识别不出任何结果;至少 1 个参考对象。
  3. 容差过松(translateTolerance 大) → 误识别太多;过严则漏识别。多次尝试。
  4. 识别结果多到爆 → 限制 bounds 只在图上某个区域识别。
  5. objectDetection 仅支持几何渲染图:Memory 方式建的图返回 {error:"geom is false, mapid is not geomrender"};且 mapid/version 必须放参数里、URL 段用 "_null","v1"(缺 mapid 报 param error, mapid is empty)。