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)
    } )
} )
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章