唯杰地图 logo唯杰地图
VJMAP
EN

recognition / 智能识别总览

vjcad/references/recognition/overview.md 5.2 KB115 行
原文

文档:vjcad/doc/recognition/index.md、vjcad/doc/recognition/table-extract.md 示例:vjcad/example/recognition/01extracttable.js

recognition 是 vjcad 的结构识别模块,目前只有一个核心能力:表格识别——把图纸里"由直线 / 多段线 + 文字组合而成"的表格,还原成有行列结构的 TableData[]。

1. 解决的问题

CAD 里的"表格"实际上是 直线 + 文字 的拼接,没有结构化数据。extractTables 帮你把:

  • 多段线 / 直线 围成的矩形网格 → 行列单元
  • 落在单元格内的文字 → 单元值
  • 跨多列 / 跨多行的合并单元格 → spans 信息
  • 嵌套图块 / 组合内的同类内容 → 可选展开

转换为:

interface TableData {
    rect: string;                       // 两对角点逗号串 "x1,y1,x2,y2"(无方括号,不保证 min/max 顺序)
    rowCount: number;
    colCount: number;
    rows: string[];                     // 各行分隔线 y 坐标,数字字符串数组(自上而下)
    cols: string[];                     // 各列分隔线 x 坐标,数字字符串数组
    spans: Record<string, string>;      // 合并单元格(已是对象)"row_col"(1 起算)-> "rowSpan,colSpan"
    datas: string[][];                  // [row][col] 单元格文本
    attr: TableAttr;                    // 识别统计(cellEmptyRatio/tableTextCount/...)
}

这些字段都不能 JSON.parse:rect 用 t.rect.split(',').map(Number) 得 [x1,y1,x2,y2](自己取 min/max);rows/cols 用 .map(Number);spans 已经是对象,值 "2,1" 再 split(',')。datas 是直接可读的单元格文本矩阵。

2. 核心 API(一个)

function extractTables(
    options?: TableExtractOptions
): TableExtractResult;

返回:

interface TableExtractResult {
    tables: TableData[];
    tol: number;        // 实际使用的距离容差
    error?: string;     // 失败原因
}

辅助:

function getTableExtractLayers(): string[];   // 全部实体出现过的图层名(去重排序)

3. 高频选项(TableExtractOptions)

选项 默认 说明
bounds null { minX, minY, maxX, maxY } 对象(Bounds),限定识别范围;不传则全图
layers 全部图层 字符串数组,限定参与识别的图层(大小写不敏感)
includeLine / includePolyline true 是否计入直线 / 多段线
includeText / includeMText true 是否计入单行 / 多行文本
includeBlocks / includeGroups true(运行时) 是否展开图块 / 组合内实体
digit 4 几何比较精度(小数位)
tol 0(自动) 端点对齐容差(number),0 / 不传则根据图纸自适应
tableEdgeMinPoint 12 表格边框最少顶点数(过滤小图形)
tableTextMinCount 4 表格内最少文字数(过滤误识别)
cellEmptyRatio 90 允许的最大空单元百分比(0–100);有字单元占比 < 100 - cellEmptyRatio 时整表丢弃。切勿按 0~1 填,0.5 会丢弃几乎所有表
debug false 控制台输出识别中间过程

4. 三种典型用法

// 1) 全图识别(最简)
const r = extractTables();

// 2) 限定矩形 + 限定图层
const r2 = extractTables({
    bounds: { minX: 0, minY: 0, maxX: 1000, maxY: 800 },
    layers: ['表格', '0'],
});

// 3) 全配置
const r3 = extractTables({
    bounds:  { minX: 0, minY: 0, maxX: 200, maxY: 100 },
    layers:  ['表格'],
    includeLine: true, includePolyline: true,
    includeText: true, includeMText: true,
    includeBlocks: false, includeGroups: false,
    digit: 4, tol: 2,
    tableEdgeMinPoint: 12, tableTextMinCount: 4,
    cellEmptyRatio: 90, debug: false,   // cellEmptyRatio 是百分比(0–100),不是 0~1
});

5. 子文档

  • 表格识别细节、TableData 结构、调优建议 → table-extract

红旗

  • 表格的"边"必须是 闭合或近闭合 的直线 / 多段线,光看着像表格但端点不对齐 → 加大 tol
  • 文字可能因 INSERT 嵌套在图块内,找不到 → 打开 includeBlocks: true
  • 调优阶段打开 debug: true:不会往控制台打印,而是在返回结果里多出 debug_table_lines / debug_table_bounds / debug_table_posflag / debug_table_corner 几个字符串字段(表格线、表格边界、位置标识、角点),需要自己解析后画到图上核对
  • 返回的 rect 是 WCS(世界坐标)的逗号串 "x1,y1,x2,y2"(两对角点,无方括号、不能 JSON.parse,用 split(',').map(Number)),不是屏幕坐标,也不是 BoundingBox 对象
  • extractTables 取实体走 Engine.getEntities(),包含已 erase 的实体(isAlive=false,软删除仍留在 items 里),识别结果可能含已删内容

参考(官方文档 MCP)

  • 文档:vjcad/doc/recognition/index.md、vjcad/doc/recognition/table-extract.md
  • 示例:vjcad/example/recognition/01extracttable.js