基于WebGL架构的3D可视化平台—三维设备管理(ThingJS实现楼宇设备管理3D可视化)

简介: 国内高层建筑不断兴建,它的特点是高度高、层数多、体量大。面积可达几万平方米到几十万平方米。这些建筑都是一个个庞然大物,高高的耸立在地面上,这是它的外观,而随之带来的内部的建筑设备也是大量的。为了提高设备利用率,合理地使用能源,加强对建筑设备状态的监视等,自然地就提出了楼宇自动化控制系统。

国内高层建筑不断兴建,它的特点是高度高、层数多、体量大。面积可达几万平方米到几十万平方米。这些建筑都是一个个庞然大物,高高的耸立在地面上,这是它的外观,而随之带来的内部的建筑设备也是大量的。为了提高设备利用率,合理地使用能源,加强对建筑设备状态的监视等,自然地就提出了楼宇自动化控制系统。下面我们将用ThingJS平台来模拟一个设备管理系统。

第一步,利用CampusBuilder搭建模拟场景。CampusBuilder的模型库有各种各样的模型,使我们搭建出的场景更逼真。使用CampusBuilde创建层级,之后再给层级加外立面就出现了当前的效果。详情移步:CampusBuilder3D场景制作工具

先看结果:演示地址

第二步,创建Equipment类,这里创建。switchControl方法主要一个完成一个计时器的功能来模拟设备警报。

class Equipment extends THING.Thing {
    constructor(app, name, obj, url) {
        super(app);
        this.name = name;
        this.obj = obj;
        this.url = url;
        this.interval = null;
        this.localPosition = [Math.floor(Math.random() * 7), 2.9, Math.floor(Math.random() * 7)];
    }
    createSelf() {
        app.create({
            type: 'Equipment',
            name: this.name,
            url: this.url,
            parent: this.obj,
            localPosition: this.localPosition,
            angle: 0
        });
    }
    switchControl(ev) {
        var flag;
        var equipment = app.query(this.name)[0];
        app.level.change(equipment);
        if (ev) {
            this.interval = setInterval(function () {
                if (flag) {
                    equipment.style.color = '#FF0000';
                    flag = false;
                } else {
                    flag = true;
                    equipment.style.color = '';
                }
            }, 500);
            console.log(this.interval + "查看是否创建了定时器");
        } else {
            console.log(this.interval);
            clearInterval(this.interval);
            if (equipment.style.color == '#FF0000')
                equipment.style.color = '';
        }
    }
}
THING.factory.registerClass('Equipment', Equipment);

  第三步,创建摄像机面板,烟感报警面板以及控制设备的开关,这里简单调整一下面板位置之后会增加两个创建设备的按钮。

//创建主面板
var panel1 = new THING.widget.Panel({
    titleText: '摄像机列表',
    closeIcon: false, // 是否有关闭按钮
    dragable: true,
    retractable: true,
    opacity: 0.9,
    hasTitle: true,
});
panel1.position = [80, 0];

var panel2 = new THING.widget.Panel({
    titleText: '烟感报警列表',
    closeIcon: false, // 是否有关闭按钮
    dragable: true,
    retractable: true,
    opacity: 0.9,
    hasTitle: true,
});
panel2.position = [80, 320];

// 创建任意对象
var dataObj1 = {
    open1: false,
    open2: false,
    open3: false,
    open4: false,
}
var dataObj2 = {
    open5: false,
    open6: false,
    open7: false,
    open8: false,
};

// 动态绑定物体
var open1 = panel1.addBoolean(dataObj1, 'open1').caption('设备01');
var open2 = panel1.addBoolean(dataObj1, 'open2').caption('设备02');
var open3 = panel1.addBoolean(dataObj1, 'open3').caption('设备03');
var open4 = panel1.addBoolean(dataObj1, 'open4').caption('设备04');
var open5 = panel2.addBoolean(dataObj2, 'open5').caption('设备01');
var open6 = panel2.addBoolean(dataObj2, 'open6').caption('设备02');
var open7 = panel2.addBoolean(dataObj2, 'open7').caption('设备03');
var open8 = panel2.addBoolean(dataObj2, 'open8').caption('设备04');

  第四步,开启场景层级切换,创建摄像机和烟感报警器各四个,创建一个数字标识index和保存equipment对象的数组equipmentGroup。

//创建equipment对象数组,以及数组标识
var equipmentGroup = [];
var index = 0;

