husq
2023-10-08 e9c3bec756225fcf21b6b4cb53f44d11d0b00aea
src/hooks/use-cesium-tsa.ts
@@ -1,68 +1,156 @@
import { ELocalStorageKey, EDeviceTypeName } from '/@/types'
import dockIcon from '/@/assets/icons/dock.png'
import rcIcon from '/@/assets/icons/rc.png'
import droneIcon from '/@/assets/icons/drone.png'
import * as Cesium from 'cesium'
import {
  getCurrentInstance,
} from 'vue'
interface billboardSetting {
    image: string,
    scale?: number,
    [key: string]: any
  image: string,
  scale?: number,
  [key: string]: any
}
interface pointSetting {
    pixelSize: number,
    outlineWidth: number,
    [key: string]: any
  pixelSize: number,
  outlineWidth: number,
  [key: string]: any
}
interface labelSetting {
    text: string,
    font: string,
    outlineWidth: number,
    [key: string]: any
  text: string | undefined,
  font: string,
  outlineWidth: number,
  [key: string]: any
}
interface pointOption {
    longitude: number
    latitude: number
    point?: pointSetting
    billboard?: billboardSetting
    label?: labelSetting
  longitude: number
  latitude: number
  point?: pointSetting
  billboard?: billboardSetting
  label?: labelSetting
  id?: string
}
// 定义全局的viewer变量防止重复生成
// eslint-disable-next-line no-var
var viewer: Cesium.Viewer | null = null
export function cesiumOperation () {
  let handler: Cesium.ScreenSpaceEventHandler
  const _init = () => {
    if (viewer) return
    // Cesium Token
    const cesiumToken = import.meta.env.VITE_CESIUM_TOKEN
    Cesium.Ion.defaultAccessToken = cesiumToken
    Cesium.Camera.DEFAULT_VIEW_FACTOR = -0.45
    // 西南东北,默认显示中国
    Cesium.Camera.DEFAULT_VIEW_RECTANGLE = Cesium.Rectangle.fromDegrees(110, -25, 110, 90)
    viewer = new Cesium.Viewer('cesiumContainer', {
      infoBox: false, // 禁用沙箱,解决控制台报错
      animation: false, // 左下角的动画仪表盘
      baseLayerPicker: false, // 右上角的图层选择按钮
      geocoder: false, // 搜索框
      homeButton: false, // home按钮
      sceneModePicker: false, // 模式切换按钮
      timeline: false, // 底部的时间轴
      navigationHelpButton: false, // 右上角的帮助按钮,
      selectionIndicator: false, // 是否显示选择指示器
      baseLayer: false,
    })
    handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas)
    viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK) // 禁用双击
    // viewer.scene.screenSpaceCameraController.minimumZoomDistance = 100
    viewer.scene.screenSpaceCameraController.maximumZoomDistance = 4500000
    loadLAYER()
  }
  // 加载图层、注解方法
  const loadLAYER = () => {
    // 天地图Key
    const TDT_Token = 'c6eea7dad4fa1e2d1e32ec0e7c9735db'
    // 天地图地图
    const TDT_IMG_C = 'https://{s}.tianditu.gov.cn/img_c/wmts?service=wmts&request=GetTile&version=1.0.0' +
      '&LAYER=img&tileMatrixSet=c&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}' +
      '&style=default&format=tiles&tk=' + TDT_Token
    // 天地图注记
    const TDT_ZJ = 'https://{s}.tianditu.gov.cn/cia_c/wmts?service=wmts&request=GetTile&version=1.0.0' +
      '&LAYER=cia&tileMatrixSet=c&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}' +
      '&style=default&format=tiles&tk=' + TDT_Token
    // 天地图图层加载
    const imageryProvider = new Cesium.WebMapTileServiceImageryProvider({
      url: TDT_IMG_C,
      layer: 'tdtImg_c',
      style: 'default',
      format: 'tiles',
      tileMatrixSetID: 'c',
      subdomains: ['t0', 't1', 't2', 't3', 't4', 't5', 't6', 't7'],
      tilingScheme: new Cesium.GeographicTilingScheme(),
      tileMatrixLabels: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19'],
      maximumLevel: 50,
    })
    viewer?.imageryLayers.addImageryProvider(imageryProvider)
    // 天地图中文注记加载
    const annotation = new Cesium.WebMapTileServiceImageryProvider({
      url: TDT_ZJ,
      layer: 'tdtImg_c',
      style: 'default',
      format: 'tiles',
      tileMatrixSetID: 'c',
      subdomains: ['t0', 't1', 't2', 't3', 't4', 't5', 't6', 't7'],
      tilingScheme: new Cesium.GeographicTilingScheme(),
      tileMatrixLabels: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19'],
      maximumLevel: 50,
    })
    viewer?.imageryLayers.addImageryProvider(annotation)
  }
export function cesiumOperation (viewer: any) {
  const cesiumExample = viewer
  const icons = new Map([
    [EDeviceTypeName.Aircraft, droneIcon],
    [EDeviceTypeName.Gateway, rcIcon],
    [EDeviceTypeName.Dock, dockIcon]
  ])
  // 清除所有标记点
  function removeAllPoint () {
    if (cesiumExample) {
      cesiumExample?.entities?.removeAll()
    if (viewer) {
      viewer?.entities?.removeAll()
    }
  }
  // 添加标记点
  function addPoint (pointOption:pointOption) {
  const addPoint = (pointOption: pointOption) => {
    if (!pointOption.longitude && !pointOption.latitude) return
    cesiumExample.entities.add({
    viewer?.entities.add({
      position: Cesium.Cartesian3.fromDegrees(pointOption.longitude, pointOption.latitude),
      billboard: pointOption.billboard,
      point: pointOption.point
      point: pointOption.point,
      label: pointOption.label,
      id: pointOption.id,
    })
  }
  // 通过点ID删除
  function removeById (id:string) {
    viewer?.entities.removeById(id)
    const pointEntity = viewer?.entities.getById(id)
    if (pointEntity && pointEntity !== undefined) {
      viewer?.entities.remove(pointEntity)
    }
  }
  // 飞行 flyto
  function flyTo (pointOption:pointOption, time: number = 3) {
  const flyTo = (pointOption: pointOption, time: number = 4) => {
    if (!pointOption.longitude && !pointOption.latitude) return
    const destination = Cesium.Cartesian3.fromDegrees(pointOption.longitude, pointOption.latitude, 1000)
    const destination = Cesium.Cartesian3.fromDegrees(pointOption.longitude, pointOption.latitude, 3000)
    const duration = time
    cesiumExample.camera.flyTo({
    viewer?.camera.flyTo({
      destination,
      duration
    })
  }
  onMounted(() => {
    if (viewer) return
    _init()
    const { appContext } = getCurrentInstance()
    const global = appContext.config.globalProperties
    global.$viewer = viewer
  })
  // 销毁地图模型
  onUnmounted(() => {
    viewer = null
  })
  return {
    addPoint,
    removeAllPoint,
    flyTo
    flyTo,
    removeById
  }
}