Cesium 测量

本文介绍了如何使用Cesium实现三维场景中的空间距离测量和面积测量功能。通过ScreenSpaceEventHandler监听鼠标事件,动态绘制折线并计算距离,以及利用几何原理计算多边形面积,为用户提供直观的测量工具。
摘要由CSDN通过智能技术生成
//测距
function measureLineSpace(viewer, handlerDis) {
    // 取消双击事件-追踪该位置
    //viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
    handlerDis = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
    var positions = [];
    var poly = null;
    // var tooltip = document.getElementById("toolTip");
    var distance = 0;
    var cartesian = null;
    var floatingPoint;
    // tooltip.style.display = "block";
    handlerDis.setInputAction(function (movement) {
        // tooltip.style.left = movement.endPosition.x + 3 + "px";
        // tooltip.style.top = movement.endPosition.y - 25 + "px";
        // tooltip.innerHTML = '<p>单击开始,右击结束</p>';
        // cartesian = viewer.scene.pickPosition(movement.endPosition);
        cartesian = viewer.scene.pickPosition(movement.endPosition);
        //cartesian = viewer.scene.camera.pickEllipsoid(movement.endPosition, viewer.scene.globe.ellipsoid);
        if("undefined" != typeof cartesian) {
            if (positions.length >= 2) {
                if (!Cesium.defined(poly)) {
                    poly = new PolyLinePrimitive(positions);
                } else {
                    positions.pop();
                    // cartesian.y += (1 + Math.random());
                    positions.push(cartesian);
                }
                // tooltip.innerHTML='<p>'+distance+'米</p>';
            }
        }
    }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

    handlerDis.setInputAction(function (movement) {
        // tooltip.style.display = "none";
        // cartesian = viewer.scene.camera.pickEllipsoid(movement.position, viewer.scene.globe.ellipsoid);
        // cartesian = viewer.scene.pickPosition(movement.position);
        //获取模型上位置
        cartesian = viewer.scene.pickPosition(movement.position);
        if (positions.length == 0) {
            positions.push(cartesian.clone());
        }
        positions.push(cartesian);
        distance = getSpaceDistance(positions);
        //在三维场景中添加Label
        var cartographic = Cesium.Cartographic.fromCartesian(cartesian);
        var longitude = Cesium.Math.toDegrees(cartographic.longitude);
        var latitude = Cesium.Math.toDegrees(cartographic.latitude);
        var height = cartographic.height+0.1;
        var textDisance = distance + "米";
        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],
            position:Cesium.Cartesian3.fromDegrees(longitude,latitude,height),
            point: {
                pixelSize: 5,
                color: Cesium.Color.RED,
                outlineColor: Cesium.Color.WHITE,
   heightReference:Cesium.HeightReference.RELATIVE_TO_GROUND,
                fillColor: Cesium.Color.GOLD,
                style: Cesium.LabelStyle.FILL_AND_OUTLINE,
                outlineWidth: 2,
                verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
                pixelOffset: new Cesium.Cartesian2(20, -20),
                clampToGround: false
    },
            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),
                clampToGround: false,
            }
        });
    }, Cesium.ScreenSpaceEventType.LEFT_CLICK);

    handlerDis.setInputAction(function (movement) {
        handlerDis.destroy(); //关闭事件句柄
        positions.pop(); //最后一个点无效
        // 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: 3,
                    clampToGround: false
                }
            };
            this.positions = positions;
            this._init();
        }
        _.prototype._init = function () {
            var _self = this;
            var _update = function () {
                return _self.positions;
            };
            //实时更新polyline.positions
            this.options.polyline.positions = new Cesium.CallbackProperty(_update, false);
            viewer.entities.add(this.options);
        };
        return _;
    })();
}
//空间两点距离计算函数
function getSpaceDistance(positions) {
    var distance = 0;
    for (var i = 0; i < positions.length - 1; i++) {
        if("undefined" == typeof(positions[i]) ||"undefined" == typeof(positions[i + 1])){
            break;
        }
        var point1cartographic = Cesium.Cartographic.fromCartesian(positions[i]);
        var point2cartographic = Cesium.Cartographic.fromCartesian(positions[i + 1]);
        /**根据经纬度计算出距离**/
        var geodesic = new Cesium.EllipsoidGeodesic();
        geodesic.setEndPoints(point1cartographic, point2cartographic);
        var s = geodesic.surfaceDistance;
        //返回两点之间的距离
        s = Math.sqrt(Math.pow(s, 2) + Math.pow(point2cartographic.height - point1cartographic.height, 2));
        distance = distance + s;
    }
    distance = distance.toFixed(2);
    distance = Number(distance);
    distance = distance > 1000 ? (distance/1000).toFixed(2) + 'km' : distance + 'm';
    return distance;
}

