Map.js

/*
 * @Author: jianlei wang
 * @Date: 2024-02-28 15:07:28
 * @Last Modified by: jianlei wang
 * @Last Modified time: 2024-06-03 14:44:15
 */

import { Cesium } from '../namespace'
import Analysis from './core/Analysis'
import Components from './core/Components'
import Handler from './core/Handler'
import { BaseLayer, Layers } from './core/Layers'
import Navigation from './core/Navigation'
import Render from './core/Render'
import Screen from './core/Screen'
import Terrain from './core/Terrain'
import Weather from './core/Weather'
import { CesiumIcon } from './utils/Default'
import { mapImg, mapSize } from './utils/Navigation'
import MilitaryPlotting from './utils/plotting'

/**
 * 地图场景
 * @class
 */
class Map {
  /**
   * 构造函数
   * @param {String} [id] 创建地图场景所需的页面元素Id
   * @param {Object} [imagery=null] 初始影像对象
   * @param {Object} [terrain=null] 初始地形对象
   * @see {@link Layers} - 图层主类
   * @see {@link Terrain} - 地形主类
   * @see {@link Handler} - Handler句柄主类
   * @see {@link Navigation} - 导航主类
   * @see {@link Weather} - 天气主类
   * @see {@link Components} - 组件主类
   * @see {@link Analysis} - 空间分析主类
   * @see {@link MilitaryPlotting} - 态势标绘主类
   * @see {@link Screen} - 场景窗口主类
   * @see {@link Render} - 渲染事件主类
   */
  constructor(id, imagery, terrain) {
    if (!id || (typeof id === 'string' && !document.getElementById(id))) {
      throw new Error('Viewer:the id is empty')
    }
    Cesium.Ion.defaultAccessToken = CesiumIcon
    this._viewer = new Cesium.Viewer(id, {
      geocoder: false,
      homeButton: false,
      sceneModePicker: false,
      baseLayerPicker: false,
      navigationHelpButton: false,
      animation: false,
      timeline: false,
      shouldAnimate: true,
      fullscreenButton: false,
      vrButton: false,
      selectionIndicator: false, // 关闭点选出现的提示框
      infoBox: false,
      requestRenderMode: false, // 开启-关闭请求的渲染模式
      baseLayer: imagery || BaseLayer.DefaultSingleImg,
      terrain: terrain,
    })
    this._viewer.container.style.position = 'relative'
    this._viewer.container.style.overflow = 'hidden'
    this._initParam()
    /**
     * 图层主类
     * @type {Layers}
     */
    this.Layers = new Layers(this._viewer)
    /**
     * 地形主类
     * @type {Terrain}
     */
    this.Terrain = new Terrain(this._viewer)
    /**
     * Handler句柄主类
     * @type {Handler}
     */
    this.Handler = new Handler(this._viewer)
    /**
     * 导航主类
     * @type {Navigation}
     */
    this.Navigation = new Navigation(this._viewer)
    /**
     * 天气主类
     * @type {Weather}
     */
    this.Weather = new Weather(this._viewer)
    /**
     * 组件主类
     * @type {Components}
     */
    this.Components = new Components(this._viewer)
    /**
     * 空间分析主类
     * @type {Analysis}
     */
    this.SpecialAnalysis = new Analysis(this._viewer)
    /**
     * 态势标绘主类
     * @type {MilitaryPlotting}
     */
    this.MilitaryPlotting = new MilitaryPlotting(this._viewer)
    /**
     * 场景窗口主类
     * @type {Screen}
     */
    this.Screen = new Screen(this._viewer)
    /**
     * 渲染事件类
     * @type {Render}
     */
    this.Render = new Render(this._viewer)
  }
  _initParam() {
    this._viewer.scene.debugShowFramesPerSecond = true // 显示帧率
    this._viewer.cesiumWidget.creditContainer.style.display = 'none' // 隐藏版权
    this._viewer.scene.globe.depthTestAgainstTerrain = true // 开启深度检测

    // 默认双击trackedEntity事件取消
    this._viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(
      Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK
    )
    // 是否支持图像渲染像素化处理
    if (Cesium.FeatureDetection.supportsImageRenderingPixelated()) {
      this._viewer.resolutionScale = window.devicePixelRatio
    }
    // 开启抗锯齿
    this._viewer.scene.postProcessStages.fxaa.enabled = true
    //设置中键放大缩小
    this._viewer.scene.screenSpaceCameraController.zoomEventTypes = [
      Cesium.CameraEventType.WHEEL,
      Cesium.CameraEventType.MIDDLE_DRAG,
      Cesium.CameraEventType.PINCH,
    ]
    //设置右键旋转
    this._viewer.scene.screenSpaceCameraController.tiltEventTypes = [
      Cesium.CameraEventType.RIGHT_DRAG,
      Cesium.CameraEventType.PINCH,
      {
        eventType: Cesium.CameraEventType.RIGHT_DRAG,
        modifier: Cesium.KeyboardEventModifier.CTRL,
      },

      {
        eventType: Cesium.CameraEventType.MIDDLE_DRAG,
        modifier: Cesium.KeyboardEventModifier.CTRL,
      },
    ]
  }

  /**
   * 地图场景
   * @type {Viewer}
   * @readonly
   */
  get viewer() {
    return this._viewer
  }

  /**
   * 控制帧率显示
   * @type {Boolean}
   */
  get fps() {
    return this._viewer.scene.debugShowFramesPerSecond
  }
  set fps(show) {
    this._viewer.scene.debugShowFramesPerSecond = show // 显示帧率
  }

  /**
   * 地图画布大小,例如:{width:1920,height:1080}
   * @type {Object}
   * @readonly
   */
  get size() {
    return mapSize(this._viewer)
  }

  /**
   * 当前地图场景图片,base64格式
   * @type {String}
   * @readonly
   */
  get image() {
    return mapImg(this._viewer)
  }

  /**
   * 场景底图
   * Cesium机制是最底层的图层为_isBaseLayer,通过lowerToBottom来控制
   * @param {ImageryLayer} imagery 参考Cesium的ImageryLayer
   */

  get baseImagery() {
    const layers = this._viewer.imageryLayers._layers
    const baseLayer = layers.find((layer) => layer._isBaseLayer)
    return baseLayer
  }

  set baseImagery(imagery) {
    const { imageryLayers } = this._viewer
    const baseLayer = imageryLayers._layers.find((layer) => layer._isBaseLayer)
    baseLayer && imageryLayers.remove(baseLayer)
    imageryLayers.lowerToBottom(imagery)
  }
}
export default Map