基于WebGL架构的3D可视化平台—粮仓3D场景

前言

什么才是智慧粮仓

正所谓“国以民为本,民以食为天”。粮食既是关系国计民生和国家经济安全的重要战略物资,也是人民群众最基本的生活资料。其中粮仓是粮食建设的根基,对保障粮食安全尤为重要。随着信息化技术发展,全国各地开始智慧粮仓的建设:

可视一体化,让粮仓“智慧”升级

可视:粮仓的园区、仓区、仓库、设备的3D可视;
可查:3D场景内查看粮情、动环、仓容、能耗、视频监控、出入库等信息;
可控:3D场景内控制仓门、仓窗、通风口、风机、空调等设备设施的开关状态;
可防:系统通过集成数据,提前预知粮食霉菌、虫害的产生与生长趋势,提早制定防治措施,实现粮食绿色、生态储藏。

以上摘自【万物可视系列之三】物联网可视化让粮仓“智慧升级”:[原文链接]
(http://blog.uinnova.cn/articles/2018/09/26/1469670300647.html)

查看Demo

实现




实现
第一步,加载场景资源。

//加载场景代码
var app = new THING.App({
    // 场景地址
    "url": "http://www.thingjs.com/./uploads/wechat/S2Vyd2lu/scene/CB20190228115320",
    //背景设置
    "skyBox": "BlueSky"
});

第二步,创建视角导航栏。给每一个按钮添加监听事件,当切换观察模式时,将其他观察模式关闭并将摄像头的视角锁定。当选择的观察模式为全局观察模式时允许摄像头操作app.camera.inputEnabled = true。

	var toolbar2 = new THING.widget.Panel({ width: '250px', captionPos: 'hover' });
toolbar2.position = [10, 10];

// 数据对象
var dataObj = {
    area01: false,
    area02: false,
    area03: false,
    overall: true,

}

THING.Utils.dynamicLoad(['lib/iconfont.js'], function () {

    var button1 = toolbar2.addImageBoolean(dataObj, 'area01').caption('宿舍区域').url('#momoda_lc-icontubiao22');
    var button2 = toolbar2.addImageBoolean(dataObj, 'area02').caption('工厂区域').url('#momoda_lc-icontubiao10');
    var button3 = toolbar2.addImageBoolean(dataObj, 'area03').caption('粮仓区域').url('#momoda_lc-icontubiao21');
    var button4 = toolbar2.addImageBoolean(dataObj, 'overall').caption('全景预览').url('#momoda_lc-icontubiao28');

    button1.on('change', function (ev) {
        dataObj.area02 = false;
        dataObj.area03 = false;
        dataObj.overall = false;
        app.camera.flyTo({
            'position': [-22.356943810261143, 13.20176112267712, 28.19482648304762],
            'target': [-53.24507055455286, 0.6162378602394785, 6.3743932170050375],
            'time': 2000,
            'complete': function () {
                app.camera.inputEnabled = false;
            }
        });
    });

    button2.on('change', function (ev) {
        dataObj.area01 = false;
        dataObj.area03 = false;
        dataObj.overall = false;
        // 摄像机飞行到某位置
        app.camera.flyTo({
            'position': [-2.8177753324747767, 16.090400887405227, 19.94073098974482],
            'target': [-2.685240969328181, -1.3204502556714408, 3.6209106265430773],
            'time': 2000,
            'complete': function () {
                app.camera.inputEnabled = false;
            }
        });

    });

    button3.on('change', function (ev) {
        dataObj.area01 = false;
        dataObj.area02 = false;
        dataObj.overall = false;
        // 摄像机飞行到某位置
        app.camera.flyTo({
            'position': [33.313117413004846, 20.17892561437951, 30.105105312212782],
            'target': [50.84710727906235, -1.7298146965736394, 10.602912178089504],
            'time': 2000,
            'complete': function () {
                app.camera.inputEnabled = false;
            }
        });


    });

    button4.on('change', function (ev) {
        dataObj.area01 = false;
        dataObj.area02 = false;
        dataObj.area03 = false;
        // 摄像机飞行到某位置
        app.camera.flyTo({
            'position': [-18.079999999999977, 80.427, 101.051],
            'target': [13.422, 2.597, 2.226],
            'time': 2000,
            'complete': function () {
                app.camera.inputEnabled = true;
            }
        });
    });
});

第三步,鼠标单击事件为粮仓添加信息面板,以及右键删除信息面板重置摄像头位置。

var panel;
app.on('SingleClick', function (ev) {

    if (ev.button == 2) {
        if (panel) {
            panel.destroy();
            panel = null;
        }
        if (curObject) {
            curObject.playAnimation('close');
            curObject = null;
            app.camera.flyTo({
                'position': [33.313117413004846, 20.17892561437951, 30.105105312212782],
                'target': [50.84710727906235, -1.7298146965736394, 10.602912178089504],
                'time': 2000,
                'complete': function () {
                    app.camera.inputEnabled = false;
                }
            });
        }
        return;
    }

    var object = ev.object;
    if (object == null || object.name == "field")
        return;
    if (panel != null) {
        panel.destroy();
        panel = null;
    }
    panel = new THING.widget.Panel({
        width: '200px',
    })
    var data = {
        type: '小米',
        admin: 'Kerwin',
        surplus: Math.round(Math.random() * 100) + '%',
        temperature: Math.round(Math.random() * 10) + '°'
    }
    // 绑定物体身上相应的属性数据
    panel.addString(object, 'id').caption('仓库编号');
    panel.addString(data, 'admin').caption('管理员');
    panel.addString(data, 'type').caption('库存种类');
    panel.addString(data, 'surplus').caption('剩余空间');
    panel.addString(data, 'temperature').caption('仓库温度');
    panel.position = [500, 50];
    //创建UIAnchor面板
    var uiAnchor = app.create({
        // 类型
        type: 'UIAnchor',
        // 父节点设置
        parent: object,
        // 要绑定的页面的 element 对象
        element: panel.domElement,
        // 设置 localPosition 为 [0, 0, 0]
        localPosition: [0, -15, 0],
        // 指定页面的哪个点放到localPosition位置上(百分比)
        pivot: [-0.2, 2.1]
    });

    uiAnchor["panel"] = panel;

    return uiAnchor;
});

第四步,鼠标左键双击时,粮仓的open动画开启并将当前粮仓保存为curObject,当curObject发生改变时执行close动画并且为curObject重新赋值。

var curObject;
app.on('dblclick', function (ev) {
    if (ev.button == 2)
        return;
    if (curObject) {
        curObject.playAnimation('close');
        curObject = null;
    }
    var object = ev.object;
    curObject = object;
    curObject.playAnimation('open');
    app.camera.flyTo({
        object: curObject,
    });
});

完整代码

//加载场景代码
var app = new THING.App({
    // 场景地址
    "url": "http://www.thingjs.com/./uploads/wechat/S2Vyd2lu/scene/CB20190228115320",
    //背景设置
    "skyBox": "BlueSky"
});


var toolbar2 = new THING.widget.Panel({ width: '250px', captionPos: 'hover' });
toolbar2.position = [10, 10];

// 数据对象
var dataObj = {
    area01: false,
    area02: false,
    area03: false,
    overall: true,

}

THING.Utils.dynamicLoad(['lib/iconfont.js'], function () {

    var button1 = toolbar2.addImageBoolean(dataObj, 'area01').caption('宿舍区域').url('#momoda_lc-icontubiao22');
    var button2 = toolbar2.addImageBoolean(dataObj, 'area02').caption('工厂区域').url('#momoda_lc-icontubiao10');
    var button3 = toolbar2.addImageBoolean(dataObj, 'area03').caption('粮仓区域').url('#momoda_lc-icontubiao21');
    var button4 = toolbar2.addImageBoolean(dataObj, 'overall').caption('全景预览').url('#momoda_lc-icontubiao28');

    button1.on('change', function (ev) {
        dataObj.area02 = false;
        dataObj.area03 = false;
        dataObj.overall = false;
        app.camera.flyTo({
            'position': [-22.356943810261143, 13.20176112267712, 28.19482648304762],
            'target': [-53.24507055455286, 0.6162378602394785, 6.3743932170050375],
            'time': 2000,
            'complete': function () {
                app.camera.inputEnabled = false;
            }
        });
    });

    button2.on('change', function (ev) {
        dataObj.area01 = false;
        dataObj.area03 = false;
        dataObj.overall = false;
        // 摄像机飞行到某位置
        app.camera.flyTo({
            'position': [-2.8177753324747767, 16.090400887405227, 19.94073098974482],
            'target': [-2.685240969328181, -1.3204502556714408, 3.6209106265430773],
            'time': 2000,
            'complete': function () {
                app.camera.inputEnabled = false;
            }
        });

    });

    button3.on('change', function (ev) {
        dataObj.area01 = false;
        dataObj.area02 = false;
        dataObj.overall = false;
        // 摄像机飞行到某位置
        app.camera.flyTo({
            'position': [33.313117413004846, 20.17892561437951, 30.105105312212782],
            'target': [50.84710727906235, -1.7298146965736394, 10.602912178089504],
            'time': 2000,
            'complete': function () {
                app.camera.inputEnabled = false;
            }
        });


    });

    button4.on('change', function (ev) {
        dataObj.area01 = false;
        dataObj.area02 = false;
        dataObj.area03 = false;
        // 摄像机飞行到某位置
        app.camera.flyTo({
            'position': [-18.079999999999977, 80.427, 101.051],
            'target': [13.422, 2.597, 2.226],
            'time': 2000,
            'complete': function () {
                app.camera.inputEnabled = true;
            }
        });


    });


});

var panel;
app.on('SingleClick', function (ev) {

    if (ev.button == 2) {
        if (panel) {
            panel.destroy();
            panel = null;
        }
        if (curObject) {
            curObject.playAnimation('close');
            curObject = null;
            app.camera.flyTo({
                'position': [33.313117413004846, 20.17892561437951, 30.105105312212782],
                'target': [50.84710727906235, -1.7298146965736394, 10.602912178089504],
                'time': 2000,
                'complete': function () {
                    app.camera.inputEnabled = false;
                }
            });
        }
        return;
    }

    var object = ev.object;
    if (object == null || object.name == "field")
        return;
    if (panel != null) {
        panel.destroy();
        panel = null;
    }
    panel = new THING.widget.Panel({
        width: '200px',
    })
    var data = {
        type: '小米',
        admin: 'Kerwin',
        surplus: Math.round(Math.random() * 100) + '%',
        temperature: Math.round(Math.random() * 10) + '°'
    }
    // 绑定物体身上相应的属性数据
    panel.addString(object, 'id').caption('仓库编号');
    panel.addString(data, 'admin').caption('管理员');
    panel.addString(data, 'type').caption('库存种类');
    panel.addString(data, 'surplus').caption('剩余空间');
    panel.addString(data, 'temperature').caption('仓库温度');
    panel.position = [500, 50];
    //创建UIAnchor面板
    var uiAnchor = app.create({
        // 类型
        type: 'UIAnchor',
        // 父节点设置
        parent: object,
        // 要绑定的页面的 element 对象
        element: panel.domElement,
        // 设置 localPosition 为 [0, 0, 0]
        localPosition: [0, -15, 0],
        // 指定页面的哪个点放到localPosition位置上(百分比)
        pivot: [-0.2, 2.1]
    });

    uiAnchor["panel"] = panel;

    return uiAnchor;
});

var curObject;
app.on('dblclick', function (ev) {
    if (ev.button == 2)
        return;
    if (curObject) {
        curObject.playAnimation('close');
        curObject = null;
    }
    var object = ev.object;
    curObject = object;
    curObject.playAnimation('open');
    app.camera.flyTo({
        object: curObject,
    });
});

你可能感兴趣的:(基于WebGL架构的3D可视化平台—粮仓3D场景)