mapdata-query
本文回答:
mapcadLayer.queryMapEntities/queryMapEntitiesByLayer—— 一条 SQL 从后端拉回批量 DWG 实体。
一、为什么要用它
直接用 svc.conditionQueryFeature 有三个坑:
- 类型名是数字 ID:后端表里
name='13'代表AcDbText,不是字符串。 - 分批请求贵:一次 HTTP + SQL 空间查询有几十 ms 开销;N 次查询 = N × 开销。
- 结果需要再处理:坐标系、缺省字段处理。
queryMapEntities 封装了这三点:
const fc = await mapcadLayer.queryMapEntities({
entTypes: ['AcDbText', 'AcDbMText'], // 自动翻译成 name='13' or name='12'
condition: "text like '%标题%'" // 再 AND 拼 where
});
返回标准 GeoJSON.FeatureCollection。
二、queryMapEntities 选项
| 选项 | 类型 | 说明 |
|---|---|---|
entTypes |
string[] |
AcDb 类型名数组;SDK 翻译并 or 拼入 where |
condition |
string |
额外 SQL where;与 entTypes 以 AND 组合 |
bounds |
[x1,y1,x2,y2] 或点数组 |
范围限定 |
isContains |
boolean |
范围查询是包含 (true) 还是相交 (false,默认) |
fields |
string |
逗号分隔字段名 |
limit |
number |
单次上限,默认 50000 |
beginpos |
number |
分页起点 |
toMapCoordinate |
boolean |
返回 CAD 坐标(默认 true);false = Mercator |
includegeom / realgeom |
boolean |
是否返回完整 geojson 几何(coordType=1 时默认 true) |
coordType |
0 | 1 |
0=只要位置坐标(轻量),1=真实几何,默认 1 |
layer |
string |
样式图层名过滤(对应 IQueryBaseFeatures.layer;按图层查更推荐用 queryMapEntitiesByLayer) |
zoom |
number |
单次查询 zoom |
mapid / version |
string |
指定图/版本(默认当前打开的) |
extra |
Record<string,any> |
透传给 conditionQueryFeature 的其它参数 |
三、常用 entTypes 翻译表
| 类型名 | ID |
|---|---|
AcDbLine |
1 |
AcDbPolyline |
2 |
AcDb2dPolyline |
3 |
AcDb3dPolyline |
4 |
AcDbSpline |
5 |
AcDbArc |
6 |
AcDbCircle |
7 |
AcDbEllipse |
8 |
AcDbBlockReference |
10 |
AcDbHatch |
11 |
AcDbMText |
12 |
AcDbText |
13 |
AcDbAttributeDefinition |
26 |
AcDbAttribute |
27 |
翻译过程 SDK 会调 svc.getConstData().entTypeIdMap 并按 service 缓存。
四、按图层查询
const fc = await mapcadLayer.queryMapEntitiesByLayer(
'道路', // 图层名(不是索引)
['AcDbLine', 'AcDbPolyline', 'AcDb2dPolyline'],
{ limit: 20000 }
);
// 内部 where: layerindex=N and (name='1' or name='2' or name='3')
entType 传 undefined → 只按图层过滤。
⚠️ 图层名 vs 索引坑(实采 2026-09-20):
layerName是在svc.getMapLayers()里按l.name匹配的图层名;查询结果里properties.layerindex是数字索引(如12),把这个索引串当 layerName 传回去会查不到图层并静默返回空 FC(不报错)。实体属性里的图层名要用getMapLayers()[layerindex].name反查。
五、combineWhere 拼多条件
const where = vjmapext.combineWhere(
"text like '%A%'",
"text like '%B%'",
"" // 空串自动忽略
);
// → (text like '%A%') or (text like '%B%')
六、buildEntTypeCondition 手动拿类型片段
自己拼 SQL:
const typeFrag = await vjmapext.buildEntTypeCondition(map, ['AcDbText','AcDbMText']);
// → "name='13' or name='12'"
const fc = await mapcadLayer.queryMapEntities({
condition: `(${typeFrag}) and color=-65536`
});
七、分页
单次 limit 最大建议 50000;大数据分页:
async function fetchAll(opts, limit = 10000) {
const all = [];
for (let begin = 0; ; begin += limit) { // 游标按 limit 步进,不能按 features.length
const fc = await mapcadLayer.queryMapEntities({ ...opts, limit, beginpos: begin });
all.push(...fc.features);
if (fc.eof || begin + limit >= (fc.recordCount ?? 0)) break; // 以 eof / recordCount 判结束
}
return all;
}
⚠️ 无法提取几何(既无 geom 也无 location)的记录会在组装 FeatureCollection 时被丢弃,所以 features.length 可能小于本页实际行数——用它判断"最后一页"会提前退出,用它推进 beginpos 会重复取数。
八、返回结构
{
type: 'FeatureCollection',
features: Feature[],
recordCount?: number, // 总数
beginpos?: number,
eof?: boolean
}
每个 Feature:
{
type: 'Feature',
id: string | number, // objectid
properties: {
name: string, // 'AcDbText' 等可读名
objectid: string,
layerindex: number,
color: number, // int32,可能负数
location?: string, // "x,y" 或 "x,y;x,y"
points?: string,
text?: string, contents?: string,
height?: number, rotate?: number,
...
},
geometry: Geometry
}
九、典型场景
1 找出所有 "总平面图" 文字
const fc = await mapcadLayer.queryMapEntities({
entTypes: ['AcDbText', 'AcDbMText'],
condition: vjmapext.combineWhere(
"text like '%总平面图%'",
"contents like '%总平面图%'"
)
});
2 取视口内某图层所有线
const bounds = map.getGeoBounds();
const fc = await mapcadLayer.queryMapEntitiesByLayer('wall', ['AcDbLine','AcDbPolyline'], {
bounds: [bounds.min.x, bounds.min.y, bounds.max.x, bounds.max.y],
isContains: false
});
3 仅要属性不要几何(速度提升)
const fc = await mapcadLayer.queryMapEntities({
entTypes: ['AcDbText'],
fields: 'objectid,text,location,color,layerindex',
includegeom: false
});
十、常见坑
- entTypes 直接传
'AcDbText':queryMapEntities的entTypes必须传数组['AcDbText']——单字符串会被逐字符当类型名查表,全部不命中,静默返回空 FeatureCollection。只有queryMapEntitiesByLayer的entType形参容忍单字符串(内部自动归一为数组)。 - bounds 单位:是 CAD 坐标,不是经纬度;要
map.fromLngLat转。 - limit 过大 + includegeom:返回数据 MB 级,网络和 parse 都慢。
- name='AcDbText' 永远命中 0 条:后端
name是数字 ID,不是可读名。 - 多个
queryMapEntities并发:OK,但服务端有 rate limit;超 30 req/s 可能被限流。 fields必须含geojson才出 Feature:行转 Feature 时 SDK 只认geom/points/location/center/insertionPoint/origin等几何字段,而geom本身是_processQueryResult从后端geojson字段合成的——fields:"objectid"这类纯属性清单会让recordCount=554但features为 0(行全被丢,不报错)。fields里写geojson而非geom。
相关
- 后续接管 → features-to-entities
- 隐藏原图 → mapdata-hider
- SQL 表达式细节 → backend/query-sql