基于 HTML5 WebGL 的智慧楼宇可视化系统
前言
可视化的智慧楼宇在 21 世纪是有急迫需求的,中国被世界称为“基建狂魔”,全球高层建筑数量位居首位,所以对于楼宇的监控是必不可少。智慧楼宇可视化系统更多突出的是管理方面的功能,即如何的全面实现优化控制和管理,节能降耗、高效、舒适、环境安全这样一个目的,可以这样说,判断一个建筑物是否具有智能建筑特点,要看它是否具有 IBMS 的系统集成,这是很重要的判定条件。IBMS 系统的建立必不可少需要硬件采集信息到后台,随着工业互联网,物联网概念的推广应用,让硬件与软件的结合变得系统化,过程化,使得智慧楼宇可视化成为可能。
本文所概述的智慧楼宇是基于一栋真实建筑可视化简化建模之后得到的效果,楼层的轮廓在系统中抽象成线条,整体拼凑起来就形成了一栋简化版的楼宇,当然其中的楼层地板也是抽象成简单的立方体包裹在对应楼层线框的里面。对应的电梯,闸机,扶梯等物体也简化抽象成六面体,线条。抽象的物体全部采用 HT 的 API 即可创建完成,所以抽象之后具有复用性,同样的方法可以采用到其它所有楼宇。
系统功能
预览地址:基于 HTML5 WebGL的智慧楼宇可视化系统 https://hightopo.com/demo/IBMS/
- 工单监测 -- 统计楼宇收到的工单信息
- 客流监测 -- 显示当日进出楼宇的人流量信息
- 消防报警 -- 统计当日楼宇的消防报警信息
- 重点区域监控 -- 显示重点区域的摄像头信息
- 停车场车位统计 -- 统计停车场车位信息
- 楼宇控制 -- 可单独控制不同类型楼层的闸机,电梯,扶梯,警报和客流的显示与隐藏,监控此时电梯,扶梯等物体的运行情况
- 告警信息 -- 实时滚动显示当前楼宇的告警信息
系统预览
楼宇效果

楼层效果

楼层控制效果

系统实现
UI 以及模型实现
2D
2d 部分的 UI 都是采用 HT 暴漏的 API 进行描绘实现,UI 部分都绘制在一个 canvas 节点上,并且全都为矢量,所以放大不会失真,两侧的实时数据通过 数据绑定 实现实时刷新,HT 在处理实时刷新的时候只会刷新当前需要刷新的区域,所以不会出现例如修改一个页面上的某个文字而导致整个 canvas 重绘。

上图所示的摄像头监控画面则是通过将 video 标签叠加在 2d 对应区域的 UI 上面,HT 对于第三方需要嵌入的 dom 节点可以通过叠加 dom 的方式在对应区域进行叠加来实现。目前摄像头采用的第三方插件多为 video.js 或者 Aliplayer 来实现嵌入,通过将对应的 iframe 嵌入到指定区域来实现,以下为嵌入的 rtmp 实时视频流的图标参考代码:
if (!cache.view) {
// 创建 iframe 节点 并且设置 style 属性
var iframe = cache.htmlView = document.createElement('iframe');
iframe.setAttribute('style', 'margin: 0; padding: 0; border: 0;');
iframe.setAttribute('id', 'cameraIframe');
iframe.src = './rtmp/rtmp.html';
cache.view = iframe;
// 调用 graphView 上的 layoutHTML 布局方法,会自动布局到上面所说的对应区域
cache.htmlView.layoutHTML = function() {
gv.layoutHTML(data, iframe, true)
}
}
// 读取 rtmp 视频流地址
var cameraURL = data.a('cameraURL');
if (cache.cameraURL !== cameraURL) {
cache.cameraURL = cameraURL;
// 获取 iframe 页面暴漏的 playVideoByUrl 方法,来执行对应的播放操作
if (cache.view.contentWindow) {
if (cache.view.contentWindow.playVideoByUrl) {
cache.view.contentWindow.playVideoByUrl(cameraURL, cache);
}
} else {
// 起定时器的目的是为了防止 contentWindow 在第一次还没有加载完成导致 contentWindow 为 null
if (window.loadFrameInterval) {
clearInterval(window.loadFrameInterval);
window.loadFrameInterval = null;
}
window.loadFrameInterval = setInterval(function() {
// 此时 contentWindow 已经加载完成,所以执行 playVideoByUrl 操作
if (cache.view.contentWindow.playVideoByUrl) {
cache.view.contentWindow.playVideoByUrl(cameraURL, cache);
clearInterval(window.loadFrameInterval);
window.loadFrameInterval = null;
}
},
100);
}
}
以下为 iframe 页面中的部分部分代码:
// 记录此时的视频播放器对象
var player = null;
// 记录此时的图标节点 cache 对象
var nodeCache = null;
// 创建视频播放器 dom 节点
function createVideoContainer() {
var div = document.createElement('div');
div.classList.add('prism-player');
div.id = 'player-con';
document.body.appendChild(div);
}
// 通过视频流地址初始化 Aliplayer 播放器
function playVideoByUrl(cameraURL, cache) {
// 如果已经初始化过 player 则需要先销毁
pauseVideo();
// 创建视频播放器 dom 节点
createVideoContainer();
// 初始化 player 播放器
player = new Aliplayer({
"id": "player-con",
"source": cameraURL,
"width": "100%",
"height": "100%",
"autoplay": true,
"isLive": true,
"rePlay": false,
"playsinline": true,
"preload": true,
"controlBarVisibility": "hover",
"useFlashPrism": true,
});
nodeCache = cache;
}
// 销毁 player 对象
function pauseVideo() {
if (player) {
player.dispose();
player = null;
document.body.removeChild(document.getElementById('player-con'));
if (nodeCache) {
nodeCache.cameraURL = null;
nodeCache = null;
}
}
}
3D
3d 部分系统采用极简的方式来表示楼宇,用到了 HT 中的 ht.Shape 节点类型,可以参考 形状手册 ,该节点类型可以指定 points 以及 segments,所以可以用来动态生成管道或者墙面,通过简化之后我们的楼宇就可以通过管道和墙面两种类型来构造,并且构造的时候如果有许多层结构相同,或者有规律的从下到上,或从上到下的形状,则只需要构造第一层以及最后一层之后其它所有楼层都可以通过计算的方式动态生成,以下为示意图:

通过上图可以知道中间所有的楼层的对应点的信息我们都可以通过计算获取,具体的实现的方式在下一节会通过伪代码阐述。
3d 部分还有个电梯的简单上下移动,该部分暂时通过模拟的方式进行移动,没有具体对接真实的电梯运行数据,其中所有的电梯都是对应的电梯线的子节点,所以电梯线部分存储了自己所能到达的楼层,则对应电梯线上的电梯也可以知道自己在垂直空间的运动范围,之后可以通过 requestAnimationFrame 来实现动画效果,如下伪代码:
// 每帧移动的距离
var moveStep = 5;
function frameFunc() {
// 电梯的移动方向 1 为向上,-1 为向下
var direction = moveNode.a('direction') || 1;
// 电梯下一帧的位置
var nextPosY = moveNode.getElevation() + moveStep * direction;
// 如果下一帧位置大于最高层的位置则改变 direction 的方向
if (nextPosY >= maxElevation) {
direction = -1;
}
// 如果下一帧位置小于最低层的位置则改变 direction 的方向
if (nextPosY <= minElevation) {
direction = 1;
}
moveNode.a('direction', direction);
moveNode.setElevation(nextPosY);
window.requestAnimationFrame(frameFunc);
}
window.requestAnimationFrame(frameFunc);
楼宇构造实现
为了方便讲解,我们以如下图错开的简单楼层来讲解:

上图第一层和最后一层都由 6 个点组成,如下图:

从上图可以看出第一层和最后一层都是由六个点组成,所以第一层和最后一层中间的所有层可以根据这两层点的数据进行计算得出,例如上面图中如果第一层和最后一层中间还有两层的话,则可以计算出对应每层的平面坐标,垂直空间的坐标可以根据第一层和最后一层的垂直距离进行平分得到,描述图如下:

若中间有两层则生成的效果图如下:

通过以上几个可视化的步骤我们可以了解到生成一栋简单的楼层所需要经历的步骤,如下为步骤图:

通过如上操作我们就可以绘制出某些楼层,如果建筑由不同的楼层结构构成,则同理可以按照如上顺序分开分别绘制,最后拼凑起来。
总结
传统的 智慧楼宇/楼宇自动化/楼宇安防/智慧园区 常会采用 BIM(建筑信息模型 Building information modeling) 软件,如 Autodesk 的 Revit 或 Bentley 这类建筑和工程软件,但这些 BIM 建模模型的数据往往过于庞大臃肿,绝大部分细节信息对楼宇自控意义不大,反而影响拖累了行业 Web SCADA 或 Web 组态监控的趋势,所以我们采用以 Hightopo 的 HT for Web 产品轻量化 HTML5/WebGL 建模的方案,实现快速建模、运行时轻量化到甚至手机终端浏览器即可 3D 可视化运维的良好效果。
以下为移动端的程序运行截图:

