# 表达式查询

当CAD图纸以内存模式方式直接打开时,因为没有转空间数据库这个过程,所以在前端无法可以通过sql对后台数据进行自定义查询,只能通过表达式进行查询。

表达式语法具体可查看文档服务端渲染表达式语法

# 表达式内置变量

变量 说明 类型 举例
gInLayerIndex 当前实体图层索引 (数值型) 0
gInObjectId 当前实体对象ID (字符串) '283' 判断如 gInObjectId=='283'
gInFeatureType 当前实体类型 (字符串) 'AcDbPolyline' 判断如 gInFeatureType=='AcDbPolyline'
gInLayerName 当前实体图层名称 (字符串) '图层1' 判断如 gInLayerName=='图层1'
gInColor 当前实体颜色 (数值型) 4278255615
gInColorRed 当前实体颜色(红色分量) (数值型) 255
gInColorGreen 当前实体颜色(绿色分量) (数值型) 255
gInColorBlue 当前实体颜色(蓝色分量) (数值型) 0
gInColorAlpha 当前实体颜色(透明度分量) (数值型) 0
println 调试输出函数
gInExtendMinX 当前实体图形范围(右下角X) (数值型) 700.10
gInExtendMinY 当前实体图形范围(右下角y) (数值型) 10.01
gInExtendMaxX 当前实体图形范围(左上角X) (数值型) 800.20
gInExtendMaxY 当前实体图形范围(左上角y) (数值型) 20.02
gInAttrs1 当前实体属性一值 (字符串) s1 线型
gInAttrs2 当前实体属性二值 (字符串) s2 扩展字典数据
gInAttrs3 当前实体属性三值 (字符串) s3 不同实体表达不一样
gInAttrs4 当前实体属性四值 (字符串) s4 字符型属性数据, 不同实体表达不一样
gInAttrs5 当前实体属性五值 (字符串) s5 字符型属性数据, 不同实体表达不一样
gInAttrn6 当前实体属性六值 (数值型) n1 颜色索引
gInAttrn7 当前实体属性七值 (数值型) n2 线型比例
gInAttrn8 当前实体属性八值 (数值型) n3 线宽
gInAttrn9 当前实体属性九值 (数值型) n4 透明度
gInAttrn10 当前实体属性十值 (数值型) n5 数值型属性数据, 不同实体表达不一样
gInAttrn11 当前实体属性11值 (数值型) n6 不同实体表达不一样
gInAttrn12 当前实体属性12值 (数值型) n7 不同实体表达不一样
gInAttrn13 当前实体属性13值 (数值型) n8 不同实体表达不一样
gInAttrn14 当前实体属性14值 (数值型) n9 不同实体表达不一样
gInAttrn15 当前实体属性15值 (数值型) n10 不同实体表达不一样
gInCoordX 当前实体坐标X数组 (数值型数组) [10,20...] gInCoordX[0]=10
gInCoordY 当前实体坐标Y数组 (数值型数组) [10,20...] gInCoordY[0]=10
gInCoordZ 当前实体坐标Z数组 (数值型数组) [10,20...] gInCoordZ[0]=10
gInCoordCount 当前实体坐标个数 (数值型) 2
gOutColorRed 返回的颜色(红色分量)(修改当前实体颜色) (数值型) 255,如gOutColorRed := 255;表示所有级别红色分量为255; 也可以是数组表示,如gOutColorRed[0] := 122;gOutColorRed[5] := 200;表示1-4级别红色分量是122,5级别以上是红色分量200
gOutColorGreen 返回的颜色(红色分量)(修改当前实体颜色) (数值型) 255,用法同上
gOutColorBlue 返回的颜色(红色分量)(修改当前实体颜色) (数值型) 255,用法同上
gOutColorAlpha 返回的颜色(透明度分量)(修改当前实体颜色) (数值型) 255,用法同上
gOutLineWidth 返回的线宽值(修改当前实体线宽值) (数值型) 3,用法同上
gOutVisible 返回是否可见(修改当前实体是否可见) (数值型) 1或0,用法同上
gOutReturn 0 不加入选择集;1加入选择集

# 支持的CAD实体类型

