1. 程式人生 > >Cesium距離測量之思路解析加原始碼

Cesium距離測量之思路解析加原始碼

今天剛好是程式設計師的節日,話不多說祝大家前途一片光明,如果你正在做測量的工具那麼我將會在稍後釋出關與面積測量的文章。

一、實現思路

首先我們需要用到的滑鼠移動事件、單擊事件和雙擊事件,具體功能如下:

1,滑鼠移動事件:判斷是否開始進行測量操作(單擊為開始標誌),如果沒有,則什麼也不做,如何開始則需要把單擊的座標作為起點,滑鼠當前位置作為終點畫線段,隨著滑鼠的移動需要不停的重新整理線段(就是刪除臨時線段,繪製新線段不斷迴圈)。

2,單擊事件:將測距狀態更新為真,當點選次數大於一次,開始繪製線段,並計算長度,這是的線段不是臨時的,而是真正的線段。

3,雙擊事件:將之前註冊的事件取消,並清空臨時物件。

二、原始碼實現

    <!--測量距離-->
    <script type="text/javascript">

        var AllEnities = []; //儲存所有繪製物件

        //測量距離
        var measureDistance = function (cesium) {
            var isDraw = false;
            var polyline = new Cesium.Entity();
            var polylinePath = [];  //點集合
            var tooltip = document.getElementById("toolTip");
            var LineEntities = [];//所有折現物件
            var disNums = []; //線路長度之和
            var StartPoint;
            var temLine = null;

            var handler = viewer.screenSpaceEventHandler;
            tooltip = document.getElementById("ToolTip");
            /***************************滑鼠移動事件***********************************/
            handler.setInputAction(function (movement) {
                var position1;
                var cartographic;
                var ray = viewer.scene.camera.getPickRay(movement.endPosition);
                if (ray)
                    position1 = viewer.scene.globe.pick(ray, viewer.scene);
                if (position1)
                    cartographic = Cesium.Ellipsoid.WGS84.cartesianToCartographic(position1);
                if (cartographic) {
                    //海拔
                    var height = viewer.scene.globe.getHeight(cartographic);
                    //地理座標(弧度)轉經緯度座標
                    var point = Cesium.Cartesian3.fromDegrees(cartographic.longitude / Math.PI * 180, cartographic.latitude / Math.PI * 180, height);
                    if (isDraw) {
                        tooltip.style.left = movement.endPosition.x + 10 + "px";
                        tooltip.style.top = movement.endPosition.y + 20 + "px";
                        tooltip.style.display = "block";
                        if (polylinePath.length < 1) {
                            return;
                        }
                        if (temLine != null) //清除臨時線
                        {
                            viewer.entities.remove(temLine);
                        }
                        if (polylinePath.length == 1 && point.x != null) {

                            temLine = viewer.entities.add({
                                polyline: {
                                    show: true,
                                    positions: [polylinePath[0], point],
                                    material: new Cesium.PolylineOutlineMaterialProperty({
                                        color: Cesium.Color.RED
                                    }),
                                    width: 2
                                }
                            });

                            AllEnities.push(temLine);
                            var distance = sum(disNums) + Number(getLineDis(polylinePath[0], point));//自己實現
                            tooltip.innerHTML = '<p>長度:' + distance.toFixed(2) + '公里</p><p>雙擊確定終點</p>';

                        }
                    }
                }

            }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

            /***************************滑鼠移動事件***********************************/


            /***************************滑鼠單擊事件***********************************/
            //完成畫線操作
            handler.setInputAction(function (movement) {
                isDraw = true;
                var position1;
                var cartographic;
                var ray = viewer.scene.camera.getPickRay(movement.position);
                if (ray)
                    position1 = viewer.scene.globe.pick(ray, viewer.scene);
                if (position1)
                    cartographic = Cesium.Ellipsoid.WGS84.cartesianToCartographic(position1);
                //世界座標轉地理座標(弧度)
                if (cartographic) {
                    //海拔
                    var height = viewer.scene.globe.getHeight(cartographic);
                    //地理座標(弧度)轉經緯度座標
                    var point = Cesium.Cartesian3.fromDegrees(cartographic.longitude / Math.PI * 180, cartographic.latitude / Math.PI * 180, height);

                    polylinePath.push(point); //加點
                    if (isDraw && polylinePath.length == 1) {
                        StartPoint = point;
                        var strartpoint = viewer.entities.add(
                         {
                             position: point,
                             point: {
                                 heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
                                 show: true,
                                 color: Cesium.Color.SKYBLUE,
                                 pixelSize: 3,
                                 outlineColor: Cesium.Color.YELLOW,
                                 outlineWidth: 1
                             },
                             label: {
                                 text: "起點",
                                 font: '14pt monospace',
                                 color: Cesium.Color.RED,
                                 backgroundColor: Cesium.Color.CORAL,
                                 style: Cesium.LabelStyle.FILL_AND_OUTLINE,
                                 outlineWidth: 2,
                                 //垂直位置
                                 heightReference: Cesium.HeightReference.NONE,
                                 verticalOrigin: Cesium.VerticalOrigin.TOP,
                                 pixelOffset: new Cesium.Cartesian2(50, 0)
                             }
                         }
                     );

                        AllEnities.push(strartpoint);

                    }

                    if (isDraw && polylinePath.length > 1) {

                        var text = 0;
                        text = sum(disNums) + Number(getLineDis(polylinePath[0], polylinePath[1]));
                        disNums.push(getLineDis(polylinePath[0], polylinePath[1]));
                        var temppoint = viewer.entities.add(
                              {
                                  position: point,
                                  point: {
                                      heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
                                      show: true,
                                      color: Cesium.Color.SKYBLUE,
                                      pixelSize: 3,
                                      outlineColor: Cesium.Color.YELLOW,
                                      outlineWidth: 1
                                  },
                                  label: {
                                      text: text.toFixed(2).toString() + '公里',
                                      font: '14pt monospace',
                                      color: Cesium.Color.RED,
                                      backgroundColor: Cesium.Color.CORAL,
                                      style: Cesium.LabelStyle.FILL_AND_OUTLINE,
                                      outlineWidth: 2,
                                      //垂直位置
                                      heightReference: Cesium.HeightReference.NONE,
                                      verticalOrigin: Cesium.VerticalOrigin.TOP,
                                      pixelOffset: new Cesium.Cartesian2(50, 0)
                                  }
                              }
                          );

                        AllEnities.push(temppoint);

                        polyline = viewer.entities.add({
                            polyline: {
                                show: true,
                                positions: polylinePath,
                                material: new Cesium.PolylineOutlineMaterialProperty({
                                    color: Cesium.Color.RED
                                }),
                                width: 2
                            }
                        });
                        AllEnities.push(polyline);
                        LineEntities.push(polyline); //加直線
                        var lastpoint = polylinePath[polylinePath.length - 1];
                        polylinePath = [lastpoint];
                    }
                }

            }, Cesium.ScreenSpaceEventType.LEFT_CLICK);

            /***************************滑鼠單擊事件***********************************/

            /***************************滑鼠雙擊事件***********************************/
            handler.setInputAction(function () {
                handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
                handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
                AllEnities.push(polyline);
                viewer.trackedEntity = undefined;
                isDraw = false;
                tooltip.style.display = "none";
                polylinePath = [];
                //LineEntities = [];
                // polyline = null;

            }, Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);

            /***************************滑鼠雙擊事件***********************************/
        }


        //獲取倆點的距離,返回公里單位值
        function getLineDis(startPoint, endPoint) {
            var x2 = (endPoint.x - startPoint.x) * (endPoint.x - startPoint.x)
            var y2 = (endPoint.y - startPoint.y) * (endPoint.y - startPoint.y);
            var dis = Math.sqrt(x2 + y2) / 1000;
            return dis.toFixed(2);
        }

        function sum(arr) {
            var s = 0;
            for (var i = arr.length - 1; i >= 0; i--) {
                s += Number(arr[i]);
            }
            return s;
        }
    </script>
    <!--測量距離-->

三、實現效果圖

距離測量
距離測量效果圖

四、更多

如果程式碼任何問題可以加群談論,我們基地的地址是:450342630

讓我們下一篇面積測量再見。