[cesium] 衛星掃描 + 地面雷達 + 實時通信過境 效果

效果圖

代碼:

/**
 * 衛星過境封裝類
 */
import CVTools from './cvTool.js';
import mouseManager from './mouseManager.js';
import Entitys from './entitys.js';
import entityFactory from './entityFactory.js';
import Handler from './handler.js';
export default class satelliteTransit{

    constructor(v){
        /**
         * 核心類
         */
        this.CoreV = v;
        /**
         * 時鐘
         */
        this.STClock = v.clock;
        /**
         * 時間速率
         */
        this.STSpeed = 10;
        /**
         * 衛星實體
         */
        this.satelliteAll = [];
        /**
         * 通信
         */
        this.Transits = [];
        /**
         * 工具
         */
        this.Tools = new CVTools();
           /**
         * mouseManager
         * 座標轉換
         */
        this.mouseManager = new mouseManager(v);
        //實體對象
        this.entitys = new Entitys(v);
        //格式數據存儲
        //查看方式區分開 以免衝突
        this.passTime = [];
        this.passTime_old = [];
        //刷新的時間
        this.renderTime = null;
        //拾取的對象
        this.pickedFeature = null;
        //標識符
        this.iden = true;
        //實體
        this.EntityObj = [];
    }
    /**
     * 初始化衛星過境
     */
    initST(){
        let _self = this;
        _self.handlerAction = new Handler(_self.coreV);
        //單擊
        _self.handlerAction.Action(function(e){
            if(!e.position){
                return false;
            }
			_self.pickedFeature = _self.mouseManager.piObj(e.position);
			if (!Cesium.defined(_self.pickedFeature) && _self.pickedFeature == undefined){
                return false;
            };
			if(_self.pickedFeature.id.description == undefined){ //自己創建的
                return false;
            };
			let f_name = _self.pickedFeature.id.name,f_position,table,position;
			try{
				position = _self.pickedFeature.id.position.getValue();
				_self.pickedFeature.type = "radar";
			}catch(e){
				position = _self.pickedFeature.id.position.getValue(_self.STClock.currentTime);
				_self.pickedFeature.type = "satellite";
			}
			f_position = _self.mouseManager.piEllipsoid(position);
			_self.pickedFeature.id.description  = _self.infoTable_2(f_name,f_position);
			//viewer.selectedEntity = selectedEntity;
			_self.pickedFeature.id.name  = f_name;
			_self.pickedFeature.temp = _self.pickedFeature.id.description + "<h2> Passes <h2>";
			_self.iden = false; //點擊事件改變標識符

        },_self.handlerAction.LEFT_CLICK)

        _self.loadCZML();
    }
    loadCZML(){ //load數據
        let _self = this;
		this.CoreV.dataSources.add(Cesium.CzmlDataSource.load('../common/3d/data/czml/test.czml')).then(function(dataSource) {
            _self.dataSource = dataSource;
			let radar = dataSource.entities.getById("Facility/AGI");
			let satellite1 = dataSource.entities.getById("Satellite/ISS");
			let satellite2 = dataSource.entities.getById("Satellite/Geoeye1");
			let transit1 = dataSource.entities.getById("Facility/AGI-to-Satellite/ISS");
			let transit2 = dataSource.entities.getById("Facility/AGI-to-Satellite/Geoeye1");
			_self.satelliteAll = [satellite1,satellite2]
            _self.Transits = [transit1,transit2]
           try{
                _self.scan();
                _self.satelliteInfo()
                _self.createEntity([radar]);
           }catch(e){
             console.log(e.message);
           }
          
		})
    }
    /**
     * 衛星信息
     */
    satelliteInfo(){
        let _self = this,pickedFeature = _self.pickedFeature;
        if(_self.Transits.length == 0){
            return false;
        };
        _self.formatTransit();
        _self.selectedEntity = this.entitys.createEntity();
        _self.selectedEntity.name = "PASS";
        _self.selectedEntity.description = _self.infoTable_1(dayjs(Cesium.JulianDate.addHours(_self.STClock.currentTime,-8,new Cesium.JulianDate())).format("YYYY-MM-DD HH:mm:ss"));
        _self.CoreV.selectedEntity = selectedEntity;
        _self.STclock.onTick.addEventListener(function(clock) {
                if(!clock.shouldAnimate)return;
                if(_self.iden)selectedEntity.description = _self.infoTable_1(_self.pass(clock));//標識符  進來展示所有衛星信息
                if(!_self.iden){
                    if(pickedFeature == null)return;
                    if("radar" == pickedFeature.type){
                        pickedFeature.id.description = pickedFeature.temp + _self.infoTable_1(_self.pass(clock));
                    }else{
                        let position = pickedFeature.id.position.getValue(clock.currentTime);
                        let f_position = _self.mouseManager.piEllipsoid(position);
                        pickedFeature.id.description = _self.infoTable_2( pickedFeature.id.name,f_position) + ' <h2> Passes </h2>' + _self.infoTable_3(_self.pass(clock),pickedFeature.id.name);
                    }
                }
        });	
        _self.STClock.onStop.addEventListener(function(clock){
            //格式化衛星數據
            if(_self.Transits.length == 0){
                return false;
            };
            _self.formatTransit();
        });
    }
    /**
     * 格式化通信數據
     */
    formatTransit(){
        let _self = this;
        if(_self.Transits.length == 0){
            return false;
        };
        _self.passTime = [],_self.passTime_old = []; //查看方式區分開 以免衝突
        _self.Tools.arrForEach(_self.Transits,function(transit,index){
            let intervals = [],interval_old = [];
            let n_interval = transit.availability._intervals;
            _self.Tools.arrForEach(n_interval,function(interval,index){
                let start = dayjs(Cesium.JulianDate.addHours(interval.start,-8,new Cesium.JulianDate())).format("YYYY-MM-DD HH:mm:ss");
                let stop = dayjs(Cesium.JulianDate.addHours(interval.stop,-8,new Cesium.JulianDate())).format("YYYY-MM-DD HH:mm:ss");
                intervals.push({name:transit.name,"startTime":start,"stopTime":stop,"interval":dayjs(stop).diff(dayjs(start), 'millisecond')});
                interval_old.push({name:transit.name,"startTime":start,"stopTime":stop,"interval":dayjs(stop).diff(dayjs(start), 'millisecond')});
            });
            _self.passTime.push(interval);
            _self.passTime_old.push(interval_old);
        });
    }
    /**
     * 創建雷達實體
     */
    createEntity(radars){
        let _self = this;
        if(radars.length == 0){
            return false;
        }
        _self.Tools.arrForEach(radars,function(radar){
            let l ,r ;
            let positions = radar.position.getValue();
            if(positions.length == 0){
                return false;
            };
            let cartographic = _self.mouseManager.piEllipsoid(positions);
            let lat = Cesium.Math.toDegrees(cartographic.latitude),lon = Cesium.Math.toDegrees(cartographic.longitude), height = cartographic.height;
            //radarscan
            r = new Cesium.HeadingPitchRoll(Cesium.Math.toRadians(90),
            Cesium.Math.toRadians(0),Cesium.Math.toRadians(0));
            l = Cesium.Cartesian3.fromDegrees(lon, lat, height);
            _self.EntityObj.push(_self.entitys.add(_self.entitys.getCustomRadar(l,r)));
        });
    }
    /**
     * 添加掃描物
     */
    scan(){
        let _self = this;
        if(_self.satelliteAll.length == 0){
            return false;
        };
        _self.Tools.arrForEach(_self.satelliteAll,function(entity,index){
            var cartesian = entity.position.getValue(this.STClock.currentTime);
            let positions = mouseManager.worldToLonlat(cartesian);
            _self.bindScan(positions,entity);
        });
    }
    pass(clock){ //當前時間
        let currentTime = dayjs(Cesium.JulianDate.addHours(clock.currentTime,-8,new Cesium.JulianDate())).format("YYYY-MM-DD HH:mm:ss");
        return currentTime;
    }
    index_rm(n){
        if(this.passTime_old.length == 0){
            return false;
        };
        this.passTime_old[n].splice(0,1); //刪除第一個
    }
     /**
     * 綁定掃描物
     */
    bindScan(positions,entityObj){
        this.scanEntity = new entityFactory({type:"dynamicCylinder",data:{positions:positions,entity:entityObj}});
        this.EntityObj.push(this.entitys.add( this.scanEntity));
     }
     /*
    * table 1
    */ 
    infoTable_1(currentTime){
        let _self = this,renderTime = _self.renderTime; 
        if(_self.passTime_old.length == 0){
            return false;
        };
		let tr = "",table = `<table class="cesium-infoBox-defaultTable"><thead><tr><th>衛星</th><th>倒計時(ms)</th><th>通信開始(date)</th><th>通信結束(date)</th><th>通信時長(ms)</th></tr></thead><tbody>`;
        _self.Tools.arrForEach(_self.passTime_old,function(pass_old,index){
             if(pass_old.length == 0){
                continue;
             }
             let interval_pass = pass_old[0]; //始終取第一個 
             if(renderTime <= 0){
                if(renderTime <= -(interval_pass.interval)){
                    _self.index_rm(index);
                }else{
                    renderTime = "PASS";
                }
            }
            tr += `<tr><td>${interval_pass.name}</td><td>${renderTime}</td><td>${interval_pass.startTime}</td><td> ${interval_pass.stopTime}</td><td> ${interval_pass.interval}</td></tr>`;
        });
        return table + tr + `</tbody></table>`;
    }
    /*
    * table 2
    */ 
    infoTable_2(f_name,cartesian){
        if(f_name == undefined && cartesian == undefined){
            return false;
        };
        let tr = "",table = `<h2> Position </h2><table class="cesium-infoBox-defaultTable"><thead><tr><th>Name</th><th>Latitude</th><th>Longitude</th><th>Elevation</th></tr></thead><tbody>`;
        let f_point = [ parseInt(cartesian.longitude / Math.PI * 180), parseInt(cartesian.latitude / Math.PI * 180)];
        tr = `<tr><td>${f_name}</td><td>${f_point[0]}°</td><td>${f_point[1]}°</td><td> ${parseInt(cartesian.height)}</td></tr>`;
        return table + tr + `</tbody></table>`;
    }
    /*
    * table 3
    */ 
    infoTable_3(currentTime,featureName){
        let _self = this,renderTime = _self.renderTime; 
        if(_self.passTime.length == 0 && featureName == undefined){
            return false;
        };
        let t_interval = function(){
            _self.Tools.arrForEach(_self.passTime,function(passTime,index){
                if(passTime[0].name.indexOf(featureName)!=-1)return passTime[i];
            });
        }
        let intervals = t_interval();
        var tr = "",table = `<table class="cesium-infoBox-defaultTable"><thead><tr><th>衛星</th><th>倒計時(ms)</th><th>通信開始(date)</th><th>通信結束(date)</th><th>通信時長(ms)</th></tr></thead><tbody>`;
        _self.Tools.arrForEach(intervals,function(interval,index){
            renderTime =  dayjs(interval.startTime).diff(dayjs(currentTime));
            if(renderTime <= 0)renderTime = 0;
            tr += `<tr><td>${interval.name}</td><td>${renderTime}</td><td>${interval.startTime}</td><td> ${interval.stopTime}</td><td> ${interval.interval}</td></tr>`;
        });
        return table + tr + `</tbody></table>`;
    }
     /**
     * 向後飛行
     */
    STBack(){
        this.STSpeed = -10;
        this.STClock.multiplier = this.STSpeed;
    }
    /**
     * 向前飛行
     */
    STForward(){
        this.STSpeed = 10;
        this.STClock.multiplier = this.STSpeed;
    }
    /**
     * 開始飛行
     */
    startST(){
        this.STClock.shouldAnimate = true; 
    }
    /**
     * 暫停飛行
     */
    pauseST(){
        this.STClock.shouldAnimate = false;
    }
    /**
     * 清除飛行
     */
    removeST(){
        let _self = this;
        if(_self.EntityObj.legnth == 0){
            return false;
        }
      
        _self.Tools.arrForEach(_self.EntityObj,function(entity,index){
           _self.entitys.remove(entity);
       });
       _self.CoreV.dataSources.remove(_self.dataSource);
       _self.CoreV.clock.shouldAnimate = false;
       _self.handlerAction.destroy();
       _self.handlerAction = null;
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章