cesium-長(zhǎng)度測(cè)量和面積測(cè)量

(更新)多謝網(wǎng)友的提醒誉简,面積測(cè)量的小問(wèn)題已經(jīng)修改柄沮,經(jīng)測(cè)試可正常使用

網(wǎng)上找的大神的實(shí)現(xiàn)方法有點(diǎn)問(wèn)題回梧,實(shí)現(xiàn)有一些bug,作為cesium新手一個(gè)祖搓,棄之不忍狱意,只好硬著頭皮修改了,不過(guò)還好問(wèn)題不大拯欧,再次mark一下详囤,下次就可以直接用了


image.png
import Cesium from "cesium/Cesium";
import widgets from "cesium/Widgets/widgets.css";

export default {
    
  //測(cè)量空間直線距離 
  /******************************************* */
  measureLineSpace(viewer, handler) {
    // 取消雙擊事件-追蹤該位置
    viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
    
    handler = new Cesium.ScreenSpaceEventHandler(viewer.scene._imageryLayerCollection);
    var positions = [];
    var poly = null;
    // var tooltip = document.getElementById("toolTip");
    var distance = 0;
    var cartesian = null;
    var floatingPoint;
    // tooltip.style.display = "block";

    handler.setInputAction(function (movement) {
      // tooltip.style.left = movement.endPosition.x + 3 + "px";
      // tooltip.style.top = movement.endPosition.y - 25 + "px";
      // tooltip.innerHTML = '<p>單擊開(kāi)始,右擊結(jié)束</p>';
      // cartesian = viewer.scene.pickPosition(movement.endPosition);
      let ray = viewer.camera.getPickRay(movement.endPosition);
      cartesian = viewer.scene.globe.pick(ray, viewer.scene);
      //cartesian = viewer.scene.camera.pickEllipsoid(movement.endPosition, viewer.scene.globe.ellipsoid);
      if (positions.length >= 2) {
        if (!Cesium.defined(poly)) {
          poly = new PolyLinePrimitive(positions);
        } else {
          positions.pop();
          // cartesian.y += (1 + Math.random());
          positions.push(cartesian);
        }
        distance = getSpaceDistance(positions);
        // console.log("distance: " + distance);
        // tooltip.innerHTML='<p>'+distance+'米</p>';
      }
    }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

    handler.setInputAction(function (movement) {
      // tooltip.style.display = "none";
      // cartesian = viewer.scene.camera.pickEllipsoid(movement.position, viewer.scene.globe.ellipsoid);
      // cartesian = viewer.scene.pickPosition(movement.position);
      let ray = viewer.camera.getPickRay(movement.position);
      cartesian = viewer.scene.globe.pick(ray, viewer.scene);
      if (positions.length == 0) {
        positions.push(cartesian.clone());
      }
      positions.push(cartesian);
      //在三維場(chǎng)景中添加Label
      //   var cartographic = Cesium.Cartographic.fromCartesian(cartesian);
      var textDisance = distance + "米";
      // console.log(textDisance + ",lng:" + cartographic.longitude/Math.PI*180.0);
      floatingPoint = viewer.entities.add({
        name: '空間直線距離',
        // position: Cesium.Cartesian3.fromDegrees(cartographic.longitude / Math.PI * 180, cartographic.latitude / Math.PI * 180,cartographic.height),
        position: positions[positions.length - 1],
        point: {
          pixelSize: 5,
          color: Cesium.Color.RED,
          outlineColor: Cesium.Color.WHITE,
          outlineWidth: 2,
        },
        label: {
          text: textDisance,
          font: '18px sans-serif',
          fillColor: Cesium.Color.GOLD,
          style: Cesium.LabelStyle.FILL_AND_OUTLINE,
          outlineWidth: 2,
          verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
          pixelOffset: new Cesium.Cartesian2(20, -20),
        }
      });
    }, Cesium.ScreenSpaceEventType.LEFT_CLICK);

    handler.setInputAction(function (movement) {
      handler.destroy(); //關(guān)閉事件句柄
      positions.pop(); //最后一個(gè)點(diǎn)無(wú)效
      // viewer.entities.remove(floatingPoint);
      // tooltip.style.display = "none";

    }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);

    var PolyLinePrimitive = (function () {
      function _(positions) {
        this.options = {
          name: '直線',
          polyline: {
            show: true,
            positions: [],
            material: Cesium.Color.CHARTREUSE,
            width: 10,
            clampToGround: true
          }
        };
        this.positions = positions;
        this._init();
      }

      _.prototype._init = function () {
        var _self = this;
        var _update = function () {
          return _self.positions;
        };
        //實(shí)時(shí)更新polyline.positions
        this.options.polyline.positions = new Cesium.CallbackProperty(_update, false);
        viewer.entities.add(this.options);
      };

      return _;
    })();

    //空間兩點(diǎn)距離計(jì)算函數(shù)
    function getSpaceDistance(positions) {
      var distance = 0;
      for (var i = 0; i < positions.length - 1; i++) {

        var point1cartographic = Cesium.Cartographic.fromCartesian(positions[i]);
        var point2cartographic = Cesium.Cartographic.fromCartesian(positions[i + 1]);
        /**根據(jù)經(jīng)緯度計(jì)算出距離**/
        var geodesic = new Cesium.EllipsoidGeodesic();
        geodesic.setEndPoints(point1cartographic, point2cartographic);
        var s = geodesic.surfaceDistance;
        //console.log(Math.sqrt(Math.pow(distance, 2) + Math.pow(endheight, 2)));
        //返回兩點(diǎn)之間的距離
        s = Math.sqrt(Math.pow(s, 2) + Math.pow(point2cartographic.height - point1cartographic.height, 2));
        distance = distance + s;
      }
      return distance.toFixed(2);
    }
  },

  //****************************測(cè)量空間面積************************************************//
measureAreaSpace(viewer, handler){  
  // 取消雙擊事件-追蹤該位置
  viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
  // 鼠標(biāo)事件
    handler = new Cesium.ScreenSpaceEventHandler(viewer.scene._imageryLayerCollection);
    var positions = [];
    var tempPoints = [];
    var polygon = null;
    // var tooltip = document.getElementById("toolTip");
    var cartesian = null;
    var floatingPoint;//浮動(dòng)點(diǎn)
    // tooltip.style.display = "block";
    
    handler.setInputAction(function(movement){
        // tooltip.style.left = movement.endPosition.x + 3 + "px";
        // tooltip.style.top = movement.endPosition.y - 25 + "px";
    // tooltip.innerHTML ='<p>單擊開(kāi)始镐作,右擊結(jié)束</p>';
        // cartesian = viewer.scene.pickPosition(movement.endPosition); 
      let ray = viewer.camera.getPickRay(movement.endPosition);
      cartesian = viewer.scene.globe.pick(ray, viewer.scene);
        //cartesian = viewer.scene.camera.pickEllipsoid(movement.endPosition, viewer.scene.globe.ellipsoid);
        if(positions.length >= 2){
            if (!Cesium.defined(polygon)) {
                polygon = new PolygonPrimitive(positions);
            }else{
                positions.pop();
                // cartesian.y += (1 + Math.random());
                positions.push(cartesian);
            }
            // tooltip.innerHTML='<p>'+distance+'米</p>';
        }
    },Cesium.ScreenSpaceEventType.MOUSE_MOVE);
    
    handler.setInputAction(function(movement){
        // tooltip.style.display = "none";
        // cartesian = viewer.scene.pickPosition(movement.position); 
      let ray = viewer.camera.getPickRay(movement.position);
      cartesian = viewer.scene.globe.pick(ray, viewer.scene);
        // cartesian = viewer.scene.camera.pickEllipsoid(movement.position, viewer.scene.globe.ellipsoid);
        if(positions.length == 0) {
            positions.push(cartesian.clone());
        }
        //positions.pop();
        positions.push(cartesian);
        //在三維場(chǎng)景中添加點(diǎn)
        var cartographic = Cesium.Cartographic.fromCartesian(positions[positions.length - 1]);
        var longitudeString = Cesium.Math.toDegrees(cartographic.longitude);
        var latitudeString = Cesium.Math.toDegrees(cartographic.latitude);
        var heightString = cartographic.height;
        tempPoints.push({ lon: longitudeString, lat: latitudeString ,hei:heightString});
        floatingPoint = viewer.entities.add({
            name : '多邊形面積',
            position : positions[positions.length - 1],         
            point : {
                pixelSize : 5,
                color : Cesium.Color.RED,
                outlineColor : Cesium.Color.WHITE,
                outlineWidth : 2,
                heightReference:Cesium.HeightReference.CLAMP_TO_GROUND 
            }
        }); 
    },Cesium.ScreenSpaceEventType.LEFT_CLICK);
     
    handler.setInputAction(function(movement){
        handler.destroy();
        positions.pop();
        //tempPoints.pop();
        // viewer.entities.remove(floatingPoint);
        // tooltip.style.display = "none";
        //在三維場(chǎng)景中添加點(diǎn)
        // var cartographic = Cesium.Cartographic.fromCartesian(positions[positions.length - 1]);
        // var longitudeString = Cesium.Math.toDegrees(cartographic.longitude);
        // var latitudeString = Cesium.Math.toDegrees(cartographic.latitude);
        // var heightString = cartographic.height;
        // tempPoints.push({ lon: longitudeString, lat: latitudeString ,hei:heightString});
 
        var textArea = getArea(tempPoints) + "平方公里";
        viewer.entities.add({
            name : '多邊形面積',
            position : positions[positions.length - 1],
            // point : {
            //  pixelSize : 5,
            //  color : Cesium.Color.RED,
            //  outlineColor : Cesium.Color.WHITE,
            //  outlineWidth : 2,
            //  heightReference:Cesium.HeightReference.CLAMP_TO_GROUND 
            // },
            label : {
                text : textArea,
                font : '18px sans-serif',
                fillColor : Cesium.Color.GOLD,
                style: Cesium.LabelStyle.FILL_AND_OUTLINE,
                outlineWidth : 2,
                verticalOrigin : Cesium.VerticalOrigin.BOTTOM,
        pixelOffset : new Cesium.Cartesian2(20, -40),
        heightReference:Cesium.HeightReference.CLAMP_TO_GROUND
            }
        });     
    }, Cesium.ScreenSpaceEventType.RIGHT_CLICK );   
 
    var radiansPerDegree = Math.PI / 180.0;//角度轉(zhuǎn)化為弧度(rad) 
    var degreesPerRadian = 180.0 / Math.PI;//弧度轉(zhuǎn)化為角度
    
    //計(jì)算多邊形面積
    function getArea(points) {
        
        var res = 0;
        //拆分三角曲面
 
        for (var i = 0; i < points.length - 2; i++) {
            var j = (i + 1) % points.length;
            var k = (i + 2) % points.length;
            var totalAngle = Angle(points[i], points[j], points[k]);
 
            
            var dis_temp1 = distance(positions[i], positions[j]);
            var dis_temp2 = distance(positions[j], positions[k]);
            res += dis_temp1 * dis_temp2 * Math.abs(Math.sin(totalAngle)) ;
            console.log(res);
        }
        
        
        return (res/1000000.0).toFixed(4);
    }
 
    /*角度*/
    function Angle(p1, p2, p3) {
        var bearing21 = Bearing(p2, p1);
        var bearing23 = Bearing(p2, p3);
        var angle = bearing21 - bearing23;
        if (angle < 0) {
            angle += 360;
        }
        return angle;
    }
    /*方向*/
    function Bearing(from, to) {
        var lat1 = from.lat * radiansPerDegree;
        var lon1 = from.lon * radiansPerDegree;
        var lat2 = to.lat * radiansPerDegree;
        var lon2 = to.lon * radiansPerDegree;
        var angle = -Math.atan2(Math.sin(lon1 - lon2) * Math.cos(lat2), Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1) * Math.cos(lat2) * Math.cos(lon1 - lon2));
        if (angle < 0) {
            angle += Math.PI * 2.0;
        }
        angle = angle * degreesPerRadian;//角度
        return angle;
    } 
 
    var PolygonPrimitive = (function(){
        function _(positions){
            this.options = {
                name:'多邊形',
                polygon : {
                    hierarchy : [],
                    // perPositionHeight : true,
          material : Cesium.Color.GREEN.withAlpha(0.5),
          // heightReference:20000
                }
            };
            
            this.hierarchy = {positions};
            this._init();
        }
    
        _.prototype._init = function(){
            var _self = this;
            var _update = function(){
                return _self.hierarchy;
            };
            //實(shí)時(shí)更新polygon.hierarchy
            this.options.polygon.hierarchy = new Cesium.CallbackProperty(_update,false);
            viewer.entities.add(this.options);
        };
    
        return _;
    })();
 
    function distance(point1,point2){
        var point1cartographic = Cesium.Cartographic.fromCartesian(point1);
        var point2cartographic = Cesium.Cartographic.fromCartesian(point2);
        /**根據(jù)經(jīng)緯度計(jì)算出距離**/
        var geodesic = new Cesium.EllipsoidGeodesic();
        geodesic.setEndPoints(point1cartographic, point2cartographic);
        var s = geodesic.surfaceDistance;
        //console.log(Math.sqrt(Math.pow(distance, 2) + Math.pow(endheight, 2)));
        //返回兩點(diǎn)之間的距離
        s = Math.sqrt(Math.pow(s, 2) + Math.pow(point2cartographic.height - point1cartographic.height, 2)); 
        return s;
    }
}


}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末藏姐,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子该贾,更是在濱河造成了極大的恐慌羔杨,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,194評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件杨蛋,死亡現(xiàn)場(chǎng)離奇詭異兜材,居然都是意外死亡理澎,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門(mén)曙寡,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)糠爬,“玉大人,你說(shuō)我怎么就攤上這事举庶≈此恚” “怎么了朗鸠?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,780評(píng)論 0 346
  • 文/不壞的土叔 我叫張陵陋守,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我翘地,道長(zhǎng)添祸,這世上最難降的妖魔是什么滚粟? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,388評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮刃泌,結(jié)果婚禮上凡壤,老公的妹妹穿的比我還像新娘。我一直安慰自己耙替,他們只是感情好亚侠,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,430評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著俗扇,像睡著了一般硝烂。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上铜幽,一...
    開(kāi)封第一講書(shū)人閱讀 49,764評(píng)論 1 290
  • 那天滞谢,我揣著相機(jī)與錄音,去河邊找鬼除抛。 笑死狮杨,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的到忽。 我是一名探鬼主播橄教,決...
    沈念sama閱讀 38,907評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼喘漏!你這毒婦竟也來(lái)了护蝶?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,679評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤翩迈,失蹤者是張志新(化名)和其女友劉穎滓走,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體帽馋,經(jīng)...
    沈念sama閱讀 44,122評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡搅方,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,459評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了绽族。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片姨涡。...
    茶點(diǎn)故事閱讀 38,605評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖吧慢,靈堂內(nèi)的尸體忽然破棺而出涛漂,到底是詐尸還是另有隱情,我是刑警寧澤检诗,帶...
    沈念sama閱讀 34,270評(píng)論 4 329
  • 正文 年R本政府宣布匈仗,位于F島的核電站,受9級(jí)特大地震影響逢慌,放射性物質(zhì)發(fā)生泄漏悠轩。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,867評(píng)論 3 312
  • 文/蒙蒙 一攻泼、第九天 我趴在偏房一處隱蔽的房頂上張望火架。 院中可真熱鬧,春花似錦忙菠、人聲如沸何鸡。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,734評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)骡男。三九已至,卻和暖如春傍睹,著一層夾襖步出監(jiān)牢的瞬間隔盛,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,961評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工焰望, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留骚亿,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,297評(píng)論 2 360
  • 正文 我出身青樓熊赖,卻偏偏與公主長(zhǎng)得像来屠,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子震鹉,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,472評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容