# Expression Query

When CAD drawings are opened directly in memory mode, there is no process of converting to a spatial database, so the frontend cannot perform custom queries on backend data via sql. Queries can only be performed through js scripts or through expressions. For expression syntax details, see the document Server-side Rendering Expression Syntax.

Tip

js scripts are easier to understand and get started with, but slightly slower in performance Expressions are harder to understand and master, but perform better We recommend using js scripts

# Built-in Variables

Variable Description Type Example
gInLayerIndex Current entity layer index (numeric) 0
gInObjectId Current entity object ID (string) '283' e.g. gInObjectId=='283'
gInFeatureType Current entity type (string) 'AcDbPolyline' e.g. gInFeatureType=='AcDbPolyline'
gInLayerName Current entity layer name (string) 'Layer1' e.g. gInLayerName=='Layer1'
gInColor Current entity color (numeric) 4278255615
gInColorRed Current entity color (red component) (numeric) 255
gInColorGreen Current entity color (green component) (numeric) 255
gInColorBlue Current entity color (blue component) (numeric) 0
gInColorAlpha Current entity color (alpha component) (numeric) 0
println Debug output function
gInExtendMinX Current entity extent (bottom-right X) (numeric) 700.10
gInExtendMinY Current entity extent (bottom-right Y) (numeric) 10.01
gInExtendMaxX Current entity extent (top-left X) (numeric) 800.20
gInExtendMaxY Current entity extent (top-left Y) (numeric) 20.02
gInAttrs1 Current entity attribute 1 value (string) s1 linetype
gInAttrs2 Current entity attribute 2 value (string) s2 extended dictionary data
gInAttrs3 Current entity attribute 3 value (string) s3 varies by entity type
gInAttrs4 Current entity attribute 4 value (string) s4 string attribute data, varies by entity type
gInAttrs5 Current entity attribute 5 value (string) s5 string attribute data, varies by entity type
gInAttrn6 Current entity attribute 6 value (numeric) n1 color index
gInAttrn7 Current entity attribute 7 value (numeric) n2 linetype scale
gInAttrn8 Current entity attribute 8 value (numeric) n3 line width
gInAttrn9 Current entity attribute 9 value (numeric) n4 transparency
gInAttrn10 Current entity attribute 10 value (numeric) n5 numeric attribute data, varies by entity type
gInAttrn11 Current entity attribute 11 value (numeric) n6 varies by entity type
gInAttrn12 Current entity attribute 12 value (numeric) n7 varies by entity type
gInAttrn13 Current entity attribute 13 value (numeric) n8 varies by entity type
gInAttrn14 Current entity attribute 14 value (numeric) n9 varies by entity type
gInAttrn15 Current entity attribute 15 value (numeric) n10 varies by entity type
gInCoordX Current entity X coordinate array (numeric array) [10,20...] gInCoordX[0]=10
gInCoordY Current entity Y coordinate array (numeric array) [10,20...] gInCoordY[0]=10
gInCoordZ Current entity Z coordinate array (numeric array) [10,20...] gInCoordZ[0]=10
gInCoordCount Current entity coordinate count (numeric) 2
gOutColorRed Output color (red component) (modify current entity color) (numeric) 255, e.g. gOutColorRed := 255; means all levels have red component 255; can also be array, e.g. gOutColorRed[0] := 122;gOutColorRed[5] := 200; means levels 1-4 have red 122, level 5+ has red 200
gOutColorGreen Output color (green component) (modify current entity color) (numeric) 255, same usage as above
gOutColorBlue Output color (blue component) (modify current entity color) (numeric) 255, same usage as above
gOutColorAlpha Output color (alpha component) (modify current entity color) (numeric) 255, same usage as above
gOutLineWidth Output line width (modify current entity line width) (numeric) 3, same usage as above
gOutVisible Output visibility (modify current entity visibility) (numeric) 1 or 0, same usage as above
gOutReturn 0 do not add to selection set; 1 add to selection set