app.on('load', function (ev) {

    app.level.change(ev.campus);

    for (var i = 0; i < 8; i++) {
        var type = null;
        if (i < 4) {
            type = 'http://model.3dmomoda.cn/models/62A8A75C75044E6AB3D8463FA0CB67AF/0/gltf/';
        } else {
            type = 'http://model.3dmomoda.cn/models/641A9B800DE5431E8C84DC290F8EFDE6/0/gltf/';
        }
        var equipment = new Equipment(app, 'equipment' + index++, app.query('floor' + (Math.floor(Math.random() * 5) + 1))[0], type);
        equipment.createSelf();
        equipmentGroup.push(equipment);
    }
});

  第五步,为每个设备对应的创建控制开关。

open1.on('change', function (ev) {
        equipmentGroup[0].switchControl(ev);
    });
    open2.on('change', function (ev) {
        equipmentGroup[1].switchControl(ev);
    });
    open3.on('change', function (ev) {
        equipmentGroup[2].switchControl(ev);
    });
    open4.on('change', function (ev) {
        equipmentGroup[3].switchControl(ev);
    });
    open5.on('change', function (ev) {
        equipmentGroup[4].switchControl(ev);
    });
    open6.on('change', function (ev) {
        equipmentGroup[5].switchControl(ev);
    });
    open7.on('change', function (ev) {
        equipmentGroup[6].switchControl(ev);
    });
    open8.on('change', function (ev) {
        equipmentGroup[7].switchControl(ev);
    });

  最后一步,创建两个按钮来控制创建设备。

new THING.widget.Button('创建烟感报警', function () {
    var type = 'http://model.3dmomoda.cn/models/641A9B800DE5431E8C84DC290F8EFDE6/0/gltf/';
    var equipment = new Equipment(app, 'equipment' + index++, app.query('floor' + (Math.floor(Math.random() * 5) + 1))[0], type,);
    equipment.createSelf();
    equipmentGroup.push(equipment);
    app.level.change(app.query(equipment.name)[0]);
});

new THING.widget.Button('创建摄像头', function () {
    var type = 'http://model.3dmomoda.cn/models/62A8A75C75044E6AB3D8463FA0CB67AF/0/gltf/';
    var equipment = new Equipment(app, 'equipment' + index++, app.query('floor' + (Math.floor(Math.random() * 5) + 1))[0], type,);
    equipment.createSelf();
    equipmentGroup.push(equipment);
    app.level.change(app.query(equipment.name)[0]);
});

  

在编写过程还是走了不少弯路的,最主要的就是计时器的卸载问题,最初的版本写来写去发现不能控制警报的关闭,后来才 发现计时器没有卸载,警报不但不会关闭而且闪动的频率越来越快。更改之后创建了Equipment这个类来控制所有设备,通过创建这个类的对象给他赋id,父物体,模型地址。这里控制器在开关被触发的时候创建一个新的计时器并赋给的这个对象,再次触发时清除这个计时器,警报的动画就关闭了。演示地址

最后附上完整代码:

/**
 * 说明:创建App,url为场景地址(可选)
 */
var app = new THING.App({
    url: "http://www.thingjs.com/./uploads/wechat/oLX7p05lsWJZUIxnIWsNXAzJ40X8/scene/CampusBuilder20181126134710",    // 场景地址
    "skyBox": "BlueSky"
});

//创建主面板
var panel1 = new THING.widget.Panel({
    titleText: '设备列表',
    closeIcon: false, // 是否有关闭按钮
    dragable: true,
    retractable: true,
    opacity: 0.9,
    hasTitle: true,
    titleImage: 'https://www.thingjs.com/static/images/example/icon.png'
});
panel1.position = [80, 0];

var panel2 = new THING.widget.Panel({
    titleText: '设备列表',
    closeIcon: false, // 是否有关闭按钮
    dragable: true,
    retractable: true,
    opacity: 0.9,
    hasTitle: true,
    titleImage: 'https://www.thingjs.com/static/images/example/icon.png'
});
panel2.position = [80, 320];
// 创建任意对象
var dataObj1 = {
    open1: false,
    open2: false,
    open3: false,
    open4: false,
}
var dataObj2 = {
    open5: false,
    open6: false,
    open7: false,
    open8: false,
};

