viewer_s3m_single.vue 10.3 KB
<!--
 * @Author: jiangbotao
 * 本例中使用了铁岭的倾斜摄影数据发布的服务
 * 1、必须同时发布为三维和Rest数据服务
 * 2、使用要素查询方式来选择倾斜摄影覆盖面(a、矢量面紧贴S3M;b、矢量面构筑entity)
 * 3、使用Popup来弹出倾斜摄影覆盖面的信息
 * @Date: 2019-12-03 22:52:56
 * @LastEditors: jiangbotao
 * @LastEditTime: 2019-12-09 13:33:21
 * @FilePath: \superglobevue\src\components\viewer.vue
 -->
<template>
    <div>
		<div id="cesiumContainer" v-bind:style="styleObject"></div>
		<div id='loadingbar' class="spinner">
			<div class="spinner-container container1">
				<div class="circle1"></div>
				<div class="circle2"></div>
				<div class="circle3"></div>
				<div class="circle4"></div>
			</div>
			<div class="spinner-container container2">
				<div class="circle1"></div>
				<div class="circle2"></div>
				<div class="circle3"></div>
				<div class="circle4"></div>
			</div>
			<div class="spinner-container container3">
				<div class="circle1"></div>
				<div class="circle2"></div>
				<div class="circle3"></div>
				<div class="circle4"></div>
			</div>
		</div>
        <!-- 气泡HTML -->
        <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-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>
	</div>
</template>

