基于 HTML5 WebGL 的加油站 3D 可视化监控

2024-08-30 11:08

本文主要是介绍基于 HTML5 WebGL 的加油站 3D 可视化监控,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言

随着数字化,工业互联网,物联网的发展,我国加油站正向有人值守,无人操作,远程控制的方向发展,传统的人工巡查方式逐渐转变为以自动化控制为主的在线监控方式,即采用数据采集与监控系统 SCADA。SCADA 系统的推广使用,大大提高了我国加油站的监控效率,本文所讲的则是通过对加油站的可视化建模,结合 HT 的 3D 可视化以及 2D 监控面板来实现对加油站的可视化监控。三维可视化监控系统是将三维的可视化技术和数据采集与监控技术融合,充分发挥了两种技术的核心优势,并通过数据库进行数据共享,共同构成一种全新的 SCADA 系统。该系统中也结合了海康的摄像头监控,通过调用海康提供的摄像头地址,实时的将视频流传输到前台,并且展示在 2d 页面上。在真实的系统中,每个加油机以及加油罐都有自己对应需要展示的数据,这个可以根据自己需要展示的内容来设计 2d 面板,之后根据后台传来的数据进行展示。数据采集与监控系统通过各类的传感器实时采集监控对象的各类数据,上传数据库并实时共享给三维可视化技术搭建的监控对象的三维可视化模型及场景,最后通过监控系统直观的展示出来,极大的提高了监控对象数据的表达能力和工作人员的工作效率。

该系统中实现了对加油机,油罐的监控,以及对加油站内的摄像头进行调取并显示,本文会讲解使用 HT 来搭建该系统的步骤,以及对场景中使用到的部分关键代码进行说明。

预览地址:基于 HTML5 WebGL 的加油站 3D 可视化监控 http://www.hightopo.com/demo/gas-station-demo/

界面效果预览

视频监控效果

加油机监控效果

油罐监控效果

加油站切换效果

因为系统中对许多的加油站进行建模,所以系统中可以根据 url 地址的 stationCode 来区分不同的加油站,即 stationCode 为该加油站的唯一标识,当然该系统可以嵌入到任何第三方的系统中,HT 只需要第三方页面给一个 dom,就可以将该页面放到该 dom 中,例如上图 3d 场景,ht 可以通过 g3d.addToDOM(el) 来将 3d 场景的 dom append 到 el 这个 dom 下,g3d 为 ht 中 ht.graph3d.Graph3dView 的实例,具体可查看 3D 手册

HT 搭建系统步骤

1.制作模型

在 ht 的 3D 场景中部分简单的建模可以根据 ht 的 api 来进行搭建,例如墙面,管道,六面体,地板等等基本 3d 模型,例如如果想制作一个三维的球体模型,则可以通过以下代码:

1 var node = new ht.Node();
2 node.s({
3     "shape3d": "sphere" // 此处指定该 node style 的 shape3d 为 sphere 即球体的意思
4 });

如果需要使用代码来进行较为复杂些的建模,则可以通过指定模型的顶点信息来进行搭建,大体可理解为 3d 中的模型都是由三角面进行拼接而成的,所以指定该模型的所有三角面就可以构造出该模型,三角面又是由三个顶点信息构成,所以指定模型的顶点信息也可以构建模型,具体可以参考 建模手册

但是在我们这个加油站可视化监控系统中,我们的加油机模型以及油罐和加油站外景的模型都是十分复杂的模型,如果采用上述两种方法:

  1. 通过第一种简单的墙面,球体,六面体等模型拼接出加油站是不现实的,因为模型没有那么全面,而且贴图部分也不好分开贴,所以不可行。
  2. 通过指定顶点信息来构造加油站的所有模型,这部分虽然在理论上是可行的,但是计算顶点信息需要大量的工作,可想而知代码部分的工作量是不小的,所以不可行。

目前 ht 可以支持 obj 模型的导入,所以设计师可以根据加油站拍摄的外景图片对加油站场景以及加油机,油罐等的模型进行建模,obj 模型可以使用主流的 3dMAX 等的建模工具进行搭建,之后导入到 ht 中进行显示。对于系统中需要交互的模型则要分开进行建模,例如加油机模型不可和加油站场景的 obj 模型在同一个 obj 中,例如下图分开方式:

2.搭建场景

上一步中我们已经得到了场景所需要的所有模型,在 ht 中可以通过 ht.Default.loadObj(objUrl, mtlUrl, params) 来加载 obj 的模型,之后通过 ht.Default.setShape3dModel(name, model) 来注册模型,loadObj 用来读取模型的顶点信息以及贴图部分的信息,就是上一步中所指的第二点通过顶点信息来构造模型,此时顶点信息已经由 obj 模型提供,所以拿到顶点信息,贴图等信息之后,可以通过 setShape3dModel 来注册模型,具体使用方法请参考 OBJ 手册,之后可以通过 ht 的 node 图元来使用该模型,具体使用方法如下:

1 var node = new ht.Node();
2 node.s({
3     "shape3d": name
4 });

上面的 name 就是通过 ht.Default.setShape3dModel(name, model) 中的 name 得到的,表示此图元使用该模型来展示。

构成该监控系统的还有用来展示加油机,油罐模型的具体监控参数的面板,ht 中所有的 2d 都为矢量,所以放大不会失真,2d 面板也是通过一个个图元进行摆放展示,通过调整每个图元的样式来美化图元,具体的样式可参考 风格手册。

油罐 2d 面板展示如下:

3.对接数据

上一步中我们已经把需要展示的模型以及需要展示的监控数据进行了设计,并且在场景中进行了摆放,所以该步骤中则需要对数据进行对接,目前对接部分包括:

  1. 2d 面板两侧的数据对接
  2. 视频监控的对接

第一条的对接可以通过 socket 或者 ajax 来进行,将后台数据传输到前台之后动态绑定到界面上显示即可,ht 中通过数据绑定来驱动界面上内容的动态刷新,具体的绑定操作可以查看 数据绑定手册。

系统中摄像头监控部分主要是通过将第三方的视频 dom 嵌入到 ht 的图纸中,ht 中可以通过 renderHTML 来嵌入 dom,嵌入 dom 的原理其实也是在图纸的对应位置加入一个 node 图元,根据图纸的缩放值(zoom),以及横向偏移值(tx),纵向偏移值(ty) 的图纸信息以及该图元的 position, width, height 的图元信息来动态的计算 dom 的宽高和 dom 的位置,具体代码可以参考如下:

 1 let rect = node.getRect(), // 获取该 node 的包围矩形信息2 zoom = graphView.getZoom(), // 获取图纸的缩放值3 tx = graphView.tx(), // 获取图纸的横向偏移值4 ty = graphView.ty(); // 获取图纸的纵向偏移值5 // 下面操作为对 node 的包围矩形进行缩放6 rect.x *= zoom;7 rect.y *= zoom;8 rect.width *= zoom;9 rect.height *= zoom;
10 
11 // div 的 left 即为下面的 x 坐标, top 即为下面的 y 坐标
12 let x = tx + rect.x;
13 let y = ty + rect.y;
14 
15 div.style.position = 'absolute';
16 div.style.width = rect.width + 'px';
17 div.style.height = rect.height + 'px';
18 div.style.left = x + 'px';
19 div.style.top = y + 'px';

上面代码展示了动态摆放 dom 到 ht 图纸的原理,所以用户可以根据自己的需求将 dom 元素放到 2d 图纸中去,该系统中的监控模块 dom 就是通过该方式的原理进行动态摆放,从下图可以看出 dom 叠加的效果。

4.制作动画效果

该系统中动画效果比较简单,主要就是点击加油机或者油罐时,将视角飞向该物体,并且二维面板上显示对应的监控数据,视角的切换主要是修改 3D 场景的 eye 以及 center 的数据,但是 ht 中提供了更为方便的操作函数 flyTo,所以主要代码即为下面一行:

1 // node 即为要飞向的节点 例如加油机
2 // 第二参数为配置参数
3 g3d.flyTo(node, { animation: true, direction: [-16, 6, 8], distance: 600 });