# Supported CAD Entity Types

Class Name Description Type Value
AcDbLine Line 1
AcDbPolyline Polyline 2
AcDb2dPolyline 2D Polyline 3
AcDb3dPolyline 3D Polyline 4
AcDbSpline Spline 5
AcDbArc Arc 6
AcDbCircle Circle 7
AcDbEllipse Ellipse 8
AcDbCurve Curve 9
AcDbBlockReference Block Reference 10
AcDbHatch Hatch 11
AcDbMText Multiline Text 12
AcDbText Single-line Text 13
AcDbShape Shape 14
AcDbRasterImage Raster Image 15
AcDbWipeout Wipeout 16
AcDb2LineAngularDimension Angular Dimension [two lines] 17
AcDb3PointAngularDimension Angular Dimension [three points] 18
AcDbAlignedDimension Aligned Dimension 19
AcDbArcDimension Arc Dimension 20
AcDbDiametricDimension Diametric Dimension 21
AcDbOrdinateDimension Ordinate Dimension 22
AcDbRadialDimension Radial Dimension 23
AcDbRadialDimensionLarge Radial Dimension Large 24
AcDbRotatedDimension Rotated Dimension 25
AcDbAttributeDefinition Attribute Definition 26
AcDbAttribute Block Attribute 27
AcDbTable Table 28
AcDbMLeader MLeader 29
AcDbRegion Region 30
AcDbPolyFaceMesh Polyface Mesh 31
AcDbPolygonMesh Polygon Mesh 32
AcDbSurface Surface 33
AcDb3dSolid 3D Solid 34
AcDbFace 3D Face 35
AcDbSolid Solid 36

# Expression Examples

Query all lines in the drawing js

return gInFeatureType=='AcDbLine'
1

Query all 3D polylines with layer name "Layer1" in the drawing

return (gInFeatureType=='AcDb3dPolyline' && gInLayerName=='Layer1')
1

Query red single-line text in the drawing

return (gInFeatureType=='AcDbText' && gInColorRed==255 &&  gInColorGreen==0 &&  gInColorBlue==0)
1

Query entity with objectid of 9BE in the drawing

return gInObjectId=='9BE'
1

Query all text in the drawing (single-line text, multiline text, attribute definition, block attribute)

return (gInFeatureType=='AcDbText' || gInFeatureType=='AcDbMText' || gInFeatureType=='AcDbAttributeDefinition' || gInFeatureType=='AcDbAttribute')
1

Query all block entities in the drawing

return gInFeatureType=='AcDbBlockReference'
1

Query lines with length 10 in the drawing

return (gInFeatureType=='AcDbLine' && gInAttrn11 == 10)
1

Query circles with radius 5 in the drawing

return (gInFeatureType=='AcDbCircle' && gInAttrn12 == 5)
1

Query all polylines in the drawing with layer "grid lines" and coordinate x greater than 10

return (gInFeatureType == 'AcDbPolyline' &&  gInLayerName == 'grid lines' && gInExtendMinX >= 10)
1

# Query Method

 /**
 * Expression query for entities
 * @param param Parameters
 * @param cb Callback for processing each point in the result. If null is returned, the default handler is used
 */
exprQueryFeature(param: IExprQueryFeatures, cb?: (point: [number, number]) => [number, number] | null | undefined): Promise<any>;
   /**
 * Expression query entity parameters
 */