// 动态绑定物体
var open1 = panel1.addBoolean(dataObj1, 'open1').caption('设备01');
var open2 = panel1.addBoolean(dataObj1, 'open2').caption('设备02');
var open3 = panel1.addBoolean(dataObj1, 'open3').caption('设备03');
var open4 = panel1.addBoolean(dataObj1, 'open4').caption('设备04');
var open5 = panel2.addBoolean(dataObj2, 'open5').caption('设备01');
var open6 = panel2.addBoolean(dataObj2, 'open6').caption('设备02');
var open7 = panel2.addBoolean(dataObj2, 'open7').caption('设备03');
var open8 = panel2.addBoolean(dataObj2, 'open8').caption('设备04');

new THING.widget.Button('创建烟感报警', function () {
    var type = 'http://model.3dmomoda.cn/models/641A9B800DE5431E8C84DC290F8EFDE6/0/gltf/';
    var equipment = new Equipment(app, 'equipment' + index++, app.query('floor' + (Math.floor(Math.random() * 5) + 1))[0], type,);
    equipment.createSelf();
    equipmentGroup.push(equipment);
    app.level.change(app.query(equipment.name)[0]);
});

new THING.widget.Button('创建摄像头', function () {
    var type = 'http://model.3dmomoda.cn/models/62A8A75C75044E6AB3D8463FA0CB67AF/0/gltf/';
    var equipment = new Equipment(app, 'equipment' + index++, app.query('floor' + (Math.floor(Math.random() * 5) + 1))[0], type,);
    equipment.createSelf();
    equipmentGroup.push(equipment);
    app.level.change(app.query(equipment.name)[0]);
});
//创建equipment对象数组,以及数组标识
var equipmentGroup = [];
var index = 0;


app.on('load', function (ev) {

    app.level.change(ev.campus);

    for (var i = 0; i < 8; i++) {
        var type = null;
        if (i < 4) {
            type = 'http://model.3dmomoda.cn/models/62A8A75C75044E6AB3D8463FA0CB67AF/0/gltf/';
        } else {
            type = 'http://model.3dmomoda.cn/models/641A9B800DE5431E8C84DC290F8EFDE6/0/gltf/';
        }
        var equipment = new Equipment(app, 'equipment' + index++, app.query('floor' + (Math.floor(Math.random() * 5) + 1))[0], type);
        equipment.createSelf();
        equipmentGroup.push(equipment);
    }

    open1.on('change', function (ev) {
        equipmentGroup[0].switchControl(ev);
    });
    open2.on('change', function (ev) {
        equipmentGroup[1].switchControl(ev);
    });
    open3.on('change', function (ev) {
        equipmentGroup[2].switchControl(ev);
    });
    open4.on('change', function (ev) {
        equipmentGroup[3].switchControl(ev);
    });
    open5.on('change', function (ev) {
        equipmentGroup[4].switchControl(ev);
    });
    open6.on('change', function (ev) {
        equipmentGroup[5].switchControl(ev);
    });
    open7.on('change', function (ev) {
        equipmentGroup[6].switchControl(ev);
    });
    open8.on('change', function (ev) {
        equipmentGroup[7].switchControl(ev);
    });

});

class Equipment extends THING.Thing {
    constructor(app, name, obj, url) {
        super(app);
        this.name = name;
        this.obj = obj;
        this.url = url;
        this.interval = null;
    }
    createSelf() {
        app.create({
            type: 'Equipment',
            name: this.name,
            url: this.url,
            parent: this.obj,
            localPosition: [Math.floor(Math.random() * 7), 2.9, Math.floor(Math.random() * 7)],
            angle: 0
        });
    }
    switchControl(ev) {
        var flag;
        var equipment = app.query(this.name)[0];
        app.level.change(equipment);
        if (ev) {
            this.interval = setInterval(function () {
                if (flag) {
                    equipment.style.color = '#FF0000';
                    flag = false;
                } else {
                    flag = true;
                    equipment.style.color = '';
                }
            }, 500);
            console.log(this.interval + "查看是否创建了定时器");
        } else {
            console.log(this.interval);
            clearInterval(this.interval);
            if (equipment.style.color == '#FF0000')
                equipment.style.color = '';
        }
    }
}

THING.factory.registerClass('Equipment', Equipment);

  