上述第二个参数具体可参考上述所提供的 3D 手册,direction:默认undefined,眼睛处于目标的方向(相对目标,受到目标自身旋转影响,distance :默认undefined(未定义的话则使用下面的ratio模式计算距离),浮点类型,表示眼睛跟中心的固定距离,上述所用到的两个参数解释即为此。

该函数还有一个使用方法为当第一参数传值为 null 空时,视角会调整看向场景内所有节点,所以利用此功能可能看到加油站的全景。

系统中还有一个效果是虚化背景,虚化背景的原理就是修改场景中所有模型的透明度,例如该系统中通过遍历所有节点,将当前节点的透明度设置为 0.1,则在视觉上我们看到的场景即为虚化的场景,具体节点的样式属性可以参考上面已经给出的风格手册,关键代码如下:

 1 // 遍历场景中所有图元 2 dataModel.each((d) = >{3     // opacityMap 用来记录当前某个节点没有虚化之前的透明度值4     if (!opacityMap[d.getId()]) {5         opacityMap[d.getId()] = {6             'shape3d.opacity': d.s('shape3d.opacity'),7             'shape3d.transparent': d.s('shape3d.transparent'),8             'all.opacity': d.s('all.opacity'),9             'all.transparent': d.s('all.transparent'),
10             'left.opacity': d.s('left.opacity'),
11             'left.transparent': d.s('left.transparent'),
12             'right.opacity': d.s('right.opacity'),
13             'right.transparent': d.s('right.transparent'),
14             'front.opacity': d.s('front.opacity'),
15             'front.transparent': d.s('front.transparent'),
16             'back.opacity': d.s('back.opacity'),
17             'back.transparent': d.s('back.transparent'),
18             'top.opacity': d.s('top.opacity'),
19             'top.transparent': d.s('top.transparent'),
20             'bottom.opacity': d.s('bottom.opacity'),
21             'bottom.transparent': d.s('bottom.transparent'),
22             '3d.selectable': d.s('3d.selectable')
23         };
24     }
25     // 设置当前节点的透明度 opacity 为需要虚化至多大透明度 系统中为 0.1
26     d.s({
27         'shape3d.opacity': opacity,
28         'shape3d.transparent': true,
29         'all.opacity': opacity,
30         'all.transparent': true,
31         'left.opacity': opacity,
32         'left.transparent': true,
33         'right.opacity': opacity,
34         'right.transparent': true,
35         'front.opacity': opacity,
36         'front.transparent': true,
37         'back.opacity': opacity,
38         'back.transparent': true,
39         'top.opacity': opacity,
40         'top.transparent': true,
41         'bottom.opacity': opacity,
42         'bottom.transparent': true,
43         '3d.selectable': false
44     });
45 });

上面代码执行之后场景中所有的节点就被虚化,因为每个节点虚化所需要设置的透明度属性不同,所以一共有上面十几种样式属性需要判断设置,具体的样式名称可以参考上文提出的风格手册,以下为虚化效果:

场景中有双击便利店进入便利店内景的操作,具体交互以及效果如下图:

5.优化场景

当 3d 场景中点或者面的数量较多时,3d 面板,公告板部分较多时,ht 中有几种优化策略可以进行优化,我们知道 3d 场景中的所有模型都是由三角面构成的,而三角面又是由三个顶点构成的,所以如果场景中的点或者面比较多的时候场景会出现一定的卡顿,GPU 渲染会比较费时,在 ht 中可以通过在控制台输入 g3d.showDebugTip() 来显示当前场景一共有多少面和顶点,具体效果如下:

其中 Vertices 为点的数量,Faces 为面的数量。

所以在 ht 中可以有以下 4 种直观优化策略可以优化:

  1. 减少模型的面数
  2. 使用批量处理场景中大量的相同图元
  3. 对 3d 面板使用缓存
  4. 当场景视角距离较远时隐藏部分细节图元,或者当场景视角距离某个模型很近时,隐藏看不见的图元以提高性能

第一种情况可以在设计建模时通过各种减面的手段来减少模型的面数,这一部分优化的空间是最大的,也是效果最明显的。

第二种情况可以使用批量,批量能提高性能的原理在于,当图元一个个独立绘制模型时性能较差,而但一批图元聚合成一个大模型进行一次性的绘制时, 则会极大提高WebGL刷新性能,具体可参考 批量手册。

第三种情况使用 shape3d.image.cache 这个属性来开启面板的缓存,当我们一个场景中如果需要使用大量的类似公告板的功能,我们可以利用上面的属性对该节点设置缓存,具体使用方法可以参考 3D手册。

