Cesium 给地图注册自定义事件

需求: 制作地图工具箱: 旋转,飞行,点位拾取等 以点位拾取举例

功能描述: 如下图所示 在这里插入图片描述

一、 事件传感器:Sensor

所有事件机制类的基类,提供事件的派发和监听事件

//事件派发机制
import Emitter from './Emitter'

export default class Sensor {
    static type = 'sensor'

    constructor () {
        this.$emitter = new Emitter()
    }

    //注册事件: 供子类重构 每一种事件具体的注册和删除都不同 attach也一样 
    attach() {
        return this
    }

    //删除事件
    detach() {
        return this
    }

    //监听事件
    on ( type, ...fn ) {
        this.$emitter.on( type, ...fn )
        return this
    }

    //移除
    off () {
        this.$emitter.off( type, ...fn )
        return this
    }
    
    //触发
    trigger ( sensorEvent ) {
        this.$emitter.trigger( sensorEvent )
        
        return this
    }

}
二、点位拾取对象: Pick

区分click和hover两种事件的区别:
hover: 蓝点跟着鼠标走 持续拿到hover事件的点 持续移除之前的并且生成现在的小蓝点
click: 蓝点停留在点击点 并需要触发 传进来的回调函数 也就会业务中的显示弹窗的函数

export default class Pick extends Sensor {
    static type = 'Pick'

    constructor ( ) {
        super()

        //初始化小蓝点
        this._initEntity()
        //指定click和hover的this对象为本身
        this.onClick = this.onClick.bind( this )
        this.hover = this.hover.bind( this )
    }

    _initEntity() {
        //小蓝点实体配置信息
        this.entityOpts = {
            point: {
                pixelSize: 10,
                color: Cesium.Color.CORNFLOWERBLUE,
                distanceDisplayCondition: new Cesium.DistanceDisplayCondition(200.0, 1000000.0)
            }
        }
        //存储小蓝点
        this.entities = new Entites( {
            type: 'pick',
            detail: '座标拾取'
        } )
    }

    //注册座标取点
    attach() {
        this.ctl.click( this.onClick )
        this.ctl.hover( this.hover )
        return this
    }

    //注销座标取点
    detach() {
        this.remove()
        this.ctl.remove( this.onClick )
        this.ctl.remove( this.hover )
        return this
    }

    /**
     * 依赖于地图点击事件
     * @param { Event } event 地图点击事件对象
     */
    onClick ( event ) {
        // 删除之前添加的点
        this.remove()
        // 获取座标
        let c3 = Point.toC3( event.position, this.ctl );

        if(c3) {
            let point = Point.c3ToFd( c3, this.ctl )
            
            this.addEntity(point)
            // 点击后需要 触发调用 回调函数
            let pickEvent = new PickEvent( {
                point,
                c3,
                ctl: this.ctl
            } )
            this.trigger( pickEvent )
        }
    }

    //依赖地图的鼠标划过事件  event {startPosition: a, endPosition: a}
    hover(event) {
        this.removeEntity()

        let c3 = Point.toC3( event.endPosition, this.ctl );
        if(c3) {
            let point = Point.c3ToFd( c3, this.ctl )
            this.addEntity(point)
        }
    }

    // 在点击位置添加 entity 点
    addEntity(point) {
        let entity = new Cesium.Entity( {
            ...this.entityOpts,
            znvPoint: this,
            position : Cesium.Cartesian3.fromDegrees( point.lng, point.lat, 100 ),
        } )
        this.entities.add( entity )
    }

    //移除之前操作添加的 entity 点
    removeEntity () {
        this.entities.destory()
        return this
    }
}
三、在地图对象上提供注册事件方法

地图对象是用的最广泛的对象。在这里设定一个sensor对象装上所有的自定义事件,可以对自定义事件进行统一管理

class MapCtl{
    /**
     * 注册自定义事件
     * @param { Sensor } sensor 传感器对象 
     */
    register ( sensor, callback ) {
        if ( this.sensor[ sensor.type ] == null ) {
            this.sensor[ sensor.type ] = sensor
        }
        if ( typeof callback === 'function' ) {
            callback( sensor )
        }
    }

    //清除所有自定义事件
    clear () {
        for (let type in this.sensor ) {
            this.sensor[ type ].detach()
        }
    }

}

四、注册Pick

在页面初始化的时候就注册这个事件

CesiumCtl.register( new Pick(), ( sensor ) => { 
    // 座标获取
    sensor.on( 'pick', ( event ) => {
        this.showPickDailog(event)
    } )
} )
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章