目录
相关文章
|
3月前
|
人工智能 监控 数据可视化
企业级LLMOps落地指南:蜂巢架构×可视化编排实战
本文将基础的单应用扩展成多应用,并实现工作流组件,包括:多应用模块设计、工作流模块设计、LangGraph实现图应用、前端Vue-Flow组件使用、工作流转LLM工具设计思路、关联工作流登技巧。
209 3
企业级LLMOps落地指南:蜂巢架构×可视化编排实战
|
3月前
|
Ubuntu 编译器 C语言
在Ubuntu22.04平台上交叉编译针对Rv1126架构的GCC13.2.0编译器的步骤。
遵循上述步骤,您应该能够在Ubuntu 22.04平台上成功交叉编译适用于RISC-V架构RV1126的GCC 13.2.0编译器,允许您为目标硬件构建应用程序和操作系统组件。
159 10
|
3月前
|
运维 监控 Java
初创代购选单体,千万级平台用微服务:一张表看懂架构选型红线
在跨境电商代购系统年交易额超3.2万亿元的背景下,本文对比微服务与单体架构的技术原理、适用场景及实战案例,结合性能、运维、成本等维度,为企业提供架构选型指南,助力实现高效扩展与稳定运营。
|
9月前
|
Java Linux C语言
《docker基础篇:2.Docker安装》包括前提说明、Docker的基本组成、Docker平台架构图解(架构版)、安装步骤、阿里云镜像加速、永远的HelloWorld、底层原理
《docker基础篇:2.Docker安装》包括前提说明、Docker的基本组成、Docker平台架构图解(架构版)、安装步骤、阿里云镜像加速、永远的HelloWorld、底层原理
766 90
|
6月前
|
SQL 人工智能 前端开发
JeecgBoot 低代码平台 v3.7.4 发布,后台架构大升级
JeecgBoot 是一款基于 SpringBoot2.x/3.x 和 SpringCloud Alibaba 的企业级 AI 低代码平台,采用前后端分离架构(Ant Design & Vue3),支持 Mybatis-plus 和 Shiro。它集成了强大的代码生成器,可一键生成前后端代码,无需手动编写,大幅减少重复工作。平台支持 DeepSeek、ChatGPT 和 Ollama 等主流大模型,提供 AI 对话
377 9
|
8月前
|
SQL 消息中间件 Kafka
Flink+Paimon+Hologres,面向未来的一体化实时湖仓平台架构设计
本文介绍了阿里云实时数仓Hologres负责人姜伟华在Flink Forward Asia 2024上的分享,涵盖实时数仓的发展历程、从实时数仓到实时湖仓的演进,以及总结。文章通过三代实时数仓架构的演变,详细解析了Lambda架构、Kafka实时数仓分层+OLAP、Hologres实时数仓分层复用等方案,并探讨了未来从实时数仓到实时湖仓的演进方向。最后,结合实际案例和Demo展示了Hologres + Flink + Paimon在实时湖仓中的应用,帮助用户根据业务需求选择合适的方案。
1210 20
Flink+Paimon+Hologres,面向未来的一体化实时湖仓平台架构设计
|
7月前
|
SQL 消息中间件 Serverless
​Flink+Paimon+Hologres,面向未来的一体化实时湖仓平台架构设计
​Flink+Paimon+Hologres,面向未来的一体化实时湖仓平台架构设计
181 4
|
8月前
|
存储 SQL 监控
转转平台IM系统架构设计与实践(二):详细设计与实现
以转转IM架构为起点,介绍IM相关组件以及组件间的关系;以IM登陆和发消息的数据流转为跑道,介绍IM静态数据结构、登陆和发消息时的动态数据变化;以IM常见问题为风景,介绍保证IM实时性、可靠性、一致性的一般方案;以高可用、高并发为终点,介绍保证IM系统稳定及性能的小技巧。
133 6
|
9月前
|
存储 消息中间件 小程序
转转平台IM系统架构设计与实践(一):整体架构设计
本文描述了转转IM为整个平台提供的支撑能力,给出了系统的整体架构设计,分析了系统架构的特性。
222 10
|
9月前
|
监控 JavaScript 数据可视化
建筑施工一体化信息管理平台源码,支持微服务架构,采用Java、Spring Cloud、Vue等技术开发。
智慧工地云平台是专为建筑施工领域打造的一体化信息管理平台,利用大数据、云计算、物联网等技术,实现施工区域各系统数据汇总与可视化管理。平台涵盖人员、设备、物料、环境等关键因素的实时监控与数据分析,提供远程指挥、决策支持等功能,提升工作效率,促进产业信息化发展。系统由PC端、APP移动端及项目、监管、数据屏三大平台组成,支持微服务架构,采用Java、Spring Cloud、Vue等技术开发。
320 7

热门文章

最新文章