cesium动态绘制圆,矩形,自定义区域

在这里插入图片描述

cesium动态绘制圆,矩形,自定义区域

自己封装了一个类,可以放在js文件中引入项目,具体使用和代码如下

class Draw {

    constructor(viewer, config) {
        /**cesium实例对象 */
        this.viewer = viewer
        /**绘制要素的相关配置
         * 默认配置
         * {
            borderColor: Cesium.Color.BLUE,  边框颜色
            borderWidth: 2, 边框宽度
            material: Cesium.Color.GREEN.withAlpha(0.5),填充材质
        }
        */
        this.config = config || {
            borderColor: Cesium.Color.BLUE,
            borderWidth: 2,
            material: Cesium.Color.GREEN.withAlpha(0.5),
        }
        /**存贮绘制的数据 坐标 */
        this.infoDetail = { point: [], line: [], rectangle: [], circle: [], planeSelf: [] }
        this.handler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas)
    }
    /******* 
     * @function: function
     * @return {*}
     * @author: xk
     * @description: 绘制点数据
     */
    drawPoint() {
        this.handler.destroy()

        this.handler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas)
        this.handler.setInputAction((click) => {
            /**点击位置笛卡尔坐标 */
            let cartesian = this.viewer.camera.pickEllipsoid(click.position, this.viewer.scene.globe.ellipsoid)
            /**笛卡尔转弧度坐标 */
            let cartographic = Cesium.Cartographic.fromCartesian(cartesian, this.viewer.scene.globe.ellipsoid, new Cesium.Cartographic())
            /**点击位置经度 */
            let lng = Cesium.Math.toDegrees(cartographic.longitude)
            /**点击位置维度 */
            let lat = Cesium.Math.toDegrees(cartographic.latitude)
            /**实体的唯一标注 */
            let id = new Date().getTime()
            this.viewer.entities.add({
                position: Cesium.Cartesian3.fromDegrees(lng, lat, 0),
                name: 'point',
                id: id,
                point: {
                    color: this.config.material,
                    pixelSize: 12,
                    outlineColor: this.config.borderColor,
                    outlineWidth: this.config.borderWidth
                }
            })
            this.infoDetail.point.push({ id: id, position: [lng, lat] })

        }, Cesium.ScreenSpaceEventType.LEFT_CLICK)

        this.handler.setInputAction((click) => {
            this.handler.destroy();
        }, Cesium.ScreenSpaceEventType.RIGHT_CLICK)
    }

    /******* 
     * @function: function
     * @description: 绘制矩形区域
     * @return {*}
     * @author: xk
     */
    drawRectangle() {
        this.handler.destroy()
        /**
         * 矩形四点坐标
         */
        let westSouthEastNorth = []
        /**实体的唯一标注 */
        let id = null
        /**地图点击对象 */
        this.handler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas)
        this.handler.setInputAction((click) => {
            /**点击位置笛卡尔坐标 */
            let cartesian = this.viewer.camera.pickEllipsoid(click.position, this.viewer.scene.globe.ellipsoid)
            /**笛卡尔转弧度坐标 */
            let cartographic = Cesium.Cartographic.fromCartesian(cartesian, this.viewer.scene.globe.ellipsoid, new Cesium.Cartographic())
            /**点击位置经度 */
            let lng1 = Cesium.Math.toDegrees(cartographic.longitude)
            /**点击位置维度 */
            let lat1 = Cesium.Math.toDegrees(cartographic.latitude)
            /**边框坐标 */
            westSouthEastNorth = [lng1, lat1]
            id = new Date().getTime()
            if (westSouthEastNorth) {
                this.handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK)
            }
            /**面实例对象 */
            let polygons = this.viewer.entities.add({
                name: 'rectangle',
                id: id,
                polygon: {
                    hierarchy: new Cesium.CallbackProperty(function () {
                        return {
                            positions: Cesium.Cartesian3.fromDegreesArray(westSouthEastNorth)
                        }
                    }, false),
                    height: 0,
                    // 填充的颜色,withAlpha透明度
                    material: this.config.material,
                    // 是否被提供的材质填充
                    fill: true,
                    // 是否显示
                    show: true,
                },
                polyline: {
                    positions: new Cesium.CallbackProperty(function () { return Cesium.Cartesian3.fromDegreesArray(westSouthEastNorth) }false),
                    material: this.config.borderColor,
                    width: this.config.borderWidth,
                    zIndex: 1
                }
            })
            this.handler.setInputAction((move) => {
                let cartesian = this.viewer.camera.pickEllipsoid(move.endPosition, this.viewer.scene.globe.ellipsoid)
                let cartographic = Cesium.Cartographic.fromCartesian(cartesian, this.viewer.scene.globe.ellipsoid, new Cesium.Cartographic())
                let lng = Cesium.Math.toDegrees(cartographic.longitude)
                let lat = Cesium.Math.toDegrees(cartographic.latitude)

                westSouthEastNorth = [lng1, lat1, lng1, lat, lng, lat, lng, lat1, lng1, lat1]


            }, Cesium.ScreenSpaceEventType.MOUSE_MOVE)
        }, Cesium.ScreenSpaceEventType.LEFT_CLICK)


        this.handler.setInputAction(() => {
            this.handler.destroy();
            this.infoDetail.rectangle.push({ id: id, position: westSouthEastNorth })
        }, Cesium.ScreenSpaceEventType.RIGHT_CLICK)
    }
    /******* 
     * @function: function
     * @description: 绘制圆形区域
     * @return {*}
     * @author: xk
     */
    drawCircle() {
        this.handler.destroy()
        /**实体的唯一标注 */
        let id = null

        /**圆半径 */
        let radius = 0
        /**圆心 */
        let lngLat = []
        /**鼠标事件 */
        this.handler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas)
        this.handler.setInputAction((click) => {
            id = new Date().getTime()
            let cartesian = this.viewer.camera.pickEllipsoid(click.position, this.viewer.scene.globe.ellipsoid)
            let cartographic = Cesium.Cartographic.fromCartesian(cartesian, this.viewer.scene.globe.ellipsoid, new Cesium.Cartographic())
            let lng = Cesium.Math.toDegrees(cartographic.longitude)
            let lat = Cesium.Math.toDegrees(cartographic.latitude)
            lngLat = [lng, lat]
            let entity = this.viewer.entities.add({
                position: new Cesium.CallbackProperty(function () { return new Cesium.Cartesian3.fromDegrees(...lngLat, 0) }, false),
                name: 'circle',
                id: id,
                ellipse: {
                    height: 0,
                    outline: true,
                    material: this.config.material,
                    outlineColor: this.config.borderColor,
                    outlineWidth: this.config.borderWidth
                }
            })
            entity.ellipse.semiMajorAxis = new Cesium.CallbackProperty(function () { return radius }, false)
            entity.ellipse.semiMinorAxis = new Cesium.CallbackProperty(function () { return radius }, false)

            if (lngLat) {
                this.handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK)
            }
            this.handler.setInputAction((move) => {
                let cartesian2 = this.viewer.camera.pickEllipsoid(move.endPosition, this.viewer.scene.globe.ellipsoid)
                radius = Cesium.Cartesian3.distance(cartesian, cartesian2)
            }, Cesium.ScreenSpaceEventType.MOUSE_MOVE)
        }, Cesium.ScreenSpaceEventType.LEFT_CLICK)

        this.handler.setInputAction(() => {

            this.infoDetail.circle.push({ id: id, center: lngLat, radius: radius })
            this.handler.destroy();
        }, Cesium.ScreenSpaceEventType.RIGHT_CLICK)


    }
    /******* 
     * @function: function
     * @description: 自定义区域绘制
     * @return {*}
     * @author: xk
     */
    drawPlane() {
        this.handler.destroy()
        /**实体的唯一标注 */
        let id = new Date().getTime()
        /**记录拐点坐标 */
        let positions = [],
            /**记录返回结果 */
            codeInfo = [],
            /**面的hierarchy属性 */
            polygon = new Cesium.PolygonHierarchy(),
            _polygonEntity = new Cesium.Entity(),
            /**面对象配置 */
            polyObj = null
        this.handler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);
        // left
        this.handler.setInputAction((movement) => {
            let cartesian = this.viewer.camera.pickEllipsoid(movement.position, this.viewer.scene.globe.ellipsoid);
            let cartographic = Cesium.Cartographic.fromCartesian(cartesian, this.viewer.scene.globe.ellipsoid, new Cesium.Cartographic())
            let lng = Cesium.Math.toDegrees(cartographic.longitude)
            let lat = Cesium.Math.toDegrees(cartographic.latitude)


            if (cartesian && cartesian.x) {
                if (positions.length == 0) {
                    positions.push(cartesian.clone());
                }
                codeInfo.push([lng, lat])
                positions.push(cartesian.clone());
                polygon.positions.push(cartesian.clone())
                if (!polyObj) {
                    _polygonEntity.polyline = {
                        width: this.config.borderWidth,
                        material: this.config.borderColor,
                        clampToGround: false
                    }
                    _polygonEntity.polyline.positions = new Cesium.CallbackProperty(function () {
                        return positions
                    }, false)

                    _polygonEntity.polygon = {

                        hierarchy: new Cesium.CallbackProperty(function () {
                            return polygon
                        }, false),

                        material: this.config.material,
                        clampToGround: false
                    }
                    _polygonEntity.name = 'planeSelf'

                    _polygonEntity._id = id
                    polyObj = this.viewer.entities.add(_polygonEntity)
                }
            }
        }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
        // mouse
        this.handler.setInputAction((movement) => {
            let cartesian = this.viewer.camera.pickEllipsoid(movement.endPosition, this.viewer.scene.globe.ellipsoid);
            let cartographic = Cesium.Cartographic.fromCartesian(cartesian, this.viewer.scene.globe.ellipsoid, new Cesium.Cartographic())
            let lng = Cesium.Math.toDegrees(cartographic.longitude)
            let lat = Cesium.Math.toDegrees(cartographic.latitude)

            if (positions.length >= 0) {
                if (cartesian && cartesian.x) {
                    positions.pop()
                    positions.push(cartesian);
                    polygon.positions.pop()
                    polygon.positions.push(cartesian);
                    codeInfo.pop()
                    codeInfo.push([lng, lat]);
                }
            }
        }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

        // right
        this.handler.setInputAction((movement) => {
            this.infoDetail.planeSelf.push({ id: id, positions: codeInfo })

            this.handler.destroy();
            positions.push(positions[0]);
        }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);

    }

    /******* 
     * @function: function
     * @return {*}
     * @author: xk
     * @description: 绘制线段
     */
    drawLine() {
        this.handler.destroy()
        /**实体的唯一标注 */
        let id = null
        /**记录拐点坐标 */
        let positions = [],
            /**记录返回结果 */
            codeInfo = [],
            /**面的hierarchy属性 */
            polygon = new Cesium.PolygonHierarchy(),
            _polygonEntity = new Cesium.Entity(),
            /**面对象配置 */
            polyObj = null
        this.handler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);
        // left
        this.handler.setInputAction((movement) => {
            id = new Date().getTime()
            let cartesian = this.viewer.camera.pickEllipsoid(movement.position, this.viewer.scene.globe.ellipsoid);
            let cartographic = Cesium.Cartographic.fromCartesian(cartesian, this.viewer.scene.globe.ellipsoid, new Cesium.Cartographic())
            let lng = Cesium.Math.toDegrees(cartographic.longitude)
            let lat = Cesium.Math.toDegrees(cartographic.latitude)

            if (cartesian && cartesian.x) {
                if (positions.length == 0) {
                    positions.push(cartesian.clone());
                }
                codeInfo.push([lng, lat])
                positions.push(cartesian.clone());
                polygon.positions.push(cartesian.clone())
                if (!polyObj) {
                    _polygonEntity.polyline = {
                        width: this.config.borderWidth,
                        material: this.config.borderColor,
                        clampToGround: false
                    }
                    _polygonEntity.polyline.positions = new Cesium.CallbackProperty(function () {
                        return positions
                    }, false)
                    _polygonEntity.name = 'line'
                    _polygonEntity._id = id

                    polyObj = this.viewer.entities.add(_polygonEntity)
                }
            }

        }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
        // mouse
        this.handler.setInputAction((movement) => {
            let cartesian = this.viewer.camera.pickEllipsoid(movement.endPosition, this.viewer.scene.globe.ellipsoid);
            let cartographic = Cesium.Cartographic.fromCartesian(cartesian, this.viewer.scene.globe.ellipsoid, new Cesium.Cartographic())
            let lng = Cesium.Math.toDegrees(cartographic.longitude)
            let lat = Cesium.Math.toDegrees(cartographic.latitude)

            if (positions.length >= 0) {
                if (cartesian && cartesian.x) {
                    positions.pop()
                    positions.push(cartesian);
                    codeInfo.pop()
                    codeInfo.push([lng, lat]);
                }
            }
        }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

        // right
        this.handler.setInputAction((movement) => {
            this.infoDetail.line.push({ id: id, positions: codeInfo })
            this.handler.destroy();
        }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
    }
    /******* 
     * @function: function
     * @description: 移除实体对象
     * @return {*}
     * @author: xk
     */
    removeEntity() {
        this.handler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas)
        this.handler.setInputAction((move) => {
            /**实体对象信息  {id:entities,primitive:。。} */
            let pick = this.viewer.scene.pick(move.endPosition);

            if (pick && pick.id && pick.id.id) {
                document.body.style.cursor = "pointer";
                this.handler.setInputAction((click) => {
                    let newPoint
                    switch (pick.id.name) {

                        case 'point':
                            /**删除某一条数据 */
                            newPoint = this.infoDetail.point.filter(item => item.id != pick.id._id)
                            this.infoDetail.point = newPoint
                            break
                        case 'line':
                            /**删除某一条数据 */
                            newPoint = this.infoDetail.line.filter(item => item.id != pick.id._id)
                            this.infoDetail.line = newPoint
                            break
                        case 'rectangle':
                            /**删除某一条数据 */
                            newPoint = this.infoDetail.rectangle.filter(item => item.id != pick.id._id)
                            this.infoDetail.rectangle = newPoint
                            break

                        case 'planeSelf':
                            /**删除某一条数据 */
                            newPoint = this.infoDetail.planeSelf.filter(item => item.id != pick.id._id)
                            this.infoDetail.planeSelf = newPoint
                            break
                        case 'circle':
                            /**删除某一条数据 */
                            newPoint = this.infoDetail.circle.filter(item => item.id != pick.id._id)
                            this.infoDetail.circle = newPoint
                            break
                        default: break
                    }
                    this.viewer.entities.remove(pick.id)
                }, Cesium.ScreenSpaceEventType.LEFT_CLICK)

            } else {

                document.body.style = "cursor: default;";

            }
        }, Cesium.ScreenSpaceEventType.MOUSE_MOVE)
    }
    /******* 
     * @function: function
     * @return {*}
     * @author: xk
     * @description: 返回绘制数据
     */
    backInfoDetail() {
        return this.infoDetail
    }




}

使用

let draw = new Draw(viewer,{borderColor:Cesium.Color.RED,material:Cesium.Color.BLUE.withAlpha(0.5)})  //viewer 初始化的cesium对象,自定义配置项,可以不用,就使用默认样式
draw.drawCircle() //圆形区域
draw.drawRectangle()//矩形区域
draw.drawPlane()//自定义区域绘制
draw.removeEntity()//移除选区  鼠标移动到上面 点击清除

//一般是绑定在具体的按钮上,来判断要执行哪一个绘制方法  左键点击绘制,右键点击结束
  • 12
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 13
    评论
要实现cesium动态绘制矩形,可以使用Cesium的Primitive API和MouseEvents。具体步骤如下: 1. 创建矩形entity并添加到场景中。 ``` var entity = viewer.entities.add({ rectangle: { coordinates: Cesium.Rectangle.fromDegrees(-100.0, 20.0, -90.0, 30.0), material: Cesium.Color.RED.withAlpha(0.5), outline: true, outlineColor: Cesium.Color.BLACK } }); ``` 2. 获取鼠标左键按下和移动事件,并更新矩形的坐标。 ``` var startPosition; var mouseHandler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas); mouseHandler.setInputAction(function(movement) { startPosition = movement.position; }, Cesium.ScreenSpaceEventType.LEFT_DOWN); mouseHandler.setInputAction(function(movement) { if (Cesium.defined(startPosition)) { var endPosition = movement.position; var startCartesian = viewer.scene.camera.pickEllipsoid(startPosition, viewer.scene.globe.ellipsoid); var endCartesian = viewer.scene.camera.pickEllipsoid(endPosition, viewer.scene.globe.ellipsoid); if (Cesium.defined(startCartesian) && Cesium.defined(endCartesian)) { var startCartographic = Cesium.Cartographic.fromCartesian(startCartesian); var endCartographic = Cesium.Cartographic.fromCartesian(endCartesian); var west = Math.min(startCartographic.longitude, endCartographic.longitude); var east = Math.max(startCartographic.longitude, endCartographic.longitude); var south = Math.min(startCartographic.latitude, endCartographic.latitude); var north = Math.max(startCartographic.latitude, endCartographic.latitude); entity.rectangle.coordinates = Cesium.Rectangle.fromDegrees(west, south, east, north); } } }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); ``` 3. 获取鼠标左键松开事件,结束矩形绘制。 ``` mouseHandler.setInputAction(function(movement) { startPosition = undefined; }, Cesium.ScreenSpaceEventType.LEFT_UP); ``` 这样,当用户按下鼠标左键并移动时,就可以动态绘制矩形

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

LBY_XK

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

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

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

打赏作者

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

抵扣说明:

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

余额充值