时间:2024-07-28
肖现臣
(济南市勘察测绘研究院,山东 济南 250101)
近年来,智慧城市、数字孪生城市是数字化城市建设的热点,随着应用与研究的进展,诞生了许多数字化城市系统,为城市基础设施查询、分析、显示和管理提供了极大便利,同时进一步促进了数字城市理论的发展[1]。
在数字化城市建立的过程中,GIS与BIM技术发挥了极为重要的作用[2]。对于城市级、规划片区级的大场景三维数字城市的建设,目前技术比较成熟,可选的基础技术方案有ArcGIS API for JavaScript 4.X系列、Cesium等[3],且都具有各自的技术生态链,提供系统构建各环节的技术支持。而GIS与BIM在城市细部空间的应用,即关注点在小型园区、工厂、加油站、泵站等较小范围的小场景三维地理信息系统,作为大场景数字化城市系统的补充,能够关注到更多、更细粒度的研究内容,是建设数字孪生城市不可或缺的一部分。
本文研究了如何基于Three.js框架搭建小场景三维地理信息系统,并对实践过程中形成的关键技术进行阐述。
Three.js是一个开源JavaScript三维渲染引擎,它对WebGL进行封装的同时不损失其灵活性,并提供了易于使用的开发接口,让前端开发人员在不需要掌握很多数学和图形学知识的情况下,也能够轻松在浏览器端进行三维应用的研发,不但降低了门槛,也大大提升了效率。同时,Three.js的开源特性,让基于Three.js构建的三维应用可免费用于商业和非商业用途,减少项目成本。
选取Three.js搭建小场景三维地理信息系统的另一个优点是它对多类模型的支持能力,Three.js支持obj、glTF、3ds max、FBX、Collada、Babylon、draco等众多三维模型格式,可最大可能将现有三维模型数据运用到建设项目,无须重复建模,减少工作量和成本。
Three.js作为对WebGL的封装,具有简单易用的特点。使用Three.js的场景(scene)、相机(camera)、渲染器(renderer)三大组件即可完成初始化。初始化后,便可进行模型加载及上层应用的开发。
数据是地理信息系统的基础,本研究将涉及的数据划分为模型数据和属性数据两类。
模型数据主要存储的是模型的空间几何信息和必要的属性信息(如模型名称、唯一标识ID等)。对于模型数据的组织,参考具体模型的格式以文件、模型服务的两种形式进行组织,如obj格式模型以文件组织、glTF模型发布为数据服务,Three.js对此两种形式均提供了支持,通过其loader机制可以方便地实现模型的连接、加载。
属性数据存储的是模型丰富的社会经济属性、挂接附件等信息,以传统关系型数据库进行存储,如Microsoft SQL Server,并通过模型的唯一标识与模型建立关联。属性数据在基于Three.js的三维地理信息系统中通过搭建后台服务、前端发起AJAX请求的方式进行获取。
由于Three.js将绘图中心作为坐标系统原点即(0,0,0)[4],且场景操控的中心点也默认是原点,这样做的优点是方便增加其他辅助模型或部件。因此,为了将地理实体模型放置在原点附近展示,需要建立模型自身地理坐标系到Three.js坐标系统的映射机制。
而小场景的模型、部件往往是分开建模、多文件存储的,为保证多个模型的相对位置关系正确,我们做了如下处理:
(1)以加载的第一个地理实体模型的中心点作为基准,将该模型的中心点映射到Three.js坐标系统的原点,将该模型偏移、放置到映射后的位置。这样就建立了模型坐标与Three.js坐标系的映射。
(2)由于地理实体模型都具有相同的参考系,后续加载的模型,以此映射进行坐标偏移、定位放置,即可确保地理实体模型之间正确的相对位置关系。
(1)模型加载
前文提到Three.js对多种格式的三维模型提供了支持,同时其也提供了接口一致的加载方式,即loader机制,如通过OBJLoader加载obj模型、通过GLTFLoader加载glTF模型等,使得模型的加载非常容易。
(2)模型图层化管理
对地理数据进行分层加载并图层化管理,是地理信息系统常用的数据管理思路,如图1所示。
图1 模型图层化管理
在Three.js中,并没有地理图层的概念和机制,但是提供了图层对象Layers和模型图层属性layers,图层对象Layers可用于控制可见性,通过Three.js渲染器渲染场景的时候,场景中的模型图层属性layers必须和相机的图层属性layers一致,模型才会被渲染出来。因此,可借助图层对象Layers和模型图层属性layers实现地理信息系统的图层管理机制。实现方法如下:
①模型加载之前创建一个图层对象Layers。
②模型加载后,将图层对象Layers赋值给模型的图层属性layers,这样可以通过图层属性layers区分模型所属图层。
③图层显示与隐藏的控制通过切换相机的图层属性来实现,将图层对象Layers传入camera.layers.toggle()方法即可。
对地理实体的属性进行查询,是用户基于空间位置了解地物的社会经济信息的常用操作,也是二三维地理信息系统的一个必备的基础功能。基于Three.js搭建小场景三维地理信息应用,也可以实现此功能。下面以点选查询功能的实现为例阐述属性查询的相关技术。
属性查询的关键点在于捕获地理要素,在Three.js工程中即为捕获模型,需要用到Raycaster射线类。Raycaster射线类用于鼠标去获取在三维场景中被鼠标选中的一些物体。它的使用也非常简便,步骤如下:
(1)首先,在当前Three.js实例所在的窗口对象中绑定鼠标click事件onMouseClick。
(2)在click事件中,可以获取鼠标点击处的坐标,根据此坐标和相机位置创建Raycaster实例。
(3)使用Raycaster实例的intersectObjects方法计算捕获到的地理实体模型。
(4)对捕获的地理实体通过材质做高亮显示,并通过弹窗展示模型属性或挂接的外部社会经济属性信息,模型属性查询与高亮显示如图2所示。
图2 模型属性查询与高亮显示
场景漫游对于三维地理信息系统是一个比较重要的功能,常用的漫游方式有地上地下漫游、室内室外漫游、街区路线漫游等,其原理是通过以一定的时间间隔不断地切换相机和场景的位置,达到呈现给用户的三维视图平滑过渡的效果。
在Three.js中,通过不断更新相机的位置和轨迹球控制器(Three.js自带的场景操控工具)的目标朝向可以实现场景的漫游,如图3所示,其实现流程有以下几个关键步骤:
图3 场景漫游的实现流程
(1)路径规划
规划漫游路线,并在漫游路线中选取若干初始过程点(具有三维坐标的空间点),为正确还原路线走向,可在路线方向变化较大的区域,适当多选取过程点。
(2)获取漫游过程点
为实现平滑、顺畅的漫游效果,需要对初始过程点进行曲线拟合、过程点重采样,生成场景漫游中实际使用的过程点。本研究中,通过Three.js提供的THREE.CatmullRomCurve3曲线函数实现了基于初始过程点拟合三维样条曲线,并通过曲线按漫游步长进行重采样,获取到最终漫游过程点,重采样形成的过程点越多,漫游效果就越平滑。
(3)漫游实现
通过编程实现场景的漫游,原理是首先将漫游当前点设置到第一个过程点:通过改变相机位置将Three.js的场景中心位置移动到第一个过程点,并通过当前点与下一个过程点的两个坐标计算漫游方向,以此设置轨迹球控制器的朝向。然后按照时间间隔将当前点设定到下一个过程点,时间间隔可按设定的速率和两点之间的距离进行计算。依次移动当前点到下一个过程点,完成场景的漫游。
为优化漫游效果,减少开发难度,本研究采用了第三方动画工具TWEEN.js,通过TWEEN.js自动增加补间动画使漫游更加平滑、顺畅。
小场景地理信息应用往往在加载重点关注区域的同时,也会加载一定缓冲区范围内的地形、建筑、道路网等地理要素,一是为了衬托场景,不至于太单调,二是为了区分场景的位置,便于了解周边地物等。周边地理要素加载后,如何突出重点研究区域是小场景要解决的一个问题,重点区域标注是常用的方法。
Three.js中的标注方法有多种,本文就实现思路和优缺点进行简要阐述。实现标注有以下几种方法:
(1)传统HTML元素实现,使用DOM绘制元素、CSS设置样式。优点是实现简单,缺点是与场景结合的效果不好。
(2)使用Three.js的文字对象,并可结合文字贴图THREE.TextGeometry进行美化。优点是实现简单,效果与场景同步;缺点是设置颜色和动画复杂,耗费资源大。
(3)使用Three.Sprite精灵,不但支持加载图片,还可以通过canvas绘制图形和文字。优点是文字效果丰富,方便绘制,尤其对于熟悉canvas编程的人员学习成本较少。缺点是生成后,分辨率固定,放大后会产生失真。
(4)使用底层着色器接口实现。优点是可较自由地定制开关、颜色、材质、动画,效果丰富,与场景结合最好。缺点是学习成本很高。
具体项目应用中,可根据实际需求,通过以上多种方法的结合实现标注效果,如图4所示。
图4 通过着色器和Three.Sprite实现的重点区域标注(棱锥、文字框)
酷炫的动画、流光特效,不但可以让三维场景运动起来,还能营造强烈的视觉冲击,给人留下深刻的印象。本节介绍几个常用特效的实现技术。
(1)线状地物流光效果
线状地物流光效果常用于道路、地下管道等地理实体,用于突出流动效果,本文基于纹理偏移机制实现了道路的流光效果(图5),实现关键技术如下:
图5 道路流光效果
①首先准备一张流光纹理图片,图片为线状需包含高光部分、暗色部分,才能做出流动的效果。
②使用THREE.TextureLoader加载图片为纹理,并设置属性wrapS、wrapT为THREE.RepeatWrapping意为可重复,设置needsUpdate为true意为需要更新。
③新建材质,将纹理作为贴图赋值给材质。
④将材质赋给道路(线状地物),在帧动画中不断改变纹理的偏移值(如texture.offset.x+=0.02),即可实现流光效果。
(2)建筑物线框模式
建筑物线框模式指的是隐藏建筑物的表面细节,仅展示建筑物的轮廓线,可以达到精简界面烘托重点的作用。
本文实现建筑物线框的思路是通过THREE.EdgesGeometry方法提取建筑物模型的边线,然后通过THREE.LineSegments构造线条对象,并应用线状材质,到达线框模型的效果,如图6所示。
图6 线框模式实现效果
(3)后处理特效
三维地理信息系统的构建,对界面或模型进行调光、调色是必不可少的,Three.js提供了许多的后期处理通道,不但可以减少对复杂的着色器的使用,还能实现功能强大的光效设置,如辉光、边缘泛光、抗锯齿等,后处理特效可以通过THREE.EffectComposer组合器组合使用,给小场景三维地理信息系统建设提供了丰富的效果支持。
本文探索了基于Three.js三维渲染引擎构建小场景三维地理信息系统的技术路线,并研究了在Three.js框架下实现地理模型加载、图层化管理、属性查询、场景漫游、模型特效处理等关键功能的相关技术,为构建智慧城市、智慧园区等小场景应用铺平了道路。
研究表明,基于Three.js构建小场景三维地理信息系统的技术思路是可行的,Three.js对于模型加载与管理、系统功能建设、特效处理等的支持是丰富的、易用的,相比其他方案具有框架开源节约成本、兼容模型格式多、开发友好、特效丰富、易于集成等独特优势,这些都有助于Three.js在三维地理信息系统构建中进一步推广应用。
BIM技术与GIS技术的结合应用,已经成为一种势在必行的趋势[5],相信基于Three.js的小场景三维地理信息系统建设方案将会在未来智慧城市、数字孪生城市的建设中得到更多的应用和发展。
我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自各大过期杂志,内容仅供学习参考,不准确地方联系删除处理!