<script>
import URL_CONFIG from "./../config/urlConfig.vue";
const Cesium = window.Cesium;
export default {
    data: function() {
        return {
            styleObject: {
                width: "100%",
                height: '100%',
                position: "absolute",
                top: "0px",
                bottom: "0px",
                left: "0px",
                backgroundColor: "#000000"
            },
            smviewer: {}
        };
    },
    mounted: function() {
        // cesium视图
        this.viewer = new Cesium.Viewer("cesiumContainer", { navigationInstructionsInitiallyVisible: false });
        // 使用自定义的navigation
        var options = {};
        options.enableCompass= true;
        options.enableZoomControls= true;
        options.enableDistanceLegend= true;
        options.enableCompassOuterRing= true;
        this.viewer.extend(Cesium.viewerCesiumNavigationMixin, options);
        // 隐藏logo
        $(".cesium-widget-credits")[0].style.visibility = "hidden";
        // 隐藏导航工具
        $(".cesium-viewer-navigationContainer")[0].style.visibility="hidden";
        // 必要的引用对象
        var smviewer = this.viewer;
        var scene = this.viewer.scene;
        var widget = this.viewer.cesiumWidget;
        var camera = scene.camera;
        // 场景位置,用于popup定位
        var scenePosition = null;
        var infoboxContainer = document.getElementById("bubble");
        var table = document.getElementById("tab");

        try {
            // 添加s3m图层
            var promise2 = scene.addS3MTilesLayerByScp("http://www.supermapol.com/realspace/services/3D-dynamicDTH/rest/realspace/datas/Config%20-%201/config", 
                { name: "oblique photography" });
            Cesium.when.all([promise2], function(obliqueLayers){ 
                // 等倾斜摄影数据加载完了再去加载矢量面,否则矢量面找不到目标去贴对象
                // 先定位,开始渲染定位区域的倾斜
                camera.setView({ 
                    destination : new Cesium.Cartesian3(-2623004.4174251584, 3926981.958360567, 4287374.829655093),
                    orientation : {
                        heading: 4.39611370540786,
                        pitch : -0.43458664812464143,
                        roll : 2.0174972803488345e-11
                    }
                });
                // 去除加载动画
                $('#loadingbar').remove();
            });
        } catch (e) {
            if (widget._showRenderLoopErrors) {
                var title = '渲染时发生错误,已停止渲染。';
                widget.showErrorPanel(title, undefined, e);
            }
        }
        // 倾斜摄影模型下的矢量数据面
        var dataSourceName = '铁岭矢量面'; // 数据源名称
        var dataSetName = 'New_Region3D_1'; // 数据集名称
        var dataServiceUrl = 'http://www.supermapol.com/realspace/services/data-dynamicDTH/rest/data/featureResults.rjson?returnContent=true';
        
        // 鼠标左键的触发事件,查询要素并弹出显示
        var handler = new Cesium.ScreenSpaceEventHandler(this.viewer.canvas);
        handler.setInputAction(function(e) {
            // 删除可能存在的identify-area的entity,它是我们后面查询的用于标识模型的三维面
            smviewer.entities.removeById('identify-area');
            // 当前位置
            var position = scene.pickPosition(e.position);
            // 设置场景位置
            scenePosition = position;
            var cartographic = Cesium.Cartographic.fromCartesian(position);
            var longitude = Cesium.Math.toDegrees(cartographic.longitude);
            var latitude = Cesium.Math.toDegrees(cartographic.latitude);
            var queryPoint = { // 查询点对象
                x: longitude,
                y: latitude
            };
            // 将当前点转换为地理坐标后进行查询
            queryByPoint(queryPoint);
        }, Cesium.ScreenSpaceEventType.LEFT_CLICK);

        $("#close").click(function(){
            // 关闭气泡
            smviewer.entities.removeAll();
            $("#bubble").hide();
        });
        // 每一帧都去计算气泡的正确位置
        scene.postRender.addEventListener(function(){ 
            if (scenePosition) {
                var canvasHeight = scene.canvas.height;
                var windowPosition = new Cesium.Cartesian2();
                Cesium.SceneTransforms.wgs84ToWindowCoordinates(scene, scenePosition, windowPosition);
                infoboxContainer.style.bottom = (canvasHeight - windowPosition.y + 45) + 'px';
                infoboxContainer.style.left = (windowPosition.x - 70) + 'px';
                infoboxContainer.style.visibility = "visible";
            }
        });

        // 通过点击查询用于表示单体化的面要素,添加到场景中高亮显示。
        function queryByPoint(queryPoint) {
            var queryObj = {
                "getFeatureMode": "SPATIAL",
                "spatialQueryMode": "INTERSECT",
                "datasetNames": [dataSourceName + ":" + dataSetName],
                "geometry": {
                    id: 0,
                    parts: [1],
                    points: [queryPoint],
                    type: "POINT"
                }
            };

            var queryObjJSON = JSON.stringify(queryObj); // 转化为JSON字符串作为查询参数
            $.ajax({
                type: "post",
                url: dataServiceUrl,
                data: queryObjJSON,
                success: function(result) {
                    var resultObj = JSON.parse(result);
                    if (resultObj.featureCount > 0) {
                        var selectedFeature = resultObj.features[0];
                        addClapFeature(selectedFeature);
                        // console.log(selectedFeature);
                        $("#bubble").show();
                        for (var i=table.rows.length-1; i>-1; i--){
                            table.deleteRow(i);
                        }
                        for(var index in selectedFeature.fieldNames){
                            var newRow = table.insertRow();
                            var cell1 = newRow.insertCell();
                            var cell2 = newRow.insertCell();
                            cell1.innerHTML = selectedFeature.fieldNames[index];
                            cell2.innerHTML = selectedFeature.fieldValues[index];
                        }
                    }else{
                        $("#bubble").hide();
                    }
                },
                error: function(msg) {
                    console.log(msg);
                }
            })
        }

        // 将数据服务查询到的要素添加到场景中高亮显示,表示选中效果。
        // 两种方法:
        // a. 矢量面紧贴S3M
        // b. 使用entity模型
        function addClapFeature(feature) {
            var lonLatArr = getLonLatArray(feature.geometry.points);
            smviewer.entities.add({
                id: 'identify-area',
                name: '单体化标识面',
                polygon: {
                    hierarchy: Cesium.Cartesian3.fromDegreesArray(lonLatArr),
                    material: new Cesium.Color(1.0, 0.0, 0.0, 0.3),
                },
                clampToS3M: true // 贴在S3M模型表面
            });
            // console.log(lonLatArr);
            // smviewer.entities.add({
            //     id: 'identify-area',
            //     name: '单体化标识面',
            //     polygon: {
            //         hierarchy: Cesium.Cartesian3.fromDegreesArray(lonLatArr),
            //         material: new Cesium.Color(0.0, 1.0, 0.0, 0.3),
            //         // perPositionHeight: true,
            //         extrudedHeight: 100,
            //         height: 50,
            //         vertexFormat : Cesium.EllipsoidSurfaceAppearance.VERTEX_FORMAT,
            //         outline : true,
            //         outlineColor : Cesium.Color.BLACK
            //     },
            // });
        }

        // 得到[经度,纬度,经度,纬度...]形式的数组,用于构造面。
        function getLonLatArray(points) {
            var point3D = [];
            points.forEach(function(point) {
                point3D.push(point.x);
                point3D.push(point.y);
            });
            return point3D;
        }
    }
};
</script>

<style>
.compass {
    top: 10px;
}
.navigation-controls {
    top: 130px;
}
.bubble {
    padding: 5px;
    border-radius: 5px;
}
#tab {
    height: unset;
    text-align: left;
}
</style>