类名称 说明 类型值
AcDbLine 直线 1
AcDbPolyline 多段线 2
AcDb2dPolyline 二维折线 3
AcDb3dPolyline 三维多段线 4
AcDbSpline 样条曲线 5
AcDbArc 圆弧 6
AcDbCircle 7
AcDbEllipse 椭圆 8
AcDbCurve 曲线 9
AcDbBlockReference 块参照 10
AcDbHatch 填充 11
AcDbMText 多行文本 12
AcDbText 单行文本 13
AcDbShape 型实体 14
AcDbRasterImage 栅格图片 15
AcDbWipeout 遮罩实体 16
AcDb2LineAngularDimension 角度标注[两条线] 17
AcDb3PointAngularDimension 角度标注[三点] 18
AcDbAlignedDimension 对齐标注 19
AcDbArcDimension 圆弧标注 20
AcDbDiametricDimension 直径标注 21
AcDbOrdinateDimension 坐标标注 22
AcDbRadialDimension 半径标注 23
AcDbRadialDimensionLarge 半径折线标注 24
AcDbRotatedDimension 转角标注 25
AcDbAttributeDefinition 属性注记 26
AcDbAttribute 块属性 27
AcDbTable 表格 28
AcDbMLeader 引线标注 29
AcDbRegion 面域 30
AcDbPolyFaceMesh 多面网格实体 31
AcDbPolygonMesh 多边形网格 32
AcDbSurface 曲面 33
AcDb3dSolid 三维实体 34
AcDbFace 三维面 35

# 表达式示例说明

查询图中的所有的直线

gInFeatureType=='AcDbLine'
1

查询图中图层名称为图层1的所有三维多段线

gInFeatureType=='AcDb3dPolyline' and gInLayerName=='图层1'
1

查询图中红色单行文本

gInFeatureType=='AcDbText' and gInColorRed==255 and  gInColorGreen==0 and  gInColorBlue==0
1

查询图中objectid为9BE的实体

gInObjectId=='9BE'
1

查询图中所有文本(单行文本、多行文本、属性注记、块属性)

gInFeatureType=='AcDbText' or gInFeatureType=='AcDbMText' or gInFeatureType=='AcDbAttributeDefinition' or gInFeatureType=='AcDbAttribute'
1

查询图中所有块实体

gInFeatureType=='AcDbBlockReference'
1

查询图中长度为10的直线

gInFeatureType=='AcDbLine' and gInAttrn11 = 10
1

查询图中半径为5的圆

gInFeatureType=='AcDbCircle' and gInAttrn12 = 5
1

图询图中所有多段线并且图层为网格线,同时坐标x需大于10

gInFeatureType == 'AcDbPolyline' and  gInLayerName == '网格线' and gInExtendMinX >= 10
1

# 查询方法

 /**
 * 表达式查询实体
 * @param param 参数
 * @param cb 结果中每个点的处理回调。如果返回空的话,则用默认处理方法
 */
exprQueryFeature(param: IExprQueryFeatures, cb?: (point: [number, number]) => [number, number] | null | undefined): Promise<any>;
   /**
 * 表达式查询实体参数
 */
