(六)Cesium使用CallbackProperty交互绘制图形,点线面圆

import * as Cesium from 'cesium'
import { useCesiumStore } from '@/stores/useCesiumStore.js'
import { toRaw } from 'vue'

export function drawShape(type) {
    const viewer = toRaw(useCesiumStore().viewer)  // 获取viewer对象
    let activeShapePoints = []  // 存放当前绘制的多边形的点坐标
    let activeShape = null  // 存放当前绘制的多边形对象
    let floatingPoint = null  //存储第一个点并判断是否开始获取鼠标移动结束位置
    let drawingMode = null
    const hander = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas)
    switch (type) {
        case 'drawPoint':
            drawingMode = 'point'
            break
        case 'drawLine':
            drawingMode = 'line'
            // console.log(viewer.entities.values);
            break
        case 'drawPolygon':
            drawingMode = 'polygon'
            break
        case 'drawCircle':
            drawingMode = 'circle'
            break
        case 'drawRectangle':
            drawingMode = 'rectangle'
            break
        case 'clearDraw':
            console.log(viewer.entities.values.length);
            // viewer.entities.removeAll()  //清除所有图形
            clearDraw()
            viewer.scene.canvas.style.cursor = 'default'    //恢复鼠标形状
            break
        default:
            break
    }

    //清除图形
    function clearDraw  () {
        for (let i = 0; i < viewer.entities.values.length; i++) {
            if (viewer.entities.values[i].name === 'Point' || viewer.entities.values[i].name === 'Line' || viewer.entities.values[i].name === 'Polygon' || viewer.entities.values[i].name === 'Rectangle' || viewer.entities.values[i].name === 'Ellipse') {
                viewer.entities.remove(viewer.entities.values[i])
                i-- //删除后索引减一,数组塌陷
            }
        }
    }

    viewer.scene.canvas.style.cursor = 'crosshair'

    //绘制点
    const drawPoint = (position) => {
        const pointGeometry = viewer.entities.add({
            name: 'Point',
            position: position,
            point: {
                color: Cesium.Color.BLUE,
                pixelSize: 8,
                outlineColor: Cesium.Color.YELLOW,
                outlineWidth: 2
            }
        })
        return pointGeometry
    }

    //绘制形状功能
    const drawShape = (positionData) => {
        let shape = null
        //如果为线时
        if (drawingMode === 'line') {
            shape = viewer.entities.add({
                name: 'Line',
                polyline: {
                    positions: positionData,
                    width: 5,
                    material: new Cesium.PolylineOutlineMaterialProperty({
                        color: Cesium.Color.GOLD
                    }),
                    clampToGround: true //贴地
                }
            })
        }
        else if (drawingMode === 'polygon') {  //如果模式选择绘制多边形,调用绘制多边形
            shape = viewer.entities.add({
                name: 'Polygon',
                polygon: {
                    hierarchy: positionData,
                    material: new Cesium.ColorMaterialProperty(Cesium.Color.BLUE.withAlpha(0.7)),
                }
            })
        }
        else if (drawingMode === 'circle') {   //如果模式选择绘制圆,调用绘制圆
            let value = typeof positionData.getValue === 'function' ? positionData.getValue(0) : positionData //当传入的positionData为SampledPositionProperty时,取第一个值
            shape = viewer.entities.add({
                name: 'Ellipse',
                position : activeShapePoints[0], //圆心
                ellipse : { //椭圆
                    semiMinorAxis:new Cesium.CallbackProperty(function(){
                        //半径,两点之间的距离
                        let r = Math.sqrt(Math.pow(value[0].x - value[value.length - 1].x,2) + Math.pow(value[0].y - value[value.length - 1].y,2)) //半径
                        return r ? r : r + 1
                    }, false),
                    semiMajorAxis:new Cesium.CallbackProperty(function(){
                        //半径,两点之间的距离
                        let r = Math.sqrt(Math.pow(value[0].x - value[value.length - 1].x,2) + Math.pow(value[0].y - value[value.length - 1].y,2)) //半径
                        return r ? r : r + 1
                    }, false),
                    material: Cesium.Color.BLUE.withAlpha(0.5),  //颜色
                    outline: true
                }           
            })
        }
        else if (drawingMode === 'rectangle') {       //如果模式选择绘制矩形,调用绘制矩形
            let arr = typeof positionData.getValue === 'function' ? positionData.getValue(0) : positionData //当传入的positionData为SampledPositionProperty时,取第一个值
            shape = viewer.entities.add({
                name: 'Rectangle',
                rectangle: {
                    coordinates: new Cesium.CallbackProperty(function(){
                        let obj = Cesium.Rectangle.fromCartesianArray(arr)
                        return obj
                    }, false),
                    material:Cesium.Color.RED.withAlpha(0.5)
                }
            })
        }
        return shape
    }
    

    //注册鼠标左键单击事件
    hander.setInputAction( (event) => {
        let earthPosition = viewer.scene.pickPosition(event.position)
        if (drawingMode === 'point') {  //如果模式选择绘制点,调用绘制点
            drawPoint(earthPosition)
        }else if (drawingMode === 'polygon' || drawingMode === 'line' || drawingMode === 'circle' || drawingMode ==='rectangle') {
            if (Cesium.defined(earthPosition)) {
                if (activeShapePoints.length === 0) {  //如果是第一次点击,则记录第一个点
                    floatingPoint = drawPoint(earthPosition)
                    activeShapePoints.push(earthPosition)
                    //动态点通过CallbackProperty更新位置
                    const dynamicPositions = new Cesium.CallbackProperty(function(){
                        if(drawingMode === 'polygon') {
                            return new Cesium.PolygonHierarchy(activeShapePoints)
                        }
                        return activeShapePoints
                },false)
                activeShape = drawShape(dynamicPositions)
                }
                activeShapePoints.push(earthPosition)  //记录当前点
                // drawPoint(earthPosition)  //绘制动态点
                if((drawingMode === 'rectangle' && activeShapePoints.length === 3) || (drawingMode === 'circle' && activeShapePoints.length === 3)){  //绘制矩形时,判断是否绘制完成
                    hander.destroy() //销毁事件处理器
                    viewer.scene.canvas.style.cursor = 'default'    //恢复鼠标形状
                    viewer.entities.remove(floatingPoint) //删除重复的第一个点
                    floatingPoint = undefined  //清空变量
                    activeShape = undefined //清空变量
                    activeShapePoints = []  //清空数组
                }
            }
        }
    },Cesium.ScreenSpaceEventType.LEFT_CLICK)

    //注册鼠标移动事件
    hander.setInputAction( (event) => {
        if (Cesium.defined(floatingPoint)) {
            //获取鼠标移动到的最终位置
            const newPosition = viewer.scene.pickPosition(event.endPosition)
            // console.log(newPosition);
            if (Cesium.defined(newPosition)) {
                //动态去除数组中最后一个点,并添加一个新的点,保证只保留鼠标位置点
                activeShapePoints.pop()
                activeShapePoints.push(newPosition)
            }
        }
    },Cesium.ScreenSpaceEventType.MOUSE_MOVE)

    //注册鼠标右键单击事件
    hander.setInputAction( () => {
        hander.destroy() //销毁事件处理器
        viewer.scene.canvas.style.cursor = 'default'    //恢复鼠标形状

        activeShapePoints.pop()  //删除最后一个点
        if(activeShapePoints.length){
            drawShape(activeShapePoints)  //绘制多边形或线
        } 
        viewer.entities.remove(floatingPoint) //删除重复的第一个点
        viewer.entities.remove(activeShape)  //删除动态图形
        floatingPoint = undefined  //清空变量
        activeShape = undefined //清空变量
        activeShapePoints = []  //清空数组
    },Cesium.ScreenSpaceEventType.RIGHT_CLICK)
    //清除图形

   
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值