Bootstrap

cesium中测距

示例1: 

MeasureManager.js

import * as Cesium from 'cesium'

export default class MeasureManager {
    constructor(viewer) {
        this.viewer = viewer
    }

    distance() {
        const viewer = this.viewer
        // 存储点
        const positions = []
        // 存储标签
        let label = null
        const handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas)
        // 注册鼠标左击事件
        handler.setInputAction(evt => {
            var cartesian = viewer.scene.pickPosition(evt.position);
            if (!cartesian) return
            positions.push(cartesian.clone())
            if (positions.length >= 2) {
                handler.destroy()
            }
        }, Cesium.ScreenSpaceEventType.LEFT_CLICK)
        handler.setInputAction(evt => {
            var cartesian = viewer.scene.pickPosition(evt.endPosition);
            if (!cartesian) return
            if (positions.length >= 2) {
                positions.pop()
                positions.push(cartesian.clone())
            } else if (positions.length === 1) {
                positions.push(cartesian.clone())
                this.addLine(positions)
                label = this.addLabel(positions[0], this.getLength(positions))
            }
            if (label) {
                label.label.text.setValue(this.getLength(positions))
                label.position.setValue(positions[1])
            }
        }, Cesium.ScreenSpaceEventType.MOUSE_MOVE)
        handler.setInputAction(evt => {
            handler.destroy()
        }, Cesium.ScreenSpaceEventType.RIGHT_CLICK)
    }
    addLine(positions) {
        const viewer = this.viewer
        viewer.entities.add(
            new Cesium.Entity({
                polyline: {
                    positions: new Cesium.CallbackProperty(() => positions, false),
                    width: 2,
                    material: Cesium.Color.YELLOW,
                    clampToGround: true,
                }
            })
        )
    }
    addLabel(point, text) {
        const viewer = this.viewer
        return viewer.entities.add(
            new Cesium.Entity({
                position: point,
                label: {
                    text: text,
                    font: '14px sans-serif',
                    style: Cesium.LabelStyle.FILL_AND_OUTLINE, //FILL  FILL_AND_OUTLINE OUTLINE
                    fillColor: Cesium.Color.YELLOW,
                    showBackground: true, //指定标签后面背景的可见性
                    backgroundColor: new Cesium.Color(0.165, 0.165, 0.165, 0.8), // 背景颜色
                    backgroundPadding: new Cesium.Cartesian2(6, 6), //指定以像素为单位的水平和垂直背景填充padding
                    pixelOffset: new Cesium.Cartesian2(0, -25),
                    disableDepthTestDistance: Number.POSITIVE_INFINITY
                }
            })
        )
    }
    getLength(points) {
        // 计算距离
        var length = Cesium.Cartesian3.distance(points[0], points[1]);
        if (length > 1000) {
            length = `${(length / 1000).toFixed(2)}km`
        } else {
            length = `${length.toFixed(2)}m`
        }
        return length
    }
}

 测试:

<template>
    <div class="main">
        <div id="cesiumContainer"></div>
    </div>

</template>
  
<script setup>
import * as Cesium from 'cesium';
import MeasureManager from './MeasureManager.js';

onMounted(() => {
    const cesiumViewer = new Cesium.Viewer("cesiumContainer", {
        terrainProvider: Cesium.createWorldTerrain(),
        infoBox: false, //信息面板
        timeline: false, //底部的时间轴
        fullscreenButton: false, //右下角的全屏按钮
    });
    cesiumViewer._cesiumWidget._creditContainer.style.display = "none"; //隐藏logo版权

    const measureManager = new MeasureManager(cesiumViewer)
    measureManager.distance()
})
</script>
<style lang="scss" scoped>
.main {
    position: relative;
    height: 100vh;
    width: 100vw;


    #cesiumContainer {
        position: absolute;
        height: 100vh;
        width: 100vw;
    }

}
</style>

如果希望label显示在线的中间,修改如下:

// 计算中点
let centerPoint = Cesium.Cartesian3.midpoint(positions[0], positions[1], new Cesium.Cartesian3());

示例2:

<template>
    <div class="main">
        <div id="cesiumContainer"></div>
    </div>

</template>
  
<script setup>
import * as Cesium from 'cesium';
//测量空间直线距离
/******************************************* */
function 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>单击开始,右击结束</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);
        //在三维场景中添加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(); //关闭事件句柄
        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: 10,
                    clampToGround: true
                }
            };
            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++) {
            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;
            //console.log(Math.sqrt(Math.pow(distance, 2) + Math.pow(endheight, 2)));
            //返回两点之间的距离
            s = Math.sqrt(Math.pow(s, 2) + Math.pow(point2cartographic.height - point1cartographic.height, 2));
            distance = distance + s;
        }
        return distance.toFixed(2);
    }
}
onMounted(() => {
    const cesiumViewer = new Cesium.Viewer("cesiumContainer", {
        terrainProvider: Cesium.createWorldTerrain(),
        infoBox: false, //信息面板
        timeline: false, //底部的时间轴
        fullscreenButton: false, //右下角的全屏按钮
    });
    cesiumViewer._cesiumWidget._creditContainer.style.display = "none"; //隐藏logo版权

    measureLineSpace(cesiumViewer)
})
</script>
<style lang="scss" scoped>
.main {
    position: relative;
    height: 100vh;
    width: 100vw;


    #cesiumContainer {
        position: absolute;
        height: 100vh;
        width: 100vw;
    }

}
</style>

在线预览:

WebGIS之家WebGIS之家,openlayers示例源码,cesium示例源码,openlayers在线调试预览,cesium在线调试预览,webgis,数字地球,数字孪生icon-default.png?t=N7T8https://www.webgishome.com/preview?id=107&example_name=measureDistance&title=%E6%B5%8B%E9%87%8F%E8%B7%9D%E7%A6%BB

;