# SQL查询

当CAD图纸以几何渲染方式打开时,后台会自动把CAD的数据转换为空间数据并保存至空间数据库。在前端可以通过sql对后台数据进行自定义查询。

# 后台表结构

具体可查看文档服务端条件查询和表达式查询

针对后台数据库表结构,使用sql语句条件部分进行数据查询。只需要写where后面的部分

表结构如下

字段名 类型 说明
id integer id
objectid text 实体id(块objectid命名规则:块id_引用的块定义id1_引用的块定义id2(可能有多个)_实体id; 组objectid命名规则:组id$实体id_实体内元素索引;表格命名规则:表格id@实体id_实体内元素索引,其余实体命名规则: id_实体内元素索引
layerindex integer 图层索引
name text 实体类型值,如"1"表示AcDbLine,具体值查看下面的“支持的CAD实体类型”
color int 颜色(根据rgb颜色计算此值,例如黑色为0x000000,加上透明度为0xFF000000, 变成无符号 0xff000000<<0结果为 -16777216)
data blob 几何数据
s1 text 线型
s2 text 扩展字典数据
s3 text 坐标数据,不同实体表达不一样
s4 text 字符型属性数据, 不同实体表达不一样
s5 text 字符型属性数据, 不同实体表达不一样
n1 float 颜色索引
n2 float 线型比例
n3 float 线宽
n4 float 透明度
n5 float 数值型属性数据, 不同实体表达不一样
n6 float 数值型属性数据, 不同实体表达不一样
n7 float 数值型属性数据, 不同实体表达不一样
n8 float 数值型属性数据, 不同实体表达不一样
n9 float 数值型属性数据, 不同实体表达不一样
n10 float 数值型属性数据, 不同实体表达不一样
geom GEOMETRY 实体外包矩形

# 表结构及每个字段对应的意义及说明

id objectid layerindex name color s3 s4 s5 n5 n6 n7 n8 n9 n10
数据库id 整型 实体id 字符型 图层索引 整型 类型值 字符型 颜色 整型 字符型 字符型 字符型 数值型 数值型 数值型 数值型 数值型 数值型
1 (AcDbLine 直线) points thickness length
2 (AcDbPolyline 多段线 points bulge data3d area isclosed linetypeScale thickness elevation
3 (AcDb2dPolyline 二维折线) points area isclosed polyType thickness elevation
4 (AcDb3dPolyline 三维多段线) points area isclosed polyType
5 (AcDbSpline 样条曲线) points area isclosed isFit fitTol degree
6 (AcDbArc 圆弧) center area isclosed radius startAngle endAngle thickness
7 (AcDbCircle 圆) center area isclosed radius thickness
8 (AcDbEllipse 椭圆) center majorAxis area isclosed radius startAngle endAngle
9 (AcDbCurve 曲线) area isclosed
10 (AcDbBlockReference 块参照) positon attributeDef blockname rotate scaleX scaleY scaleZ
11 (AcDbHatch 填充) points patternName elevation patternAngle patternScale
12 (AcDbMText 多行文本) location contents text height width rotate textHeight actualHeight actualWidth
13 (AcDbText 单行文本) location text height rotate horzMode
14 (AcDbShape 型实体) positon normal rotate size
15 (AcDbRasterImage 栅格图片) origin
16 (AcDbWipeout 遮罩实体) 16
17 (AcDb2LineAngularDimension 角度标注[两条线])
18 (AcDb3PointAngularDimension 角度标注[三点])
19 (AcDbAlignedDimension 对齐标注)
20 (AcDbArcDimension 圆弧标注)
21 (AcDbDiametricDimension 直径标注)
22 (AcDbOrdinateDimension 坐标标注)
23 (AcDbRadialDimension 半径标注)
24 (AcDbRadialDimensionLarge 半径折线标注)
25 (AcDbRotatedDimension 转角标注)
26 (AcDbAttributeDefinition 属性注记) location text contents height rotate horzMode
27 (AcDbAttribute 块属性) location text contents height rotate horzMode
28 (AcDbTable 表格) positon attributeDef contents rotate scaleX scaleY scaleZ
29 (AcDbMLeader 引线标注) location contents text height width rotate textHeight actualHeight actualWidth
30 (AcDbRegion 面域) points indices data3d area perimeter
31 (AcDbPolyFaceMesh 多面网格实体) points indices data3d
32 (AcDbPolygonMesh 多边形网格) points indices data3d
33 (AcDbSurface 曲面) points indices data3d
34 (AcDb3dSolid 三维实体) points indices data3d
35 (AcDbFace 三维面) points indices data3d

# SQL示例说明

只需要写where后面的部分

查询图中的所有的直线

name='1'
1

查询图中图层索引为0的所有三维多段线

name='4' and layerindex=0
1

查询图中红色单行文本

name='13' and color=-16776961
1

查询图中objectid为9BE的实体

objectid='9BE'
1

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

name='13' or name='12' or name='26' or name='27'
1

查询图中objectIdEA10D19A开头的块实体

objectid like 'EA_%'  or objectid like '10D_%'  or objectid like '19A_%'  
1

查询图中长度为10的直线

name='1' and n6 = 10
1

查询图中半径为5的圆

name='7' and n7 = 5
1

# 条件查询

 /**
 * 条件查询实体
 * @param param 参数
 * @param cb 结果中每个点的处理回调。如果返回空的话,则用默认处理方法
 */
conditionQueryFeature(param: IConditionQueryFeatures, cb?: (point: [number, number]) => [number, number] | null | undefined): Promise<any>;
/**
 * 条件查询实体参数
 */
export  interface IConditionQueryFeatures extends IQueryBaseFeatures {
    /** 条件. */
    condition: string;
    /** 范围.或者点坐标数组 */
    bounds?: [number, number, number, number] | [number, number][];
    /** 是否获取交点 bounds 为点坐标数组时有效,默认false */
    isGetIntersections?: boolean;
    /** 记录开始位置. */
    beginpos?: number;
    /** 是否返回几何数据,为了性能问题,realgeom为false时,如果返回条数大于1.只会返回每个实体的外包矩形,如果条数为1的话,会返回此实体的真实geojson;realgeom为true时每条都会返回实体的geojson */
    includegeom?: boolean;
    /** 是否返回真实实体几何geojson.与 includegeom参数,结合使用。参考includegeom的用法*/
    realgeom?: boolean;
    /** 是否为包含关系, true为包含关系,false为相交关系,默认false. (传入了bounds进行范围查询时有效)*/
    isContains?: boolean;
}
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

查询图中所有文字示例

let query = await svc.conditionQueryFeature({
    condition: `name='13' or name='12' or name='26' or name='27'`, // 只需要写sql语句where后面的条件内容,字段内容请参考文档"服务端条件查询和表达式查询"
    fields: "",
    geom: true,
    limit: 100000 //设置很大,相当于把所有的圆都查出来。不传的话,默认只能取100条
})
1
2
3
4
5
6
显示代码
全屏显示


# 点查询

 /**
 * 点查询实体
 * @param param 参数
 * @param cb 结果中每个点的处理回调。如果返回空的话,则用默认处理方法
 */
pointQueryFeature(param: IPointQueryFeatures, cb?: (point: [number, number]) => [number, number] | null | undefined): Promise<any>;
  
/**
 * 点查询实体参数
 */
export  interface IPointQueryFeatures extends IQueryBaseFeatures {
    /** 查询的坐标X. */
    x: number;
    /** 查询的坐标Y. */
    y: number;
    /** 像素大小. */
    pixelsize?: number;
    /** 条件. */
    condition?: string;
    /** 返回最大的几何字节数. */
    maxGeomBytesSize?: number;
    /** 当前一个像素表示多少几何长度,如果输入了此值,则为此值为主,否则,根据输入的zoom值后台自动计算. */
    pixelToGeoLength?: number;
}

/**
 * 查询实体参数
 */
export  interface IQueryBaseFeatures {
    /** 当前级别. */
    zoom?: number;
    /** 地图ID(为空时采用当前打开的mapid). */
    mapid?: string;
    /** 地图版本(为空时采用当前打开的地图版本). */
    version?: string;
    /** 图层名称(为空时采用当前打开的地图图层名称). */
    layer?: string;
    /** 返回最多的记录条数. */
    limit?: number;
    /** 是返回的字段列表,多个之是用逗号,分开,如. "name,objectid" */
    fields?: string;
    /** 是否为几何图形查询. */
    geom?: boolean;
    /** GeoJSON几何数据简化墨托卡距离,默认为零,不简化。例如允许10级别以上一个像素级别的误差,可用 map.pixelToGeoLength(1, 10) * vjmap.Projection.EQUATORIAL_SEMIPERIMETER * 2 / map.getGeoBounds(1.0).width() */
    simplifyTolerance?: boolean;
    /** 启动cache(内存打开的图形有效). */
    useCache?: boolean;
    /** 查询返回的坐标默认为墨卡托坐标,返回会程序会自动转化为cad坐标,如果要直接返回cad地图坐标,需要把toMapCoordinate设置为true. */
    toMapCoordinate?: boolean;
}
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

示例 叠加图形上点击选择CAD实体

# 矩形查询

 /**
 * 矩形查询实体
 * @param param 参数
 * @param cb 结果中每个点的处理回调。如果返回空的话,则用默认处理方法
 */
rectQueryFeature(param: IRectQueryFeatures, cb?: (point: [number, number]) => [number, number] | null | undefined): Promise<any>;
   

/**
 * 矩形查询实体参数
 */
export  interface IRectQueryFeatures extends IQueryBaseFeatures {
    /** 查询的坐标X1. (如果x1,y1,x2,y2同时不输的话,表示是查询整个图的范围 */
    x1?: number;
    /** 查询的坐标Y1. */
    y1?: number;
    /** 查询的坐标X2. */
    x2?: number;
    /** 查询的坐标Y2. */
    y2?: number;
    /** 条件. */
    condition?: string;
    /** 返回最大的几何字节数. */
    maxGeomBytesSize?: number;
}

/**
 * 查询实体参数
 */
export  interface IQueryBaseFeatures {
    /** 当前级别. */
    zoom?: number;
    /** 地图ID(为空时采用当前打开的mapid). */
    mapid?: string;
    /** 地图版本(为空时采用当前打开的地图版本). */
    version?: string;
    /** 图层名称(为空时采用当前打开的地图图层名称). */
    layer?: string;
    /** 返回最多的记录条数. */
    limit?: number;
    /** 是返回的字段列表,多个之是用逗号,分开,如. "name,objectid" */
    fields?: string;
    /** 是否为几何图形查询. */
    geom?: boolean;
    /** GeoJSON几何数据简化墨托卡距离,默认为零,不简化。例如允许10级别以上一个像素级别的误差,可用 map.pixelToGeoLength(1, 10) * vjmap.Projection.EQUATORIAL_SEMIPERIMETER * 2 / map.getGeoBounds(1.0).width() */
    simplifyTolerance?: boolean;
    /** 启动cache(内存打开的图形有效). */
    useCache?: boolean;
    /** 查询返回的坐标默认为墨卡托坐标,返回会程序会自动转化为cad坐标,如果要直接返回cad地图坐标,需要把toMapCoordinate设置为true. */
    toMapCoordinate?: boolean;
}
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

示例 数据自动生成CAD工程剖面图 (opens new window)

矩形查询也可以使用条件查询 conditionQueryFeature,查询条件bounds为一个矩形范围[number, number, number, number]。

# 多边形查询

多边形查询 可以使用条件查询 conditionQueryFeature,查询条件bounds为一个坐标数组 Array<[number, number]>。

示例 多边形选择实体 (opens new window)

# 分页查询

如果数据很多时,可以采用分页查询

如查询图中所有直线段(直线,二三维多段线)

 // 在图中查找所有的直线段
const  getMapHVLines = async () => {
    // 查找图中所有的直线,二三维多段线
    let queryEntTypes = ['AcDbLine', 'AcDbPolyline', 'AcDb2dPolyline', 'AcDb3dPolyline'];
    let cond = queryEntTypes.map(t => `name='${getTypeNameById(t)}'`).join(' or '); // sql条件

    let result = [];
    let beginPos = 0; // 记录查询开始位置
    // 有可能记录数会很多,这里用分页查询
    while(true) {
        let query = await svc.conditionQueryFeature({
            condition: cond, // 只需要写sql语句where后面的条件内容,字段内容请参考文档"服务端条件查询和表达式查询"
            fields: "objectid,points,envelop", // 只要id,坐标
            beginpos: beginPos, // 记录开始位置
            limit: 100000 // 每次查10万条
        });
        beginPos += query.result.length; // 开始位置位置挪动
        result.push(...query.result || []);
        if (result.length >= query.recordCount) break;
    }

    result = result.filter(e => {
        let points = e.points.split(";");
        if (points.length !=2 ) return false;
        e.geoStart = vjmap.GeoPoint.fromString(points[0]);
        delete e.geoStart.z;// 不考虑z值
        e.geoEnd = vjmap.GeoPoint.fromString(points[1]);
        delete e.geoEnd.z;// 不考虑z值

        if (e.geoStart.x > e.geoStart.x) {
            // 交换下
            let temp = e.geoStart;
            e.geoStart = e.geoEnd;
            e.geoEnd = temp;
        }
        e.startPoint = e.geoStart.toString();
        e.endPoint =  e.geoEnd.toString();
        if (e.startPoint == e.endPoint) {
            // 同一个点
            return false;
        }
        let line = points.map(e=>vjmap.geoPoint(e.split(",")))
        let isVLine = vjmap.isZero(line[0].x - line[1].x);//竖线
        let isHLine = vjmap.isZero(line[0].y - line[1].y);//横线
        if (!(isVLine || isHLine)) return false; // 并且是横线或竖线

        e.isHorzLine = isHLine;
        return true
    })
    return result;
}
// 实体类型ID和名称映射
const { entTypeIdMap } = await svc.getConstData();
const getTypeNameById = name => {
    for(let id in entTypeIdMap) {
        if (entTypeIdMap[id] == name) {
            return id
        }
    }
}
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