基于 HTML5 WebGL 的智慧楼宇可视化系统的更多相关文章
- 基于 HTML5 WebGL 的智慧楼宇三维可视化监控
前言 可视化的智慧楼宇在 21 世纪是有急迫需求的,中国被世界称为"基建狂魔",全球高层建筑数量位居首位,所以对于楼宇的监控是必不可少.智慧楼宇可视化系统更多突出的是管理方面的功能 ...
- 基于 HTML5 WebGL 的地铁站 3D 可视化系统
前言 工业互联网,物联网,可视化等名词在我们现在信息化的大背景下已经是耳熟能详,日常生活的交通,出行,吃穿等可能都可以用信息化的方式来为我们表达,在传统的可视化监控领域,一般都是基于 Web SCAD ...
- 基于 HTML5 + WebGL 的地铁 3D 可视化系统
前言 工业互联网,物联网,可视化等名词在我们现在信息化的大背景下已经是耳熟能详,日常生活的交通,出行,吃穿等可能都可以用信息化的方式来为我们表达,在传统的可视化监控领域,一般都是基于 Web SCAD ...
- 基于 HTML5 WebGL 的发动机 3D 可视化系统
前言 工业机械产品大多体积庞大.运输成本高,在参加行业展会或向海外客户销售时,如果没有实物展示,仅凭静态.简单的图片说明书介绍,无法让客户全面了解产品,不仅工作人员制作麻烦,客户看得也费力.如 ...
- 基于 HTML5 WebGL 的 智慧楼宇能源监控系统
前言 21世纪,在能源危机和全球气候变暖的压力下,太阳能等可再生能源越来越受到关注,其中光伏建筑一体化逐渐成为绿色发展方式和生活方式,加强节能降耗,支持低碳产业和新能源.可再生能源发展,也已经成为国家 ...
- 基于 HTML5 WebGL 的高炉炼铁厂可视化系统
前言 在当今 工业4.0 新时代的推动下,不仅迎来了 工业互联网 的发展,还开启了 5G 时代的新次元.而伴随着带宽的提升,网络信息飞速发展,能源管控上与实时预警在工业互联网中也占着举足轻 ...
- 基于 HTML5 WebGL 的 水泥工厂可视化系统
前言 如今的制造行业,基于数据进行生产策略制定与管理已经成为一种趋势,特别是 工业4.0 的浪潮下,数据战略已经成为很多制造企业的优先战略,而数据可视化以更直观的方式,帮助指导决策,成为数据分析传递信 ...
- 基于 HTML5 + WebGL 的无人机 3D 可视化系统
前言 近年来,无人机的发展越发迅速,既可民用于航拍,又可军用于侦察,涉及行业广泛,也被称为“会飞的照相机”.但作为军事使用,无人机的各项性能要求更加严格.重要.本系统则是通过 Hightopo 的 ...
- 基于 HTML5 WebGL 的挖掘机 3D 可视化应用
前言 在工业互联网以及物联网的影响下,人们对于机械的管理,机械的可视化,机械的操作可视化提出了更高的要求.如何在一个系统中完整的显示机械的运行情况,机械的运行轨迹,或者机械的机械动作显得尤为的重要,因 ...
随机推荐
- esri mdb 数据库导入 到postgreSQL
需求: 项目升级,需要将esri的个人数据库(mdb格式)导入到开源数据库postgreSQL中. 思路: 使用fwtools工具导出到数据库中. 环境: windows+fwtools+postgr ...
- Go 每日一库之 viper
简介 上一篇文章介绍 cobra 的时候提到了 viper,今天我们就来介绍一下这个库. viper 是一个配置解决方案,拥有丰富的特性: 支持 JSON/TOML/YAML/HCL/envfile/ ...
- DataFrame数据合并
一.join 作用:默认情况下,他是把行索引相同的数据合并到一起注意:以左为准,没有的部分用NaN补全 例子 import pandas as pd import numpy as np df1 = ...
- Mklink 转移文件/文件夹
使用Mklink可以创建一个目录链接,从而完美转移文件/文件夹 MS官方文档 https://docs.microsoft.com/en-us/windows-server/administratio ...
- Markdown 标记 粘贴到 小书 匠 才知道 哦
# 一级标题## 这是二级标题### 三级标题##### 五级 高阶== 低阶-- [TOC] > 这是一级引用>>这是二级引用>>> 这是三级引用 ```java ...
- Python学习,第三课 - 数据类型
前言. 本次针对Python中的数据类型,做详细的总结 1.数字 2 是一个整数的例子. 长整数 不过是大一些的整数. 3.23和52.3E-4是浮点数的例子.E标记表示10的幂.在这里,52.3E- ...
- .Net Core建站(2):EF Core+CodeFirst数据库迁移
上一篇的话,说了下怎么使用EF7 实现 CodeFirst去生成数据库, 其实还有好多问题的,这次一点一点的解决吧,都挺简单,不过零零散散的,, 1.读取配置文件,获得链接字符串 2.使用数据库进行增 ...
- HTML-02-常用标签演示
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- win10打开相机提示我们找不到你的相机
- 虚拟环境vitualenv的使用
在使用 Python 开发的过程中,工程一多,难免会碰到不同的工程依赖不同版本的库的问题: 亦或者是在开发过程中不想让物理环境里充斥各种各样的库,引发未来的依赖灾难. 此时,我们需要对于不同的工程使用 ...