//测量面积

function measureLineSpaceArea(viewer, handlerSpaceArea) {
    // 取消双击事件-追踪该位置
    //viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
    handlerSpaceArea = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
    var positions = [];
    var poly = null;
    // var tooltip = document.getElementById("toolTip");
    var distance = 0;
    var cartesian = null;
    var floatingPoint;
    // tooltip.style.display = "block";
    handlerSpaceArea.setInputAction(function (movement) {
        cartesian = viewer.scene.pickPosition(movement.endPosition);
        if("undefined" != typeof cartesian){
            if (positions.length >= 2) {
                if (!Cesium.defined(poly)) {
                    poly = new PolyLinePrimitive(positions);
                } else {
                    positions.pop();
                    // cartesian.y += (1 + Math.random());
                    positions.push(cartesian);
                }
            }
        }
    }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
    var firstPosition;
    var spaceTempPoints = [];
    handlerSpaceArea.setInputAction(function (movement) {
        // tooltip.style.display = "none";
        // cartesian = viewer.scene.camera.pickEllipsoid(movement.position, viewer.scene.globe.ellipsoid);
        // cartesian = viewer.scene.pickPosition(movement.position);
        //获取模型上位置
        cartesian = viewer.scene.pickPosition(movement.position);
        if (positions.length == 0) {
            positions.push(cartesian.clone());
        }
        if(!firstPosition){
            firstPosition = cartesian;
        }
        positions.push(cartesian);
        var cartographic = Cesium.Cartographic.fromCartesian(cartesian);
        var longitude = Cesium.Math.toDegrees(cartographic.longitude);
        var latitude = Cesium.Math.toDegrees(cartographic.latitude);
        var height = cartographic.height+0.1;
        spaceTempPoints.push({ lon: longitude, lat: latitude ,hei:height});
    }, Cesium.ScreenSpaceEventType.LEFT_CLICK);

    handlerSpaceArea.setInputAction(function (movement) {
        handlerSpaceArea.destroy(); //关闭事件句柄
        positions.pop(); //最后一个点无效
        positions.push(firstPosition);
        var cartographic = Cesium.Cartographic.fromCartesian(firstPosition);
        var longitude = Cesium.Math.toDegrees(cartographic.longitude);
        var latitude = Cesium.Math.toDegrees(cartographic.latitude);
        var height = cartographic.height+0.1;
        //添加面积提示entity
        var textArea = getSpanceArea(spaceTempPoints) + "平方米";
        viewer.entities.add({
            name : '测量-多边形面积',
            position : Cesium.Cartesian3.fromDegrees(longitude,latitude,height),
            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
                clampToGround: false,
                showBackground:true
            }
        });
        // viewer.entities.remove(floatingPoint);
        // tooltip.style.display = "none";
    }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
    var radiansPerDegree = Math.PI / 180.0;//角度转化为弧度(rad)
    var degreesPerRadian = 180.0 / Math.PI;//弧度转化为角度
    //计算多边形面积
    function getSpanceArea(points) {
        var res = 0;
        //拆分三角曲面
        for (var i = 0,j=1; j < points.length - 1; j++) {
            var k = j+1;
            var totalAngle = SpaceAngle(points[i], points[j], points[k]);
            var dis_temp1 = getDistance(positions[i], positions[j]);
            var dis_temp2 = getDistance(positions[j], positions[k]);
            var sinV = Math.sin(totalAngle*3.14/180);
            sinV = Math.abs(sinV);
            var res1 = dis_temp1 * dis_temp2 * sinV/2 ;
            res += res1;
        }
        return (res).toFixed(2);
    }
    /*角度*/
    function SpaceAngle(p1, p2, p3) {
        var bearing21 = SpaceBearing(p2, p1);
        var bearing23 = SpaceBearing(p2, p3);
        var angle = bearing21 - bearing23;
        if (angle < 0) {
            angle += 360;
        }
        return angle;
    }
    /*方向*/
    function SpaceBearing(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 PolyLinePrimitive = (function () {
        function _(positions) {
            this.options = {
                name: '直线',
                polyline: {
                    show: true,
                    positions: [],
                    material: Cesium.Color.CHARTREUSE,
                    width: 3,
                    clampToGround: false,
                    zIndex:100
                }
            };
            this.positions = positions;
            this._init();
        }
        _.prototype._init = function () {
            var _self = this;
            var _update = function () {
                return _self.positions;
            };
            //实时更新polyline.positions
            this.options.polyline.positions = new Cesium.CallbackProperty(_update, false);
            viewer.entities.add(this.options);
        };
        return _;
    })();

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值