# BIM数据库(Alpha版)
# 一、简介
BIM(Building Information Modeling)建筑物信息建模,将传统建筑生命周期涉及要素进行数字化。借助数字化后的BIM时空数据,各业务或运营人员可在不同阶段进行进行业务辅助决策。同时,专业人员可基于BIM时空数据集挖掘潜在价值,构建丰富外围应用,为建筑智慧化赋能。BIM数据库,屏蔽底层复杂的BIM存储模型,对外提供统一友好的BIM时空数据查询及计算服务。
# 二、功能特性
BIM数据库,围绕BIM数据的核心概念“构件”,将与构件相关的各类附属信息,如属性,空间位置等,以RDB表的方式作为操作对象,通过使用SQL语言进行数据交互操作。
# 特性
- 以构件为中心:所有表的信息都能关联到唯一对应的构件上,即每张表都存在
element_id
的字段 - 数据拉平:在BIM模型中的嵌套数据被拉平为行列表形式,但不改变在逻辑上BIM本身是一种嵌套结构
- 域分类:对BIM中的不同信息,会按照自然归属、使用便捷性、甚至底层存储的分区特性等综合因素进行域划分,宏观意义上可以认为一个域表示一个命名空间,域的选择影响操作对象(TABLE、FUNCTION)的可见性。跨域数据禁止连接操作。
# 数据类型
数据类型 | 描述 | 范围及示例 |
---|---|---|
BOOLEAN | Logical values | 取值: TRUE, FALSE, UNKNOWN |
TINYINT | 1 byte signed integer | 范围 -128 到 127 |
SMALLINT | 2 byte signed integer | 范围 -32768 到 32767 |
INTEGER, INT | 4 byte signed integer | 范围 -2147483648 到 2147483647 |
BIGINT | 8 byte signed integer | 范围 -9223372036854775808 到 9223372036854775807 |
DECIMAL(p, s) | Fixed point | 示例: 123.45 表示为 DECIMAL(5, 2). |
NUMERIC | Fixed point | |
REAL, FLOAT | 4 byte floating point | 6位小数点后精度 |
DOUBLE | 8 byte floating point | 15位小数点后精度 |
CHAR(n), CHARACTER(n) | Fixed-width character string | 固定宽度字符串 |
VARCHAR(n), CHARACTER VARYING(n) | Variable-length character string | 可变长字符串 |
BINARY(n) | Fixed-width binary string | 固定宽度二进制字符串 |
VARBINARY(n), BINARY VARYING(n) | Variable-length binary string | 可变长二进制字符串 |
DATE | Date | 示例: DATE ‘1969-07-20’ |
TIME | Time of day | 示例: TIME ‘20:17:40’ |
TIMESTAMP [ WITHOUT TIME ZONE ] | Date and time | 示例: TIMESTAMP ‘1969-07-20 20:17:40’ |
GEOMETRY | Geometry | 示例: ST_GeomFromText(‘POINT (30 10)’) |
# 非标量类型
类型 | 描述 | 示例 |
---|---|---|
ANY | 任一类型,类似Object | |
UNKNOWN | 未知类型,常用作占位符 | |
ROW | 拥有1或多列的行数据 | 实例: Row(f0 int null, f1 varchar) |
MAP | MAP key和value的映射集合 | |
MULTISET | 无序集合,可能包含重复数据 | 示例: int multiset |
ARRAY | 有序的、连续的集合,可能包含重复数据 | 示例: varchar(10) array |
# 几何类型
空间数据被表示为编码为well-known text(WKT)的字符串或编码为well-known binary(WKB)的二进制字符串。
在你要使用文字的地方, 应用ST_GeomFromText
函数, 例如ST_GeomFromText('POINT (30 10)')
.
数据类型 | WKT示例 |
---|---|
POINT | ST_GeomFromText('POINT (30 10)') 2D空间的点; ST_GeomFromText('POINT Z(30 10 2)') 3D空间的点 |
LINESTRING | ST_GeomFromText('LINESTRING (30 10, 10 30, 40 40)') |
POLYGON | ST_GeomFromText('POLYGON ((30 10, 40 40, 20 40, 10 20, 30 10))') ; ST_GeomFromText('POLYGON ((35 10, 45 45, 15 40, 10 20, 35 10), (20 30, 35 35, 30 20, 20 30))') |
MULTIPOINT | ST_GeomFromText('MULTIPOINT ((10 40), (40 30), (20 20), (30 10))') 等价 ST_GeomFromText('MULTIPOINT (10 40, 40 30, 20 20, 30 10)') |
MULTILINESTRING | ST_GeomFromText('MULTILINESTRING ((10 10, 20 20, 10 40), (40 40, 30 30, 40 20, 30 10))') |
MULTIPOLYGON | ST_GeomFromText('MULTIPOLYGON (((30 20, 45 40, 10 40, 30 20)), ((15 5, 40 10, 10 20, 5 10, 15 5)))') |
# 几何检测
操作符 | 描述 |
---|---|
ST_Contains(geom1, geom2) | 返回geom1是否包含geom2。 |
ST_ContainsProperly(geom1, geom2) | 返回geom1是否包含geom2但不与之相交的边界。 |
ST_Covers(geom1, geom2) | 返回geom2中是否没有点在geom1之外。 |
ST_Crosses(geom1, geom2) | 返回geom1是否与geom2交叉。 |
ST_Disjoint(geom1, geom2) | 返回geom1和geom2是否不相交。 |
ST_DWithin(geom1, geom2, distance) | 返回geom1和geom是否在彼此的距离之内 |
ST_EnvelopesIntersect(geom1, geom2) | 返回geom1的envelope是否与geom2的envelope相交。 |
ST_Equals(geom1, geom2) | 返回geom1是否等于geom2。 |
ST_Intersects(geom1, geom2) | 返回geom1是否与geom2相交。 |
ST_Overlaps(geom1, geom2) | 返回geom1是否与geom2重叠。 |
ST_Touches(geom1, geom2) | 返回geom1是否触及geom2。 |
ST_Within(geom1, geom2) | 返回geom1是否在geom2内。 |
# 数学操作符和函数
操作符语法 | 描述 |
---|---|
+ numeric | 返回 numeric |
- numeric | 返回负 numeric |
numeric1 + numeric2 | 双数之和 |
numeric1 - numeric2 | 双数之差 |
numeric1 * numeric2 | 双数之积 |
numeric1 / numeric2 | 返回数字1除以数字2的结果。 |
POWER(numeric1, numeric2) | 返回numeric1提高到numeric2的幂数。 |
ABS(numeric) | 返回数字的绝对值 |
MOD(numeric1, numeric2) | 返回numeric1除以numeric2的余数(模数)。只有当numeric1为负数时,其结果才是负数。 |
SQRT(numeric) | 返回数字的平方根。 |
LN(numeric) | 返回数字的自然对数(基数e)。 |
LOG10(numeric) | 返回数字的底10对数 |
EXP(numeric) | 返回e提高到numeric的幂数。 |
CEIL(numeric) | 将数字向上舍入,返回大于或等于数字的最小的整数。 |
FLOOR(numeric) | 将数字向下舍入,返回小于或等于数字的最大整数。 |
RAND([seed]) | 生成一个介于0和1之间的随机双数,可以选择用seed初始化随机数发生器。 |
RAND_INTEGER([seed, ] numeric) | 生成一个介于0和数字-1之间的随机整数,可以选择用种子初始化随机数发生器。 |
ACOS(numeric) | the arc cosine of numeric |
ASIN(numeric) | the arc sine of numeric |
ATAN(numeric) | the arc tangent of numeric |
ATAN2(numeric, numeric) | the arc tangent of the numeric coordinates |
CBRT(numeric) | 返回数字的立方根 |
COS(numeric) | 返回数字的余弦值。 |
COT(numeric) | 返回numeric的余切值。 |
DEGREES(numeric) | 将数字从弧度转换为度数 |
PI() | 返回一个比任何其他值更接近pi的值 |
RADIANS(numeric) | 将数字从度数转换为弧度 |
ROUND(numeric1 [, numeric2]) | 将数字1四舍五入到可选的数字2(如果没有指定0)位数,直到小数点。 |
SIGN(numeric) | 返回numeric的符号。 |
SIN(numeric) | 返回数字的正弦值。 |
TAN(numeric) | 返回numeric的正切值。 |
TRUNCATE(numeric1 [, numeric2]) | 将numeric1截断到可选的numeric2(如果没有指定0)位,直到小数点。 |
# 字符串操作符和函数
操作符语法 | 描述 |
---|---|
string || string | 连接两个字符串 |
CHAR_LENGTH(string) | 返回一个字符串的长度 |
CHARACTER_LENGTH(string) | 如 CHAR_LENGTH(string) |
UPPER(string) | 返回一个转换为大写的字符串 |
LOWER(string) | 返回一个转换为小写的字符串 |
POSITION(string1 IN string2) | 返回字符串string1首次出现在string2中的位置 |
POSITION(string1 IN string2 FROM integer) | 返回string1在string2中第一次出现的位置,从一个给定的点开始(不是标准SQL) |
TRIM( { BOTH | LEADING | TRAILING } string1 FROM string2) | 从string1的开始/结束/两端删除只包含string1中的字符的最长字符串。 |
OVERLAY(string1 PLACING string2 FROM integer [ FOR integer2 ]) | 用string2替换string1的一个子串 |
SUBSTRING(string FROM integer) | 返回从给定点开始的字符串的子串 |
SUBSTRING(string FROM integer FOR integer) | 返回从给定点开始的字符串的子串,长度为给定值。 |
INITCAP(string) | 返回string,每个单词的第一个字母转换为大写,其余为小写。单词是由非字母数字字符分隔的字母数字字符序列。 |
# 条件函数和操作符
操作符语法 | 描述 |
---|---|
CASE value WHEN value1 [, value11 ]* THEN result1 [ WHEN valueN [, valueN1 ]* THEN resultN ]* [ ELSE resultZ ] END | CASE 后跟简单值 |
CASE WHEN condition1 THEN result1 [ WHEN conditionN THEN resultN ]* [ ELSE resultZ ] END | CASE WHEN后跟BOOL表达式 |
NULLIF(value, value) | 如果数值相同,则返回NULL。 例如,NULLIF(5, 5) 返回NULL;NULLIF(5, 0) 返回5。 |
COALESCE(value, value [, value ]*) | 如果第一个值为空,则提供一个值。 例如,COALESCE(NULL, 5) 返回5。 |
# JSON访问
操作符语法 | 描述 |
---|---|
JSON_EXISTS(jsonValue, path [ { TRUE | FALSE | UNKNOWN | ERROR } ON ERROR ] ) | 一个jsonValue是否满足使用JSON路径表达式path描述的搜索标准 |
JSON_VALUE(jsonValue, path [ RETURNING type ] [ { ERROR | NULL | DEFAULT expr } ON EMPTY ] [ { ERROR | NULL | DEFAULT expr } ON ERROR ] ) | 使用JSON路径表达式path从jsonValue中提取一个SQL标量 |
JSON_QUERY(jsonValue, path [ { WITHOUT [ ARRAY ] | WITH [ CONDITIONAL | UNCONDITIONAL ] [ ARRAY ] } WRAPPER ] [ { ERROR | NULL | EMPTY ARRAY | EMPTY OBJECT } ON EMPTY ] [ { ERROR | NULL | EMPTY ARRAY | EMPTY OBJECT } ON ERROR ] ) | 使用path JSON路径表达式从jsonValue提取一个JSON对象或JSON数组 |
# 三、访问方式
目前BIM数据库仅支持以OPENAPI的形式进行使用,其调用方法如下:
请求URL:
/bimspace/query/entrypoint
请求方式:
POST
请求参数
Query:
token=xxxcxx&buildingId=bbbbxxx (buildingId为建筑ID,必填)
1Body:
{ "query": "SELECT name, entity_type FROM TBIM_ELEMENT LIMIT 2", "params": [] //预编译参数,替换query中的?占位 }
1
2
3
4响应参数
{ "code":0, "message": "ok", "data": { "count": 2, //结果集计数 "columnIdx": { //列在rs中的下标,如name位于rs[]的0号元素 "name": 0, "entity_type": 1 }, "columns": ["name", "entity_type"], //所有列 "rs":[["洗手间的墙", "TBIM_WALL"]] //结果集 } }
1
2
3
4
5
6
7
8
9
10
11
12
13查询限制
查询语句请尽量细化过滤条件,避免一次性查过多数据,避免编写复杂嵌套语句,单次查询超过1000条数据将返回失败,10S未返亦将返回失败。
# 四、数据查询
- 归属域:BIM(系统默认工作空间,写查询语句时可不显式声明)
构件元素
TBIM_ELEMENT
,主要表示单个构件本身的信息字段名称 字段类型 字段定义 是否可为NULL element_id varchar 系统字段,构件ID 否 building_id varchar 建筑ID 否 name varchar 构件名称 否 entity_type varchar 构件类型 否 description varchar 构件描述 是 关于构件类型的定义:
构件类型(entity_type) 类型描述 TBIM_ROOF 屋顶
| TBIM_CURTAINWALL | 幕墙 | | TBIM_DOOR | 门 | | TBIM_RAMP | 斜坡 | | TBIM_PILE | 桩 | | TBIM_BEAM | 梁 | | TBIM_COVERING | 占地/覆盖 | | TBIM_RAILING | 栏杆 | | TBIM_SLAB | 厚板/楼板 | | TBIM_SHADINGDEVICE | 遮光装置 | | TBIM_STAIR | 楼梯 | | TBIM_PLATE | 板条/板材 | | TBIM_CHIMNEY | 烟囱 | | TBIM_FOOTING | 基础/地板 | | TBIM_COLUMN | 柱 | | TBIM_STAIRFLIGHT | 单段楼梯 | | TBIM_WALL | 墙 | | TBIM_RAMPFLIGHT | 单段斜坡 | | TBIM_MEMBER | 成员 | | TBIM_WINDOW | 窗 | | TBIM_BUILDING | 建筑 | | TBIM_SPACE | 空间 | | TBIM_BUILDINGSTOREY | 楼层 | | TBIM_SITE | 场所 | | TBIM_STATION | 工位 | | TBIM_PLANE_SPACE | 平面空间 |
构件属性
TBIM_PROPERTY
,存储构件的属性信息字段名称 字段类型 字段定义 是否可为NULL element_id varchar 系统字段,构件ID 否 building_id varchar 建筑ID 否 name varchar 属性名称 否 properties varchar/json 属性值,JsonObject,可视为字符串进行解析 否 description varchar 属性描述 是 构件关系
TBIM_RELATION
,构件与构件之间的关联关系字段名称 字段类型 字段定义 是否可为NULL relating_element_id varchar 主构件ID 否 relating_element_type varchar 主构件类型,见"构件类型定义" 否 related_element_id varchar 关联构件ID 否 related_element_type varchar 关联构件类型,见"构件类型定义" 否 relate_type varchar 关系类型 否
# 五、空间计算
BIM数据的很大价值在于具有可计算(computable)的特点,BIM数据库支持使用如下Function进行空间计算,特别的,使用**"SP"**域存放与空间相关的数据用于辅助计算:
空间位置信息表 Loc
. 归属域SP
字段名称 | 字段类型 | 字段定义 | 是否可为NULL |
---|---|---|---|
element_id | varchar | 系统字段,构件ID | 否 |
central_point | point | 构件包围盒中心点,当为虚拟构件时值为NULL | 是 |
entity_type | varchar | 构件类型 | 否 |
tree_path | varchar | 构件在BIM树中的关系链,以$ElementId->$ElementId的形式串接, 如el1->el2->el3 | 否 |
rel_path | varchar | 构件在BIM树中的关系链,以$entity_type->$entity_type的形式串接, 如TBIM_BUILDING->TBIM_BUILDINGSTOREY | 否 |
space_name | varchar | 构件归属房间的名称 | 是 |
floor_name | varchar | 构件归属楼层的名称 | 是 |
空间算子:
直线距离
方法:
ST_3DDistance(Point start, Point end)
参数:
| 参数 | 类型 | 说明 | -------| ----- | ------------- | ------------ | | start | Point几何类型 | 测量起点坐标 | | end | Point几何类型 | 测量终点坐标 |
说明:该方法入参需要构造Poin类型的几何数据结构,使用
ST_GeomFromText('POINT Z(30 10 2)')
或ST_MakePoint(30,10,2)
示例:
SELECT ST_3DDistance(ST_MakePoint(0,0,0), ST_MakePoint(1,1,1));
构件体积测量(单位m³):
方法:
double BM_MeasureVolume(String elementId)
参数:
参数 类型 说明 elementId varchar 可绘制(非虚拟构件)的构件ID 说明:该方法依赖相应构件对应的MESH网格数据,无该数据和计算无效时返回-1
示例:
SELECT BM_MeasureVolume('elesmiidxxf')
构件表面积测量(单位㎡):
方法 :
double BM_MeasureBoundarySize(String elementId)
参数:参数 类型 说明 elementId varchar 可绘制(非虚拟构件)的构件ID 说明:该方法依赖相应构件对应的MESH网格数据,无该数据和计算无效时返回-1
示例:
SELECT BM_MeasureBoundarySize('elesmiidxxf')
构件横截面积测量(单位㎡):
方法:
double BM_MeasureCrossSectionBoundarySize(String elementId, Point axis, BigDecimal ratio)
参数:参数 类型 说明 elementId varchar 可绘制(非虚拟构件)的构件ID axis point 横切轴,可选(0,0,1)、(0,1,0)、(1,0,0),即分别表示沿着Z、Y、X轴进行横切 ratio double 横切比率,例如0.5表示从中间横切 说明:该方法依赖相应构件对应的MESH网格数据,无该数据和计算无效时返回-1
示例:
SELECT BM_MeasureCrossSectionBoundarySize('elesmiidxxf', ST_MakePoint(0,0,1), 0.5)
综合示例:
成本预估:
场景:装修需求,要对某大厅内的柱子异色粉刷,评估耗材量
思路:筛选指定空间的柱子类型构件,使用空间测量函数计算可粉刷表面积后代入评估公式计算
表达:
SELECT SUM(t.粉刷面积 * ${单位面积耗材}) AS 总耗材 FROM (SELECT (BM_MeasureBoundarySize(element_id) - BM_MeasureCrossSectionBoundarySize(element_id, ST_MakePoint(0,1,0),0.1) * 2) AS 粉刷面积 FROM SP.LOC WHERE floorName='22F' AND spaceName='中央大厅' AND entity_type='TBIM_COLUMN') AS t