基於 HTML5 WebGL 的計量站三維可視化監控系統 Web 組態工控應用

来源:https://www.cnblogs.com/htdaydayup/archive/2019/04/16/10714737.html
-Advertisement-
Play Games

得益於 HTML5 WebGL 技術的成熟,從技術上對工控管理的可視化,數據可視化變得簡單易行!完成對工控設備的管理效率,資源管理,風險管理等的大幅度提高,同時也對國家工業4.0計劃作出有力響應! 如本案例所示,是一個基於 HTML5 WebGL 技術實現的計量站三維可視化監控系統,在本案例中,具... ...


得益於 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,在本案例中能夠得到一些啟發。

 

 

 

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 快速查找所有存儲過程中是否包含某個字元串 ...
  • 一、通過SQL語句訪問遠程資料庫 --OPENROWSET函數 使用OPENROWSET()是個不錯的選擇,也可以用做跨庫查詢包括增、刪、改、查 下麵就來介紹一下OPENROWSET函數的運用 包含訪問 OLE DB 數據源中的遠程數據所需的全部連接信息。當訪問鏈接伺服器中的表時,這種方法是一種替代 ...
  • [20190415]11g下那些latch是共用的.txthttp://andreynikolaev.wordpress.com/2010/11/23/shared-latches-by-oracle-version/--//oracle並沒有文檔準確說明那些latch是支持共用,作者的鏈接通過使用 ...
  • 一臺老舊的資料庫伺服器(SQL Server 2005)突然報如下錯誤,而且資料庫處於RECOVERY PENDING ,檢查錯誤日誌,發現這個錯誤是突然出現的。沒有任何其它人為誤操作導致 Date 2019/4/15 10:57:47 Log SQL Server (Archive #1 - 20... ...
  • 《工業大數據白皮書(2019版)》基於工業大數據技術、產業發展現狀,重點圍繞“工業數據管理”這一熱點議題,提煉了當前工業領域數據管理的重要方法,完善了工業大數據標準體系,為推動工業大數據落地應用和戰略部署提供標準化支撐。 ...
  • 本文節選自作者書籍《軟體架構設計:大型網站技術架構與業務架構融合之道》。作者微信公眾號:架構之道與術。公眾號底部菜單有書友群可以加入,與作者和其他讀者進行深入討論。也可以在京東、天貓上購買紙質書籍。 6.6 事務實現原理之2:Undo Log 6.6.1 Undo Log是否一定需要 說到Undo ...
  • 各版本下載地址:http://download.redis.io/releases,本教程使用版本為redis-5.0.4。 附錄: (一)執行make命令報錯解決方案: 報錯內容: 解決方案: 在終端輸入如下命令,安裝Xcode命令行工具: 安裝完成後,繼續從make命令往下執行即可。 註:如有錯 ...
  • 背景 說到異常處理,你可能直接會認為不就是 try catch 的事情,至於寫一篇文章單獨來說明嗎? 如果你是這麼想的,那麼本篇說不定會給你驚喜哦~ 而且本篇聚焦在圖片的異常處理。 場景 學以致用,有具體的應用場景,能夠加深我們對知識的掌握。 我們以簡書的文章列表為例,如下圖: 假設產品有這樣的需求 ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...