CESIUM 学习 – 三维分析之通视分析,坡度分析,淹没分析,视域分析

  • Post author:
  • Post category:其他


import mouseManager from './mouseManager.js';
import Primitives from './primitives.js';
import Entitys from './entitys.js';
import Tools from './cvTool.js';
import entityFactory from './entityFactory.js';
export default class Analyser{
    
   ...
/**
     * 两点通视分析
     * @param {*} options 
     */
    createVisibility(options){
        //判断是否有值
        options = Cesium.defaultValue(options, Cesium.defaultValue.EMPTY_OBJECT);
        
        var viewer = options.viewer,_self = this;
        
        if (!Cesium.defined(viewer)) {
            throw new Cesium.DeveloperError('viewer is required.');
        }
        var analyser=options.analyser;
        if (!Cesium.defined(analyser)) {
            throw new Cesium.DeveloperError('analyser is required.');
        }
        analyser.state= this.BEYONANALYSER_STATE.PREPARE;
 
        var visiblyEffect=function(options){
            this.id = Cesium.defaultValue(options.id,Cesium.createGuid());
            this._markers=[];
            this._lines=[];
            this._pickedObjs=[];
            this.posArray=[];
            this._resultTip=viewer.entities.add({
                id:this.id,
                label : {
                    //name: 'visiblyEffect',
                    //show : false,
                    fillColor:Cesium.Color.YELLOW,
                    showBackground : true,
                    font : '14px monospace',
                    horizontalOrigin : Cesium.HorizontalOrigin.LEFT,
                    verticalOrigin : Cesium.VerticalOrigin.BOTTOM,
                    pixelOffset : new Cesium.Cartesian2(0, -10)
                }
            });
            //交互操作
            var scope = this;
            analyser.handler.setInputAction(function (movement) {
                //var cartesian = Cesium.pickGlobe(viewer.scene,movement.position);
                let cartesian = _self.mouseManager.piTerrainToModule(movement.position);
                scope.posArray.push(cartesian);
                if(scope._markers.length==0){
                    //scope.reset();
                    var startSphere = viewer.entities.add({
                        position : cartesian,
                        ellipsoid : {
                            radii : new Cesium.Cartesian3(2.0, 2.0, 2.0),
                            material : Cesium.Color.BLUE
                        },
                        label:{
                            text:"视线起点",
                            fillColor:Cesium.Color.YELLOW,
                            pixelOffset:{
                                x:0,y:-20
                            },
                            scale:0.5
                        }
                    });  
                    //objectsToExclude.push(startSphere);
                    scope._markers.push(startSphere);
                    analyser.state= _self.BEYONANALYSER_STATE.OPERATING;
                }else if(scope._markers.length==1){
                    var redSphere = viewer.entities.add({
                        position : cartesian,
                        ellipsoid : {
                            radii : new Cesium.Cartesian3(2.0, 2.0, 2.0),
                            material : Cesium.Color.RED
                        }
                    });
                    scope._markers.push(redSphere);
                    
                    var results=analyser.getIntersectObj(scope.posArray[0],cartesian,scope._markers,true);
                    //分析一下是否都有position
                    for (let index = results.length-1; index >=0; index--) {
                        const element = results[index];
                        if(!Cesium.defined(element.position)){
                            results.splice(index,1);
                        }                    
                    }
                    if(!Cesium.defined(results[0].position)){
                        throw new Cesium.DeveloperError("position is undefined");
                    }
                    var pickPos1=results[0].position;
                    var dis=Cesium.Cartesian3.distance(pickPos1,cartesian);                
                    var bVisibility=dis<5?true:false;
                    var arrowPositions=[scope.posArray[0],results[0].position];
                    var greenLine=viewer.entities.add({
                            polyline : {
                                positions : arrowPositions,
                                width : 10,
                                arcType : Cesium.ArcType.NONE,
                                material : new Cesium.PolylineArrowMaterialProperty(Cesium.Color.GREEN)
                            }
                        });
                        scope._lines.push(greenLine);
                    if(!bVisibility){
                        var unArrowPositions=[results[0].position,cartesian];
                        var redLine=viewer.entities.add({
                            polyline : {
                                positions : unArrowPositions,
                                width : 10,
                                arcType : Cesium.ArcType.NONE,
                                material : new Cesium.PolylineArrowMaterialProperty(Cesium.Color.RED)
                            }
                        });
                        scope._lines.push(redLine);
                    }
                    
                    showIntersections(results);
                    var pos1=scope.posArray[0];
                    var pos2=cartesian;
                    var rad1 = Cesium.Cartographic.fromCartesian(pos1);
                    var rad2 = Cesium.Cartographic.fromCartesian(pos2);
                    var degree1 = {longitude:rad1.longitude / Math.PI * 180,latitude:rad1.latitude / Math.PI * 180,height:rad1.height};
                    var degree2 = {longitude:rad2.longitude / Math.PI * 180,latitude:rad2.latitude / Math.PI * 180,height:rad2.height};
 
                    var length_ping = Math.sqrt(Math.pow(pos1.x-pos2.x,2)+Math.pow(pos1.y-pos2.y,2)+Math.pow(pos1.z-pos2.z,2));
                    var length_h = Math.abs(degree2.height-degree1.height);
                    var length = Math.sqrt(Math.pow(length_ping,2)+Math.pow(length_h,2));
                    //console.log(degree1);
                    var visTxt=bVisibility?'是':'否';
                    var text =
                        '起点坐标: ' + ('   (' + degree1.longitude.toFixed(6))+ '\u00B0' +',' +(degree1.latitude.toFixed(6))+ '\u00B0'+',' +degree1.height.toFixed(2)+')' +
                        '\n终点坐标: ' + ('   (' + degree2.longitude.toFixed(6))+ '\u00B0' +',' +(degree2.latitude.toFixed(6))+ '\u00B0'+',' +degree2.height.toFixed(2)+')' +
                        '\n垂直距离: ' + '   ' + length_h.toFixed(2) +'m'+
                        '\n水平距离: ' + '   ' + length_ping.toFixed(2) +'m'+
                        '\n空间距离: ' + '   ' + length.toFixed(2) +'m'+
                        '\n是否可视: ' + '   ' + visTxt;
                    
                    _self.showTip(scope._resultTip,true,cartesian,text,{
                        fillColor:Cesium.Color.YELLOW
                    });
                    analyser.state= _self.BEYONANALYSER_STATE.END;
                }
            }, Cesium.ScreenSpaceEventType.LEFT_CLICK );
 
            var info;
            analyser.handler.setInputAction(function (movement) {
                var cartesian =viewer.scene.pickPosition(movement.endPosition);
                if(analyser.state === _self.BEYONANALYSER_STATE.PREPARE){               
                    info ='点击设定起点';
                    _self.showTip(scope._resultTip,true,cartesian,info);
                }else if(analyser.state === _self.BEYONANALYSER_STATE.OPERATING){               
                    info ='点击分析通视情况';
                    _self.showTip(scope._resultTip,true,cartesian,info);
                }
            },Cesium.ScreenSpaceEventType.MOUSE_MOVE);
 
            function showIntersections(results) {        
                for (let i = 0; i < results.length; ++i) {
                    var object = results[i].object;
                    if(object){
                        if (object instanceof Cesium.Cesium3DTileFeature) {
                            scope._pickedObjs.push(object);
                            object.oldColor=object.color.clone();
                            object.color = Cesium.Color.fromAlpha(Cesium.Color.YELLOW, object.color.alpha);
                        }else if (object.id instanceof Cesium.Entity) {
                            var entity=object.id;
                            scope._pickedObjs.push(entity);
                            var color=entity.polygon.material.color.getValue();
                            entity.polygon.oldColor=color.clone();
                            entity.polygon.material = Cesium.Color.fromAlpha(Cesium.Color.YELLOW, color.alpha);
                        }
                    }
                    
                    scope._markers.push(viewer.entities.add({
                        position : results[i].position,
                        ellipsoid : {
                            radii : new Cesium.Cartesian3(0.8, 0.8, 0.8),
                            material : Cesium.Color.RED
                        }
                    }));
                }
            }
 
        }
        visiblyEffect.prototype.remove = function () {
            //恢复颜色
            for (i = 0; i < this._pickedObjs.length; ++i) {
                var object=this._pickedObjs[i];
                if (object instanceof Cesium.Cesium3DTileFeature) {
                    object.color = object.oldColor.clone();
                }else if (object instanceof Cesium.Entity) {
        
                    object.polygon.material = object.polygon.oldColor.clone();                
                }
            }
            this._pickedObjs.length=0;
 
            for (let index = 0; index < this._markers.length; index++) {
                var element = this._markers[index];
                viewer.entities.remove(element);            
            }
            this._markers.length=0;
 
            for (let index = 0; index < this._lines.length; index++) {
                var element = this._lines[index];
                viewer.entities.remove(element);            
            }
            this._lines.length=0;
 
            viewer.entities.remove(this._resultTip);   
            this._resultTip=undefined;        
        }
        return new visiblyEffect(options);
    }
    
/**
     * 淹没分析
     * @param {} options 
     */
    createSubmergedAnalyseEffect(options){
        options = Cesium.defaultValue(options, Cesium.defaultValue.EMPTY_OBJECT);
         /**
         * 点击
         */
        let _self = this,viewer = options.viewer,maxH = options.maxH
        ,interval = options.interval,speed = options.speed;
        _self.waterEntity = null;
        let analyser=options.analyser;
 
        this.positions = [];
        this.polyObj = null;
        this.tempPoints = [];
        this.entity = [];
        analyser.handler.setInputAction(function (e) {//第一次点击
            if(_self.Tools.nullBool(e.position)){
                return false;
            }
            let cartesian = _self.mouseManager.screenToWorld(e.position);
            if(_self.positions == 0){
                _self.positions.push(cartesian.clone())
            }
            _self.positions.push(cartesian); //模拟
 
            let cartographic = Cesium.Cartographic.fromCartesian(_self.positions[_self.positions.length - 1]);
            _self.tempPoints.push({ lon: Cesium.Math.toDegrees(cartographic.longitude), lat:  Cesium.Math.toDegrees(cartographic.latitude) ,hei:cartographic.height});
            /**
             * 创建实体
             */
            let entity = _self.entitys.createEntity();
            entity.position = cartesian;
            entity.point = _self.entitys.getPoint();
            _self.entity.push(_self.entitys.add(entity)); //创建点
        },Cesium.ScreenSpaceEventType.LEFT_CLICK);
        /**
         * 移动
         */
        analyser.handler.setInputAction(function (e) {
            if(_self.Tools.nullBool(e.endPosition)){
                 return false;
            }
            let cartesian = _self.mouseManager.screenToWorld(e.endPosition);
            if(_self.positions.length >= 2){
                if (!Cesium.defined(_self.polyObj)) {
                    _self.polyObj = new entityFactory({type:"createPolygon",data:{positions:_self.positions,material:Cesium.Color.WHITE.withAlpha(0.1)}});
                    _self.waterEntity = _self.entitys.add(_self.polyObj);
                    _self.entity.push(_self.waterEntity); //创建线
                }else{
                    _self.positions.pop();
                    _self.positions.push(cartesian.clone());
                }
            }
        }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
        /**
         * 右键取消
         */
        analyser.handler.setInputAction(function (e) {
            if(_self.Tools.nullBool(e.position)){
                return false;
            }
            analyser.handler.destroy(); //关闭事件句柄
            _self.positions.pop(); //最后一个点无效
            //二秒后开始进入淹没分析
            setTimeout(function () {
                if (_self.waterEntity) {
                    viewer.scene.globe.depthTestAgainstTerrain = true;
                    _self.waterEntity.polygon.heightReference = "CLAMP_TO_GROUND";
                    _self.waterEntity.polygon.material = "./img/water.png";
                    var h = 0.0;
                    _self.waterEntity.polygon.extrudedHeight = h;
                    var st = setInterval(function () {
                        h = h + speed;
                        if (h >= maxH) {
                            h = maxH;//给个最大值
                            clearTimeout(st); //结束
                        }
                        _self.waterEntity.polygon.extrudedHeight = h;
                    }, interval);
                }
            }, 2000);
            $("body").append('<div  id="video_div" style="position:absolute;right:10px;bottom:10px;"><video width="350" height="250" src="video/yanmo.mp4" controls autoplay></video></div>');
            setTimeout(function () {
                $("#video_div").remove();
            },10000)
        },Cesium.ScreenSpaceEventType.RIGHT_CLICK);
    }
 
 
 
}