[cesium] 三維分析之通視分析,坡度分析,淹沒分析,視域分析

 

 

/**
 * 通視分析
 */
import Analyser from '../analyser.js';
export default class Visibility extends Analyser{
	/**
	 * 初始化
	 * @param {*} supers 
	 * @param {*} opt 
	 */
	constructor(supers,opt){
		super(supers);
		//opt = Cesium.defaultValue(opt, Cesium.defaultValue.EMPTY_OBJECT);	//判斷是否有值
		this.opt = opt;
		this.analyser();
	}
	/**
	 * 創建分析
	 */
	analyser(){
        if (!Cesium.defined(this._viewer)) {
            throw new Cesium.DeveloperError('viewer is required.');
		}
		return new VisiblyEffect(this);
	}
}
/**
 * 內部分析類
 * @param {*} _that 
 */
const VisiblyEffect = class {
	constructor(_that){
		this._that = _that;
		this.options = _that.opt;
		this.viewer = _that._viewer;
		this.id = Cesium.createGuid();
		this._markers=[];
		this._lines=[];
		this._pickedObjs=[];
		this.posArray=[];
		this._resultTip = this.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)
			}
		});
		this.state = _that.BEYONANALYSER_STATE.PREPARE;
		this.init();
	}
	init(){
		//點擊
		var _self = this,_that = _self._that;
		_that.handler.setInputAction(function (movement) {
			//var cartesian = Cesium.pickGlobe(viewer.scene,movement.position);
			let cartesian = _that.mouseManager.piTerrainToModule(movement.position);
			_self.posArray.push(cartesian);
			if(_self._markers.length==0){
				//scope.reset();
				var startSphere = _self.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
					}
				});  
				_self._markers.push(startSphere);
				_self.state= _that.BEYONANALYSER_STATE.OPERATING;
			}else if(_self._markers.length==1){
				var redSphere = _self.viewer.entities.add({
					position : cartesian,
					ellipsoid : {
						radii : new Cesium.Cartesian3(2.0, 2.0, 2.0),
						material : Cesium.Color.RED
					}
				});
				_self._markers.push(redSphere);

				var results = _that.getIntersectObj(_self.posArray[0],cartesian,_self._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=[_self.posArray[0],results[0].position];
				var greenLine=_self.viewer.entities.add({
						polyline : {
							positions : arrowPositions,
							width : 10,
							arcType : Cesium.ArcType.NONE,
							material : new Cesium.PolylineArrowMaterialProperty(Cesium.Color.GREEN)
						}
					});
					_self._lines.push(greenLine);
				if(!bVisibility){
					var unArrowPositions=[results[0].position,cartesian];
					var redLine=_self.viewer.entities.add({
						polyline : {
							positions : unArrowPositions,
							width : 10,
							arcType : Cesium.ArcType.NONE,
							material : new Cesium.PolylineArrowMaterialProperty(Cesium.Color.RED)
						}
					});
					_self._lines.push(redLine);
				}
				
				_self.showIntersections(results);
				var pos1=_self.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;
				
					_that.showTip(_self._resultTip,true,cartesian,text,{
					fillColor:Cesium.Color.YELLOW
				});
				_self.state= _that.BEYONANALYSER_STATE.END;
			}
		}, Cesium.ScreenSpaceEventType.LEFT_CLICK );
		//移動
		var info;
		_that.handler.setInputAction(function (movement) {
			var cartesian = _self.viewer.scene.pickPosition(movement.endPosition);
			if(_self.state === _that.BEYONANALYSER_STATE.PREPARE){               
				info ='點擊設定起點';
				_that.showTip(_self._resultTip,true,cartesian,info);
			}else if(_self.state === _that.BEYONANALYSER_STATE.OPERATING){               
				info ='點擊分析通視情況';
				_that.showTip(_self._resultTip,true,cartesian,info);
			}
		},Cesium.ScreenSpaceEventType.MOUSE_MOVE);
	}
	showIntersections(results){
		let _self = this;
		for (let i = 0; i < results.length; ++i) {
			var object = results[i].object;
			if(object){
				if (object instanceof Cesium.Cesium3DTileFeature) {
					_self._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);
				}
			}
			
			_self._markers.push(_self.viewer.entities.add({
				position : results[i].position,
				ellipsoid : {
					radii : new Cesium.Cartesian3(0.8, 0.8, 0.8),
					material : Cesium.Color.RED
				}
			}));
		}
	}
	remove(){
		 //恢復顏色
		 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];
			this.viewer.entities.remove(element);            
		}
		this._markers.length=0;

		for (let index = 0; index < this._lines.length; index++) {
			var element = this._lines[index];
			this.viewer.entities.remove(element);            
		}
		this._lines.length=0;

		this.viewer.entities.remove(this._resultTip);   
		this._resultTip=undefined;        
	}
}

 

/**
 * 淹沒分析
 */
import Analyser from '../analyser.js';
export default class Submerged extends Analyser{
	
	constructor(supers,opt){
		super(supers);
		//opt = Cesium.defaultValue(opt, Cesium.defaultValue.EMPTY_OBJECT);	//判斷是否有值
		this._resultTip = this._viewer.entities.add({
			id:Cesium.createGuid(),
			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)
			}
		});
		this.positions = [];
        this.polyObj = null;
        this.tempPoints = [];
		this.entity = [];
		this.state = this.BEYONANALYSER_STATE.PREPARE; //0
		this.waterEntity = null;
		this.analyser(opt);
	}
	analyser(options){
		/**
         * 點擊
         */
		let _self = this,viewer = this._viewer,info = ""
		,maxH = options.maxH == undefined ? 50 :options.maxH
		,interval = options.interval == undefined ?10 : options.interval
		,speed = options.speed == undefined ? 1 : options.speed;
       
        _self.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);
        /**
         * 移動
         */
        _self.handler.setInputAction(function (e) {
            if(_self.Tools.nullBool(e.endPosition)){
                 return false;
			}
			let cartesian = _self.mouseManager.screenToWorld(e.endPosition);
			if(_self.state === _self.BEYONANALYSER_STATE.PREPARE){               
				info ='點擊設定範圍';
				_self.showTip(_self._resultTip,true,cartesian,info);
			}else if(_self.state === _self.BEYONANALYSER_STATE.OPERATING){               
				info ='右鍵分析淹沒情況';
				_self.showTip(_self._resultTip,true,cartesian,info);
			}
            if(_self.positions.length >= 2){
                if (!Cesium.defined(_self.polyObj)) {
                    _self.polyObj = new _self.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());
				}
				if(_self.positions.length > 4)_self.state = _self.BEYONANALYSER_STATE.OPERATING;
            }
        }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
        /**
         * 右鍵取消
         */
        _self.handler.setInputAction(function (e) {
            if(_self.Tools.nullBool(e.position)){
                return false;
			}
            _self.handler.destroy(); //關閉事件句柄
			_self.positions.pop(); //最後一個點無效
			_self.state = _self.BEYONANALYSER_STATE.END; //分析結束
            //二秒後開始進入淹沒分析
            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);
	}


}

 

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