一种基于glTF的BIM数据与GIS数据的整合方法
技术领域
本发明涉及建筑智能化技术领域,具体是一种基于glTF的BIM数据与GIS数据的整合方法。
背景技术
在建筑工程业界,建筑信息模型与管理(BIM)被广泛认为是一种能够提高生产效率和交付质量的新型工具。BIM主要针对建筑个体本身,将建筑工程图纸从传统的二维模式转变为可视化的三维模型,并且包含了建筑生命周期中所有的建筑信息。方便了设计、施工、运维等各方对于项目信息的提取,大大提高了建筑项目准确度与生产效率。为了确保信息数据能够在建筑工程行业内部完整、一致并且正确地进行传递与交流,IFC作为唯一国际公认的开放性BIM数据标准,采用了电脑编程EXPRESS语言进行数据描述来定义建筑物及其内部构件关系。保证了的数据在各阶段的完整性。
地理信息系统(GIS)作为一种特定的在信息软件支持下,对整个或部分空间的相关环境地理分布数据提供采集、储存、管理、分析以及显示等功能的技术系统,也在逐渐被运用到生活中的各个领域,如水文地理分析、灾害防治、商业服务、交通运输管理等。相对于BIM关注的是建筑本身的信息,GIS则针对的是建筑周边乃至整片区域或是整座城市的地理环境信息。这类信息的收集与使用不仅能够为建筑本身的规划与设计提供参考依据,还可以协助完成以整片区域或整座城市为规模的规划与设计,推动未来概念中三维数字化城市的建设与发展。
对于BIM来说,BIM的整个生命周期从设计、施工到运维都是针对BIM单体精细化模型的,但是其不可能脱离周边的宏观的地理环境要素,成为空中楼阁。而三维GIS一直致力于宏观地理环境的研究,提供各种空间查询及空间分析功能,并且在BIM的运维阶段,三维GIS可以为其提供决策支持,因此BIM需要三维GIS。
对于三维GIS来说,BIM数据是三维GIS的另一个重要的数据来源,能够让三维GIS从宏观走向微观,同时可以实现精细化管理。另一个方面,与BIM数据的融合使三维GIS从室外走向室内,实现室内外一体化的管理。
BIM和GIS都依赖各自的数据格式。因此如何有效的整合BIM与GIS数据成为了结合两种技术的关键。
目前,整合BIM与GIS数据的方法主要有三种:第一种是将GIS数据转换成BIM数据,即大多数情况下将CityGML格式转换成IFC格式达到结合二者技术的效果。但是在转换的过程中存在部分数据的丢失并且由于CityGML模型数据量大,会导致转换后BIM模型数据量过载等问题。第二种方法是将BIM模型转换成GIS模型。即将IFC格式转换成CityGML格式。由于BIM数据比较精细数据量偏大导致计算量大、读取速度缓慢、画质低等问题并且转化过程中会导致部分BIM模型信息丢失。第三种方式是建立通用的数据模型作为IFC和CItyGML中间的转换工具并保证数据可以进行双向转换。但是目前制作新的数据模型的工作量大、耗时长往往仅适用于解决小的特定问题,不具有普适性。
在目前市场上有一些相关的BIM-GIS的平台产品。如ArcGIS Pro、Infrawork和FZKViewer。但是他们在信息的完整性、渲染效果、兼容性以及传输速度都分别有一定程度的缺失。
发明内容
本发明的目的在于提供一种基于glTF的BIM数据与GIS数据的整合方法,该方法能够克服传统整合过程中出现的信息丢失、数据量过载和可视化效果不佳的问题,实现BIM数据与GIS数据的有效整合。
本发明解决其技术问题所采用的技术方案是:
一种基于glTF的BIM数据与GIS数据的整合方法,包括以下步骤:
S1、提取IFC模型文件中的项目信息、场地信息、建筑物信息、楼层信息、房间信息、洞口信息以及建筑构件属性信息,提取IFC模型文件时生成属性信息模型,根据属性信息模型生成一份JSON格式的属性信息文件;
S2、对IFC模型文件构件信息进行预处理,提取IFC模型文件中的构件几何信息,通过几何变换生成glTF格式建筑模型,再生成一份与属性信息文件相匹配的glTF建筑模型文件;所述预处理在IFC模型文件中构件的名称后面增加“@”与“构件ID”;
S3、将JSON格式的属性信息文件与glTF格式的建筑模型文件进行信息匹配,形成具有属性信息的glTF建筑模型;
S4、将glTF建筑模型导入Cesium平台,通过平移变换和旋转变换将glTF建筑模型放入世界地理坐标系中,使glTF建筑模型所有的建筑信息都与地理空间关联,并在GIS中可视化。
进一步的,步骤S1所述提取IFC模型文件时,使用开源工具包IFCOpenShell、Autodesk Revit或者开源工具包xBIM对IFC模型文件进行解析。
进一步的,步骤S1的属性信息模型是在提取IFC模型属性信息时对属性信息进行结构化的存储所创造的模型,该模型具有多层次多类别的特点,包含了IFC建筑模型中的主要属性信息,能够与GIS数据进行对接并产生作用;属性信息模型包含六层结构,由上至下依次为项目信息层、场地信息层、建筑信息层、楼层信息与房间信息层、构件属性信息层以及洞口信息层;建立属性信息模型时由下而上依次建立,具体包含以下步骤:
S121、建立第六层洞口信息层的对象opening,将对象opening设为一个类,该类的属性为洞口位置和洞口尺寸;洞口与构件的关联关系用两种成员表示,一种成员为剖空元素voidelement,剖空元素表示洞口所依附的构件,另一种成员为填充元素fillelement,填充元素表示放置于洞口内部的元素;两种成员的数据类型均为字符串,表示与洞口关联的构件ID;
S122、建立第五层构件属性信息层的对象objectInstance,将对象objectInstance设为一个类,根据构件族的类别,设定不同的类来区分不同的构件;如建筑构件中,需要建立墙、门、窗、楼板等类;构件实例类的属性(property)为IFC文件中族构件对应的信息,如材质信息和ID;所有属性的数据类型均为字符串(string)类型;其中,建筑类构件(architectureObject)的一个成员为洞口类,数据类型为opening;
S123、建立第四层楼层信息的对象storey,将对象storey设为一个类,该类的属性为楼层描述、楼层高度和楼层位置;
建立第四层房间信息的对象room,将对象room设为一个类;该类的属性为房间描述、限制信息和尺寸信息;
S124、建立第三层建筑信息层的对象building,将对象building设为一个类;该类的属性为地址信息和楼层数目;该类的成员为建筑内部的楼层和房间的集合(List),集合中的元素为楼层的类(storey)和房间的类(room);
S125、建立第二层场地信息层的对象site,将对象site设为一个类;该类的属性为测绘点位置、项目点位置及方向、场地业主名称、承包方名称、项目开工日期;该类的成员为场地中所有建筑的集合(List),集合中的元素为建筑的类(building);
S126、建立第一层项目信息层的对象project,将对象project设为一个类;该类的属性为项目标号和项目描述;该类的成员包含项目场地,数据类型为site。
进一步的,步骤S1生成JSON格式的属性信息文件是将提取的IFC信息按照属性信息模型的结构层次填入相应的位置,具体包含以下步骤:
S131、建立一个元素为opening的集合opeList用于存放洞口元素;遍历IFC文档中所有的IfcOpeningElement,根据洞口的名称建立相应的opening对象;通过洞口元素的IfcRelVoidsElement找到该洞口的剖空元素,令opening.voidelement=IfcRelVoidsElement.ID;
通过洞口元素的IfcRelFillElement找到该洞口的填充元素,若不存在,则opening.fillelement=null;
若存在,令opening.fillelement=IfcRelFillElement.ID,将新生成的对象放入opeList中;
S132、建立三个元素为objectInstance的集合arcList、stcList以及MEPList,arcList、stcList以及MEPList分别用于建筑类构件,结构类构件以及MEP类构件;遍历IFC文档中所有的IfcElement的子类,包含IfcBuildingElement、IfcElectricalElement、IfcDistributionElement、IfcElementAssembly、IfcElementComponent、IfcEquipmentElement、IfcFeatureElement、IfcFurnishingElement以及IfcTransportElement,若遍历到的构件元素类型在属性信息模型的第五层有对应的类,则根据遍历到的构件元素名称建立相应的objectInstance对象;将构件元素的属性信息填写到objectInstance对应的属性中;判断构件族的类别,若该构件属于建筑构件,则遍历opeList中所有的洞口对象,若opening.voidelement与当前族构件的ID相同,则令objectInstance.opening=opening,并将其加入arcList集合中;若族构件不含有任何洞口,则直接放入arcList集合中;若该构件属于结构构件,则将其加入stcList中;若该构件属于MEP构件,则将其加入MEPList中;
S133、创建一个元素为storey的空集合styList;遍历IFC文档中所有的IfcBuildingStorey元素,对于每一个IfcBuildingStorey元素,根据楼层名称创建一个storey对象;将IfcBuildingStorey元素的属性填写入storey对应的属性中;遍历IFC文档中的IfcRelContainedinsSpatialStructure元素,该元素表示了建筑构件与楼层间的关联性;若遍历到的元素包含当前楼层元素,则将判断与当前楼层关联的建筑构件的类别,并将构件对象放入对应arcList、stcList或MEPList集合中;将每一个创建好的storey对象放入styList集合中;
S134、创建一个元素为room的空集合rmList;遍历IFC文档中所有的IFCSpace元素,对于每一个IFCSpace元素,根据其房间名创建一个room对象,将IfcSpace元素的属性填写入room对应的属性中;将每一个创建好的room对象放入rmList集合中;
S135、创建building对象,并获取IFC文档中的IFCBuilding元素,将IfcBuilding元素的属性信息填写入building对应的属性中;令building.storey=stylist;令building.room=rmList;
S136、创建site对象,并获取IFC文档中的IfcSite元素,将IfcSite元素的属性信息填写入site对应的属性中;令site.building=building;令building.room=rmList;
S137、创建project对象,并获取IFC文档中的IFCProject元素,将IfcProject元素的属性信息填写如project对应的属性中;令project.building=building;
S138、使用序列化JSON文件的工具对project对象进行序列化处理,生成一份含有完整属性信息的JSON文件。
进一步的,步骤S2的预处理是将IFC中构件的名称由“原名称”改为“原名称+@+构件ID”,如“wall-architecture-300mm@321322”;此操作的原因是在提取几何信息并进行几何转换的时候,族构件的属性信息是不保留的,为了让转换后的几何信息与属性信息联系起来,需要将族构件的名字添加上其ID名称;具体实现方法包含以下步骤:
S211、遍历IFC文档中所有的IfcElement元素,若遍历到的IfcElement为一个族构件,则令IfcElement.Name=IfcElement.Name+“@”+IfcElement.ID;
S212、完成循环后生成一份经过构件信息预处理的IFC文件。
进一步的,步骤S2提取IFC模型文件中的构件几何信息可采用下面两种方法:
S22a、使用开源工具包IfcOpenShell中的IfcConvert将IFC文件转换为.obj或.dae格式的三维几何模型,剔除IFC文件中的所有属性信息,仅保留几何信息;
S22b、使用工具包IfcEngine对IFC文件中的几何信息进行抽取;IfcEngine支持对IFC格式中的使用主要几何表达方式的元素进行读取和解析,如Brep(边界表示)、SweptSolid(扫描实体几何)和MappedRepresentation(构造实体几何)。
进一步的,步骤S2生成glTF格式建筑模型包含以下步骤:
S231、将提取的构件几何信息分解成一组几何单元,每个几何单元均表示几何信息中单个三维物体;
S232、建立glTF模型的场景Scene;场景包含一系列需要渲染的三维物体,用节点Node对所述三维物体进行标识,将每个几何单元转换为具有几何信息的Node,其中几何单元中的几何表达统一转换为三角形网格的面片形式,再通过glTF编码压缩为二进制文件;
步骤S2在生成一份与属性信息文件相匹配的glTF建筑模型文件时,将每一个Node的名称与ID分离,将ID单独写入Node中,包含以下步骤:
S241、用针对JSON格式的解析器对glTF文件进行解析;
S242、读取文件中的每一个Node,获取Node的名称Node.name;
S243、使用正则表达式(@“[0-9][0-9][0-9][0-9][0-9][0-9]”)来匹配Node.name中“@+ID”的部分,获取Node中的族构件ID信息,设其为IDnumber;
S244、在Node中新建一个ID对象,令Node.ID=IDnumber。
进一步的,步骤S3所述信息匹配先将族构件的几何模型与属性信息进行关联,即用glTF中的Node节点与属性文件中的构件属性信息进行匹配,获取Node节点所代表族构件的属性信息;再通过族构件来向上获取对应的楼层信息、房间信息、建筑信息、场地信息和项目信息,向下获取族构件包含的洞口信息;
将族构件的几何模型与属性信息进行关联时包含以下步骤:
S311、对于一个glTF中的Node节点,通过指令Node.ID获取该Node节点的ID名称;
S312、解析属性信息的JSON文件,在project中遍历所有的building对象;对于每一个building对象,遍历其中所有的storey;对于每一个storey对象,遍历其中achitectureObject、structureObject和MEPObject三个几何中的objectInstance;若当前objectInstance.ID==Node.ID,则构件几何模型与构件属性信息匹配成功;
通过族构件来向上获取对应的楼层信息、房间信息、建筑信息、场地信息和项目信息具体包含以下步骤:
S321、当几何模型中Node节点与属性JSON文件中的构件信息匹配成功后,获取构件对象上一层级的对象,即构件对象所在的列表;
S322、通过构件所在的列表,获取列表对象上一层级的对象,即构件所在的楼层。
S323、获取楼层对象上一层级的对象,即楼层所在的建筑;
S324、获取建筑对象上一层级的对象,即建筑所在的场地;
S325、获取场地对象上一层级的对象,即场地所属的项目;
向下获取族构件包含的洞口信息时包含以下步骤:
S331、当向上获取完构件所在的楼层、建筑、场地和项目信息后,判断该构件是否属于建筑类构件,若是建筑类构件,则继续寻找关联的洞口信息;若不是,则构件无法成为洞口的剖空元素,即不包含洞口信息;
S332、查找属性文件中构件对象下的opening对象,若opening对象为空,则说明该构件对象不是任何剖空元素,即不包含洞口信息;若opening对象不为空,则获取该opening对象的信息。
通过上述步骤S321~S325对Node节点与构件属性信息匹配的同时,也可以
同时向上获取Node对应构件向上的其他层级属性,如“wall-architecture-300mm”(构件)-“architectureOject”(建筑类构件)-“1st Floor”(楼层)-“TEACHINGBUILDING”(建筑)-“School Project”(项目)。
通过上述步骤S331~S332对Node节点与构件属性信息匹配的同时,可以同时向下获取与Node对应构件关联的洞口,如“wall-architecture-300mm”(构件)-“opening 50mm”(洞口)。
进一步的,步骤S4将glTF建筑模型导入Cesium时,向Cesium的场景的基元中添加元素,其中元素的种类选择glTF格式,可通过调用Cesium的API函数scene.primitives.add(Cesium.Model.fromGltf(文件名.glTF))来实现。
进一步的,步骤S4将glTF建筑模型放入世界地理坐标系中包含以下步骤:
S411、由导入glTF文件查找对应的JSON属性信息文件,在属性信息文件中查找项目的世界坐标信息,即测绘点信息;通过测绘点位置,在导入glTF模型时,将modelMatrix的中心点center设为与测绘点相同的位置,则glTF模型将在GIS地理信息环境中被平移到其在真实世界中的位置,得到平移矩阵M1;
S412、在glTF建筑模型文件对应的JSON属性信息文件中,查找项目的项目点信息;以测绘点为中心点,将glTF建筑模型按项目坐标系方向与世界坐标系正北方向的偏转角度进行等量的旋转,得到glTF模型在GIS地理信息环境中的真实位置,得到旋转矩阵M2;
使glTF建筑模型所有的建筑信息都与地理空间关联包含以下步骤:
S421、将步骤S411得到的平移矩阵M1与步骤S412得到的旋转矩阵M2相乘,得到平移旋转矩阵M3;
S422、在JSON属性文件中遍历所有的场地,对于每一个场地元素,获取场地项目坐标系的位置;将场地项目位置矩阵与平移旋转矩阵M3叉乘,得到场地在真实世界坐标系中的位置;
S423、在JSON属性文件中遍历的所有的场地中,遍历其中每一个建筑,获取建筑项目坐标系位置;将建筑项目位置矩阵与平移旋转矩阵M3叉乘,得到建筑在真实世界坐标系中的位置;
S424、在JSON属性文件中遍历的所有的建筑中,遍历其中每一个楼层,获取楼层项目坐标系位置;将楼层项目矩阵与平移旋转矩阵M3叉乘,得到楼层在真实世界坐标系中的位置;
S425、在JSON属性文件中遍历的所有的楼层中,遍历其中每一个房间,获取房间项目坐标系位置;将房间项目矩阵与平移旋转矩阵M3叉乘,得到房间在真实世界坐标系中的位置;
S426、在JSON属性文件中遍历的所有的楼层中,遍历其中每一个构件,获取构件项目坐标系位置;将构件项目矩阵与平移旋转矩阵M3叉乘,得到构件在真实世界坐标系中的位置;
S427、在JSON属性文件中遍历所有的构件中,判断该构件是否为建筑构件;若是,判断该构件是否关联任何洞口元素;若存在洞口元素,获取洞口项目坐标系位置;将洞口项目矩阵与平移旋转矩阵M3叉乘,得到洞口在真实世界坐标系中的位置。
本发明的有益效果是:
一、本发明使用最新的3D场景和模型高效传输和加载的JSON文件标准glTF作为BIM数据和GIS数据整合的媒介,良好的利用了glTF三维模型能够在web端高速传输、加载和渲染的优点,克服了GIS-BIM数据整合时在可视化表达上画质不佳,加载速度慢和三维模型计算量庞大的缺陷。
二、本发明使用了工业交换标准格式IFC作为BIM模型读取的数据格式,该种格式与绝大部分建筑行业的软件和数据格式兼容,因此本发明可以兼容建筑行业的其他BIM模型格式。
三、本发明将IFC格式的BIM模型进行了拆分,将BIM模型的几何信息和属性信息分离成两个独立的文件,即glTF和JSON,减少了计算机在计算BIM数据时的难度,提升了响应前端请求的效率。
四、本发明的应用系统构建在web端,相比与传统的单机软件,web端应用具有易操作性,便捷性的特点。方便从地理信息供应商实时调用地理信息;另外,本发明使用Cesium作为集成性的地理信息素材库,能够将本发明发展成基于GIS-BIM的平台即服务,即为建筑项目提供基础平台,针对与不同项目的需求在平台上搭建定制化的应用,易于解决建筑工程中的实际问题。
五、本发明具有与物联网连接的潜力,能够将物理世界的感应信息与平台中的构件信息相连接,形成真实环境与虚拟环境的映射关系,对于建立智慧城市的通用数据环境和基础平台具有技术上的指导与影响。
附图说明
下面结合附图和实施例对本发明进一步说明:
图1是本发明的流程示意图;
图2是本发明BIM数据属性信息模型的结构示意图;
图3是本发明建立属性信息模型的示意图;
图4是本发明属性信息模型中族构件信息结构示意图;
图5是本发明生成属性信息文件的示意图;
图6是本发明对IFC几何信息抽取与转换的示意图;
图7是本发明将建筑几何信息与属性信息进行匹配的方法流程图;
图8是本发明将建筑信息与地理空间数据库对接的示意图。
具体实施方式
如图1所示,本发明提供一种基于glTF的BIM数据与GIS数据的整合方法,包括以下步骤:
S1、提取IFC模型文件中的项目信息、场地信息、建筑物信息、楼层信息、房间信息、洞口信息以及建筑构件属性信息,提取IFC模型文件时生成属性信息模型,根据属性信息模型生成一份JSON格式的属性信息文件;
S2、对IFC模型文件构件信息进行预处理,提取IFC模型文件中的构件几何信息,通过几何变换生成glTF格式建筑模型,再生成一份与属性信息文件相匹配的glTF建筑模型文件;所述预处理在IFC模型文件中构件的名称后面增加“@”与“构件ID”;
S3、将JSON格式的属性信息文件与glTF格式的建筑模型文件进行信息匹配,形成具有属性信息的glTF建筑模型;
S4、将glTF建筑模型导入Cesium平台,通过平移变换和旋转变换将glTF建筑模型放入世界地理坐标系中,使glTF建筑模型所有的建筑信息都与地理空间关联,并在GIS中可视化。
为了方便理解,本实施例使用一个常见的学校教学楼BIM模型,对如何通过本发明方法将教学楼BIM模型与GIS系统中的校园周边地理环境整合进行阐述,从而对本发明提出的基于glTF的BIM与GIS数据整合方法进行进一步的说明。
该学校教学楼BIM模型为一份IFC文件,将其命名为TB.ifc。该IFC文件为该教学楼从设计规划阶段到施工阶段使用的BIM模型,保存了完整了项目信息和场地信息。
本实施例使用.Net 4.5框架和Visual Studio 2015作为集成开发环境,通过添加RevitAIP.dll引用来实现对BIM模型的读取和编辑操作。在VS中,创建C#项目并添加RevitAPI.dll,创建一个新的Class并通过继承IExternalCommand即可以编写Revit外部指令。首先通过命令Read(IFCFileReadOptions)来读取TB.ifc。
结合图2与图3所示,接着开始建立属性信息模型,即IFC文件中主要实体对象所对应的类。
先建立洞口的类,命名为opening。在opening类下定义其属性,见表1:
表1
其中,location表示了opening的位置,数据类型为XYZ;XYZ代表了三维坐标值,包含了三个double变量。dimension表示了opening的尺寸。洞口类的两个member(voidelement,fillelement)分别表示了洞口的剖空元素和填充元素的ID。
结合图4所示,然后建立族构件的基类(Base class)objectInstance;应用继承关系,根据族构件科目、类型建立不同的派生类(Derived class),见表2:
表2
由表2所示,建筑类、结构类和MEP类分别有五类主要构件对象,每一个对象都被创建为一个class,族构件类总共拥有三层的属性信息:
公共属性信息(public property):指所有的族构件都拥有的属性信息,如ID,Manufacture(制造厂商),Uniclass;
科目属性信息(subject property):指一个科目的构件特有的属性信息,如结构类构件的strength;
私有属性信息(private property):指一个类型的族构件所特有的属性信息,如pipe类的diameter(直径)。
族构件的主要公共属性信息包括材质信息(material),特性信息(identity)和尺寸信息(size)。其中,identity属性包含了name(构件名称),manufacture(制造厂商),cost(价格),URL(链接),Uniclass。size属性包含了length,width,height等长宽高信息。material为一个集合,包含了一个构件的所有的材质信息,例如种类,颜色,热传导性等。
族构件的主要科目属性信息为建筑构件包含的洞口信息,数据类型为元素为opening的集合。族构件的私有属性信息针对不同的族具有截然不同的内容,故每种族构件的类在一部分的属性信息是相同的,另一部分是不同的。
再创建房间的类,命名为room。在room类下定义其属性,见表3:
表3
由表3可见,字符串类型的description表示了该房间的描述信息,如房间功能。浮点数类型的属性变量level,top offset,area,perimeter分别表示房间的层高,顶端高度,面积和周长。数据类型为列表的shapepresentation表示了房间的几何形状,包含了一组多线段的顶点。
然后创建楼层的类,命名为storey。在storey类下定义属性,见表4:
表4
由表4可见,楼层类的成员architectureObject是一个元素为objectInstance的列表,表示了该楼层包含的建筑类构件;structureObject是一个元素为objectInstance的列表,表示了该楼层包含的结构类构件;MEPObject是一个元素为objectInstance的列表,表示了该楼层包含的MEP类构件。
然后创建建筑的类,命名为building。在building类下定义属性,见表5:
表5
由表5可见,数据类型为字符串的属性address表示了建筑的地址信息,数据类型为整数的storeynumber表示了建筑的楼层数目,建筑类的成员storeys表示建筑中楼层的集合,rooms是一个元素为room的列表,表示了该建筑包含的房间。
然后创建场地的类,命名为site,在site类下定义属性,见表6:
表6
由表6可见,数据类型为XYZ的surveypoint、projectpoint、projectdirection分别表示测绘点,项目点和项目点方向;字符串类型的属性owner,contractor,startdate分别表示业主,承包商和开工日期;成员有buildings表示场地上含有的建筑(一般一份IFC文件中只有一个建筑元素)。
最后创建项目的类,命名为project,在project类定义属性,见表7:
表7
由表7可见,数据类型为字符串的属性projectnumber、description分别表示项目标号和项目描述,成员为projectsite,表示项目的场地信息。
结合图5所示,建立完成属性信息模型后,根据属性信息模型将TB.ifc的属性信息提取并形成独立的属性文件。首先建立三个元素为objectInstance的列表arList、stcList、MEPList分别用于放置建筑类,结构类和MEP类的族构件。接着,创建一个元素为opening的集合openList用于存放洞口元素。接下来需要从IFC数据中获得洞口和构件的对象。在VS中,使用容器(collector)和过滤器(filter)可以对IFC模型的数据进行有效的筛选或排除。容器用来获取和解析读取的模型信息,将模型数据拷贝到一个可以被不断过滤的空间中;过滤器可以自由配置需要过滤的数据种类或对象实体,在确定好需要过滤的数据类型/种类/实例后,将其与容器组合使用,可以获取容器中的目标数据。使用ElementClassFilter(typeof(Ifcopening))从collecter中获取IFC文件中所有的IfcOpeningElement实体集合,遍历集合中的每一个IfcOpeningElement,根据洞口名称建立对应的opening对象;将洞口的属性信息填入opening对应的属性中;通过洞口元素的IfcRelVoidsElement,找到与其关联的剖空元素,令opening.voidelement=IfcRelVoidsElement.ID。查找洞口元素的填充元素,若存在,则令opening.fillelement=IfcRelFillElement.ID。接着使用opeList.add(opening)将对象加入列表中。
对于每一种族构件的类,建立一个新容器,并通过
ElementClassFilter(typeof(IfcBuildingElement))来配置相应的过滤器。如wall类对应的过滤器应设置为过滤IfcWall对象。在遍历对象集合中的每一个IfcElement对象,建立对应的族构件对象,将IFC的属性信息填写入新建的对象的property后放入对应的族构件列表中。以TB.IFC的一堵墙为例,编写指令:wall newwall=new wall()建立一个新的墙对象,令newwall.identity.Uniclass=IfcWall.PropertySet(other).Uniclass来赋值构件的Uniclass编号。对于遍历的族构件,若为建筑类构件,则遍历opeList中的洞口对象,若opening.voidelement与当前族构件ID相同,则令objectInstance.opening=opening。
创建一个元素为storey的列表styList用于收纳storey对象。建立一个新容器,并将过滤的对象设为IfcBuildingStorey,获得IFC中所有的楼层元素。对于每一个元素,建立相应的storey对象,将IfcBuildingStorey的元素填写入storey的属性中。遍历IFC文档的IfcRelContainedinsSpatialStructure元素,该元素包含了两个元素:楼层元素与族构件元素,表示了族构件的对应楼层。若遍历到的元素中的楼层元素为当前楼层元素IfcBuildingStorey,则将判断与当前楼层关联的建筑构件的类别,若为建筑类构件,则将之前创建的构建对象放入storey.architectureObject列表中;若为结构类构件,则将之前创建的构件对象放入storey.structureObject列表中;若为MEP类构件,则将之前创建的构件对象放入storey.MEPObject中。将每一个创建好的storey对象放入styList集合中。
创建一个元素为room的空集合rmList。建立新容器,并将过滤的对象设为IfcSpace。遍历每一个IfcSpace元素,创建相应的room对象,将IfcSpace元素的属性写入room对于的属性中。以TB.ifc中一个房间为例,通过指令room office=new room()创建新的房间对象,令office.topoffset=IfcSpace.IfcRelDefineProperty.IfcPropertyset(constrain).topoffset来获得房间的顶端高度。将每一个填写好属性信息的对象放入rmList中。
创建一个building对象(默认本例中只有一栋研究建筑)。建立新容器,并将过滤的对象设为IfcBuilding,获取过滤的第一个IfcBuilding元素。将IfcBuilding中的地址、楼层数目信息填写入building.address和building.storeynumber中。通过指令building.rooms=rmList使TB.ifc中所有的房间与TB建筑关联;通过指令building.storeys=styList使TB.ifc中所有的楼层与TB建筑关联。
创建一个site对象(默认本例中只有一个场地)。建立新容器,并将过滤器的对象设为IfcSite,获取过滤的第一个IfcSite元素。将IfcSite的第一个角度数转换为浮点数并赋给site.surverypoint[1],即项目点的北纬值;将IfcSite的第二个角度数赋值给site.surveypoint[2],及项目点的东经值,将其他的属性信息按如上方法填写如site对象的属性中。令site.buildings.add(building)使建筑对象与场地对象关联。
创建一个project对象,从读取的IFC文档对象中直接获取项目的标号和描述信息。令project.proejectsite=site使项目对象与场地对象关联。
在完成各层级的属性信息填写后,使用C#工具包JsonConvert对project对象进行序列化,得到JSON格式的属性信息文件,将其命名为TB_attribute.json。
结合图6所示,步骤S2是对BIM几何信息进行提取和转换,即将TB.ifc中的构件几何信息提取出来并经过处理、变换形成一个glTF模型。
应用过滤器筛选IFC文件中所有族构件元素,遍历每一个族构件,新建一个字符串变量,令string newname=IfcBuildingElement.Name+“@”IfcBuildingElment.ID.tostring(),使newname的字符等于族构件的名称加上族构件的ID。将newname赋值给当前族构件的名字,即IfcBuildingElment.Name=newname。完成循环后,TB.ifc中所有的构件名称都被修改,另存为新的IFC文件TB_update.ifc。
使用开源工具包IfcOpenShell中的IfcConvert将TB_update.ifc中的几何信息抽取并形成.obj格式的纯三维模型文件,将其保存为TB_update.obj。用开源图形转换工具obj2gltf将TB_update.obj转换为以Node节点为几何单元表达的glTF模型,将其保存为TB_update.gltf。
由于glTF是基于JSON编写的三维场景与模型交换格式,因此在编辑glTF模型时可以直接使用JSON的解析器进行解析。在本例中,使用.NET下的json.NET对TB_update.gltf进行解析。遍历TB_update.gltf中的accessor.nodes下的所有对象,对于每一个node对象,通过node.name获取该节点的名称。例如在
TB_update.gltf中表达一堵墙的节点的名称为
“wall-architecture-300mm@231232”。通过使用正则表达式对node.name中的ID号进行匹配搜找。在.NET下,使用Regex类对字符串进行模式匹配。编写指令:RegexIDmatch=new Regex(@“@\d\d\d\d\d\d”),即可以对墙的名字就像拆分,找到墙的ID号为231232;通过简单的字符串加减法,找到墙的原名称“wall-architecture-300mm”。在node对象下,新建键值对nodeID:ID,使每一个node都具有ID对象。另存为该gltf模型为TB_update2.gltf。通过上述步骤,IFC文件的几何信息被抽取并转换成了具有构件ID标识的glTF模型。
结合图7所示,步骤S3是对BIM属性信息与几何信息匹配,即将表达建筑几何特征的TB_update2.gltf和表达建筑语义信息的TB_attribute.json进行关联。
首先,将TB_update2.gltf中的Node节点与TB_attribute.json中的族构件属性信息进行ID匹配。对一个TB_update2.accessor.nodes下的每一个Node节点,通过TB_update2.accessor.nodes[n].nodeID来获取当前节点的ID。
在浏览器端直接解析TB_attribute.json文件,遍历TB_attribute.project.projectsite.buildings[0].storeys中的每一个楼层,对于每一个楼层对象,遍历其中的
storey.architectureObject,storey.structureObject
和storey.MEPObject三个列表中的所有的构件对象objectInstance,若存在objectInstance.ID与TB_update2.accessor.nodes[n].nodeID相同,则族构件几何信息与属性匹配成功。
接着,向上获取Node节点对于族构件的所在楼层,所在建筑,所在场地和所属项目信息。根据匹配到的objectInstance对象在TB_attribute.json中所处的位置,寻找上一级的对象。例如,在TB_attribute.json中批到到的一个Node节点对应的族构件为
TB_attribute.project.projectsite.buildings[0].storeys[2].architectureObject[32]。则根据该族构件,获取到向上一级的楼层对象的值为Level 3;根据该楼层对象,获取到向上一级的建筑对象的值为TBbuilding;根据该建筑对象,获取到向上一级的场地对象的值为TBconstructionsite;根据该场地对象,获取到向上一级的项目对象为TBproject。
向上获取完族构件的关联信息后,向下获取与族构件形成依附关系的洞口信息。首先,判断匹配的族构件的是否在architectureObject的列表中;若不是,则该构件不是任何洞口的剖空元素。若在列表中,则遍历向下一级的对象。根据上一个例子,遍历族构件对象的下一级
TB_attribute.project.projectsite.buildings[0].storeys[2].architectureObject[32].openings中所有的对象,获得一个洞口元素Pipeopening10mm。通过上述步骤,一个Node节点匹配到了完整的属性信息:
TBproject——TBconstructionsite——TBbuilding——Level3——architecturewall300mm——Pipeopening10mm
步骤S4是对BIM与GIS数据整合,即将TB_update2.gltf导入地理信息平台cesium中,并通过平移和旋转变换将其置入正确的世界坐标系中,最终将TB的建筑信息与cesium中的地理空间数据库整合。
在HTML中引用cesium.js,通过调用cesium的API函数scene.primitives.add(Cesium.Model.fromGLtf(../TB_update2.gltf))来向cesium场景中添加TB_update2.gltf建筑模型。
设其导入TB_update2.gltf模型在世界坐标系中的默认位置为(x0,y0,z0),将其组织为3×1矩阵M0,而通过TB_attribute.project.site.surveypoint得到的TB建筑在真实世界中的坐标为(xtb,ytb,ztb),将其组织为3×1矩阵Mtb。通过Mtb与M0相减和处理得到从默认位置到真实位置的4×4平移矩阵M1。
通过TB_attribute.project.projectsite.surveypoint.projectdirection获取项目坐标系的正方向(xd,yd,0),通过与正北方向(1,0,0)比较得出项目坐标系的方向与正北方向的偏转角度θ,得到4×4偏转矩阵M2。
通过将平移矩阵与旋转矩阵叉乘,得到平移旋转矩阵M3=M1×M2。通过平移旋转矩阵,TB_update2.gltf被转置到其真实的地理位置上,并且具有正确的朝向。
结合图8所示,在将TB_update2.gltf转移到真实的地理位置后,接着将建筑信息与真实地理空间关联,即将TB_attribute.json中各层级的属性信息与其真实坐标位置关联,并且利用cesium的Entity API对建筑信息在GIS中进行可视化表达。
首先获取TB_attribute.project.projectsite.surveypoint,运用函数viewer.entities.add(point)并在point对象下输入surverypoint的坐标,即可以在GIS环境中用实点来表达该项目的测绘点的位置。
接着,通过TB_attribute.project.projectsite.buildings[0].location获取属性文件中建筑在项目坐标系的坐标;通过与平移旋转矩阵M3相乘,得到建筑在世界坐标系的位置。通过包围盒算法计算出在GIS环境中TB建筑的包围盒,使用运用函数viewer.entities.add(boxes)并在boxes对象下输入立方体的尺寸,形成一个TB建筑的包围盒立体图形。
然后,遍历TB_attribute.project.projectsite.buildings[0].rooms中的每一个房间元素,通过room.location获取房间在项目坐标系的坐标;通过room.shaperepresentation获取描述房间边界的多边形的顶点坐标集合;通过room.topoffset-room.level得到房间的净高度。通过与平移旋转矩阵M3相乘,获得这些点在真实世界坐标系的坐标。使用cesium中的多边形函数将顶点集合中的点重新连成多边形,并通过拉伸函数(extrusion)将多边形拉伸为高度为房间净高度的多面体图形。该多面体图形描述了房间的基本形状。用不同的颜色填充多面体,可以表达房间的不同属性。例如,TB建筑中的办公室用红色表示,教室用蓝色表示。
接着,遍历TB_attribute.project.projectsite.buildings[0].storeys中的每一个楼层元素,通过storey.location获取房间在项目坐标系的坐标。通过与平移旋转矩阵M3相乘,得到楼层在世界坐标系的位置和高度。对于不同高度的楼层,用viewer.entities.add(polygon)建立与包围盒边界相同的楼层平面,用色条的颜色变化表示不同楼层的高低变化。
最后,遍历TB_attribute.json中所有的洞口对象,通过opening.location获取洞口在项目坐标系的坐标。通过与平移旋转矩阵M3相乘,得到洞口在世界坐标系的位置。通过opening.dimension的描述绘制相应的图形。从而将建筑属性信息与地理空间关联并用图形可视化表达。
以上所述,仅是本发明的较佳实施例而已,并非对本发明作任何形式上的限制;任何熟悉本领域的技术人员,在不脱离本发明技术方案范围情况下,都可利用上述揭示的方法和技术内容对本发明技术方案做出许多可能的变动和修饰,或修改为等同变化的等效实施例。因此,凡是未脱离本发明技术方案的内容,依据本发明的技术实质对以上实施例所做的任何简单修改、等同替换、等效变化及修饰,均仍属于本发明技术方案保护的范围内。