基于 HTML5 WebGL 的计量站三维可视化监控系统 Web 组态工控应用
得益于 HTML5 WebGL 技术的成熟,从技术上对工控管理的可视化,数据可视化变得简单易行!完成对工控设备的管理效率,资源管理,风险管理等的大幅度提高,同时也对国家工业4.0计划作出有力响应!
如本案例所示,是一个基于 HTML5 WebGL 技术实现的计量站三维可视化监控系统,在本案例中,具体宏观的展示一个油田站点的整体场景,然后点击可以进入内景看到油田计量站内景的具体情况,同时可以看到各个设备的参数的当前状态。
同样的其中功能组件具有很高的复用性,所以也会非常方便的应用到其他场景中!
如下所示,便是本案例运行动态图:
此项目链接:基于 HTML5 WebGL 的计量站三维可视化监控系统 Web 组态工控应用
(http://www.hightopo.com/demo/metering-station/)

在这个场景中主要有如下几个功能:
1、点击来回切换场景;
2、管线流动效果;
3、数据面板动态显示;
确认功能需求后就可以开始实施实现,动手实现之前要先确认场景有哪些,如下所示主要有油田外景和内景。
外景:

内景:

技能储备
本 demo 需要掌握 HT for Web 的 2d 和 3d 相关 技术,具体技术参考资料可以去 HT for Web 官网图扑软件了解。
实现功能
1、默认视角
在三维场景中,需要先设置一个默认视角,当重新打开页面时候直接回到默认视角,通过 setFar , setEye 和 setCenter 方法实现。
gv.setFar(100000);
gv.setEye([1247, 600, 1972]);
gv.setCenter([0, 0, 0]);
2、视角限制
由于三维场景的特性,如果不作出视角限制,就会出现穿模,翻底等现象,尤其本案例有天空球效果,如果不作出视角限制当用户无限拉远后会出现视角跑到天空球外,场景消失问题,这将会非常尴尬!
具体实现是通过 setEye 方法和 setCenter 方法控制场景的 eye 和 center 变量实现,放置到 gv.mp 函数内。
mp(listener, scope, ahead) 增加自身属性变化事件监听器
//限制eye
gv.mp(function (e) {
if (e.property === 'eye') {
if (gv.getEye()[1] < 90) {
gv.getEye()[1] = 90;
}
if (gv.getEye()[1] > 1500) {
gv.getEye()[1] = 1500;
}
if (gv.getEye()[0] > 2400) {
gv.getEye()[0] = 2400;
}
if (gv.getEye()[0] < -2400) {
gv.getEye()[0] = -2400;
}
if (gv.getEye()[2] > 2500) {
gv.getEye()[2] = 2500;
}if (gv.getEye()[2] < -2400) {
gv.getEye()[2] = -2400;
}
}
})
3、点击切换场景
通过 mi 添加交互事件监听器为要点机交互模型绑定事件,通过 e.kind 判断点击事件,然后通过 tag 标签名获取要点击交互的模型对象。
首先在点击时候有个拉近效果和周围模型透明化效果,则是通过 flyTo 实现拉近效果和 setStyle 方法实现拉近后其他模型透明化。
具体代码如下:
gv.mi(function (e) {
if (e.kind === 'clickData') {
for (var i = 1; i <= 2; i++) {
if (e.data.getTag() === 'engineRoom' + i) {
//点击拉近场景
gv.flyTo(e.data, {
animation: true,
distance: 500
});
//选中模型实化
e.data.setStyle('shape3d.transparent', false);
e.data.setStyle('shape3d.opacity', 1);
//其他模型透明化
dm.each(data => {
if (data.getTag() != 'engineRoom' + i) {
data.setStyle('shape3d.transparent', true);
data.setStyle('shape3d.opacity', 0.3);
data.setStyle('all.transparent', true);
data.setStyle('all.opacity', 0.5);
}
})
}
}
}
})
实现效果如下:

然后在完成拉近场景和透明化其他模型后,开始搞场景切换效果。
场景切换的核心是通过 gv.deserialize() 反序列化显示路径对应场景,通过输入场景路径参数,在回调函数内完成场景渲染显示,代码如下:
gv.deserialize('scenes/油田.json', function (json, dm, gv, datas) {
if (json.title) document.title = json.title;
if (json.a['json.background']) {
var bgJSON = json.a['json.background'];
if (bgJSON.indexOf('displays') === 0) {
var bgGv = new ht.graph.GraphView();
bgGv.deserialize(bgJSON);
bgGv.addToDOM();
graphView.addToDOM(bgGv.getView());
}
else if (bgJSON.indexOf('scenes') === 0) {
var bgG3d = new ht.graph3d.Graph3dView();
bgG3d.deserialize(bgJSON);
bgG3d.addToDOM();
graphView.addToDOM(bgG3d.getView());
}
graphView.handleScroll = function () { };
}
})
但在在这之前有一个问题,就是如何处理当前场景和通过反序列化渲染显示场景的关系,如果不作处理,就会出现当前场景和要切换显示的场景重合问题,所以在点击切换场景过程中,要先清空当前场景,为后来要切换的场景腾出地方。
所以在前面要先加一行代码:
dm.clear();
做完处理后,现在是完成了切换过去效果,但还有要切换回来的功能,这个实现非常简单,取了个巧,直接 window.location.reload(); 刷新页面就好。
最终这部分完整代码如下:
function jump(position3d) {
var timer = setInterval(function () {
clearInterval(timer)
var distance = ht.Default.getDistance(gv.getEye(), position3d);
if (distance <= 501) {
var home = g2d.dm().getDataByTag('home');
home.s('2d.visible', true);
var line = g2d.dm().getDataByTag('line');
line.s('2d.visible', true);
dm.clear();
gv.deserialize('scenes/油田.json', function (json, dm, gv, datas) {
if (json.title) document.title = json.title;
if (json.a['json.background']) {
var bgJSON = json.a['json.background'];
if (bgJSON.indexOf('displays') === 0) {
var bgGv = new ht.graph.GraphView();
bgGv.deserialize(bgJSON);
bgGv.addToDOM();
graphView.addToDOM(bgGv.getView());
}
else if (bgJSON.indexOf('scenes') === 0) {
var bgG3d = new ht.graph3d.Graph3dView();
bgG3d.deserialize(bgJSON);
bgG3d.addToDOM();
graphView.addToDOM(bgG3d.getView());
}
graphView.handleScroll = function () { };
}
})
}
}, 500)
}
我将它放置到 jump 函数内,然后将 jump 函数放到前面点击事件中调用,让代码整体简洁一些。
实现效果如下图:

4、管线流动效果和动态数据面板
最后两个功能实现非常简单,我就放到一块来说。
首先效果如下图所示:

管线流动效果的实现核心就是控制 UV 贴图偏移,所以通过动画控制器 startAnim 控制 UV 贴图偏移量就可以实现,在动画结束时,在 finishFunc 内回调函数即可实现动画循环。
pipelineAnim(0.1)
function pipelineAnim(offset1) {
var anim1 = ht.Default.startAnim({
duration: 2000,
action: function () {
offset1 += 0.015;
var pipelines = gv.dm().getDataByTag('pipeline');
pipelines.setStyle('shape3d.uv.offset', [-offset1, 0]);
},
finishFunc: function () {
pipelineAnim(offset1);
}
})
}
数据面板则是通过定时器在固定间隔时间循环执行赋予随机数即可,在这里通过随机数模拟真实数据,在实际当中是通过和后台对接实现真实数据动态变化,代码如下:
setInterval(function () {
for (var i = 1; i <= 4; i++) {
var panels = gv.dm().getDataByTag('panel' + i);
for (var j = 1; j <= 3; j++) {
if (panels.a('text' + j) != undefined) {
var num = parseFloat(Math.random() * (100 - 10 + 1) + 10, 10).toFixed(2);
var textJson = { "参数名": "出口温度", "参数值": num, "参数单位": panels.a('text' + j)['参数单位'] };
panels.a('text' + j, textJson);
}
}
}
}, 1000)
结束语
以上便是我今天给大家带来的工控案例,希望各位看官能够喜欢本demo,在本案例中能够得到一些启发。
基于 HTML5 WebGL 的计量站三维可视化监控系统 Web 组态工控应用的更多相关文章
- 基于 HTML5 WebGL 的智慧楼宇三维可视化监控
前言 可视化的智慧楼宇在 21 世纪是有急迫需求的,中国被世界称为"基建狂魔",全球高层建筑数量位居首位,所以对于楼宇的监控是必不可少.智慧楼宇可视化系统更多突出的是管理方面的功能 ...
- 基于 HTML5 + WebGL 的宇宙(太阳系) 3D 可视化系统
前言 近年来随着引力波的发现.黑洞照片的拍摄.火星上存在水的证据发现等科学上的突破,以及文学影视作品中诸如<三体>.<流浪地球>.<星际穿越>等的传播普及,宇宙空间 ...
- 基于 HTML5 WebGL 的发动机 3D 可视化系统
前言 工业机械产品大多体积庞大.运输成本高,在参加行业展会或向海外客户销售时,如果没有实物展示,仅凭静态.简单的图片说明书介绍,无法让客户全面了解产品,不仅工作人员制作麻烦,客户看得也费力.如 ...
- 基于 HTML5 WebGL 的加油站 3D 可视化监控
前言 随着数字化,工业互联网,物联网的发展,我国加油站正向有人值守,无人操作,远程控制的方向发展,传统的人工巡查方式逐渐转变为以自动化控制为主的在线监控方式,即采用数据采集与监控系统 SCADA.SC ...
- 基于 HTML5 WebGL 的地铁站 3D 可视化系统
前言 工业互联网,物联网,可视化等名词在我们现在信息化的大背景下已经是耳熟能详,日常生活的交通,出行,吃穿等可能都可以用信息化的方式来为我们表达,在传统的可视化监控领域,一般都是基于 Web SCAD ...
- 基于 HTML5 + WebGL 实现 3D 可视化地铁系统
前言 工业互联网,物联网,可视化等名词在我们现在信息化的大背景下已经是耳熟能详,日常生活的交通,出行,吃穿等可能都可以用信息化的方式来为我们表达,在传统的可视化监控领域,一般都是基于 Web SCAD ...
- 基于 HTML5 + WebGL 的地铁 3D 可视化系统
前言 工业互联网,物联网,可视化等名词在我们现在信息化的大背景下已经是耳熟能详,日常生活的交通,出行,吃穿等可能都可以用信息化的方式来为我们表达,在传统的可视化监控领域,一般都是基于 Web SCAD ...
- 基于 HTML5 WebGL 的挖掘机 3D 可视化应用
前言 在工业互联网以及物联网的影响下,人们对于机械的管理,机械的可视化,机械的操作可视化提出了更高的要求.如何在一个系统中完整的显示机械的运行情况,机械的运行轨迹,或者机械的机械动作显得尤为的重要,因 ...
- 基于 HTML5 + WebGL 的 3D 可视化挖掘机
前言 在工业互联网以及物联网的影响下,人们对于机械的管理,机械的可视化,机械的操作可视化提出了更高的要求.如何在一个系统中完整的显示机械的运行情况,机械的运行轨迹,或者机械的机械动作显得尤为的重要,因 ...
随机推荐
- js获取当前页面url信息方法(JS获取当前网址信息)
设置或获取对象指定的文件名或路径. alert(window.location.pathname) 设置或获取整个 URL 为字符串. alert(window.location.href); 设置或 ...
- C++ 随机数字以及随机数字加字母生成
#include <time.h>#include <sys/timeb.h>void MainWindow::slot_clicked(){ QString strRand; ...
- 实现serializable接口的作用
最重要的两个原因是: 1.将对象的状态保存在存储媒体中以便可以在以后重新创建出完全相同的副本: 2.按值将对象从一个应用程序域发送至另一个应用程序域. 实现serializable接口的作用是就是可以 ...
- Linux 环境下为VirtualBox安装增强功能
VirtualBox安装CentOS后,再安装增强功能就可以共享文件夹.粘贴板以及鼠标无缝移动,主要步骤如下: 1.yum -y update 2.yum -y install g++ gcc gcc ...
- 在 Linux 上创建虚拟机规模集和部署高度可用的应用
利用虚拟机规模集,可以部署和管理一组相同的.自动缩放的虚拟机. 可以手动缩放规模集中的 VM 数,也可以定义规则,以便根据资源使用情况(如 CPU 使用率.内存需求或网络流量)进行自动缩放. 在本教程 ...
- 在table中选中某条数据,让其显示对应详细信息
在第一个页面中使用 ccms.dialog.open({url:url+$(this).attr("code"),id:"dialogPic",width:10 ...
- 使用 sar 和 kSar 来发现 Linux 性能瓶颈
作者: Vivek Gite 译者: LCTT qhwdw | sar 命令用用收集.报告.或者保存 UNIX / Linux 系统的活动信息.它保存选择的计数器到操作系统的 /var/log/sa/ ...
- python已写内容中可能的报错及解决办法
理论上我发的每个短文,直接复制放到py里面,python xx.py是可以执行的,不过因为版本,编码什么的问题会有报错,详见这里 报错: SyntaxError: Non-ASCII characte ...
- 作业一 制作PC配置 吴昊
- 18年11月5日 NOIP模拟赛
T1 题解 对于k=100的情况,贪心 对于100%的数据 可以发现,当前的决策只对后面的开采有影响,且剩余耐久度与之后的开采收益成正比,如果倒着考虑这个问题,得出i-n的星球1点耐久度所能获得的最大 ...