第四种情况我们可以在眼睛距离场景很远的时候隐藏部分细节图元,类似地图缩放到很小的时候,具体的城市会隐藏掉,放大到具体模型细节时,其它看不见的图元可以相应设置隐藏,这样可以提高不少的性能。

手机端效果

 

这篇关于基于 HTML5 WebGL 的加油站 3D 可视化监控的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1120644

相关文章

prometheus如何使用pushgateway监控网路丢包

《prometheus如何使用pushgateway监控网路丢包》:本文主要介绍prometheus如何使用pushgateway监控网路丢包问题,具有很好的参考价值,希望对大家有所帮助,如有错误... 目录监控网路丢包脚本数据图表总结监控网路丢包脚本[root@gtcq-gt-monitor-prome

Spring Boot集成Druid实现数据源管理与监控的详细步骤

《SpringBoot集成Druid实现数据源管理与监控的详细步骤》本文介绍如何在SpringBoot项目中集成Druid数据库连接池,包括环境搭建、Maven依赖配置、SpringBoot配置文件... 目录1. 引言1.1 环境准备1.2 Druid介绍2. 配置Druid连接池3. 查看Druid监控

如何在Ubuntu 24.04上部署Zabbix 7.0对服务器进行监控

《如何在Ubuntu24.04上部署Zabbix7.0对服务器进行监控》在Ubuntu24.04上部署Zabbix7.0监控阿里云ECS服务器,需配置MariaDB数据库、开放10050/1005... 目录软硬件信息部署步骤步骤 1:安装并配置mariadb步骤 2:安装Zabbix 7.0 Server

使用Python绘制3D堆叠条形图全解析

《使用Python绘制3D堆叠条形图全解析》在数据可视化的工具箱里,3D图表总能带来眼前一亮的效果,本文就来和大家聊聊如何使用Python实现绘制3D堆叠条形图,感兴趣的小伙伴可以了解下... 目录为什么选择 3D 堆叠条形图代码实现:从数据到 3D 世界的搭建核心代码逐行解析细节优化应用场景:3D 堆叠图

前端如何通过nginx访问本地端口

《前端如何通过nginx访问本地端口》:本文主要介绍前端如何通过nginx访问本地端口的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、nginx安装1、下载(1)下载地址(2)系统选择(3)版本选择2、安装部署(1)解压(2)配置文件修改(3)启动(4)

HTML中meta标签的常见使用案例(示例详解)

《HTML中meta标签的常见使用案例(示例详解)》HTMLmeta标签用于提供文档元数据,涵盖字符编码、SEO优化、社交媒体集成、移动设备适配、浏览器控制及安全隐私设置,优化页面显示与搜索引擎索引... 目录html中meta标签的常见使用案例一、基础功能二、搜索引擎优化(seo)三、社交媒体集成四、移动

HTML input 标签示例详解

《HTMLinput标签示例详解》input标签主要用于接收用户的输入,随type属性值的不同,变换其具体功能,本文通过实例图文并茂的形式给大家介绍HTMLinput标签,感兴趣的朋友一... 目录通用属性输入框单行文本输入框 text密码输入框 password数字输入框 number电子邮件输入编程框

HTML img标签和超链接标签详细介绍

《HTMLimg标签和超链接标签详细介绍》:本文主要介绍了HTML中img标签的使用,包括src属性(指定图片路径)、相对/绝对路径区别、alt替代文本、title提示、宽高控制及边框设置等,详细内容请阅读本文,希望能对你有所帮助... 目录img 标签src 属性alt 属性title 属性width/h

CSS3打造的现代交互式登录界面详细实现过程

《CSS3打造的现代交互式登录界面详细实现过程》本文介绍CSS3和jQuery在登录界面设计中的应用,涵盖动画、选择器、自定义字体及盒模型技术,提升界面美观与交互性,同时优化性能和可访问性,感兴趣的朋... 目录1. css3用户登录界面设计概述1.1 用户界面设计的重要性1.2 CSS3的新特性与优势1.

HTML5 中的<button>标签用法和特征

《HTML5中的<button>标签用法和特征》在HTML5中,button标签用于定义一个可点击的按钮,它是创建交互式网页的重要元素之一,本文将深入解析HTML5中的button标签,详细介绍其属... 目录引言<button> 标签的基本用法<button> 标签的属性typevaluedisabled