export  interface IExprQueryFeatures extends IQueryBaseFeatures {
    /** Expression. */
    expr: string;
    /** Record start position. */
    beginpos?: number;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

When writing expressions, you need to return based on condition evaluation. Format:

return true; // or return false;
1

For example, to query all block entities in the drawing, the expression is:

return gInFeatureType == 'AcDbBlockReference'
1

Query usage:

let query = await svc.exprQueryFeature({
    // Expression syntax
    // expr: `gOutReturn := if((gInFeatureType == 'AcDbPolyline' and  gInLayerName == 'grid lines' and gInExtendMinX >= ${center.x} ), 1, 0);`,
    // Now also supports js syntax
    // expr: `if (gInFeatureType == 'AcDbPolyline' &&  gInLayerName == 'grid lines' && gInExtendMinX >= ${center.x} ) {
    //         return true;
    //     } else {
    //         return false;
    //     }`,
    // Filter all block entities (expression syntax)
    // expr: `gOutReturn := if((gInFeatureType == 'AcDbBlockReference'), 1, 0);`,
    // Filter all block entities (js syntax)
    expr: `return gInFeatureType == 'AcDbBlockReference'`,
    fields: "objectid,blockname,envelop",
    useCache: true,
    limit: 1000000 // Large value, equivalent to finding all
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
显示代码
全屏显示


# Combining Expression Query and SQL Query

View online demo: Multiple queries for maximum sub-entity area of block objects (opens new window)

// --Multiple queries for maximum sub-entity area of block objects--Query the entity with the largest area in blocks, first via expression query, then via condition query. Analyze results together
let svc = new vjmap.Service(env.serviceUrl, env.accessToken)
let res = await svc.openMap({
    mapid: env.exampleMapId,
    mapopenway: vjmap.MapOpenWay.GeomRender, // Open in geometry rendering mode
    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"]; // Block name list to find. Block names can be found in the cloud management platform by clicking a block entity and checking blockname in the right-side properties

const handleQuery= async () => {
    let query = await svc.exprQueryFeature({
        expr: `return gInFeatureType == 'AcDbBlockReference'`,
        fields: "objectid,blockname,layername,positon,rotate,scaleX,scaleY,scaleZ", // Empty means all fields
        geom: false, // Memory mode
        useCache: true,
        limit: 1000000 // Large value, equivalent to finding all
    })
    if (query.error) {
        message.error(query.error)
        return
    }
    // Filter results by block name
    //  let findBlockName = new Set(blockNames);
    let objectIds = new Set(); // Block object objectid values
    let blockEntities = [];
    for(let i = 0; i < query.result.length; i++) {
        let blockname = query.result[i].blockname;
        // if (!findBlockName.has(blockname)) {
        // If not in the target list
        //     continue
        // }
        blockEntities.push(query.result[i])
        objectIds.add(query.result[i].objectid)
    }

    // Below, condition query for specific sub-entities contained in all blocks by objectid. This data cannot be obtained via memory query. Only after geometry processing decomposes blocks into individual sub-entities can condition query be used
    // In condition query, sub-entities of the same block all have objectid prefixed with that block's objectid_
    // Entity id
    // Block objectid naming rule: block_id_referenced_block_def_id1_referenced_block_def_id2(may have multiple)_entity_id_#;
    // Table naming rule: objectid naming rule: block_id_referenced_block_def_id1_referenced_block_def_id2(may have multiple)_entity_id_@;
    // Group objectid naming rule: $entity_id_element_index_in_entity$group_id;

    // Build sql condition, query all block objectid_ prefixed at once for efficiency
    // For fuzzy search, % can be used as wildcard in like. % defines wildcards before/after the pattern. like 'k%' finds strings ending with 'k'
    let condtionIds = Array.from(objectIds).map(id => `objectid like '${id}_%' `).join(" or ") // Concatenate all matching ids

    let condQuery = await svc.conditionQueryFeature({
        condition:  condtionIds, // objectid matching the above condition
        fields: "objectid,area",
        geom: true,
        limit: 100000 // Set large, equivalent to getting all. Default 100 if not specified
    })

    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)
    }

    // Find related entities under all blocks, find the sub-entity with maximum area
    let showDatas = []
    for(let block of blockEntities) {
        // All starting with block objectid_ are sub-entities of that block
        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(`Query result count: ${blockEntities.length} Press F12 to view console for details`);
};

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