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

摘要:
面积可达几万平方米到几十万平方米。为了提高设备利用率,合理地使用能源,加强对建筑设备状态的监视等,自然地就提出了楼宇自动化控制系统。下面我们将用ThingJS平台来模拟一个设备管理系统。CampusBuilder的模型库有各种各样的模型,使我们搭建出的场景更逼真。详情移步:CampusBuilder3D场景制作工具先看结果:演示地址第二步,创建Equipment类,这里创建。switchControl方法主要一个完成一个计时器的功能来模拟设备警报。

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

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

先看结果:演示地址

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

第二步,创建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);

免责声明:文章转载自《基于WebGL架构的3D可视化平台—三维设备管理(ThingJS实现楼宇设备管理3D可视化)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇C#解析json的两种方式「小技巧」利用Chrome手动找出豆瓣小站和新浪微音乐的歌曲地址下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

APP测试之Monkey压力测试(一)

(一)Monkey简介 Monkey意指猴子,顽皮淘气。所以Monkey测试,顾名思义也就像猴子一样在软件上乱敲按键,猴子什么都不懂,就爱捣乱。Monkey原理也是类似,通过向系统发送伪随机的用户事件流(如按键输入、触摸屏输入、滑动Trackball、手势输入等操作),来对设备上的程序进行压力测试,检测程序多久的时间会发生异常。Monkey包括许多选项,它...

Microsoft SyncToy 文件同步工具

Microsoft SyncToy SyncToy 是由 微软 推出的一款免费的文件夹同步工具。虽然名字中有一个 Toy,但是大家可千万不要误以为它的功能弱爆了。实际上,我感觉这款软件还真是摆脱了微软大多数软件给人复杂和臃肿的印象,通过很简单的操作便能够完成复杂的操作,免去了大量重复的手动复制、移动操作。 SyncToy 支持三种同步模式: syn...

485串口的串口服务器介绍特点说明

       rs485串口服务器是一款工业级串口服务器设备,拥有高规格的电气保护,ISO9001国际质量认证,采用协议栈技术,不宕机、不死机、数据不丢失,整机2年质保,技术支持终身服务,在-40℃—85℃环境下可运行,进口芯片,独立CPU。RS485串口转以太网,6-30V宽电压供电,软件+硬件+CPU三级看门狗稳定不宕机。        rs485串口...

C++开源库详细介绍

C++在“商业应用”方面,曾经是天下第一的开发语言,但这一桂冠已经被java抢走多年。因为当今商业应用程序类型,已经从桌面应用迅速转移成Web应 用。当Java横行天下之后,MS又突然发力,搞出C#语言,有大片的曾经的C++程序员,以为C++要就此沉沦,未料,这三年来,C++的生命力突然被 严重地增强了。主力原因就是开源的软件、基础软件(比如并发原生支持,...

运维工具大宝典之开源平台篇

fromhttp://cio.it168.com/a2015/1128/1782/000001782714_all.shtml 【IT168技术】在运维工具大宝典系列第一篇文章《运维工具大宝典之运维需求篇》中,云智慧对上云企业的运维需求进行的汇总,其中第6条“对开源的强烈需求”主要是来自运维人员,特别是技术大牛,他们喜欢一切尽在掌握的感脚,而这就需要开源运...

HTTPWatch使用

注意:现在httpwatch也可以集成到火狐浏览器中. 一.介绍 HttpWatch是强大的网页数据分析工具.集成在Internet Explorer工具栏.包括网页摘要.Cookies管理.缓存管理.消息头发送/接受.字符查询.POST 数据和目录管理功能.报告输出.HttpWatch 是一款能够收集并显示深层信息的软件。它不用代理服务器或一些复杂的网络...