超图iClient3DforCesium地形、影像、模型、在线影像交互示例

超图iClient3DforCesium地形、影像、模型、在线影像交互示例


描述

数据源:基于iserver发布的三维场景(地形、影像、BIM模型) + 在线arcgis影像
应用:目录树展示源数据列表、目录树控制源数据可视化结果显隐、BIM模型点选查询关联属性


示例代码

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1">
        <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
        <title>模型交互示例</title>
        <link href="../../Build/Cesium/Widgets/widgets.css" rel="stylesheet">
        <link href="./css/pretty.css" rel="stylesheet">
        <script src="./js/jquery.min.js"></script>
        <script src="./js/config.js"></script>
        <script src="./js/bootstrap.min.js"></script>
        <script src="./js/bootstrap-select.min.js"></script>
        <script src="./js/bootstrap-treeview.js"></script>
        <script src="./js/spectrum.js"></script>
        <script type="text/javascript" src="../../Build/Cesium/Cesium.js"></script>
    </head>
    <body>
        <div id="cesiumContainer"></div>
        <div id='tool-menu' class='tool-menu'>
            <a data-toggle='dropdown' id='layerMangerBtn' title='图层管理' class='tool-menu-btn tool-menu-btn-inverse'>
                <span class='smicon-layerlist tool-menu-btn-icon'></span>
                <div class="dropDown-container treeview-dropDown-container" id="treeContainer">
                    <div id='layerTree'></div>
                </div>
            </a>
        </div>
        <div id="bubble" class="bubble" style="bottom:0;left:82%;display:none;" >
            <div id="tools" style="text-align : right">
                <span  style="color: rgb(95, 74, 121);padding: 5px;position: absolute;left: 10px;top: 4px;">对象属性</span>
                <span class="fui-export" id="bubblePosition" style="color: darkgrey; padding:5px" title="停靠"></span>
                <span  class="fui-cross" title="关闭" id="close" style="color: darkgrey;padding:5px"></span>
            </div>
            <div style="overflow-y:scroll;height:150px" id="tableContainer"><table id="tab"></table></div>
        </div> 
        <script type="text/javascript">

            function onload(Cesium) {

                // 初始化viewer部件
                var viewer = new Cesium.Viewer('cesiumContainer');

                var scene = viewer.scene;
                var widget = viewer.cesiumWidget;

                // 场景光照
                scene.lightSource.ambientLightColor = new Cesium.Color(0.65, 0.65, 0.65, 1);                

                // 添加在线影像服务                
                let onlineImageries = []; // 在线影像资源对象管理
                var arcgisonline = viewer.imageryLayers.addImageryProvider(new Cesium.ArcGisMapServerImageryProvider({
                    url: 'https://services.arcgisonline.com/arcgis/rest/services/World_Imagery/MapServer'
                }), 2);
                onlineImageries.push({name: 'arcgis-L17', provider: arcgisonline});
                
                // 对象属性展示载体                
                var infoboxContainer = document.getElementById("bubble");
                viewer.customInfobox = infoboxContainer;

                // 添加场景服务
                // 场景服务-界面管理图层数组
                let loadedLayers = [];
                try {
                    var promise = scene.open('@isever服务地址/iserver/services/3D-publish-workspace/rest/realspace');
                    Cesium.when(promise, function(layers) {
                        // 设置相机位置、方向,定位至模型
                        // 可以先不设置 待第一次渲染的时候 使用console.log()打印出相关参数 来填充此设置
                        //scene.camera.setView({
                        //    destination : new Cesium.Cartesian3(-2180753.065987198,4379023.266141494,4092583.575045952),
                        //    orientation : {
                        //        heading : 4.0392222751147955,
                        //        pitch :0.010279641987852584,
                        //        roll : 1.240962888005015e-11
                        //    }
                        //});                        

                        // 界面图层管理树形菜单控件
                        // 初始化树形目录
                        var $tree = $('#layerTree').treeview({
                            data: [{text:"图层目录", selectable:false}],
                            showIcon: true,
                            showCheckbox: true,
                            backColor: 'transparent',
                            color: '#fff',

                            // 通过NodeChecked状态设置子图层的显示与隐藏的切换
                            onNodeChecked: function(evt, node) {
                                // 判断是否选中图层管理节点
                                if (node.text == "模型图层包") {
                                    // 模型图层的父节点 所有模型图层显隐
                                    for (var i = 0; i < loadedLayers.length; i++) {
                                        if (loadedLayers[i].type == 'model') {
                                            loadedLayers[i].source.visible = true;
                                        }
                                    }
                                    return;
                                } else if (node.text == "地形图层包") {
                                    // 地形图层的父节点 所有地形图层显隐
                                    for (var i = 0; i < loadedLayers.length; i++) {
                                        if (loadedLayers[i].type == 'terrain') {
                                            viewer.terrainProvider = loadedLayers[i].source;
                                        }
                                    }
                                    return;
                                } else if (node.text == "影像图层包") {
                                    // 影像图层的父节点 所有影像图层显隐
                                    for (var i = 0; i < loadedLayers.length; i++) {
                                        if (loadedLayers[i].type == 'imagery' || loadedLayers[i].type == 'imagery-online') {
                                            loadedLayers[i].source.show = true;
                                        }
                                    }
                                    return;
                                } else if (node.text == "图层目录") {
                                    for (var i = 0; i < loadedLayers.length; i++) { 
                                        if (loadedLayers[i].type == 'model') {
                                            loadedLayers[i].source.visible = true;
                                        } else if (loadedLayers[i].type == 'terrain') {
                                            viewer.terrainProvider = loadedLayers[i].source;
                                        } else {
                                            loadedLayers[i].source.show = true;
                                        }
                                    }
                                    return;
                                }

                                // 判断是否是模型图层
                                // 先判断是否选中图层的子图层内容
                                var opLayerIndex = -1;
                                var ids = [];
                                for (var i = 0; i < loadedLayers.length; i++) {
                                    // 先判断是否选中了子图层内容
                                    if (loadedLayers[i].type == 'model') {
                                        // 只有模型节点存在子图层内容
                                        for (var j = 0; j < loadedLayers[i].nodes.length; j++) {
                                            if (loadedLayers[i].nodes[j].name == node.text) {
                                                opLayerIndex = i;
                                                ids = range(loadedLayers[i].nodes[j].source.startID, loadedLayers[i].nodes[j].source.endID);
                                                break;
                                            }
                                        }
                                    }
                                    if (opLayerIndex != -1) {
                                        break;
                                    }

                                    // 再判断是否选中的是图层节点本省
                                    if (loadedLayers[i].name == node.text) {
                                        opLayerIndex = i;
                                        break;
                                    }
                                }

                                if (ids.length > 0) {
                                    // 设置子图层id对应的内容显隐
                                    loadedLayers[opLayerIndex].source.setOnlyObjsVisible(ids,true);
                                } else if (opLayerIndex != -1) {
                                    // 图层节点本身
                                    if (loadedLayers[opLayerIndex].type == 'model') {
                                        // 模型图层
                                        loadedLayers[opLayerIndex].source.visible = true;
                                    } else if (loadedLayers[opLayerIndex].type == 'terrain') {
                                        // 地形图层
                                        viewer.terrainProvider = loadedLayers[opLayerIndex].source;
                                    } else {
                                        // 影像图层
                                        loadedLayers[opLayerIndex].source.show = true;
                                    }
                                }
                            },
                            onNodeUnchecked: function(evt, node) {
                                // 判断是否选中图层管理节点
                                if (node.text == "模型图层包") {
                                    // 模型图层的父节点 所有模型图层显隐
                                    for (var i = 0; i < loadedLayers.length; i++) {
                                        if (loadedLayers[i].type == 'model') {
                                            loadedLayers[i].source.visible = false;
                                        }
                                    }
                                    return;
                                } else if (node.text == "地形图层包") {
                                    // 地形图层的父节点 所有地形图层显隐
                                    for (var i = 0; i < loadedLayers.length; i++) {
                                        if (loadedLayers[i].type == 'terrain') {
                                            viewer.terrainProvider = new Cesium.EllipsoidTerrainProvider({}); // 空地形
                                        }
                                    }
                                    return;
                                } else if (node.text == "影像图层包") {
                                    // 影像图层的父节点 所有影像图层显隐
                                    for (var i = 0; i < loadedLayers.length; i++) {
                                        if (loadedLayers[i].type == 'imagery' || loadedLayers[i].type == 'imagery-online') {
                                            loadedLayers[i].source.show = false;
                                        }
                                    }
                                    return;
                                } else if (node.text == "图层目录") {
                                    for (var i = 0; i < loadedLayers.length; i++) { 
                                        if (loadedLayers[i].type == 'model') {
                                            loadedLayers[i].source.visible = false;
                                        } else if (loadedLayers[i].type == 'terrain') {
                                            viewer.terrainProvider = new Cesium.EllipsoidTerrainProvider({}); // 空地形
                                        } else {
                                            loadedLayers[i].source.show = false;
                                        }
                                    }
                                    return;
                                }

                                // 判断是否是模型图层
                                // 先判断是否选中图层的子图层内容
                                var opLayerIndex = -1;
                                var ids = [];
                                for (var i = 0; i < loadedLayers.length; i++) {
                                    // 先判断是否选中了子图层内容
                                    if (loadedLayers[i].type == 'model') {
                                        // 只有模型节点存在子图层内容
                                        for (var j = 0; j < loadedLayers[i].nodes.length; j++) {
                                            if (loadedLayers[i].nodes[j].name == node.text) {
                                                opLayerIndex = i;
                                                ids = range(loadedLayers[i].nodes[j].source.startID, loadedLayers[i].nodes[j].source.endID);
                                                break;
                                            }
                                        }
                                    }
                                    if (opLayerIndex != -1) {
                                        break;
                                    }

                                    // 再判断是否选中的是图层节点本省
                                    if (loadedLayers[i].name == node.text) {
                                        opLayerIndex = i;
                                        break;
                                    }
                                }

                                if (ids.length > 0) {
                                    // 设置子图层id对应的内容显隐
                                    loadedLayers[opLayerIndex].source.setOnlyObjsVisible(ids,false);
                                } else if (opLayerIndex != -1) {
                                    // 图层节点本身
                                    if (loadedLayers[opLayerIndex].type == 'model') {
                                        // 模型图层
                                        loadedLayers[opLayerIndex].source.visible = false;
                                    } else if (loadedLayers[opLayerIndex].type == 'terrain') {
                                        // 地形图层
                                        viewer.terrainProvider = new Cesium.EllipsoidTerrainProvider({}); // 空地形
                                    } else {
                                        // 影像图层
                                        loadedLayers[opLayerIndex].source.show = false;
                                    }
                                }
                            },
                            onNodeSelected: function(evt, node) {
                                // 模型节点子图层选中时 模型渲染状态

                                var opLayerIndex = -1;
                                var ids = [];
                                for (var i = 0; i < loadedLayers.length; i++) {
                                    // 先判断是否选中了子图层内容
                                    if (loadedLayers[i].type == 'model') {
                                        // 只有模型节点存在子图层内容
                                        for (var j = 0; j < loadedLayers[i].nodes.length; j++) {
                                            if (loadedLayers[i].nodes[j].name == node.text) {
                                                opLayerIndex = i;
                                                ids = range(loadedLayers[i].nodes[j].source.startID, loadedLayers[i].nodes[j].source.endID);
                                                break;
                                            }
                                        }
                                    }
                                    if (ids.length > 0) {
                                        break;
                                    }
                                }

                                if (ids.length > 0) {
                                    loadedLayers[opLayerIndex].source.releaseSelection();
                                    loadedLayers[opLayerIndex].source.setSelection(ids);
                                } else {
                                    loadedLayers[opLayerIndex].source.removeAllObjsColor();
                                }
                            }
                        });
                        // 树形目录根节点
                        var rootNode = $tree.treeview('getNode', 0);
                        // 属性目录分成三类子节点:
                        // 第一类: 模型节点
                        var modelNode = $tree.treeview('addNode', [rootNode, {text:"模型图层包", showDel: true, fontSize: '10pt',
                            state: {checked: true}}]);
                        // 第二类: 地形节点
                        var terrainNode = $tree.treeview('addNode', [rootNode, {text:"地形图层包", showDel: true, fontSize: '10pt',
                            state: {checked: true}}]);
                        // 第三类: 影像节点
                        var imageryNode = $tree.treeview('addNode', [rootNode, {text:"影像图层包", showDel: true, fontSize: '10pt',
                            state: {checked: true}}]);

                        // 解析图层 设置图层挂载数据 
                        layers.forEach((layer, index) => {
                            
                            // 将图层添加到loadedLayers便于管理
                            if (layer._isS3MB || layer._isS3MBlock) {
                                // 模型图层
                                // 模型图层需要查询属性,需要挂载数据
                                // 设置图层挂载的数据
                                layer.setQueryParameter({
                                    url: '@isever服务地址/services/data-publish-workspace/rest/data',
                                    dataSourceName: "datasource-publish",
                                    isMerge: true
                                });

                                // decodeURI(layer.name)
                                loadedLayers.push({name: layer.name, checked: true, type: 'model', source: layer, nodes: []});

                                // 树形目录添加模型图层节点
                                var childNode = $tree.treeview('addNode', [modelNode, {text: layer.name, showDel: true, 
                                    fontSize: '10pt', state: {checked: true}}]);
                                // 添加当前图层的内容信息
                                layer.datasetInfo().then(function(result) {
                                    for (var i = 0; i < result.length; i++) {
                                        loadedLayers[loadedLayers.length - 1].nodes.push({name: result[i].datasetName, 
                                            checked: true, type: 'model-node', source: result[i], nodes: []});

                                        // 添加到树形目录
                                        $tree.treeview('addNode', [childNode, {text: result[i].datasetName, showDel: true,
                                            fontSize: '10pt', state: {checked: true}}]);
                                    }
                                });
                           } else if (layer.imageryProvider) {
                                // 影像图层
                                loadedLayers.push({name: decodeURIComponent(layer.imageryProvider.tablename), checked: true, type: 'imagery', source: layer, nodes: []});

                                // 添加到树形目录
                                $tree.treeview('addNode', [imageryNode, {text: decodeURIComponent(layer.imageryProvider.tablename), showDel: true, 
                                    fontSize: '10pt', state: {checked: true}}]);
                            } else if (layer._isTerrainZ) {
                                // decodeURIComponent:可以转换@等特殊字符和中文
                                // decodeURI:只能转换中文
                                // 地形图层
                                loadedLayers.push({name: decodeURIComponent(layer.tablename), checked: true, type: 'terrain', source: layer, nodes: []});
                                
                                // 添加到树形目录
                                $tree.treeview('addNode', [terrainNode, {text: decodeURIComponent(layer.tablename), showDel: true, 
                                    fontSize: '10pt', state: {checked: true}}]);
                            }
                        });

                        // 更新在线影像图层
                        onlineImageries.forEach((online, index) => {
                            // 添加到界面管理图层数组
                            loadedLayers.push({name: online.name, checked: true, type: 'imagery-online', source: online, nodes: []});
                            // 添加到树形目录
                            $tree.treeview('addNode', [imageryNode, {text: online.name, showDel: true, 
                                    fontSize: '10pt', state: {checked: true}}]);
                        });

                    });
                } catch (e) {
                    if (widget._showRenderLoopErrors) {
                        var title = '渲染时发生错误,已停止渲染。';
                        widget.showErrorPanel(title, undefined, e);
                    }
                }

                //点击对象查询对象属性
                let labelPickedWorker = [
                    {name: '名字', value: "", key: 'MODELNAME'},
                    {name: '编码', value: "", key: 'MODELCODE'},
                ]
                var table = document.getElementById("tab");
                viewer.pickEvent.addEventListener(function(feature){
                    $("#bubble").show();
                    for (i = table.rows.length-1;i > -1;i--){
                        table.deleteRow(i);
                    }
                    for(var key in feature ){
                        for (var i = 0; i < labelPickedWorker.length; i++) {
                            if (key == labelPickedWorker[i].key) {
                                var newRow = table.insertRow();
                                var cell1 = newRow.insertCell();
                                var cell2 = newRow.insertCell();
                                cell1.innerHTML = labelPickedWorker[i].name;
                                cell2.innerHTML = feature[key];
                            }
                        }
                    } 
                });
                $("#bubblePosition").click(function(){
                    if($("#bubblePosition").hasClass("fui-export")){
                        viewer.customInfobox = undefined;
                        $("#bubble").removeClass("bubble").addClass("float");
                        $("#bubblePosition").removeClass("fui-export").addClass("fui-bubble");
                        $("#bubblePosition")[0].title = "悬浮";
                        $("#bubble").css({'left' : '82%','bottom' : '45%'});
                        $("#tableContainer").css({'height':'350px'});
                    }
                    else if($("#bubblePosition").hasClass("fui-bubble")){
                        $("#bubble").removeClass("float").addClass("bubble");
                        $("#bubblePosition").removeClass("fui-bubble").addClass("fui-export");
                        $("#bubblePosition")[0].title = "停靠";
                        $("#tableContainer").css({'height':'150px'});
                        viewer.customInfobox = infoboxContainer;
                    }
                });
                $("#close").click(function(){
                    $("#bubble").hide();
                });

                function range(startID,endID){
                    var array=[];
                    for(var i = startID; i < endID + 1; i++){
                        array.push(i);
                    }
                    return array;
                }
                //图层目录的隐藏显示
                $(document).on('click.dropDown-container touchstart.dropDown-container','[data-toggle=dropdown]',function(evt){
                    evt.stopPropagation();
                    var target = evt.target;
                    if(!target.contains(evt.currentTarget) && target.tagName != 'SPAN'){
                        return ;
                    }
                    var $this = $(this), $parent, isActive;
                    var $target = $this.children('div.dropDown-container');
                    if($target.length == 0){
                        $('.dropDown-container').removeClass('dropDown-visible');
                        return ;
                    }
                    isActive = $target.hasClass('dropDown-visible');
                    $('.dropDown-container').removeClass('dropDown-visible');
                    if(!isActive){
                        $target.addClass('dropDown-visible');
                    }
                    return false;
                });
                var height = $('body').height()*0.85 + 'px';
                $('#treeContainer').css({'height' : height,'min-width' : '260px','text-align' : 'left'});
            }

            if (typeof Cesium !== 'undefined') {
                window.startupCalled = true;
                onload(Cesium);
            }
        </script>
    </body>
</html>