export  interface IExprQueryFeatures extends IQueryBaseFeatures {
    /** 表达式. */
    expr: string;
    /** 记录开始位置. */
    beginpos?: number;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

写表达式时,需要根据条件判断是否返回,格式为:

gOutReturn := if((表达式), 1, 0);
1

如查询图中所有块实体,表达式为

gInFeatureType == 'AcDbBlockReference'
1

查询写法为

gOutReturn := if((gInFeatureType == 'AcDbBlockReference'), 1, 0);
1

查询写法为:

let query = await svc.exprQueryFeature({
    // expr: `gOutReturn := if((gInFeatureType == 'AcDbPolyline' and  gInLayerName == '网格线' and gInExtendMinX >= ${center.x} ), 1, 0);`,
    // 过滤出所有块对象实体
    expr: `gOutReturn := if((gInFeatureType == 'AcDbBlockReference'), 1, 0);`,
    fields: "objectid,blockname,envelop",
    useCache: true,
    limit: 1000000 // 数量大些,相当于查找所有的
})
1
2
3
4
5
6
7
8
显示代码
全屏显示


# 表达式查询和Sql查询结合使用

在线查看示例多种查询块对象子实体面积最大值 (opens new window)

// --多种查询块对象子实体面积最大值--查询块中面积最大的实体,先通过表达式查询,再通过条件查询。一起分析结果
let svc = new vjmap.Service(env.serviceUrl, env.accessToken)
let res = await svc.openMap({
    mapid: env.exampleMapId,
    mapopenway: vjmap.MapOpenWay.GeomRender, // 以几何数据渲染方式打开
    style: vjmap.openMapDarkStyle()
})
if (res.error) {
    message.error(res.error)
}
let mapExtent = vjmap.GeoBounds.fromString(res.bounds);
let prj = new vjmap.GeoProjection(mapExtent);
let center = mapExtent.center();
let map = new vjmap.Map({
    container: 'map', // container ID
    style: svc.rasterStyle(),
    center: prj.toLngLat(center),
    zoom: 2,
    renderWorldCopies: false
});
map.attach(svc, prj);
map.fitMapBounds();

map.addControl(new vjmap.NavigationControl());
map.addControl(new vjmap.MousePositionControl({showZoom: true}));

// let blockNames = ["M_F13", "_AXISO"]; // 要查找的块名称列表 块名称可通过在云端管理平台中点击块实体,右侧属性中的blockname

const handleQuery= async () => {
    let query = await svc.exprQueryFeature({
        // 先表达式查询所有的块实体,因为如何用条件查询的话,块已经转为了离散的空间数据,不能整体查了,所以先通过表达式查询出块信息
        /// 以下是查所有块。如果要查询某个具体的块名可以这样写  expr: `gOutReturn := if((gInFeatureType == 'AcDbBlockReference' and gInAttrs4 == '您要查询的块名称'), 1, 0);`,
        expr: `gOutReturn := if((gInFeatureType == 'AcDbBlockReference'), 1, 0);`,
        fields: "objectid,blockname,layername,positon,rotate,scaleX,scaleY,scaleZ", // 为空的话,表达所有字段
        geom: false, // 内存模式
        useCache: true,
        limit: 1000000 // 数量大些,相当于查找所有的
    })
    if (query.error) {
        message.error(query.error)
        return
    }
    // 根据要过滤的块名称过滤结果
    //  let findBlockName = new Set(blockNames);
    let objectIds = new Set(); // 块对象的objectid值
    let blockEntities = [];
    for(let i = 0; i < query.result.length; i++) {
        let blockname = query.result[i].blockname;
        // if (!findBlockName.has(blockname)) {
        // 如果不在要找的里面
        //     continue
        // }
        blockEntities.push(query.result[i])
        objectIds.add(query.result[i].objectid)
    }

    // 下面根据所有块的objectid去条件查询下面块中所包含的具体子实体。这个数据通过内存查询查不到。只有通过几何处理把块分解成了一个个子实体了,通过条件查询去查
    // 条件查询中同一个块实体的objectid都是为此块的objectid_开头的
    // 实体id
    // 块objectid命名规则:块id_引用的块定义id1_引用的块定义id2(可能有多个)_实体id_#;
    // 表格命名规则:objectid命名规则:块id_引用的块定义id1_引用的块定义id2(可能有多个)_实体id_@;
    // 组objectid命名规则:$实体id_实体内元素索引$组id;

    // 构造sql条件,所有块objectid_开头的一次先查出来。提高效率
    // 模糊查找可能like中的匹配符%查找。%符号用于在模式的前后定义通配符。like 'k%'查找以字母 'k' 结尾
    let condtionIds = Array.from(objectIds).map(id => `objectid like '${id}_%' `).join(" or ") // 把所有符合条件的id用字符串连起来

    let condQuery = await svc.conditionQueryFeature({
        condition:  condtionIds, // objectid符合上面的条件就可以。
        fields: "objectid,area",
        geom: true,
        limit: 100000 //设置很大,相当于把所有的都查出来。不传的话,默认只能取100条
    })

    if (query.error) {
        message.error(query.error)
        return
    }
    let blockFeatures = []
    for(let i = 0; i < condQuery.result.length; i++) {
        let item = condQuery.result[i];
        blockFeatures.push(item)
    }

    // 查找所有块下面的相关的实体,找出面积最大的子实体
    let showDatas = []
    for(let block of blockEntities) {
        // 以块objectid_开头的都是块的子实体
        let blockFeature = blockFeatures.filter(b => b.objectid.indexOf(block.objectid + "_") === 0)
        let maxArea = Math.max(...blockFeature.filter(b => b.area).map(d => d.area))
        showDatas.push({
            ...block,
            area: maxArea
        })
    }
    console.table(showDatas)
    message.info(`查询到符合的记数条数:${blockEntities.length} 请按F12查看控制台具体数据`)
};

handleQuery();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100