core/Handler.js

/*
 * Handler句柄主类
 * @Author: jianlei wang
 * @Date: 2024-02-17 12:14:01
 * @Last Modified by: jianlei wang
 * @Last Modified time: 2024-08-15 17:58:41
 */

import { Cesium } from '../../namespace'
import {
  getCatesian3FromPX,
  transformCartesianToWGS84,
} from '../utils/Coordinate'
import { randomId } from '../utils/Generate'
import {
  addHandler,
  destroyHandler,
  initPickGlobal,
  mouseStyle,
  resetGlobeHandler,
  initPickWmts,
} from '../utils/Handler'
import CreateRemindertip from '../utils/ReminderTip'

/**
 * Handler句柄主类
 * @class
 */
class Handler {
  /**
   * 构造函数
   * @param {Object} viewer 地图场景对象
   */
  constructor(viewer) {
    this._viewer = viewer
    this._handlerCollection = []
    this._pickEnabled = false
    this._onTip = false
    this._tipValue = undefined
  }

  /**
   * 新增一个Handler句柄对象
   * @param {String} id 给定id
   * @returns {ScreenSpaceEventHandler} handler对象,参考Cesium的ScreenSpaceEventHandler类
   */
  add(id) {
    const _id = id || randomId()
    const index = this.getIndexById(_id)
    if (index != -1) {
      throw new Error('The current ID object already exists')
    }
    const handler = addHandler(this._viewer, _id)
    this._handlerCollection.push(handler)
    return handler
  }

  /**
   * 根据ID获取handler对象
   * @param {String} id id
   * @returns 句柄对象索引下标
   */
  getIndexById(id) {
    return this._handlerCollection.findIndex((handler) => handler.id === id)
  }

  /**
   * 开启全局对象拾取(针对于矢量和wms服务数据)
   * @param {Boolean} bool - 是否开启
   * @param {objectCallback} callback - 回调函数,返回拾取对象集合
   */
  pickEnabled(bool, callback) {
    this._pickEnabled = bool
    let handler = resetGlobeHandler(this._viewer)
    bool && initPickGlobal(this._viewer, handler, callback)
  }

  /**
   * 开启WMTS服务数据拾取
   * @param {Boolean} bool - 是否开启
   * @param {GeoserverWmtsOptions} options - WMTS服务参数
   * @param {objectCallback} callback - 回调函数,返回拾取对象
   */
  pickWmtsEnabled(bool, options, callback) {
    this._pickEnabled = bool
    let handler = resetGlobeHandler(this._viewer)
    bool && initPickWmts(this._viewer, handler, options, callback)
  }
  /**
   * 拾取坐标位置
   * @param {Boolean} bool - 是否开启
   * @param {PickPosCallback} callback - 回调函数,返回拾取位置坐标
   */
  pickPos(bool, callback) {
    let handler = resetGlobeHandler(this._viewer)
    if (bool) {
      mouseStyle(this._viewer, 'pickPos')
      handler.setInputAction((event) => {
        let pos = getCatesian3FromPX(this._viewer, event.position)
        if (!pos) return
        const position = {
          cartesian: pos,
          degree: transformCartesianToWGS84(pos),
        }
        callback && typeof callback === 'function' && callback(position)
      }, Cesium.ScreenSpaceEventType.LEFT_CLICK)
    } else {
      mouseStyle(this._viewer, 'default')
      destroyHandler(handler)
    }
  }

  /**
   * 鼠标跟随提示
   * @param {boolean} bool 是否开启跟随
   * @param {HTMLElement|String|Null} innerHTML
   */
  onTip(bool, innerHTML) {
    let id = 'handler-on-tip'
    if (bool) {
      const handler = this.add(id)
      handler.setInputAction((event) => {
        CreateRemindertip(innerHTML || this._tipValue, event.endPosition, true)
      }, Cesium.ScreenSpaceEventType.MOUSE_MOVE)
    } else {
      CreateRemindertip('', null, false)
      this.remove(id)
      this._tipValue = undefined
    }
  }
  /**
   * 重置全局handler
   */
  resetGlobal() {
    resetGlobeHandler(this._viewer)
  }

  /**
   * 根据id移除handler对象
   * @param {*} id 句柄id
   */
  remove(id) {
    const index = this.getIndexById(id)
    if (index != -1) {
      this._handlerCollection[index].destroy()
      this._handlerCollection.splice(index, 1)
    }
  }
  /**
   * 清除handler集并注销全局handler
   */
  destroy() {
    this._handlerCollection.forEach((handler) => {
      destroyHandler(handler)
    })
    this._handlerCollection = []
    window.globeHandler && destroyHandler(window.globeHandler)
  }
}

export default Handler