【Cesium】动态绘制---距离测量及多边形绘制

距离测量功能实现流程:

1.鼠标连续点击生成连续的多个点,使用红色圆圈表示;

2.计算相邻点之间的距离,进行累加,将结果标记在当前点击位置;

3.绘制图形支持线和面两种显示效果;

4.鼠标右键点击结束绘制,并解绑绘制功能。

 一、实现代码如下:

/**
 * @description: 距离测量
 * @param: drawingMode参数为"line"或者"polygon",当为"line"时,标记路径为线条;当为"polygon"时,标记路径为多边形
 */

function calDrawLines(viewer, drawingMode) {

    let activeShapePoints = [];
    let activeShape;
    let floatingPoint;

    viewer.screenSpaceEventHandler.setInputAction(function (event) {
        // We use `viewer.scene.globe.pick here instead of `viewer.camera.pickEllipsoid` so that
        // we get the correct point when mousing over terrain.
        const ray = viewer.camera.getPickRay(event.position);
        const earthPosition = viewer.scene.globe.pick(ray, viewer.scene);
        if (Cesium.defined(earthPosition)) {
            if (activeShapePoints.length === 0) {
                floatingPoint = createPoint(earthPosition, activeShapePoints);
                activeShapePoints.push(earthPosition);
                const dynamicPositions = new Cesium.CallbackProperty(function () {
                    if (drawingMode === "polygon") {
                        return new Cesium.PolygonHierarchy(activeShapePoints);
                    }
                    return activeShapePoints;
                }, false);
                activeShape = drawShape(dynamicPositions, drawingMode);
            }
            activeShapePoints.push(earthPosition);
            createPoint(earthPosition, activeShapePoints);
        }
    }, Cesium.ScreenSpaceEventType.LEFT_CLICK);

    viewer.screenSpaceEventHandler.setInputAction(function (event) {
        if (Cesium.defined(floatingPoint)) {
            const ray = viewer.camera.getPickRay(event.endPosition);
            const newPosition = viewer.scene.globe.pick(ray, viewer.scene);
            if (Cesium.defined(newPosition)) {
                floatingPoint.position.setValue(newPosition);
                activeShapePoints.pop();
                activeShapePoints.push(newPosition);
            }
        }
    }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

    viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(
        Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK
    );

    // 鼠标右击移除
    viewer.screenSpaceEventHandler.setInputAction(function (event) {
        terminateShape();
        viewer.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
    }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);


    function terminateShape() {
        activeShapePoints.pop();
        drawShape(activeShapePoints, drawingMode);
        viewer.entities.remove(floatingPoint);
        viewer.entities.remove(activeShape);
        floatingPoint = undefined;
        activeShape = undefined;
        activeShapePoints = [];
    }

    function createPoint(worldPosition, activeShapePoints) {
        var distance = calDistance(activeShapePoints);
        const point = viewer.entities.add({
            position: worldPosition,
            point: {
                color: Cesium.Color.GREEN,
                pixelSize: 10,
                heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
                disableDepthTestDistance: Number.POSITIVE_INFINITY,
            },
            label: {
                text: distance + "米",
                horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
                verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
                pixelOffset: new Cesium.Cartesian2(0, -20),
                font: '20px monospace',
                showBackground: true,
                backgroundColor: Cesium.Color.BLACK.withAlpha(1),
                backgroundPadding: new Cesium.Cartesian2(17, 10),
                disableDepthTestDistance: Number.POSITIVE_INFINITY
            }
        });
        return point;
    }


    function drawShape(positionData, drawingMode) {
        let shape;
        if (drawingMode === "line") {
            shape = viewer.entities.add({
                polyline: {
                    positions: positionData,
                    clampToGround: true,
                    width: 5,
                    material: Cesium.Color.RED
                },
            });
        } else if (drawingMode === "polygon") {
            shape = viewer.entities.add({
                polygon: {
                    hierarchy: positionData,
                    material: new Cesium.ColorMaterialProperty(
                        Cesium.Color.GREEN.withAlpha(1)
                    ),
                },
            });
        }
        return shape;
    }

    function calDistance(positions) {
        var distance = 0;
        for (var i = 0; i < positions.length - 1; i++) {
            distance += Cesium.Cartesian3.distance(positions[i], positions[i + 1]);
        }
        return distance.toFixed(2)
    }
}

二、 源码下载:附带cesium框架,一键运行。

Cesium实现动态距离测量资源-CSDN文库

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

鱼遇雨愈愉

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值