图形分析
分类代号:C.4 本章共 6 个接口
这一组接口都是 vjmap 的"增值分析"能力,参数差异大、且对输入的 DWG/图像质量要求很高,因此 SDK 采用 pass-through 风格:你按下面文档组参数,SDK 负责 POST 与错误处理,不做参数字段级强校验。
全部走 POST /api/v1/map/cmd/{cmd}/_null/v1(_null 表示不绑定具体 mapid,参数里自带)。
快速索引
| 序号 | SDK 方法 | cmd |
|---|---|---|
| 30 | cmd_map_diff / cmdMapDiff |
mapDiff |
| 31 | cmd_map_compare / cmdMapCompare |
mapCompare |
| 32 | cmd_extract_table / cmdExtractTable |
extractTable |
| 33 | cmd_extract_center_lines / cmdExtractCenterLines |
extractCenterLines |
| 34 | cmd_match_object / cmdMatchObject |
objectMatch |
| 35 | cmd_image_svg_to_dwg / cmdImageSvgToDwg |
imageSvgToDwg |
30 · 像素差异 mapDiff
比较两张 DWG 渲染成图片后的像素差异,返回增删改的像素块外包矩形中心点。
请求参数
| 字段 | 类型 | 默认 | 说明 |
|---|---|---|---|
mapid1 / version1 |
string | — | 旧图(version 缺省取该图最新版) |
mapid2 / version2 |
string | — | 新图 |
layer1 / layer2 |
string | "" |
两张图各自参与对比的 style 名 |
size |
int | 4096 | 渲染网格边长(像素) |
cellsize |
int | 10 | 差异判定的单元格大小(像素) |
diffMinPixel |
int | 0 | 单元格内差异像素数阈值,低于则忽略 |
diffMinAlpha |
int | 25 | alpha 差异阈值 |
diffMinColor |
int | 6 | RGB 颜色差异阈值 |
noCompareNew |
bool | false | 不统计"新增"差异 |
noCompareDelete |
bool | false | 不统计"删除"差异 |
响应(实采:同图 vs 同图)
{
"del": "",
"modify": "",
"new": "",
"status": true
}
有差异时 del / modify / new 是 x1,y1,x2,y2;x3,y3,x4,y4 格式的字符串;svc.cmd_map_diff() 不做 parse,调用方按需切分。
Python
res = svc.cmd_map_diff(
mapid1="sys_zp", version1="v1",
mapid2="sys_zp", version2="v2",
cellsize=10, diffMinColor=6,
)
31 · 实体对比 mapCompare
和 mapDiff 不同:mapCompare 比较的是 DWG 实体,不是渲染像素。
请求参数
| 字段 | 类型 | 默认 | 说明 |
|---|---|---|---|
mapid1 / version1, mapid2 / version2 |
string | — | 两张图 |
layer1 / layer2 |
string | — | 无效:cmdMapCompare 读了 layer1 但从未使用,layer2 根本不读——实体对比总是整图,不能按 style 限定 |
noCompareProps |
bool | false | 不比较实体扩展属性,只比几何 |
comparePropMaxSize |
int | 5000 | 参与属性比较的实体数量上限 |
后端会先做一次快速 hash 去重。两张图是同一文件时直接拒绝(与 mapDiff 返回空差异不同):
{"error": "The files to be compared are the same<mapid>", "status": false}
⚠️ 报错文案里
same与 mapid 之间缺空格(服务端原文如此);HTTP 仍是 200,调用方须自查status/error字段。
真实对比时返回:
{
"status": true,
"addEntities": [...], // 仅在新图存在的实体 [{name, objectid, bounds}]
"deleteEntities": [...], // 仅在旧图存在
"modifyEntities": [...], // 两边都有但有差异(含 differents 明细)
"mapid1EntityCount": 123,
"mapid2EntityCount": 130
}
Python
svc.cmd_map_compare(mapid1="a", version1="v1", mapid2="a", version2="v2",
noCompareProps=True)
32 · 表格提取 extractTable
自动从 DWG 里识别"线条围出来的表格",返回单元格网格与每格文本。最常用于检图、清单导出。
请求参数
| 字段 | 说明 |
|---|---|
mapid / version |
要识别的图 |
layer |
可选,只在某 style / layer 上跑 |
bounds |
可选,限定在地图坐标系下的 bbox([x1,y1,x2,y2]) |
condition |
可选,后端条件表达式(同 queryFeatures 的 condition) |
isContains |
可选,bounds 内包含模式(默认相交) |
geom |
可选,是否带几何参与识别(默认 true) |
pageLimit |
可选,内部查询分页上限 |
findChildMapRects |
可选,同时提取子图框范围 |
响应(实采:sys_zp/v1,无额外参数)
{
"tables": [{
"attr": {
"cellEmptyRatio": 45,
"tableCellMaxCount": 70,
"tableTextCount": 39,
"unLinkLineRatio": 0
},
"colCount": 4,
"cols": ["587693680.21", "587698180.22", "587717259.64", "..."],
"datas": [["类目", "数量", "价格", "说明"], [...]],
"rows": ["...", "..."]
}]
}
cols/rows:单元格网格线的坐标;datas[i][j]:每格文本(可能含编码乱码,视 DWG 字体而定)。
Python
res = svc.cmd_extract_table(mapid="sys_zp", version="v1")
for t in res.get("tables", []):
print(t["colCount"], "x", len(t["rows"]))
Node.js
const res = await svc.cmdExtractTable({ mapid: 'sys_zp', version: 'v1' });
console.log(res.tables?.length);
33 · 中心线提取 extractCenterLines
对闭合多边形(如道路、管线)抽取中心线。
请求参数
| 字段 | 说明 |
|---|---|
mapid / version |
源图 |
layer |
可选,限定 style / layer |
bounds |
可选,限定地图坐标 bbox |
condition |
可选,后端条件表达式(同 queryFeatures 的 condition,不是 expr) |
isContains |
可选,bounds 包含模式(默认 false 相交) |
pageLimit |
可选,内部查询分页上限 |
bMergeLine / bMergeNode / bConnectGrapLine 等 |
可选,中心线合并/连接调优开关(b 前缀 bool 系列) |
响应(实采:sys_zp/v1)
{
"centerlines": [
[[587562497.79, 3103857885.77], [587556239.69, 3103860401.38]],
[[587603886.22, 3103921932.46], [587602627.19, 3103925333.77]]
]
}
centerlines 是"多段折线数组";每条线由若干 [x, y] 顶点构成。
Python
res = svc.cmd_extract_center_lines(mapid="sys_zp", version="v1")
for line in res["centerlines"]:
print("line with", len(line), "verts")
34 · 目标匹配 objectMatch
在底图中找与模板图形相似的子图(样式 + 尺寸)。常用于批量识别图章、标注块、设备。
请求参数
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
mapid / version |
string | — | 底图(模板与搜索都在这张图内) |
objectBounds |
string | — | 必填:模板图形所在 bbox [x1,y1,x2,y2](地图坐标)。必须是字符串形态——直接传 JSON 数组 [0,0,50,50] 会被拒 {"error":"param error, objectBounds is empty"} |
objectIds |
string | — | 或用实体 id 列表指定模板(与 objectBounds 二选一) |
mapBounds |
string | 全图范围 | 搜索范围 bbox,缺省用图档 drawBounds/dbBounds |
layer / layeron |
string | — | 底图 style / 参与渲染的图层 |
method |
string | matchTemplate |
匹配算法 |
score |
number | 0.6 | 相似度阈值 |
maxCount |
int | 100 | 最大命中数 |
canOverlap |
bool | false | 命中框是否允许重叠 |
maxOverlap |
number | 0.2 | 允许的最大重叠比例 |
toleranceAngle |
number | 0 | 角度容差(度) |
useToleranceRange |
bool | false | 启用尺寸容差区间,配合 tolerance1~tolerance4 |
minReduceArea |
number | 256 | 小于此面积的命中框被忽略 |
featureCount |
int | 128 | 特征点数量 |
size |
int | 16384 | 内部渲染分辨率 |
响应
成功时返回(注意字段名是 match):
{
"status": true,
"match": [
{ "bounds":"[x1,y1,x2,y2]", "angle": 0.0, "score": 0.92 },
...
]
}
Python
res = svc.cmd_match_object(
mapid="sys_zp", version="v1",
objectBounds="[587661000,3103886000,587661200,3103886200]",
score=0.7, toleranceAngle=90,
)
35 · SVG / 图像转 DWG imageSvgToDwg
把 SVG 字符串或位图转换成 DWG 实体。对位图会先做线条检测 + 矢量化。
请求参数
| 字段 | 说明 |
|---|---|
svg |
SVG 文本 |
image |
位图 base64 data-URL(data:image/png;base64,...,与 svg 二选一) |
layer |
结果实体的默认图层名 |
flipY |
Y 轴翻转(默认 true,SVG/位图坐标系转 CAD) |
offsetX / offsetY |
结果整体偏移 |
lineWidthScale |
线宽缩放 |
whiteColorProcessingParam / blackColorProcessingParam |
位图矢量化时的白/黑色处理参数(int) |
hasMapBounds + mapBoundLeftTopX/Y + mapBoundRightBtmX/Y |
把结果对齐到指定地图坐标范围 |
isZoomExtents |
结果 JSON 是否标记缩放到全图(默认 true) |
showLineWidth |
结果 JSON 的 LWDISPLAY(默认 true) |
retDocument |
true 时额外返回 doc(DWG JSON 字符串) |
bDisbleDrawFill |
禁用填充绘制(bool;后端拼写就是 Disble) |
响应(实采:svgData="<svg></svg>",空内容)
{
"error": "image or svg content is empty",
"status": false
}
合法输入时返回——doc 与 fileid 互斥(retDocument=true 返回 doc DWG JSON 字符串;false 时落盘成临时文件返回 fileid):
// retDocument=true
{ "status": true, "doc": "<DWG JSON 字符串>" }
// retDocument=false(默认)
{ "status": true, "fileid": "processData/xxx_tmp_60.dwg" }
可以把 doc 作为 mapdata 传给 create_entity_geo_data(见 03-query.md)渲染。
通用注意
- 这组接口都可能 耗时 >10s,SDK 默认 timeout=60s,建议在业务层再做重试与超时兜底。
- 后端遇到参数非法时常返回
{"error": "...", "status": false}——不是 HTTP 4xx/5xx。SDK 会把它当成 2xx 正常响应返回给调用方。 - 返回
"status": false时error字段的语言依系统 locale 而定(我们这里抓到了中/英混合的错误串)。