<!-- 
    电子地图    
    -编辑页面
 -->
<template>
  <div>
    <div id="earthContainer" ref="earthContainer" style="width: 100%; height: 100%; top: 300px"></div>
    <div class="earthUI_header">
      <header>
        <p>{{ earthTitle }}</p>
        <p>{{ realTime }}</p>
      </header>
    </div>
    <div>
      <a-radio-group default-value="satellite" button-style="solid" size="small" @change="radioChange" class="radioBtn" v-show="radioBtnShow">
        <a-radio-button value="satellite"> 卫星影像</a-radio-button>
        <a-radio-button value="vector"> 矢量地图</a-radio-button>
      </a-radio-group>
      <a-spin size="large" tip="地图切换中,请稍候..." :spinning="earthChangeSpin" class="earthChangeSpin"></a-spin>
    </div>

    <!-- 预警列表 -->
    <!-- <WarnInfoList /> -->

    <!-- 电线杆弹窗 -->
    <div id="cameraModal" class="cameraModal" v-show="cameraModalShow" ref="cameraModal">
      <a-spin size="large" :spinning="spinning" class="spinning"></a-spin>
      <a-button @click="roamPathSet()">视频融合</a-button>
    </div>
    <!-- 视频融合 -->
    <VideoFusionWin
      v-if="VideoFusionWinShow"
      :cameraList="cameraList"
      :monitorPosition="monitorPosition"
      :updateModel="toItemObj.updateModel"
      :isUpdate="toItemObj.isUpdate"
      :userSave="toItemObj.userSave"
    ></VideoFusionWin>
    <!-- 地标弹窗 -->
    <!-- <div id="poiModal" class="poiModal" v-show="poiModalShow" ref="poiModal">
      <div class="poiModal-content">
        <div class="poiModal-header"></div>
        <div class="poiModal-body"></div>
      </div>
    </div>-->

    <!-- 警示弹窗 -->
    <video-split-screen />

    <!-- 警示音频 -->
    <audio ref="audio" loop>
      <source src="@/assets/earthMap/audio/notify.mp3" />
    </audio>

    <!-- 云台控制弹窗 -->
    <video-window
      :id="videoWindowProps.id"
      :visible.sync="videoWindowProps.visible"
      :title="videoWindowProps.title"
      :videoUrl="videoWindowProps.videoUrl"
      :cameraIp="videoWindowProps.cameraIp"
      :cameraUser="videoWindowProps.cameraUser"
      :cameraPwd="videoWindowProps.cameraPwd"
      :isAlarm="videoWindowProps.isAlarm"
      :playRecord="videoWindowProps.playRecord"
      :warnTime="videoWindowProps.warnTime"
      :warnEvent="videoWindowProps.warnEvent"
    />

    <!-- 左侧操作栏 -->
    <Toolbar v-if="toolbarShow" :setLabelStatus="setLabelStatus"></Toolbar>
    <AddModelWin
      v-if="addModelWinShow"
      :setLabelStatus="setLabelStatus"
      :czmObject="czmObject"
      :node="node"
      :type="type"
      :lineId="lineId"
      :areaCode="areaCode"
      :areaByNodeId="areaByNodeIdModel"
      :setIconByRef="setIconByRef"
      :el="el"
      :eidtId="eidtId"
    ></AddModelWin>
    <AddRoamVideo v-if="addRoamVideoShow"></AddRoamVideo>
  </div>
</template>

<script lang="ts">
  import { Options, Vue } from 'vue-class-component';
  import sceneTree from '@/assets/earthMap/resjson/sc.json';
  import { defHttp } from '/@/utils/http/axios';
  import earthUtils from '@/utils/earthMap/earth';
  import _ from 'lodash';
  import $ from 'jquery';
  import { useUserStore } from '/@/store/modules/user';
  import { useEarthMapStore } from '/@/store/modules/earthMap';
  import Toolbar from '@/components/earthMap/Toolbar.vue';
  import AddModelWin from '@/components/earthMap/toolbar/AddModelWin.vue';
  import AddRoamVideo from '@/components/earthMap/toolbar/AddRoamVideo.vue';
  import VideoSplitScreen from '@/components/earthMap/VideoSplitScreen.vue';
  import VideoWindow from '@/components/earthMap/VideoWindow.vue';
  import WarnInfoList from '@/components/earthMap/WarnInfoList.vue';
  import { getRealTime } from '@/utils/date';
  import $mitt from '@/utils/earthMap/mitt';
  import { drawInit } from '@/utils/earthMap/earthDraw';
  import { keyControlInit } from '@/utils/earthMap/keyControlInit';
  import redFlag from '@/assets/earthMap/redFlag.png';
  import { addModel, addPin, addViewShedRadar, addShipGroundImg, addShipTrack } from '@/utils/earthMap/earthObj';
  import { drawAllShips } from '@/utils/earthMap/shipDraw';
  import hidePng from '@/assets/earthMap/hide.png';
  import alarmImg from '@/assets/earthMap/alarm.gif';
  import VideoFusionWin from './components/VideoFusionWin.vue';

  import circleDot2 from '@/assets/earthMap/circleDot2.png';
  import circleDot1 from '@/assets/earthMap/circleDot1.png';
  import circleDot3 from '@/assets/earthMap/circleDot3.png';
  import ship from '@/assets/images/ship.png';

  class HandleNodeType {
    #sn;
    #sensorCallback;
    #modelCallback;
    #markerPositionCallback;
    #polylineCallBack;
    #default;

    constructor(sn) {
      this.#sn = sn;
    }

    sensor(callback) {
      this.#sensorCallback = callback;
      return this;
    }

    // 模型回调
    modelCallback(callback) {
      this.#modelCallback = callback;
      return this;
    }

    // 微波雷达回调
    markerPosition(callback) {
      this.#markerPositionCallback = callback;
      return this;
    }

    // 区域回调
    polylineCallBack(callback) {
      this.#polylineCallBack = callback;
      return this;
    }

    default(callback) {
      this.#default = callback;
      return this;
    }

    run() {
      // 判断节点的类型
      if (!this.#sn.czmObject) {
        return null;
      }
      // 模型类型
      let tempCondition = this.#sn.czmObject.xbsjType;
      switch (tempCondition) {
        case 'Model':
          this.#modelCallback ? this.#modelCallback() : this.#default();
          break;
        case 'Pin':
          this.#markerPositionCallback ? this.#markerPositionCallback() : this.#default();
          break;
        case 'Polyline':
          this.#polylineCallBack ? this.#polylineCallBack() : this.#default();
          break;
        default:
          this.#default ? this.#default() : null;
      }
    }
  }

  function setClassEl(setClassEl1, setClassEl2, checked) {
    if (checked) {
      setClassChecked(setClassEl1, setClassEl2);
    } else {
      setClassNoChecked(setClassEl1, setClassEl2);
    }
  }

  function setClassChecked(setClassEl1, setClassEl2) {
    // node.checkStatus = 'checked'
    // node.disabled = ''
    //***设置样式为选中 */
    setClassEl1.className = 'xbsj-checkbox-wrapper xbsj-checkbox-wrapper-checked xbsj-checkbox-default';
    setClassEl2.className = 'xbsj-checkbox xbsj-checkbox-checked';
  }

  function setClassNoChecked(setClassEl1, setClassEl2) {
    // node.checkStatus = ''
    // node.disabled = 'disabled'
    // 设置为非选中
    setClassEl1.className = 'xbsj-checkbox-wrapper xbsj-checkbox-wrapper-disabled xbsj-checkbox-default';
    setClassEl2.className = 'xbsj-checkbox xbsj-checkbox-disabled';
  }

  function classMutationObserver(el, el1, checkedStauts, id) {
    // 观察器的配置(需要观察什么变动) 属性,子节点or后代节点
    const config = { attributes: true, childList: false, subtree: false };
    const callback1 = function (mutationsList, observer) {
      const checked = checkedStauts.get(id);
      const oldClassName = el.className;
      const trueClassName = 'xbsj-checkbox-wrapper xbsj-checkbox-wrapper-checked xbsj-checkbox-default';
      const noClassName = 'xbsj-checkbox-wrapper xbsj-checkbox-wrapper-disabled xbsj-checkbox-default';
      if (checked) {
        if (oldClassName == trueClassName) {
          return;
        } else {
          setClassChecked(el, el1);
        }
      } else {
        if (oldClassName == noClassName) {
          return;
        } else {
          setClassNoChecked(el, el1);
        }
      }
    };
    // 创建一个观察器实例并传入回调函数
    const observer1 = new MutationObserver(callback1);
    // 以上述配置开始观察目标节点
    observer1.observe(el, config);
  }

  function disabledMutationObserver(el) {
    const config = { attributes: true, childList: false, subtree: false };
    const callback1 = function (mutationsList, observer) {
      const el1 = mutationsList[0];
      if (el1.attributeName == 'disabled') {
        el.removeAttribute('disabled');
      }
    };
    const observe1 = new MutationObserver(callback1);
    // 以上述配置开始观察目标节点
    observe1.observe(el, config);
  }

  @Options({
    components: {
      Toolbar,
      VideoSplitScreen,
      VideoWindow,
      WarnInfoList,
      AddModelWin,
      AddRoamVideo,
      VideoFusionWin,
    },
    props: {},

  })
  export default class EarthComp extends Vue {
    /**
     * 资源创建
     */
    userStore = useUserStore();
    store = useEarthMapStore();

    earthTitle = '态势监控一张图';
    realTime = '……';
    // 注意:Earth和Cesium的相关变量放在vue中,必须使用下划线作为前缀!
    _earth = undefined;
    _earthUI = undefined;
    _viewer = undefined;
    _pin = undefined;
    _handler = undefined;
    //  sceneTree= require('@/assets/earthMap/resjson/sc.json'),
    //   sceneTree= new URL(`@/assets/earthMap/resjson/sc.json`, import.meta.url).href,
    sceneTree: any = sceneTree;
    // areaB= require('@/assets/earthMap/resjson/area_b.json'),
    url: any = {
      queryLabelList: 'military/msMapLabel/queryLabelAndDeviceList',
      queryLineList: 'military/msMapLine/list',
      queryCameraInfo: 'military/camera/site/getCameraInfoForEarth',
      queryAllModelInfo: 'military/msModelPosition/queryAllModelInfo',
      queryPatrolRouteInfo: 'military/msPatrolLine/getLineDetail',
      queryBayoneByParam: 'military/msBayonetStatistics/getBayoneByParam',
      queryAisInfo: 'military/checkpoint/msAisInfo/list',
      keepAlive: 'military/mapInfo/keepAlive',
      //雷达扫描列表
      radarList: '/military/RadarConfig/list',
      // 删除模型
      // 传感器
      deleteSensor: '/military/msModelPosition/deleteByEventSerialNum',
      // 站点
      deleteSite: '/military/camera/site/delete',
      // 标志点
      deleteMapLabel: '/military/msMapLabel/delete',
      updateMapLine: '/military/msMapLine/edit',
      deleteMapLine: '/military/msMapLine/delete',
      saveMapLine: '/military/msMapLine/add',
      // 编辑 模型
      // 传感器
      updateSensor: '/military/msModelPosition/editByEventSerialNum',
      // 站点
      updateSite: '/military/camera/site/edit',

      // 标志点
      updateMapLabel: '/military/msMapLabel/edit',

      // 模型 保存
      // 传感器
      SaveSensorModel: '/military/msModelPosition/add',
      // 站点
      saveCameraSiteModel: '/military/camera/site/add',
      // 标志点
      saveMapLabel: '/military/msMapLabel/addMapLabel',

      // 通过 线路名称 查询 线路
      queryMapLine: '/military/msMapLine/queryByName',
      querySiteById: '/military/camera/site/queryById',
      // 查询设备列表
      queryDeviceInfoList: '/military/msDeviceInfo/list',
      setDefenseArea: '/military/netty/microwaveDetector/defenceArea',
      perimeterRegionList: '/third/api/perimeterRegionList',
      perimeterControl: '/third/api/perimeterControl',
      // 雷达重新发送报警信息
      sendRadarAlarmByWebSocket: '/military/warn/sendRadarAlarmByWebSocket',
    };
    cameraData: any = {};
    cameraModalShow = false;
    poiModalShow = false;
    radioBtnShow = true;
    glmId: any = [];
    spinning = false;
    earthChangeSpin = false;
    websock: any = [];
    timer: any = null; // 保活定时器
    timer2: any = null; // 时间定时器
    // 报警清除-定时器
    alarmTrackClearTimer: any = null;
    videoWindowProps: any = {
      visible: false,
      isAlarm: false,
      id: '',
      title: '',
      videoUrl: '',
      cameraIp: '',
      cameraUser: '',
      cameraPwd: '',
      playRecord: false,
      warnTime: null,
      warnEvent: {
        happenTime: '',
        happenLoc: '',
        warnNum: 0,
        warnLevel: 0,
        warnType: 0,
        warnContent: '',
      },
    };
    // 图层管理- 模型 ref 旧值
    sceneTreeOldRefValue = '';
    sceneInfo: any = null;
    // 区域节点By Ref划分
    nodeConfigByRef = new Map();
    nodeCheckedByRef = new Map();
    areaByNodeId = new Map();
    statusByNodeId = new Map();
    imgByRef = new Map();
    radarAlarmDataMap = new Map();
    wbUnifiedResponse = false;
    hostDeviceMapById = new Map();
    alarmInfoMap = new Map();
    toolbarShow = false;

    //addModelWin
    addModelWinShow = false;
    czmObject: any = null;
    node: any = null;
    type = '';
    lineId = '';
    areaCode = '';
    areaByNodeIdModel = '';
    el: any = null;
    eidtId: any = null;
    //addroamVideo
    addRoamVideoShow = false;

    // 控制窗口显示
    VideoFusionWinShow = false;
    //传到子组件的值
    toItemObj: any = {
      updateModel: {},
      isUpdate: true,
      userSave: {},
    };
    // 节点值
    domKey: any = '';
    // 监控相机列表
    cameraList: any = [];
    // 监控相机位置
    monitorPosition: any = [];
    ///////////////////////////////////////////////////////////////////////////


    mounted() {
      let that = this;
      //随机数
      window.guid = this.guid;
      //创建地球资源
      this.createEarth();
      //获取实时日期时间
      this.getRealTime();
      //初始化websocket
      //  this.initWebSocket('domianURL')
      //阻止浏览器右键事件
      document.oncontextmenu = function (e) {
        return false;
      };

      {
        //将回调延迟到下次 DOM 更新循环之后执行(针对由jq动态增加的元素绑定事件)
        this.$nextTick(() => {
          {
            //监控点击事件
            $('.cameraModal').on('click', '.openIframe', function (e: any) {
              // web插件播放视频流
              let videoWindowProps = that.videoWindowProps;
              videoWindowProps.id = $(this).attr('id');
              videoWindowProps.title = $(this).text();
              videoWindowProps.videoUrl = $(this).attr('videoUrl');
              videoWindowProps.cameraIp = $(this).attr('cameraIP');
              videoWindowProps.cameraUser = $(this).attr('cameraUser');
              videoWindowProps.cameraPwd = $(this).attr('cameraPsd');
              videoWindowProps.isAlarm = false;
              videoWindowProps.visible = true;
              videoWindowProps.playRecord = false;
            });
          }
          // 轮询
          {
            //一个小时调用一次空接口,保持系统session不过期
            this.timer = setInterval(() => {
              this.keepAlive();
            }, 60 * 60 * 1000);

            this.alarmTrackClearTimer = setInterval(() => {
              this.radarAlarmTimeOutCheck();
            }, 6 * 1000);
          }
        });
      }
    }
    // 随机数
    guid() {
      return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
        var r = (Math.random() * 16) | 0,
          v = c == 'x' ? r : (r & 0x3) | 0x8;
        return v.toString(16);
      });
    }
    // 打开视频融合
    roamPathSet() {
      // 打开视频融合
      this.VideoFusionWinShow = true;
      // 关闭相机列表
      this.cameraModalShow = false;
    }

    // 控制子元素的显示或者隐藏
    showOrHideChild(clickNode, earthUI, parentChecked) {
      const childs = clickNode.children;
      if (childs && childs.length > 0) {
        for (const child of childs) {
          const ref = child.ref;
          const inputEl: any = document.getElementById(ref);
          if (inputEl) {
            inputEl.checked = parentChecked;
            const event = new Event('change');
            inputEl.dispatchEvent(event);
          } else {
            if (ref.startsWith('node_')) {
              const readyNode = earthUI.earth.sceneTree.$refs[ref.split('_')[1]];
              if (readyNode && readyNode.czmObject) {
                readyNode.czmObject.show = parentChecked;
              }
            } else if (ref.startsWith('nodeSecondary_')) {
              const readyNode = earthUI.earth.sceneTree.$refs[ref.split('_')[1]];
              if (readyNode && readyNode.czmObject) {
                readyNode.czmObject.show = parentChecked;
                let guid = readyNode.czmObject.pinXbsjGuid;
                let pin = window.$earth.getObject(guid);
                pin.show = !pin.show;
              }
            } else {
              if (child && child.czmObject) {
                child.czmObject.show = parentChecked;
              }
            }
            this.nodeCheckedByRef.set(ref, parentChecked);
            this.showOrHideChild(child, earthUI, parentChecked);
          }
        }
      }
    }
    // 告警模型显示/隐藏
    showAlarmPin(show) {
      this.alarmInfoMap.forEach((item, _index) => {
        item.pin.show = show;
        item.pin._div.hidden = !show;
        item.scanline.show = !show;
      });
    }
    cameraPositionChange = _.debounce(
      (that) => {
        let height = window.$earth.camera.position[2];
        if (height < 100) {
          // 相机高度小于1000米,告警显示扫描线
          that.showAlarmPin(false);
        } else if (height >= 100) {
          // 相机高度大于1000米,告警显示图标
          that.showAlarmPin(true);
        }
      },
      500,
      { maxWait: 1000 }
    );

    createEarth() {
      let that = this;
      XbsjEarthUI.create('earthContainer').then(async (earthUI: any) => {
        // 设置全局变量,可调试
        window.$uia = earthUI;
        window.$earth = earthUI.earth;
        earthUI.controls.mainBar.show = false; //隐藏主工具栏
        earthUI.controls.statusBar.show = true; //状态栏
        //图层管理
        let sceneTree = earthUI.tools.sceneTree;
        // 显示图层管理
        sceneTree.show = true;
        // 设置图层管理 ref 输入框的 回车 事件
        // ref 输入框的
        let sceneTreeInput = sceneTree._comp.$el.getElementsByClassName('xbsj-model-content-box')[0].children[1];
        // 地图右键菜单和ref输入框控制
        this.$nextTick(() => {
          // 删除ref 的 输入框
          sceneTreeInput.remove();
          // ----右键菜单样式控制--start
          // 选择需要观察变动的节点
          const targetNode = document.getElementsByClassName('menu-box')[0];
          // 观察器的配置(需要观察什么变动) 属性,子节点or后代节点
          const config = { attributes: true, childList: false, subtree: false };
          // 当观察到变动时执行的回调函数
          const callback = function (mutationsList, observer) {
            // 右键会弹出菜单的样式 此时可以活的菜单这个元素
            const el = mutationsList[0].target;
            // 菜单的展示属性
            const elDisplay = el.style.display;
            // 如果菜单的展示属性本来就是none 则什么也不做
            if (elDisplay == 'none') {
              return;
            }
            // 获取到菜单项的集合
            const childList = el.children[0].children;
            // 菜单长度
            const liSize = childList.length;
            // 当菜单为none时 不显示
            if (liSize == 0) {
              el.style.display = 'none';
            } else {
              // 长度大于零 但第一个元素是 添加文件夹时也不显示
              const text = childList[0].textContent;
              if ('添加文件夹 ' == text) {
                el.style.display = 'none';
              }
            }
          };
          // 创建一个观察器实例并传入回调函数
          const observer = new MutationObserver(callback);
          // 以上述配置开始观察目标节点
          observer.observe(targetNode, config);
          // -----右键菜单控制----end
        });
        let XE = window.XE;
        // ref 的 输入框
        // 设置 回车 事件
        sceneTreeInput.onkeydown = function (e) {
          if (e.code === 'Enter') {
            // 回车事件
            that.changeRef(earthUI.earth.sceneTree.currentSelectedNode, sceneTree._comp.$data.refvalue, that.sceneTreeOldRefValue);
          }
        };
        // 设置失去焦点事件
        sceneTreeInput.onblur = function () {
          that.changeRef(earthUI.earth.sceneTree.currentSelectedNode, sceneTree._comp.$data.refvalue, that.sceneTreeOldRefValue);
        };
        // 修改图层管理中,右键菜单的显示
        sceneTree._comp.popContextMenu = ({ item, vueObject }) => {
          that.sceneTreePopContextMenu({ item, vueObject }, earthUI);
        };
        earthUI.tools.featureProperty.disabled = true; //禁用对象属性面板

        this._earthUI = earthUI;
        this._earth = earthUI.earth;
        this._earth.interaction.picking.enabled = true; // 全局打开点击事件权限
        this._earth.czm.viewer.scene.globe.depthTestAgainstTerrain = true; //开启深度检测
        this._earth.terrainEffect.subSurfaceEnabled = false; //开启地表透明模式

        this._viewer = earthUI.earth.czm.viewer;
        this._viewer.scene.fxaa = true; //图像改善
        this._viewer.scene.globe.baseColor = Cesium.Color.BLACK;

        //加载场景资源
        //   console.log("this.sceneTree",this.sceneTree);
        // console.log("window._CONFIG['earthMapURL']",window._CONFIG['earthMapURL']);
        // console.log("window._CONFIG['satellite']",window._CONFIG['satellite']);

        this.sceneTree.children[0].czmObject.xbsjImageryProvider.TileMapServiceImageryProvider.url =
          window._CONFIG['earthMapURL'] + window._CONFIG['satellite'];
        this.sceneTree.children[1].czmObject.xbsjImageryProvider.TileMapServiceImageryProvider.url =
          window._CONFIG['earthMapURL'] + window._CONFIG['vector'];
        this.sceneTree.children[2].czmObject.xbsjTerrainProvider.XbsjCesiumTerrainProvider.url =
          window._CONFIG['earthMapURL'] + window._CONFIG['terrain'];
        // this.sceneTree.children.push(this.areaB)

        this._earth.sceneTree.root = {
          expand: true,
          title: '场景树',
          children: [this.sceneTree],
        };
        // 监控相机数据
        XE.MVVM.watch(this._earth.camera, 'position', () => {
          this.cameraPositionChange(this);
        });

        //加载地图实时资源(无人机、车辆、人员、巡逻路线等)
        // this.createRealTimeObj(earthUI)
        //监听鼠标事件
        this.listenMouseHandler(earthUI);

        //监听mitt
        this.listenMittHandler(earthUI);

        // 飞入方法
        await this.fly();

        //加载地图线路资源
        await this.createBBHLine(earthUI);

        //创建工具栏
        this.toolbarShow = true;
      });
    }
    //飞入方法
    async fly() {
      let position, rotation, viewDistance, duration;
      const sceneId = this.userStore.userInfo?.sceneId;
      await defHttp
        .get(
          {
            url: '/military/msMapScene/list',
            params: {
              pageNo: 1,
              pageSize: 999,
              sceneId: sceneId + '*',
              column: 'sceneId',
              order: 'asc',
            },
          },
          { isTransformResponse: false }
        )
        .then((response) => {
          console.log('fly', response);
          // 设置岛屿信息为数组
          this.sceneInfo = response.result.records;
          return response.result.records;
        })
        .then((res) => {
          //飞入 所属场景下的位置
          position = [res[0].cameraLon, res[0].cameraLat, res[0].cameraAltitude];
          rotation = [res[0].rotationX, res[0].rotationY, res[0].rotationZ];
          viewDistance = res[0].viewDistance;
          duration = res[0].duration;
          this._earth.camera.flyTo(position, viewDistance, rotation, duration);
          // 地图复原事件
          window.$flyTo = this.flyTo = () => {
            this._earth.camera.flyTo(position, viewDistance, rotation, duration);
          };
        });
    }

    setLoginPoint(data) {
      let position = [data.lon, data.lat, 0];
      let rotation = [data.rotationX, data.rotationY, data.rotationZ];
      let viewDistance = data.viewDistance;
      let duration = data.duration ? data.duration : 1;
      const leafConfig = {
        name: '岛屿',
        xbsjType: 'Pin',
        // far: 2500000,
        near: 3000000,
        position: position,
        // imageUrl: require('@/assets/redFlag.png'),
        imageUrl: redFlag,
        pinBuilder: {
          extText: data.sceneName,
          extTextFont: '30px 楷体',
          extTextPixelOffset: [30, -40],
          fillColor: [1, 1, 1, 0.9],
          outlineColor: [0, 0, 0, 0.9],
        },
      };

      const pin = new window.XE.Obj.Pin(window.$earth);
      pin.xbsjFromJSON(leafConfig);
      position[2] = data.altitude;
      //鼠标事件
      pin.onmouseover = () => {
        this._viewer._container.style.cursor = 'pointer';
      };
      pin.onmouseout = () => {
        this._viewer._container.style.cursor = 'default';
      };
      pin.onclick = function () {
        this._earth.camera.flyTo(position, viewDistance, rotation, duration);
      };
    }

    //设置按钮颜色状态
    setIconByRef(ref, el) {
      const status = this.statusByNodeId.get(ref);
      if (status != undefined && status != null) {
        let img = this.imgByRef.get(ref);
        const icon = el.children[0].children[2];
        if (!img) {
          img = document.createElement('img');
          this.imgByRef.set(ref, img);
        }
        if (icon.nodeName == 'I') {
          icon.replaceWith(img);
        }
        if (status == 1) {
          img.src = circleDot2;
        } else if (status == 0) {
          img.src = circleDot1;
        } else {
          img.src = circleDot3;
        }
        img.setAttribute('style', 'width:16px;height:16px;margin-top:7px');
      }
    }

    /* 使用async/await 处理异步方法顺序执行。成功的操作放到try里,失败的放在catch里 */
    async createBBHLine(earthUI = null) {
      console.log('MyScene', this.userStore.userInfo?.sceneId);
      let type = 1; //**

      let models: any = {
        ref: this.sceneInfo[0].sceneId,
        expand: true,
        title: this.sceneInfo[0].sceneName,
        children: [],
      };
      for (let record of this.sceneInfo) {
        if (record.sceneId == this.userStore.userInfo?.sceneId) {
          continue;
        }
        models.children.push({
          ref: record.sceneId,
          expand: false,
          title: record.sceneName,
          children: [],
        });
      }

      // console.log('models',models);

      // 加载区域
      // console.log("加载区域");
      await this.getLineInfo(models, type);
      // 加载站点
      // console.log("加载站点");
      await this.getCameraInfo(models, type);
      // 加载雷达和微波
      // console.log("加载雷达和微波");
      const labelItems: any = await this.getLabelInfo(models, type);
      //加载绘画资源
      await drawInit();
      //加载重点监控区域
      await keyControlInit();

      // 监听树的dom节点变化
      // console.log("监听树的dom节点变化");
      this.$nextTick(() => {
        // ----树节点复选框控制--start
        // 容器元素
        const target1 = document.getElementById('earthContainer')?.children[0].children[0].children[4].children[2].children[0].children[0];
        // 配置子元素变动时触发
        const config1 = { attributes: false, childList: true, subtree: false };
        // this的别称
        const that = this;
        // 回调事件
        const callback1 = function (mutationsList, observer) {
          for (const mutation of mutationsList) {
            // 新增元素
            const el = mutation.addedNodes[0];
            // 删除元素时不触发
            if (!el) {
              continue;
            }
            // 样式设置1
            const setClassEl1 = el.children[0].children[1];
            // 样式设置2
            const setClassEl2 = setClassEl1.children[0];

            // 查找input元素
            const inputEl = setClassEl2.querySelector('input');
            // 移除input元素的禁用属性
            inputEl.removeAttribute('disabled');
            const item = el.__vue__.item;
            // item.checkStatus = 'ignored'
            // 从元素中拿到这个元素节点对象
            const nodeObject = item._inner.sn;
            // console.log("nodeObject",nodeObject);

            // 记录ref
            const ref = nodeObject.ref;
            if (ref.startsWith('wbList') || ref.startsWith('ldList')) {
              // 展开菜单图标元素
              const iel = el.children[0].children[0];
              iel.addEventListener('click', function (e) {
                if (iel.className == 'xbsj-icon xbsj-icon-ios-arrow-forward XbsjVritualTreeItemExpandIcon') {
                  console.log('收起菜单');
                  return;
                }
                // 获取展开菜单下的元素并设置图标
                let eventTarget;
                // console.log(nodeObject.children);
                for (let index in nodeObject.children) {
                  if (index === '0') {
                    eventTarget = el.nextElementSibling;
                  } else {
                    eventTarget = eventTarget.nextElementSibling;
                  }
                  const child = nodeObject.children[index];
                  let customProp = JSON.parse(child.czmObject.customProp);
                  if (that.hostDeviceMapById.has(customProp.deviceId)) {
                    let device = that.hostDeviceMapById.get(customProp.deviceId);
                    // 设置状态
                    that.setLabelStatus(device, customProp.labelCode, child.ref, 2);
                  }

                  // 设置图标
                  that.setIconByRef(child.ref, eventTarget);
                }
              });
            }
            if (nodeObject.czmObject && nodeObject.czmObject.xbsjType == 'Pin') {
              that.setIconByRef(ref, el);
            }
            // ref不为空并且大于0时 设置为input的id属性
            if (ref && ref.length > 0) {
              inputEl.id = ref;
            }
            // 首次展开添加元素默认为true,显示展示的对象
            if (that.nodeCheckedByRef.size <= 0) {
              // item.checkStatus = 'checked'
              inputEl.checked = true;
              //***设置样式为选中 */
              setClassChecked(setClassEl1, setClassEl2, item);
              that.nodeCheckedByRef.set(ref, true);
            } else {
              // 之后的展开根据ref获取应该显示的状态是选中还是非选中
              let checked = that.nodeCheckedByRef.get(ref);
              if (checked == undefined) {
                checked = true;
                if (ref && ref.length > 0 && ref.startsWith('node_')) {
                  // 分割ref
                  const refSplit = ref.split('_');
                  // 取出真实对象
                  const readyNode = earthUI.earth.sceneTree.$refs[refSplit[1]];
                  if (readyNode && readyNode.czmObject) {
                    checked = readyNode.czmObject.show;
                  }
                } else {
                  if (nodeObject && nodeObject.czmObject) {
                    checked = nodeObject.czmObject.show;
                  }
                }
                inputEl.checked = checked;
                that.nodeCheckedByRef.set(ref, checked);
                setClassEl(setClassEl, setClassEl2, checked, item);
              } else {
                setClassEl(setClassEl, setClassEl2, checked, item);
              }
            }
            // 显示隐藏样式监听
            classMutationObserver(setClassEl1, setClassEl2, that.nodeCheckedByRef, ref);
            // input disabled属性监听
            disabledMutationObserver(inputEl);
            /**调整触发顺序,阻止默认的input change事件,并绑定自己的change事件 */
            inputEl.addEventListener(
              'change',
              function (e) {
                // 阻止其他同类型事件调用
                e.stopImmediatePropagation();
                // input元素获取
                const el = e.target;
                // 获取ref
                const ref = el.id;
                // 点击元素的earthSdk对象
                const clickNode = earthUI.earth.sceneTree.$refs[ref];
                // 真实的earthSdk对象
                let readyNode: any = null;
                // 当ref大于0,并且以node_开头时,此为虚假的对象
                if (ref && ref.length > 0 && ref.startsWith('node_')) {
                  // 分割ref
                  const refSplit = ref.split('_');
                  // 取出真实对象
                  readyNode = earthUI.earth.sceneTree.$refs[refSplit[1]];
                } else if (ref && ref.length > 0 && ref.startsWith('nodeSecondary_')) {
                  // 分割ref
                  const refSplit = ref.split('_');
                  // 取出真实对象
                  readyNode = earthUI.earth.sceneTree.$refs[refSplit[1]];
                  let guid = readyNode.czmObject.pinXbsjGuid;
                  let pin = window.$earth.getObject(guid);
                  pin.show = !pin.show;
                } else if (ref && ref.length > 0) {
                  // 真实对象就是本身
                  readyNode = clickNode;
                }
                // 控制子节点的状态同步
                that.showOrHideChild(clickNode, earthUI, el.checked);
                if (readyNode != null) {
                  // 隐藏对象
                  if (!el.checked) {
                    if (readyNode && readyNode.czmObject) {
                      readyNode.czmObject.show = false;
                    }
                    // 设置属性
                    setClassNoChecked(setClassEl1, setClassEl2, item);
                  } else {
                    // 显示对象
                    if (readyNode && readyNode.czmObject) {
                      readyNode.czmObject.show = true;
                    }
                    // 设置属性
                    setClassChecked(setClassEl1, setClassEl2, item);
                  }
                  // 设置属性
                  setClassNoChecked(setClassEl1, setClassEl2, item);
                } else {
                  // 显示对象
                  if (readyNode && readyNode.czmObject) {
                    readyNode.czmObject.show = true;
                  }
                  // 设置属性
                  setClassChecked(setClassEl1, setClassEl2, item);
                }
                // 记录当前节点状态
                that.nodeCheckedByRef.set(ref, el.checked);
              },
              true
            );
          }
        };
        // 创建一个观察器实例并传入回调函数
        const observer1 = new MutationObserver(callback1);
        // 以上述配置开始观察目标节点
        observer1.observe(target1, config1);
        // 设置label的鼠标事件
        labelItems.forEach((itemId) => {
          if (window.$earth.sceneTree.$refs[itemId]) {
            window.$earth.sceneTree.$refs[itemId].czmObject.onmouseover = () => {
              this._viewer._container.style.cursor = 'pointer';
            };
            window.$earth.sceneTree.$refs[itemId].czmObject.onmouseout = () => {
              this._viewer._container.style.cursor = 'default';
            };
          }
        });
      });
      // 隐藏图层管理 "地图场景" 一栏
      // document.getElementsByClassName('XbsjVritualTreeItem').item(0).style.display = 'none'
      this._earth.sceneTree.root.children.splice(1, 0, models);
    }

    async createRealTimeObj(earthUI = null) {
      let that = this;
      let models = {
        expand: true,
        title: '地图实况',
        children: [
          {
            expand: false,
            title: '巡逻路线',
            children: [],
          },
          {
            expand: false,
            title: '执勤巡逻',
            children: [],
          },
          {
            expand: false,
            title: '预警/报警',
            children: [],
          },
          {
            expand: false,
            title: 'AIS',
            children: [],
          },
        ],
      };
      try {
        await this.getAllModelInfo(models);
        await this.getPatrolRouteInfo(models);
        //添加对象到场景树
        // this._earth.sceneTree.root.children.push(models);
        this._earth.sceneTree.root.children.splice(1, 0, models);
      } catch (e) {
        console.log(e);
      }
    }

    //加载区域
    getLineInfo(models, type) {
      const that = this;
      return new Promise((resolve, reject) => {
        //请求线路信息
        defHttp
          .get(
            {
              url: this.url.queryLineList,
              params: {
                pageNo: 1,
                pageSize: 99999,
                sceneId: this.userStore.userInfo?.sceneId + '*',
              },
            },
            { isTransformResponse: false }
          )
          .then(async (res) => {
            // console.log('加载区域',res);

            if (res.success) {
              //一级区域
              let parentArea: any = [];
              //二级区域
              let childArea: any = [];
              res.result.records.forEach((data) => {
                if (data.parentCode) {
                  childArea.push(data);
                } else {
                  parentArea.push(data);
                }
              });
              parentArea.forEach((data) => {
                // console.log(data);

                // data.sceneId
                let updatedPositions: any = [];
                let positionsData = JSON.parse(data.positions);
                if (!positionsData) {
                  positionsData = [];
                }
                updatedPositions = positionsData;

                let lineOptions: any = {
                  maxShowHeight: 30000,
                  customProp: data.lineCode,
                };
                lineOptions.name = data.name;
                lineOptions.xbsjType = 'Polyline';
                lineOptions.width = data.width;
                lineOptions.positions = updatedPositions;
                lineOptions.loop = Boolean(data.isLoop);
                lineOptions.depthTest = Boolean(data.isDepthCheck);
                lineOptions.arcType = data.interpolation;
                let material: any = {};
                switch (data.materialType) {
                  // 实线
                  case 0:
                    material.type = 'XbsjColorMaterial';
                    material.XbsjColorMaterial = {};
                    if (!data.color || data.color.length <= 0) {
                      data.color = '[1,1,1,1]';
                    }
                    material.XbsjColorMaterial.color = JSON.parse(data.color);
                    break;
                  // 虚线
                  case 1:
                    material.type = 'XbsjPolylineDashMaterial';
                    material.XbsjPolylineDashMaterial = {};
                    material.XbsjPolylineDashMaterial.color = JSON.parse(data.color);
                    material.XbsjPolylineDashMaterial.gapColor = JSON.parse(data.intervalColor);
                    material.XbsjPolylineDashMaterial.dashLength = data.dashLength;
                    material.XbsjPolylineDashMaterial.dashPattern = data.dashStyle;
                    break;
                  // 箭头线
                  case 2:
                    material.type = 'XbsjPolylineArrowMaterial';
                    material.XbsjPolylineArrowMaterial = {};
                    material.XbsjPolylineArrowMaterial.color = JSON.parse(data.color);
                    break;
                  // 轨迹线
                  case 3:
                    material.type = 'XbsjODLineMaterial';
                    material.XbsjODLineMaterial = {};
                    material.XbsjODLineMaterial.color = JSON.parse(data.color);
                    material.XbsjODLineMaterial.totoalFrameCount = data.cycleFrame;
                    break;
                }
                lineOptions.material = material;
                let currentChildArea: any = [];
                if (childArea.length) {
                  childArea.forEach((element) => {
                    let obj = {};
                    if (data.id == element.parentCode) {
                      obj = {
                        expand: false,
                        title: element.name,
                        ref: 'nodeSecondary_' + element.id,
                        children: [],
                      };
                      let updatedPositions: any = [];
                      let positionsData = JSON.parse(element.positions);
                      if (!positionsData) {
                        positionsData = [];
                      }
                      updatedPositions = positionsData;
                      let lineOptions: any = {
                        maxShowHeight: 30000,
                        customProp: element.lineCode,
                      };
                      lineOptions.name = element.name;
                      lineOptions.xbsjType = 'Polyline';
                      lineOptions.width = element.width;
                      lineOptions.positions = updatedPositions;
                      lineOptions.loop = Boolean(element.isLoop);
                      lineOptions.depthTest = Boolean(element.isDepthCheck);
                      lineOptions.arcType = element.interpolation;
                      let material: any = {};
                      switch (element.materialType) {
                        // 实线
                        case 0:
                          material.type = 'XbsjColorMaterial';
                          material.XbsjColorMaterial = {};
                          if (!element.color || element.color.length <= 0) {
                            element.color = '[1,1,1,1]';
                          }
                          material.XbsjColorMaterial.color = JSON.parse(element.color);
                          break;
                        // 虚线
                        case 1:
                          material.type = 'XbsjPolylineDashMaterial';
                          material.XbsjPolylineDashMaterial = {};
                          material.XbsjPolylineDashMaterial.color = JSON.parse(element.color);
                          material.XbsjPolylineDashMaterial.gapColor = JSON.parse(element.intervalColor);
                          material.XbsjPolylineDashMaterial.dashLength = element.dashLength;
                          material.XbsjPolylineDashMaterial.dashPattern = element.dashStyle;
                          break;
                        // 箭头线
                        case 2:
                          material.type = 'XbsjPolylineArrowMaterial';
                          material.XbsjPolylineArrowMaterial = {};
                          material.XbsjPolylineArrowMaterial.color = JSON.parse(element.color);
                          break;
                        // 轨迹线
                        case 3:
                          material.type = 'XbsjODLineMaterial';
                          material.XbsjODLineMaterial = {};
                          material.XbsjODLineMaterial.color = JSON.parse(element.color);
                          material.XbsjODLineMaterial.totoalFrameCount = element.cycleFrame;
                          break;
                      }

                      let pos = [0, 0, 0];
                      positionsData.forEach((element) => {
                        pos[0] += element[0];
                        pos[1] += element[1];
                        pos[2] += element[2];
                      });
                      pos[0] = pos[0] / positionsData.length;
                      pos[1] = pos[1] / positionsData.length;
                      pos[2] = pos[2] / positionsData.length;
                      let pinBuilder = {
                        extTextFont: '30px 宋体',
                        extTextPixelOffset: [-40, 10],
                        fillColor: [0, 0.3450980392156863, 1, 0.9],
                        outlineColor: [1, 1, 1, 1],
                        extText: element.name,
                      };
                      let pin = addPin(element.name, hidePng, { position: pos, scale: 0.8, pinBuilder, far: 107374 });
                      lineOptions.pinXbsjGuid = pin.xbsjGuid;
                      lineOptions.material = material;
                      that._earth.sceneTree.root.children.push({ czmObject: lineOptions, ref: element.id });
                      currentChildArea.push(obj);
                      // 如果是总部
                      if (type == 1) {
                        this.nodeConfigByRef.set('nodeSecondary_' + element.id, obj);
                      }
                    }
                  });
                }

                //配置信息
                const node = {
                  ref: 'node_' + data.id,
                  expand: false,
                  title: '<防区>' + data.name,
                  children: [
                    {
                      expand: false,
                      title: '监控点位',
                      ref: 'monitor_' + window.guid(),
                      children: [],
                    },
                    {
                      expand: false,
                      title: '雷达点位',
                      ref: 'ldList_' + window.guid(),
                      children: currentChildArea,
                    },
                    {
                      expand: false,
                      title: '微波点位',
                      ref: 'wbList_' + window.guid(),
                      children: [],
                    },
                  ],
                };
                if (data.sceneId == models.ref) {
                  // console.log("当前场景下");

                  //该防区为当前场景下
                  //压入树
                  models.children.push(node);
                  this.nodeConfigByRef.set(node.ref, node);
                  this.areaByNodeId.set(node.ref, data.sceneId);
                  // return
                } else {
                  const childs = models.children;
                  for (const child of childs) {
                    if (child.ref == data.sceneId) {
                      //该防区为子场景下
                      // console.log("子场景下");
                      child.children.push(node);
                      this.nodeConfigByRef.set(node.ref, node);
                      this.areaByNodeId.set(node.ref, data.sceneId);
                    }
                  }
                }
                //放进世界场景树
                that._earth.sceneTree.root.children.push({ czmObject: lineOptions, ref: data.id });
              });
              //加载二级区域模型
              childArea.forEach((data) => {});
              this.$nextTick(() => {
                const divs = $('#earthContainer>div>div>div:nth-child(5)')
                  .children('div')
                  .eq(1)
                  .children()
                  .eq(0)
                  .children()
                  .eq(0)
                  .children()
                  .each((index, element) => {
                    // const paddingLeft = $(element).children().eq(0).css('padding-left')
                    $(element).css('display', 'none');
                  });
              });
              // console.log("models",models);
              resolve(models);
            }
          });
      });
    }
    //加载相机
    getCameraInfo(models, type) {
      return new Promise((resolve, reject) => {
        //请求电线杆信息
        defHttp.get({ url: this.url.queryCameraInfo }, { isTransformResponse: false }).then(async (res) => {
          if (res.success) {
            // console.log("res",res);
            this.setCamera(res.result, models, type);
            this.cameraData = res.result;
            resolve(models);
          }
        });
      });
    }
    async setCamera(res, models, type) {
      //根据经纬度算出该点地形高度
      let posArr: any = [],
        updatedPositions: any = [];
      const that = this;
      //地形是否开启
      if (window.$earth.sceneTree.$refs.terrain.czmObject.show) {
        res.forEach((data, index) => {
          if (data.msCameraSiteList != null) {
            data.msCameraSiteList.forEach((data, index) => {
              posArr.push(window.Cesium.Cartographic.fromDegrees(data.longitude, data.latitude));
            });
          }
        });
        var promise = window.Cesium.sampleTerrainMostDetailed(this._viewer.terrainProvider, posArr);
        updatedPositions = await window.Cesium.when(promise);
      } else {
        res.forEach((data, index) => {
          if (data.msCameraSiteList != null) {
            data.msCameraSiteList.forEach((data, index) => {
              updatedPositions.push(window.Cesium.Cartographic.fromDegrees(data.longitude, data.latitude, 0));
            });
          }
        });
      }
      // console.log("根据经纬度算出该点地形高度",res);
      // console.log("根据经纬度算出该点地形高度",updatedPositions);

      //设置电线杆
      res.forEach((data, index) => {
        // console.log("data",data);

        let siteConfig: any = null;
        const lineId = data.id;
        let childs: any = null;
        if (type == 2) {
          childs = models.children;
          for (const child of childs) {
            if ('node_' + data.id == child.ref) {
              siteConfig = child.children[0];
            }
          }
        } else {
          const parentNode = that.nodeConfigByRef.get('node_' + data.id);
          if (!parentNode) {
            return;
          }
          childs = parentNode.children;
          siteConfig = childs[0];
          // console.log("parentNode",parentNode);
        }
        if (!siteConfig) {
          return;
        }
        if (data.msCameraSiteList != null) {
          data.msCameraSiteList.forEach((data, index) => {
            // 判断电线杆状态
            let num = 0;
            if (data.msCameraSettingList != null) {
              data.msCameraSettingList.forEach((data, index) => {
                if (data.status == '3') {
                  //1-在线,2-离线,3-异常
                  num = num + 1;
                }
              });
            }
            let gltfStr;
            if (!data.modelUrl) {
              return;
            }
            let fileInfos = data.modelUrl.split('.');
            if (num == 0) {
              // gltfStr = window._CONFIG['domianURL'] + '/sys/common/static/' + fileInfos[0] + '.' + fileInfos[1];
              gltfStr = '/dt/sys/common/static/' + fileInfos[0] + '.' + fileInfos[1];
            } else if (num < data.msCameraSettingList.length) {
              let newName = fileInfos[0].substring(0, fileInfos[0].length - 1) + 'R';
              // gltfStr = window._CONFIG['domianURL'] + '/sys/common/static/' + newName + '.' + fileInfos[1];
              gltfStr = '/dt/sys/common/static/' + newName + '.' + fileInfos[1];
            } else if (num == data.msCameraSettingList.length) {
              let newName = fileInfos[0].substring(0, fileInfos[0].length - 1) + 'Y';
              // gltfStr = window._CONFIG['domianURL'] + '/sys/common/static/' + newName + '.' + fileInfos[1];
              gltfStr = '/dt/sys/common/static/' + newName + '.' + fileInfos[1];
            }
            const modelConfig = {
              ref: data.id,
              name: lineId,
              czmObject: {
                name: data.sitename,
                xbsjType: 'Model',
                url: gltfStr,
                // "color": [0.52, 0.6, 0.58, 1],
                minimumPixelSize: data.minimumPixelSize,
                // maximumScale: 0.02,
                scale: data.scale,
                xbsjScale: data.xyzScale ? data.xyzScale.split(',') : [1, 1, 1],
                xbsjPosition: [window.Cesium.Math.toRadians(data.longitude), window.Cesium.Math.toRadians(data.latitude), data.height],
                xbsjRotation: [
                  window.Cesium.Math.toRadians(data.yaw),
                  window.Cesium.Math.toRadians(data.pitch),
                  window.Cesium.Math.toRadians(data.roll),
                ],
                viewDistance: 150,
                distanceDisplayCondition: [1.0, 30000.0],
                customProp: data.id,
              },
            };

            window.$earth.sceneTree.root.children.push(modelConfig);
            //鼠标事件
            window.$earth.sceneTree.$refs[data.id].czmObject.onmouseover = () => {
              this._viewer._container.style.cursor = 'pointer';
            };
            window.$earth.sceneTree.$refs[data.id].czmObject.onmouseout = () => {
              this._viewer._container.style.cursor = 'default';
            };

            this.$nextTick(() => {
              const divs = $('#earthContainer>div>div>div:nth-child(5)')
                .children('div')
                .eq(1)
                .children()
                .eq(0)
                .children()
                .eq(0)
                .children()
                .each((index, element) => {
                  $(element).css('display', 'none');
                });
            });
            //加载相机
            let cameraList: any = [];
            if (data.msCameraSettingList) {
              for (let camera of data.msCameraSettingList) {
                let name = camera.cameraName;
                const obj = {
                  ref: 'camera_' + camera.id,
                  expand: false,
                  title: name,
                  czmObject: {
                    name: name,
                    xbsjType: 'Model',
                  },
                };
                // let id = camera.id
                cameraList.push(obj);
                // 默认设置为在线
              }
            }
            // 杆
            const node = {
              ref: 'node_' + data.id,
              title: data.sitename,
              expand: false,
              children: cameraList,
            };
            siteConfig.children.push(node);
          });
        }
      });
    }

    // 加载雷达和微波
    async getLabelInfo(models, type) {
      return new Promise((resolve, reject) => {
        //请求地图标志信息
        defHttp.get({ url: this.url.queryLabelList }, { isTransformResponse: false }).then(async (res) => {
          // console.log("请求地图标志信息",res);

          if (res.success) {
            const labelItems = await this.setLabel(res.result, models, type);
            resolve(labelItems);
          }
        });
      });
    }
    //地图标志信息
    async setLabel(res, models, type) {
      // console.log("res",res);
      const that = this;
      const args = { pageNo: 1, pageSize: 999 };
      await defHttp
        .get(
          {
            url: this.url.queryDeviceInfoList,
            params: args,
          },
          { isTransformResponse: false }
        )
        .then((reponse) => {
          if (reponse.success) {
            // console.log("queryDeviceInfoList",reponse);
            const hostDeviceList = reponse.result.records;
            for (const hostDevice of hostDeviceList) {
              that.hostDeviceMapById.set(hostDevice.id, hostDevice);
            }
            return that.hostDeviceMapById;
          } else {
            console.error('获取主机信息错误', reponse);
          }
        })
        .catch(() => {
          throw '获取主机信息错误';
        });
      //根据经纬度算出该点地形高度
      let posArr: any = [],
        updatedPositions: any = [];
      res.forEach((data, index) => {
        updatedPositions.push(window.Cesium.Cartographic.fromDegrees(data.mapLabel.labelLon, data.mapLabel.labelLat, data.mapLabel.labelHeight));
      });
      const labelItems: any = [];
      //设置标志
      res.forEach((data, index) => {
        const item: any = data.mapLabel;
        labelItems.push(item.id);
        const objConfig3 = {
          ref: item.id,
          name: item.lineId,
          czmObject: {
            customProp: '{"labelAttr":' + item.labelAttr + ',"labelCode":"' + item.labelCode + '","deviceId":"' + data.deviceId + '"}',
            name: item.labelName,
            xbsjType: 'Pin',
            imageUrl: window._CONFIG['staticDomainURL'] + '/' + item.labelImgUrl,
            position: [updatedPositions[index].longitude, updatedPositions[index].latitude, Number(item.labelHeight)],
            scale: item.labelAttr == 4 ? 1 : 0.7,
            pinBuilder: {
              extText: item.labelName,
              extTextFont: '30px 楷体',
              extTextPixelOffset: item.labelAttr == 4 ? [30, -20] : [15, -20],
              fillColor: [1, 1, 1, 0.9],
              outlineColor: [0, 0, 0, 0.9],
            },
            far: 25000,
          },
        };
        if (item.labelAttr == 4) {
          // console.log("雷达",item);
          that.statusByNodeId.set(item.id, 1);
          that.addLabelNodeToTree(item, models, objConfig3, type);
        } else {
          // console.log("微波",item);
          that.statusByNodeId.set(item.id, -10);
          that.addLabelNodeToTree(item, models, objConfig3, type);
          const device = that.hostDeviceMapById.get(data.deviceId);
          if (device) {
            //参数3 2为查询状态
            that.setLabelStatus(device, item.labelCode, item.id, 2);
          }
        }
      });
      return labelItems;
    }

    addLabelNodeToTree(item, models, objConfig3, type) {
      const that = this;
      //微波
      if (item.labelAttr == 10) {
        if (type == 2) {
          let childs1 = models.children;
          for (const child of childs1) {
            if ('node_' + item.lineId == child.ref) {
              child.children[2].children.push(objConfig3);
            }
          }
        } else {
          const parentNode = that.nodeConfigByRef.get('node_' + item.lineId);
          if (!parentNode) {
            return;
          }
          let childs2 = parentNode.children;
          childs2[2].children.push(objConfig3);
        }
      }
      //雷达
      else if (item.labelAttr == 4) {
        if (type == 2) {
          let childs1 = models.children;
          for (const child of childs1) {
            if ('node_' + item.lineId == child.ref) {
              child.children[1].children.push(objConfig3);
            }
          }
        } else {
          const parentNode = that.nodeConfigByRef.get('node_' + item.lineId);
          if (!parentNode) {
            return;
          }
          let childs2 = parentNode.children;
          childs2[1].children.push(objConfig3);
        }
      }
      //雷达(已弃用)
      else if (item.labelAttr == 4) {
        console.log('leida');

        if (type == 2) {
          let childs3 = models.children;
          for (const child of childs3) {
            for (const element of child.children[1].children) {
              if ('nodeSecondary_' + item.lineId == element.ref) {
                element.children.push(objConfig3);
              }
            }
          }
        } else {
          const parentNode1 = that.nodeConfigByRef.get('nodeSecondary_' + item.lineId);
          // console.log("nodeSecondary_",parentNode1);
          if (!parentNode1) {
            return;
          }
          const childs4 = parentNode1.children;
          childs4.push(objConfig3);
        }
      }
    }

    setLabelStatus(device, labelCode, id, code) {
      const args = {
        device: device,
        code: code, // 命令码:0-撤防 1-布防 2-状态查询 3-其他预留
        deviceType: 2, // 设备类型:1-探测主机 2-探测器 3-串口设备 4-预留
        deviceSn: labelCode, // 设备条码
      };
      // console.log("device",device);

      if (device.deviceType_dictText.indexOf('微波探测器') > -1) {
        // console.log("微波探测器");

        return (
          defHttp
            .post({ url: '/military/netty/microwaveDetector/maintenance', params: args }, { isTransformResponse: false })
            // postAction('netty/microwaveDetector/maintenance', args)
            .then((response) => {
              // console.log('response',response);

              if (response.success) {
                const status = response;
                this.statusByNodeId.set(id, status);
              } else {
                this.statusByNodeId.set(id, -10);
              }
              return response;
            })
            .catch((error) => {
              // console.log('error',error);
              this.statusByNodeId.set(id, -10);
              return error;
            })
        );
      } else if (device.deviceType_dictText.indexOf('雷达') > -1) {
        this.statusByNodeId.set(id, 1);
        //雷达周界防区列表
        return defHttp
          .get({ url: this.url.perimeterRegionList, params: { regionType: 2 } }, { isTransformResponse: false })
          .then(
            (res) => {
              // console.log(res);
              if (res.success) {
                // (未测试)
                res.result.forEach((element) => {
                  if (element.id == id) {
                    // this.statusByNodeId.set(id, element.isOnline)
                  }
                });
              } else {
                this.statusByNodeId.set(id, 1);
              }
              return res;
            },
            (err) => {
              this.statusByNodeId.set(id, 1);
              return err;
            }
          )
          .catch((err) => {
            this.statusByNodeId.set(id, 1);
            return err;
          });
      }
    }

    getAllModelInfo(models) {
      return new Promise((resolve, reject) => {
        //模型位置

        defHttp.get({ url: this.url.queryAllModelInfo }, { isTransformResponse: false }).then(async (res) => {
          if (res.success) {
            res.result.forEach((data, index) => {
              let childrenConfig: any = {},
                objConfig: any = {},
                pathConfig: any = {},
                viewshedConfig: any = {},
                pinConfig: any = {};
              let positions: any = [],
                rotations: any = [];
              switch (data.modelType) {
                case 1: //无人机
                  childrenConfig = {
                    expand: false,
                    title: '无人机_' + (index + 1) + '号',
                    children: [],
                  };
                  objConfig = {
                    ref: data.eventSerialNum,
                    czmObject: {
                      name: '无人机',
                      xbsjType: 'Model',
                      url: window._CONFIG['staticDomainURL'] + '/uav.gltf',
                      minimumPixelSize: 1000,
                      maximumScale: 20,
                      xbsjPosition: earthUtils.degreeToRadianInLngLatHeight(data.lon, data.lat, data.height),
                      distanceDisplayCondition: [10.0, 25000.0],
                    },
                  };
                  childrenConfig.children.push(objConfig);
                  // 加载视域
                  viewshedConfig = {
                    ref: 'viewshed_' + data.eventSerialNum,
                    czmObject: {
                      xbsjType: 'Viewshed',
                      name: '视域',
                      position: earthUtils.degreeToRadianInLngLatHeight(data.lon, data.lat, data.height),
                      rotation: earthUtils.degreeToRadianInLngLatHeight(data.yaw, data.pitch, data.roll),
                      near: 1.0,
                      far: 1500,
                      enabled: false,
                      show: false,
                    },
                  };
                  childrenConfig.children.push(viewshedConfig);
                  //加载历史轨迹
                  data.msModelTrajectoryList.forEach((data, index) => {
                    positions.push(earthUtils.degreeToRadianInLngLatHeight(data.lon, data.lat, data.height));
                    rotations.push(earthUtils.degreeToRadianInLngLatHeight(data.yaw, data.pitch, data.roll));
                  });
                  pathConfig = {
                    ref: 'path_' + data.eventSerialNum,
                    czmObject: {
                      xbsjType: 'Path',
                      name: '轨迹',
                      positions: positions,
                      rotations: rotations,
                      enabled: false,
                      show: true,
                      loop: false,
                      showDirection: false,
                      playing: true,
                      loopPlay: true,
                      alwaysAlongThePath: true,
                      currentSpeed: 30,
                    },
                  };
                  childrenConfig.children.push(pathConfig);
                  /* // 显示当前坐标
                    pinConfig = {
                      "ref": "pin_" + data.eventSerialNum,
                      "czmObject": {
                        "xbsjType": "Pin",
                        "name": "当前位置",
                        "position": earthUtils.degreeToRadianInLngLatHeight(data.lon, data.lat, data.height),
                        "evalString": "const width = 430;\nconst height = 70;\nfunction createLabelCanvas(p) {\n  if (p._labelDiv) {\n    p._earth.czm.viewer.container.removeChild(p._labelDiv);\n    p._labelDiv = undefined;\n  }\n  const labelDiv = document.createElement('div');\n  labelDiv.style = 'width:'+width+'px;height: '+height+'px;position: absolute; pointer-events: none;'\n\n  p._earth.czm.viewer.container.appendChild(labelDiv);\n  p._labelDiv = labelDiv;\n\n  var dis = XE.MVVM.watch(() => {\n    labelDiv.style.display = p.enabled ? 'block' : 'none';\n  });\n\n  p.disposers.push(() => {\n    if (p._labelDiv) {\n      p._earth.czm.viewer.container.removeChild(p._labelDiv);\n      p._labelDiv = undefined;\n    }\n    dis();\n  });\n\n  const labelCanvas = document.createElement('canvas');\n  labelCanvas.style = 'width: 100%;height: 100%;';\n\n  labelCanvas.width = width;\n  labelCanvas.height = height;\n  labelDiv.appendChild(labelCanvas);\n  return labelCanvas;\n}\n\nfunction createDrawFunc(p) {\n  const labelCanvas = createLabelCanvas(p);\n  const ctx = labelCanvas.getContext('2d');\n\n  function draw(w) {\n    ctx.clearRect(0, 0, width, height);\n\n    ctx.save();\n    ctx.lineWidth = 2;\n    ctx.strokeStyle = 'rgb(31, 255,255)';\n    ctx.beginPath();\n    ctx.moveTo(width, height);\n    ctx.lineTo(width-height, 22);\n    ctx.lineTo(0, 22);\n    ctx.stroke();\n    ctx.restore();\n    ctx.font = \"15px console\"; \n    ctx.fillStyle = 'rgb(255, 255, 0)';\n    ctx.fillText('" +
                          "经度:" + data.lon + "/" + "纬度:" + data.lat + "/" + "高度:" + data.height + "', 0, 20);\n    ctx.restore();\n  }\n\n  p._dDraw = draw;\n}\n\ncreateDrawFunc(p);\n\nlet d = 0;\nlet c = 0;\np._dDraw(c);\nconst preUpdateListener = p._earth.czm.scene.preUpdate.addEventListener(() => {\n  if (d !== c) {\n    c += (d - c) * 0.1;\n    if (Math.abs(c - d) < 0.1) {\n      c = d;\n    }\n    p._dDraw(c);\n  }\n});\np.disposers.push(() => preUpdateListener && preUpdateListener());\n\nconst container = p._earth.czm.viewer.container;\nconst unwatch = XE.MVVM.watch(() => [...p.winPos], winPos => {\n  if (p._labelDiv) {\n    p._labelDiv.style.left = (winPos[0] -  p._labelDiv.clientWidth) + 'px';\n    p._labelDiv.style.bottom = winPos[3]+'px';\n  } \n});\np.disposers.push(() => {\n  unwatch && unwatch();\n});",
                        "isDivImage": true,
                        "pinBuilder": {},
                        "far": 25000
                      }
                    };
                    childrenConfig.children.push(pinConfig); */
                  //加入树
                  models.children[1].children.push(childrenConfig);
                  break;
                case 2: //执勤人员
                  childrenConfig = {
                    expand: false,
                    title: '执勤人员_' + (index + 1) + '号',
                    children: [],
                  };
                  objConfig = {
                    ref: data.eventSerialNum,
                    czmObject: {
                      xbsjType: 'GroundImage',
                      name: '执勤人员',
                      playing: true,
                      width: 90,
                      height: 90,
                      position: earthUtils.degreeToRadianInLngLatHeight(data.lon, data.lat, 0),
                      imageUrls: [window._CONFIG['staticDomainURL'] + '/xunluo_point1.png', window._CONFIG['staticDomainURL'] + '/xunluo_point2.png'],
                    },
                  };
                  childrenConfig.children.push(objConfig);
                  //加载历史轨迹
                  data.msModelTrajectoryList.forEach((data, index) => {
                    positions.push(earthUtils.degreeToRadianInLngLatHeight(data.lon, data.lat, data.height));
                    rotations.push(earthUtils.degreeToRadianInLngLatHeight(data.yaw, data.pitch, data.roll));
                  });
                  pathConfig = {
                    ref: 'path_' + data.eventSerialNum,
                    czmObject: {
                      xbsjType: 'Path',
                      name: '轨迹',
                      positions: positions,
                      rotations: rotations,
                      enabled: false,
                      show: true,
                      loop: false,
                      showDirection: false,
                      playing: true,
                      loopPlay: true,
                      alwaysAlongThePath: true,
                      currentSpeed: 30,
                    },
                  };
                  childrenConfig.children.push(pathConfig);
                  //加入树
                  models.children[1].children.push(childrenConfig);
                  break;
                case 3: //可疑人员
                  childrenConfig = {
                    expand: false,
                    title: '可疑人员_' + (index + 1) + '号',
                    children: [],
                  };
                  objConfig = {
                    ref: data.eventSerialNum,
                    czmObject: {
                      xbsjType: 'GroundImage',
                      name: '可疑人员',
                      playing: true,
                      width: 90,
                      height: 90,
                      position: earthUtils.degreeToRadianInLngLatHeight(data.lon, data.lat, 0),
                      imageUrls: [window._CONFIG['staticDomainURL'] + '/keyi_point1.png', window._CONFIG['staticDomainURL'] + '/keyi_point2.png'],
                    },
                  };
                  childrenConfig.children.push(objConfig);
                  //加载历史轨迹
                  data.msModelTrajectoryList.forEach((data, index) => {
                    positions.push(earthUtils.degreeToRadianInLngLatHeight(data.lon, data.lat, data.height));
                    rotations.push(earthUtils.degreeToRadianInLngLatHeight(data.yaw, data.pitch, data.roll));
                  });
                  pathConfig = {
                    ref: 'path_' + data.eventSerialNum,
                    czmObject: {
                      xbsjType: 'Path',
                      name: '轨迹',
                      positions: positions,
                      rotations: rotations,
                      enabled: false,
                      show: true,
                      loop: false,
                      showDirection: false,
                      playing: true,
                      loopPlay: true,
                      alwaysAlongThePath: true,
                      currentSpeed: 30,
                    },
                  };
                  childrenConfig.children.push(pathConfig);
                  //加入树
                  models.children[2].children.push(childrenConfig);
                  break;
                case 11: //传感器
                  objConfig = {
                    ref: data.eventSerialNum,
                    czmObject: {
                      name: data.eventSerialNum,
                      xbsjType: 'Model',
                      url: window._CONFIG['staticDomainURL'] + '/zalan.gltf',
                      minimumPixelSize: 1000,
                      maximumScale: 0.01,
                      // xbsjPosition: [window.Cesium.Math.toRadians(data.lon), window.Cesium.Math.toRadians(data.lat), data.height],
                      xbsjPosition: earthUtils.degreeToRadianInLngLatHeight(data.lon, data.lat, data.height),
                      xbsjRotation: earthUtils.degreeToRadianInLngLatHeight(data.yaw, data.pitch, data.roll),
                      distanceDisplayCondition: [10.0, 25000.0],
                      customProp: data.eventSerialNum,
                      color: [0.08235294117647059, 1, 0, 1],
                      luminanceAtZenith: 2,
                    },
                  };
                  //加入树
                  models.children[0].children[0].children.push(objConfig);
                  break;
                default:
              }
            });
            resolve(models);
          }
        });
      });
    }

    getPatrolRouteInfo(models) {
      return new Promise((resolve, reject) => {
        //执勤巡逻路线
        defHttp.get({ url: this.url.queryPatrolRouteInfo }, { isTransformResponse: false }).then(async (res) => {
          if (res.success) {
            res.result.forEach((data, index) => {
              //将路线上的点拼成坐标数组
              let positions: any = [];
              data.msLineConstList.forEach((data, index) => {
                positions.push(earthUtils.degreeToRadianInLngLatHeight(data.lon, data.lat, data.height));
              });
              const objConfig = {
                ref: data.lineCode,
                czmObject: {
                  name: data.lineName,
                  xbsjType: 'Polyline',
                  width: 2,
                  material: {
                    type: 'XbsjODLineMaterial',
                    XbsjODLineMaterial: {
                      bgColor: [0.5, 0.5, 0.5, 1],
                      color: [0, 1, 0.11, 1],
                      totoalFrameCount: 200,
                    },
                  },
                  positions: positions,
                },
              };
              models.children[0].children.push(objConfig);
            });
            resolve(models);
          }
        });
      });
    }

    listenMouseHandler(earthUI = null) {
      let that: any = this;
      this._handler = new window.Cesium.ScreenSpaceEventHandler(this._viewer.scene.canvas);

      //取消双击旋转事件
      this._viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(window.Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
      /* MOUSE事件(有性能问题,慎用!) */

      /* 鼠标左键事件 */
      {
        this._handler.setInputAction((click: any) => {
          if (typeof this._pin !== 'undefined') {
            // 销毁指示线
            this._pin.destroy();
          }

          let pickedFeature = this._viewer.scene.pick(click.position);
          if (pickedFeature && pickedFeature.id) {
            if (pickedFeature.id.xbsjType && pickedFeature.id.xbsjType === 'Model') {
              //点击电线杆触发弹窗
              this.cameraData.forEach((data) => {
                if (!$.isEmptyObject(data.msCameraSiteList)) {
                  if (!data.msCameraSiteList) {
                    return;
                  }
                  data.msCameraSiteList.forEach((data) => {
                    if (pickedFeature.id.customProp === data.id) {
                      if ($('.cameraModal ul').length > 0) {
                        $('.cameraModal ul').remove();
                      }
                      $('.cameraModal').append('<ul></ul>');
                      if (!data.msCameraSettingList) return;
                      // 将监控相机列表传入弹窗组件中
                      this.cameraList = data.msCameraSettingList;
                      // 将监控点位置传入弹窗组件中
                      this.monitorPosition = pickedFeature.id._primitive.xbsjPosition;
                      data.msCameraSettingList.forEach((data, index) => {
                        let camera_img =
                          data.type == '4'
                            ? window._CONFIG['staticDomainURL'] + '/qiuji.png'
                            : data.type == '3'
                            ? window._CONFIG['staticDomainURL'] + '/qiangji.png'
                            : window._CONFIG['staticDomainURL'] + '/qiangji.png';
                        let cameraStatus = data.status == '1' ? 'successStatus' : data.status == '2' ? 'offlineStatus' : 'errorStatus';
                        let rtspUrl = data.cameraCode;
                        // 'rtsp://' + data.user + ':' + data.password + '@' + data.ip + window._CONFIG['cameraMain']
                        $('.cameraModal ul').append(
                          '<li><a class="openIframe" id="' +
                            data.id +
                            '" videoUrl="' +
                            rtspUrl +
                            '" cameraIP="' +
                            data.ip +
                            '" cameraUser="' +
                            data.user +
                            '" cameraPsd="' +
                            data.password +
                            '"><img src="' +
                            camera_img +
                            '" /><div class="' +
                            cameraStatus +
                            '">' +
                            data.cameraName +
                            '</div> </a></li>'
                        );
                      });
                      cameraModal.style.left = click.position.x + -45 + 'px';
                      cameraModal.style.top = click.position.y + -180 + 'px';
                      this.cameraModalShow = true;
                    }
                  });
                }
              });
            }
            //雷达扫描范围
            if (
              pickedFeature.id._xbsjOwner &&
              pickedFeature.id._xbsjOwner.customProp &&
              JSON.parse(pickedFeature.id._xbsjOwner.customProp).labelAttr == '4'
            ) {
              let labelCode = JSON.parse(pickedFeature.id._xbsjOwner.customProp).labelCode;
              console.log(pickedFeature.id._xbsjOwner);
              if (pickedFeature.id._xbsjOwner.addViewShedReturn) {
                //显示/不显示雷达扫码效果
                // pickedFeature.id._xbsjOwner.addViewShedReturn.show = !pickedFeature.id._xbsjOwner.addViewShedReturn.show;
                // console.log("pickedFeature.id._xbsjOwner.addViewShedReturn",pickedFeature.id._xbsjOwner.addViewShedReturn);

                //清空当前雷达,并将该方法指向undefined(清空)
                pickedFeature.id._xbsjOwner.addViewShedReturn.clear();
                pickedFeature.id._xbsjOwner.addViewShedReturn = undefined;
              } else {
                defHttp.get({ url: this.url.radarList, params: { radarCode: labelCode } }, { isTransformResponse: false }).then((res) => {
                  if (res.success) {
                    if (res.result.records.length > 0) {
                      let data = res.result.records[0];
                      let rgb;
                      if (data.customProp) {
                        rgb = JSON.parse(data.customProp).color;
                      }
                      let radarRadius = data.workingRadius;
                      let radarRange = data.elevation;
                      let radarShifting = data.angularRadian;
                      let left = Number(radarShifting) - Number(radarRange) / 2;
                      //参数:经纬度、半径、起始角度(正北方向)、结束角度
                      console.log('雷达扫描范围', data);

                      //弧度转角度
                      let degreePosition = radianToDegreeInLngLatHeight(
                        pickedFeature.id._xbsjOwner.position[0],
                        pickedFeature.id._xbsjOwner.position[1],
                        0.1
                      );
                      //创建雷达扫描 深度
                      // this._viewer.scene.globe.depthTestAgainstTerrain = true;
                      let rader = new CircleScan(this._viewer);
                      rader.add(degreePosition, null, radarRadius, 10000);
                      pickedFeature.id._xbsjOwner.addViewShedReturn = rader;

                      // 雷达扫描2
                      // let rader2 = this._viewer.entities.add({
                      //   position: Cesium.Cartesian3.fromDegrees(113.528333, 22.156109),
                      //   name: '雷达扫描',
                      //   ellipse: {
                      //       semiMajorAxis: 5000.0,
                      //       semiMinorAxis: 5000.0,
                      //       material: new Cesium.RadarScanMaterialProperty({
                      //           color: new Cesium.Color(1.0, 1.0, 0.0, 0.7),
                      //           speed: 20.0,
                      //       }),
                      //       height: 20.0,
                      //       heightReference: Cesium.HeightReference.RELATIVE_TO_GROUND,
                      //       outline: true,
                      //       outlineColor: new Cesium.Color(1.0, 1.0, 0.0, 1.0)
                      //   }
                      // })

                      // pickedFeature.id._xbsjOwner.addViewShedReturn= addViewShedRadar(
                      //   pickedFeature.id._xbsjOwner.position,
                      //   radarRadius,
                      //   left,
                      //   Number(radarRange) / 2 + Number(radarShifting),
                      //   [rgb.r / 255, rgb.g / 255, rgb.b / 255, rgb.a]
                      // );
                    }
                  }
                });
              }
            }
          } else {
            //关闭所有气泡窗
            that.cameraModalShow = false;
            that.poiModalShow = false;
          }
          console.debug('点击到的模型', pickedFeature);
        }, window.Cesium.ScreenSpaceEventType.LEFT_CLICK);
      }
      /* 鼠标右键事件 */
      {
        this._handler.setInputAction((click) => {
          // 判断点击位置是否有实体
          //返回具有 `primitive` 属性的对象,该属性包含场景中特定窗口坐标处的第一个(顶部)图元,如果该位置没有任何内容,则返回未定义的对象。其他属性可能会根据基元的类型进行设置,并可用于进一步识别拾取的对象。
          let pickedFeature = this._viewer.scene.pick(click.position);
          // console.log("pick",pickedFeature);

          let entity = pickedFeature && pickedFeature.id;
          console.log('pick', pickedFeature);
          console.log('entity', entity);
          if (entity == undefined) {
            return;
          }
          if (typeof pickedFeature !== 'undefined' && pickedFeature.id.xbsjType == 'Model') {
            //点击电线杆触发弹窗
            this.cameraData.forEach((data) => {
              if (!$.isEmptyObject(data.msCameraSiteList)) {
                if (!data.msCameraSettingList) {
                  return;
                }
                data.msCameraSiteList.forEach((data) => {
                  if (pickedFeature.id.customProp === data.id) {
                    window.$uia.contextMenu.pop([
                      {
                        text: '监控视域分析属性',
                        func: () => {
                          let testConfig = {
                            ref: 'testView',
                            name: '雷达视域分析',
                            position: [1.514482876761954, 0.8497520519403554, -0.7553906497788317],
                            rotation: [4.535844766941594, 0.32288591161895097, 0],
                            near: 1,
                            far: 400,
                            fovH: Math.PI / 3,
                            fovV: Math.PI / 6,
                            show: false,
                          };
                          let Viewshed = new window.XE.Obj.Viewshed(window.$earth);
                          Viewshed.xbsjFromJSON(testConfig);
                          window.$uia.showPropertyWindow(Viewshed);
                        },
                      },
                    ]);
                  }
                });
              }
            });
          }
          //巡检监控视频
          else if (typeof pickedFeature !== 'undefined' && entity._name == '视频图元') {
            // console.log(pickedFeature)
            // console.log("entity",entity)
            window.$uia.contextMenu.pop([
              {
                text: '编辑',
                func: () => {
                  $mitt.emit('addRoamPathVideoClose');
                  // store.commit('customPrimitive', entity.xbsjGuid);
                  this.store.customPrimitive = entity.xbsjGuid;
                  // 打开对应的创建巡检视频窗口
                  this.$nextTick(() => {
                    this.addRoamVideoShow = true;
                  });
                  // window.$uia.showPropertyWindow(
                  //   {},
                  //   {
                  //     component: addroamVideo,
                  //   }
                  // );
                },
              },
              {
                text: '删除',
                func: () => {
                  window.$uia.confirm('确认删除?', () => {
                    // console.log('confirmed')

                    // axios({
                    //   method: 'delete',
                    //   url: '/military/msAreaCustomPrimitive/delete',
                    //   params: { id: entity.id },
                    // })
                    defHttp
                      .delete(
                        {
                          url: '/military/msAreaCustomPrimitive/delete',
                          params: { id: entity.id },
                        },
                        { isTransformResponse: false, joinParamsToUrl: true }
                      )
                      .then((response) => {
                        if (response.code == 200) {
                          let customPrimitiveList = this.store.customPrimitiveList;
                          // console.log("a",customPrimitiveList);
                          customPrimitiveList.forEach((element, index) => {
                            const model = window.$earth.getObject(element);
                            // console.log("model.id",model.id);
                            // console.log("entity.id",entity.id);
                            if (model.id == entity.id) {
                              let customPrimitive = customPrimitiveList.splice(index, 1)[0];
                              model.destroy();
                            }
                          });
                          // store.dispatch('asyncCustomPrimitive', customPrimitiveList);
                          this.store.customPrimitiveList = customPrimitiveList;

                          // notification.close("RoamVideoSet");
                          // sessionStorage.setItem("RoamVideoSet", "false");
                        } else {
                          // Msg.error('删除失败');
                          $mitt.emit('openNotification', { msg: '删除失败', dt: 2, type: 'error', top: '50px' });
                          console.error('删除失败', response);
                        }
                      })
                      .catch((res) => {
                        console.error('错误', res);
                      });
                  });
                },
              },
            ]);
          }
          //绘画图形
          else if (typeof pickedFeature !== 'undefined' && entity.name == '绘画') {
            // console.log("entity", entity);
            window.$uia.contextMenu.pop([
              {
                text: '编辑',
                func: () => {
                  window.$uia.showPropertyWindow(entity);
                  //记录编辑前信息
                  let oldEntity = {
                    depthTest: entity.depthTest, //深度检测
                    color: [...entity.color], //颜色
                    outline: {
                      color: [...entity.outline.color], //边框颜色
                      show: entity.outline.show, //边框显示
                      width: entity.outline.width, //边框宽度
                    },
                    positions: [...entity.positions],
                  };
                  this.$nextTick(() => {
                    // 主要ui窗口
                    const mainUI = window.$uia._vm.$refs.mainUI;
                    // 所有打开的ui窗口Ref值
                    const windowsAttrList = Object.keys(mainUI.$refs);
                    // 寻找当前窗体的工具对象
                    const modelToolKey = windowsAttrList.filter((f) => f.indexOf(entity.guid) > -1)[0];
                    const modelTool = mainUI.$refs[modelToolKey][0];
                    // 当前窗体的元素
                    const el = modelTool.$el;
                    // this.cloneEl(el)
                    // 样式
                    el.style.width = '380px'; //宽度
                    el.children[2].style.padding = '0px';
                    el.children[2].style.transition = 'none';
                    el.children[2].children[0].children[0].style.minWidth = '370px';
                    // 关闭名称input
                    el.children[2].children[0].children[0].children[0].style.display = 'none';
                    // 关闭创建按钮
                    el.children[2].children[0].children[0].children[1].children[0].children[1].style.display = 'none';
                    // 关闭贴地
                    el.children[2].children[0].children[0].children[2].children[0].style.display = 'none';
                    // 关闭拉伸
                    el.children[2].children[0].children[0].children[3].children[0].style.display = 'none';
                    el.children[2].children[0].children[0].children[3].children[1].style.display = 'none';
                    el.children[2].children[0].children[0].children[3].children[2].style.display = 'none';
                    el.children[2].children[0].children[0].children[3].children[3].style.marginLeft = '8px';
                    // 右上角关闭
                    const cancelTopRightBtn = el.children[1].children[1];
                    // 取消按钮元素
                    const cancelBtn = el.children[3].children[0];
                    // 确认按钮元素
                    const okBtn = el.children[3].children[1];
                    // 取消按钮
                    cancelTopRightBtn.onclick = cancelBtn.onclick = function () {
                      //恢复原来设置
                      // console.log("oldEntity", oldEntity);
                      // console.log("entity", entity);
                      // entity.xbsjFromJSON(oldEntity)
                      // entity = JSON.parse(oldEntity)
                      entity.depthTest = oldEntity.depthTest;
                      entity.color = oldEntity.color;
                      entity.outline = oldEntity.outline;
                      entity.positions = oldEntity.positions;
                      entity.editing = false;
                    };
                    okBtn.onclick = function () {
                      let params = {
                        id: entity.customProp?.id,
                        drawData: JSON.stringify(entity),
                      };
                      // console.log("submit", entity);
                      defHttp
                        .post(
                          {
                            url: '/military/dtMapDraw/edit',
                            params: params,
                          },
                          { isTransformResponse: false }
                        )
                        .then((response) => {
                          $mitt.emit('openNotification', { msg: '编辑成功', dt: 2, type: 'success', top: '50px' });
                          // console.error('编辑成功', response);
                        })
                        .catch((response) => {
                          $mitt.emit('openNotification', { msg: '编辑失败', dt: 2, type: 'error', top: '50px' });
                          // console.error('删除失败', response);
                        });
                    };
                  });
                },
              },
              {
                text: '删除',
                func: () => {
                  window.$uia.confirm('确认删除?', () => {
                    defHttp
                      .delete(
                        {
                          url: '/military/dtMapDraw/delete',
                          params: { id: entity.customProp?.id },
                        },
                        { isTransformResponse: false, joinParamsToUrl: true }
                      )
                      .then((response) => {
                        if (response.code == 200) {
                          let shapeList = this.store.shapeList;
                          shapeList.forEach((element, index) => {
                            const model = window.$earth.getObject(element);
                            if (model.id == entity.customProp?.id) {
                              let shape = shapeList.splice(index, 1)[0];
                              model.destroy();
                            }
                          });
                          this.store.shapeList = shapeList;
                        } else {
                          $mitt.emit('openNotification', { msg: '删除失败', dt: 2, type: 'error', top: '50px' });
                          console.error('删除失败', response);
                        }
                      })
                      .catch((res) => {
                        console.error('错误', res);
                      });
                  });
                },
              },
            ]);
          }
        }, window.Cesium.ScreenSpaceEventType.RIGHT_CLICK); //右键事件
      }
      /* picked事件 */
      {
        /* let canvasbox = this._viewer.canvas, pickPosition = {}, cameraModal = this.$refs.cameraModal;//操作cameraModal组件
          canvasbox.onclick = e => {
            pickPosition.x = e.offsetX;
            pickPosition.y = e.offsetY;
            var picked = this._viewer.scene.pick(pickPosition);
            console.log("picked", picked);
            if (picked !== undefined && picked.id !== undefined) {
              console.log(e)
            } else {
              that.cameraModalShow = false;
            }
          } */
      }
    }

    listenMittHandler(earthUI = null) {
      let that = this;
      {
        $mitt.on('winShow', function (e: any) {
          that.VideoFusionWinShow = e;
        });
        //其他页面调用本页面的methods方法
        $mitt.on('openNotification', (res: any) => {
          // that.openNotification(msg, dt, type, top)
          that.openNotification(res.msg, res.dt, res.type, res.top);
        });
        $mitt.on('listenMouseHandler', function () {
          that.listenMouseHandler();
        });
        $mitt.on('removeHandler', function () {
          that.removeHandler();
        });
        $mitt.on('createBBHLine', function () {
          that.createBBHLine();
        });
        $mitt.on('createRealTimeObj', function () {
          that.createRealTimeObj();
        });
        $mitt.on('radioChangeBtnShow', function (callback) {
          that.radioChangeBtnShow(callback);
        });
        $mitt.on('loadingStatus', function () {
          that.loadingStatus();
        });
        $mitt.on('clearAlarmModel', (mittData: any) => {
          let { isWarnEvent, eventSerialNum } = mittData;
          // 清除告警模型
          if (isWarnEvent) {
            // 是告警事件 先去后台查询预警事件获取事件编号
            let url = 'military/msWarnEvent/queryWarnEventDetailList';
            let params = {
              eventSerialNum: eventSerialNum,
            };
            defHttp.get({ url, params }, { isTransformResponse: false }).then((res) => {
              if (res.success) {
                // 成功
                let data = res.result;
                for (const warnEventInfo of data) {
                  this.clearAlarmModel(warnEventInfo.eventSerialNum);
                }
              } else {
                // 失败
                console.log('失败');

                this.$message.error(res.message);
              }
            });
          } else {
            // 不是告警事件,直接清除
            this.clearAlarmModel(eventSerialNum);
          }
        });
        // 监听mqtt消息
        $mitt.on('deviceCmd', (message: any) => {
          drawAllShips(message);
        });
      }
    }

    removeHandler() {
      this._handler.removeInputAction(window.Cesium.ScreenSpaceEventType.MOUSE_MOVE); //移除鼠标事件
      this._handler.removeInputAction(window.Cesium.ScreenSpaceEventType.LEFT_CLICK); //移除鼠标事件
    }

    radioChange(e) {
      this.loadingStatus();
      if (`${e.target.value}` == 'satellite') {
        window.$earth.sceneTree.$refs.satellite.czmObject.show = true;
        window.$earth.sceneTree.$refs.vector.czmObject.show = false;
      } else if (`${e.target.value}` == 'vector') {
        window.$earth.sceneTree.$refs.vector.czmObject.show = true;
        window.$earth.sceneTree.$refs.satellite.czmObject.show = false;
      }
    }

    radioChangeBtnShow(callback) {
      this.radioBtnShow = !this.radioBtnShow;
      callback(this.radioBtnShow); //回调返回当前状态
    }

    loadingStatus() {
      this.earthChangeSpin = !this.earthChangeSpin; //加载状态
      setTimeout(() => {
        this.earthChangeSpin = !this.earthChangeSpin; //3秒后去除加载状态
      }, 3000);
    }

    keepAlive() {
      defHttp.get({ url: this.url.keepAlive }, { isTransformResponse: false }).then((res) => {});
    }

    closeClient() {
      chrome.call('close');
    }

    /* websocket-start */
    initWebSocket(configName) {
      if ('WebSocket' in window) {
        let url = '';
        switch (configName) {
          case 'domianURL': //接收后台模型数据
            // WebSocket与普通的请求所用协议有所不同,ws等同于http,wss等同于https
            // const userStore = useUserStore()
            // const orgCode = userStore.userInfo?.orgCode;
            // let userId = store.getters.userInfo.id;
            let userId = this.userStore.userInfo?.id;
            url = window._CONFIG[configName].replace('https://', 'wss://').replace('http://', 'ws://') + '/websocket/' + userId;
            // url = 'ws://127.0.0.1:5004'
            this.websock[configName] = new WebSocket(url);
            this.websock[configName].onopen = this.websocketonopen;
            this.websock[configName].onerror = this.websocketonerror;
            this.websock[configName].onmessage = this.websocketonmessage;
            this.websock[configName].onclose = this.websocketclose;
            break;
          case 'clientURL': //调用客户端监控视频窗口
            url = window._CONFIG['clientURL'];
            this.websock[configName] = new WebSocket(url);
            this.websock[configName].onopen = this.websocketonopen;
            this.websock[configName].onerror = this.websocketonerror;
            this.websock[configName].onclose = this.websocketclose;
            break;
          default:
            console.log('websocket初始化失败');
        }
        // console.log('url', url)
      } else {
        console.log('当前浏览器不支持websocket,请更换浏览器!');
      }
    }
    websocketonopen(e) {
      console.log('WebSocket连接成功');
    }
    websocketonerror(e) {
      console.log('WebSocket连接发生错误');
    }
    loreadAlarmInfo = _.debounce(
      (url, eventSerialNum) => {
        defHttp
          .get(
            {
              url: url,
              params: eventSerialNum,
            },
            { isTransformResponse: false }
          )
          // getAction(url, {eventSerialNum: eventSerialNum})
          .then((res) => {
            if (!res.success) {
              console.log('重新发送websocket报警数据失败!');
            } else {
              console.log('重新发送websocket报警数据成功!');
            }
          });
      },
      2000,
      { maxWait: 3000, trailing: true }
    );
    async websocketonmessage(e) {
      //接收后端数据
      var data = eval('(' + e.data + ')');
      const cesium = window.Cesium;
      // Cesium Math
      const math = cesium.Math;
      // earth
      const earth = window.$earth;
      //处理订阅信息
      if (data.cmd == 'new_warn_info') {
        //有新增的预警信息
        //1.调起客户端窗体
        // chrome.call("formactive");
        //2.若警示界面打开着,则刷新列表
        if ($('.infoList').css('visibility') == 'visible') {
          $mitt.emit('getWarnData');
        }
        //3.弹出监控窗口或围栏信息
        if (data.msgTxt != undefined && data.dealStatus == 1) {
          $mitt.emit('listenerVideoNum', data.msgTxt);
          //显示报警位置
          window.$earth.sceneTree.$refs[data.labelCode].czmObject.color = [1, 0.09803921568627451, 0, 1];
        } else if (data.msgTxt != undefined && data.dealStatus == 3) {
          this.$notification.open({
            key: 'fenceInfo',
            message: '围栏信息通知',
            description: data.msgTxt + '!',
            duration: 0,
          });
        } else if (data.dealStatus == 2) {
          //消除单个报警位置
          window.$earth.sceneTree.$refs[data.labelCode].czmObject.color = [0.08235294117647059, 1, 0, 1];
        } else if (data.dealStatus == 0) {
          //消除所有报警位置
          window.$earth.sceneTree.$refs.sensor.children.forEach((data, index) => {
            data.czmObject.color = [0.08235294117647059, 1, 0, 1];
          });
        }

        //4.提示音
        if (data.dealStatus !== 2 && data.dealStatus !== 0) {
          await this.$refs.audio.play();
          setTimeout(() => {
            this.$refs.audio.pause(); //N秒后暂停播放
          }, data.alarmNum * 1000);
        }
      } else if (data.cmd == 'new_microwave_warn_info' || data.cmd == 'new_radar_warn_info' || data.cmd == 'new_video_warn_info') {
        if (this.alarmInfoMap.has(data.serialNum)) {
          return;
        }
        const evalString = `
                if(p._div){
                  return
                }
                let left=p.winPos[0];
                let bottom=p.winPos[3];
                const div = document.createElement('div');
                div.style="position: absolute;left:"+left+"px;bottom:"+bottom+"px "
                const img = document.createElement('img');
                img.src="${alarmImg}";
                img.style="width:60px;height:60px"
                div.appendChild(img);
                div.onclick=()=>{
                  p.flyTo()
                }
                p._div = div;
                const root=document.getElementById('earthContainer');
                root.appendChild(div);
                XE.MVVM.watch(p.winPos,() => {
                  left=p.winPos[0]-30;
                  bottom=p.winPos[3];
                  div.style="position: absolute;left:"+left+"px;bottom:"+bottom+"px "
              })
          `;
        const pinConfig = {
          name: 'Pin1',
          xbsjType: 'Pin',
          position: [math.toRadians(data.lon), math.toRadians(data.lat), 0],
          evalString: evalString,
          // imageUrl: alarmImg,
          isDivImage: true,
          show: false,
          far: 3000,
        };
        // scanline
        const scanlineConfig = {
          name: 'AlarmScanline',
          xbsjType: 'Scanline',
          position: [math.toRadians(data.lon), math.toRadians(data.lat), 0],
          playing: true,
          radius: 30,
          timeDuration: 0.5,
          color: [1, 0, 0, 1],
          show: false,
        };
        const pin = new window.XE.Obj.Pin(window.$earth);
        const scanline = new window.XE.Obj.Scanline(window.$earth);
        //1、获取到世界坐标
        let start = cesium.Cartesian3.fromDegrees(data.lon, data.lat, 0);
        let height = await window.$earth.czm.viewer.scene.clampToHeightMostDetailed([start]).then(function (clampedCartesians) {
          //2、获取到经纬高度
          let ellipsoid = window.$earth.czm.viewer.scene.globe.ellipsoid;
          let cartographic = ellipsoid.cartesianToCartographic(clampedCartesians[0]);
          return cartographic.height;
        });
        if (height > 0) {
          pinConfig.position[2] = height;
        } else if (window.$earth.sceneTree.$refs.terrain.czmObject.show) {
          height = await cesium.sampleTerrainMostDetailed(earth._viewer.terrainProvider, [start]).then((updatedPositions) => {
            return updatedPositions[0].height ? updatedPositions[0].height : 0;
          });
          pinConfig.position[2] = height;
        } else {
          pinConfig.position[2] = 0;
        }

        // 保存报警类型到对象上
        let customProp = {};
        customProp.alarmType = data.cmd;
        pinConfig.customProp = JSON.stringify(customProp);
        scanlineConfig.customProp = JSON.stringify(customProp);
        pin.xbsjFromJSON(pinConfig);
        scanline.xbsjFromJSON(scanlineConfig);
        // 判断现在相机的高度来显示报警相关模型
        if (this._earth.camera.position[2] < 100) {
          // 隐藏 pin, 显示 scanline
          pin._div.hidden = true;
          scanline.show = true;
        } else {
          // 隐藏 scanline, 显示 pin
          pin._div.hidden = false;
          scanline.show = false;
        }
        scanline.flyTo();
        this.alarmInfoMap.set(data.serialNum, { pin: pin, scanline: scanline, timestamp: Date.now() });
        //报警弹窗
        this.videoWindowProps.title = `实时报警窗口(${data.cameraName})`;
        this.videoWindowProps.videoUrl = data.cameraCode; //相机编码
        this.videoWindowProps.isAlarm = true;
        this.videoWindowProps.visible = true;
        this.videoWindowProps.playRecord = false;

        this.videoWindowProps.warnEvent.happenTime = data.happenTime;
        this.videoWindowProps.warnEvent.happenLoc = `${Number(data.lon).toFixed(6)},${Number(data.lat).toFixed(6)}`;
        this.videoWindowProps.warnEvent.warnNum = 1;
        this.videoWindowProps.warnEvent.warnLevel = filterDictTextByCache('ms_warn_level', data.warnLevel);
        this.videoWindowProps.warnEvent.warnType = filterDictTextByCache('ms_warn_type', data.warnType);
        this.videoWindowProps.warnEvent.warnContent = data.warnContent;

        //若警示界面打开着,则刷新列表
        if ($('.infoList').css('visibility') == 'visible') {
          $mitt.emit('getWarnData');
        }

        //提示音
        await this.$refs.audio.play();
        setTimeout(() => {
          this.$refs.audio.pause(); //N秒后暂停播放
        }, 3 * 1000);
      } else if (data.cmd == 'earthMap_model_realtime_info') {
        console.log(data);
        console.log(this.radarAlarmDataMap);
        // 雷达轨迹报警数据
        const alarmContent = data.content;

        if (this.radarAlarmDataMap.has(data.eventSerialNum)) {
          // 存在雷达报警数据
          let radarAlarmData = this.radarAlarmDataMap.get(data.eventSerialNum);
          let targetMap = radarAlarmData.target;
          if (targetMap.has(data.modelId)) {
            // 存在目标数据
            let targetData = targetMap.get(data.modelId);
            let pathModel = targetData.path;
            let groundImageModel = targetData.groundImage;
            //更新目标数据
            // 更新报警数据
            let positionRadian = earthUtils.degreeToRadianInLngLatHeight(alarmContent.lon, alarmContent.lat, 0);
            // 更新路径
            pathModel.positions.push(positionRadian);
            groundImageModel.position = positionRadian;
            if (pathModel.positions.length > 1) {
              pathModel.show = true;
              groundImageModel.show = true;
            }
          } else {
            // 不存在目标数据
            // 创建目标数据
            let positionRadian = earthUtils.degreeToRadianInLngLatHeight(alarmContent.lon, alarmContent.lat, 0);
            // 路径
            let pathModel = new window.XE.Obj.Path(window.$earth);
            let pathConfig = {
              name: 'path',
              xbsjType: 'Path',
              positions: [positionRadian],
              loop: false,
              playing: true,
              width: 2,
              color: [1, 0, 0, 1],
              show: false,
              showDirection: false,
              currentSpeed: 30,
              alwaysAlongThePath: true,
              material: {
                type: 'Color',
                color: [1, 0, 0, 1],
              },
            };
            pathModel.xbsjFromJSON(pathConfig);
            // 地面图片
            let groundImageModel = new window.XE.Obj.GroundImage(window.$earth);
            let imageUrls: any = [];
            if (data.mainTarget) {
              imageUrls.push(window._CONFIG['staticDomainURL'] + '/keyi_point1.png');
              imageUrls.push(window._CONFIG['staticDomainURL'] + '/keyi_point2.png');
            } else {
              imageUrls.push(window._CONFIG['staticDomainURL'] + '/keyi_point3.png');
              imageUrls.push(window._CONFIG['staticDomainURL'] + '/keyi_point4.png');
            }
            let groundImageConfig = {
              name: 'groundImage',
              xbsjType: 'GroundImage',
              position: positionRadian,
              width: 3,
              height: 3,
              playing: true,
              imageUrls: imageUrls,
              show: false,
            };
            groundImageModel.xbsjFromJSON(groundImageConfig);
            // 保存目标数据
            let targetData = {
              path: pathModel,
              groundImage: groundImageModel,
            };
            targetMap.set(data.modelId, targetData);
          }
          // 更新时间
          const updateTime = Date.now();
          radarAlarmData.timestamp = updateTime;
          // 更新 pin 的时间
          let alarm = this.alarmInfoMap.get(data.eventSerialNum);
          if (alarm) {
            alarm.timestamp = updateTime;
          }
        } else {
          // 不存在报警数据
          // 路径
          let pathModel = new window.XE.Obj.Path(window.$earth);
          let pathConfig = {
            name: 'path',
            xbsjType: 'Path',
            positions: [earthUtils.degreeToRadianInLngLatHeight(alarmContent.lon, alarmContent.lat, 0)],
            loop: false,
            playing: true,
            width: 2,
            color: [1, 0, 0, 1],
            show: false,
            showDirection: false,
            currentSpeed: 30,
            alwaysAlongThePath: true,
            material: {
              type: 'Color',
              color: [1, 0, 0, 1],
            },
          };
          // 地面图片
          let groundImage = new window.XE.Obj.GroundImage(window.$earth);
          let imageUrls: any = [];
          if (data.mainTarget) {
            imageUrls.push(window._CONFIG['staticDomainURL'] + '/keyi_point1.png');
            imageUrls.push(window._CONFIG['staticDomainURL'] + '/keyi_point2.png');
          } else {
            imageUrls.push(window._CONFIG['staticDomainURL'] + '/keyi_point3.png');
            imageUrls.push(window._CONFIG['staticDomainURL'] + '/keyi_point4.png');
          }
          let groundImageConfig = {
            name: 'groundImage',
            xbsjType: 'GroundImage',
            playing: true,
            width: 3,
            height: 3,
            position: earthUtils.degreeToRadianInLngLatHeight(alarmContent.lon, alarmContent.lat, 0),
            imageUrls: imageUrls,
            show: false,
          };
          // 创建路径
          groundImage.xbsjFromJSON(groundImageConfig);
          // 创建地面图片
          pathModel.xbsjFromJSON(pathConfig);

          // 保存数据到map中
          let target = {
            path: pathModel,
            groundImage: groundImage,
            mainTarget: alarmContent.mainTarget,
          };
          let targetMap = new Map();
          targetMap.set(data.modelId, target);
          this.radarAlarmDataMap.set(data.eventSerialNum, {
            target: targetMap,
            timestamp: Date.now(),
          });

          if (!this.alarmInfoMap.has(data.eventSerialNum)) {
            // 不存在告警信息(小灯或扫描线)时发送
            // 事件编号到后台使其重新发送websocket报警数据
            await new Promise((r) => setTimeout(r, 500));
            if (!this.alarmInfoMap.has(data.eventSerialNum)) {
              console.log('发送websocket报警数据');
              this.loreadAlarmInfo(this.url.sendRadarAlarmByWebSocket, data.eventSerialNum);
            }
          }
        }
        if (this.videoWindowProps.visible) {
          this.videoWindowProps.warnEvent.warnNum = this.radarAlarmDataMap.get(data.eventSerialNum).target.size;
        }
        // console.debug('雷达轨迹报警数据', this.radarAlarmDataMap);
      } else if (data.cmd == '') {
        earth.sceneTree.$refs[data.eventSerialNum].destroy();
      } else if (data.cmd == 'eventPublish') {
        window.getEventData();
      }
    }
    websocketclose(e) {
      console.log('connection closed (' + e.code + ')');
      this.openNotification('websocket连接已断开', 3, 'warning');
    }
    websocketdosend(configName) {
      //发送数据
      this.spinning = !this.spinning; //加载状态
      console.log('this.websock[configName]', this.websock[configName]);
      let that = this;
      let message = {
        topic: 'Show_Single_Video',
        msg: '192.168.1.65',
      };
      //readyState:0:正在连接中,1:已建立连接,2:连接正在关闭,3:连接已关闭或连接失败
      if (that.websock[configName].readyState == 1) {
        that.websock[configName].send(JSON.stringify(message));
        that.spinning = !that.spinning; //加载状态
        console.log('已发送');
      } else {
        //重新连接websocket
        this.initWebSocket('clientURL');
        setTimeout(function () {
          if (that.websock[configName].readyState == 1) {
            that.websock[configName].send(JSON.stringify(message));
          }
          that.spinning = !that.spinning; //加载状态
        }, 3000);
      }
    }
    /* websocket-end */
    openNotification(msg, dt = 2, type = 'info', top = '300px') {
      // console.log("openNotification收到");
      // console.log("proxy",this);
      // console.log("window",window);
      // debugger
      this.$message.config({
        top: top,
        duration: dt,
        maxCount: 3,
      });
      switch (type) {
        case 'info':
          this.$message.info(msg);
          break;
        case 'success':
          this.$message.success(msg);
          break;
        case 'error':
          this.$message.error(msg);
          break;
        case 'warning':
          this.$message.warning(msg);
          break;
        default:
      }
    }
    getRandomArr(arr, count) {
      //从数组随机抽取元素
      var shuffled = arr.slice(0),
        i = arr.length,
        min = i - count,
        temp,
        index;
      while (i-- > min) {
        //打乱数组
        index = Math.floor((i + 1) * Math.random());
        temp = shuffled[index];
        shuffled[index] = shuffled[i];
        shuffled[i] = temp;
      }
      return shuffled.slice(min);
    }
    // 根据经纬度获取高度
    async getHeigthByLonLat(lon = 88.8296258, lat = 27.4061859) {
      var positions = [window.Cesium.Cartographic.fromDegrees(lon, lat)];
      // var promise = Cesium.sampleTerrain(this._viewer.terrainProvider, 13, positions);
      var promise = window.Cesium.sampleTerrainMostDetailed(this._viewer.terrainProvider, positions);
      return new Promise((resolve, reject) => {
        window.Cesium.when(promise, function (updatedPositions) {
          // updatedPositions[0].height ? updatedPositions[0].height : 0;
          resolve(updatedPositions);
        });
      });
      /* var terCartographic = new Cesium.Cartographic(1.5503694435245020004000376611976, 0.47832817936864542131039019315313, 0)
      var terHigh = this._viewer.scene.globe.getHeight(terCartographic);
      return terHigh; */
    }
    cloneModel(modelObject) {
      if (modelObject.czmObject.xbsjType === 'Model') {
        const modelConfig = {
          ref: '',
          name: modelObject.name,
          czmObject: {
            name: modelObject.czmObject.name,
            xbsjType: modelObject.czmObject.xbsjType,
            url: modelObject.czmObject.url,
            // "color": [0.52, 0.6, 0.58, 1],
            minimumPixelSize: modelObject.czmObject.minimumPixelSize,
            // maximumScale: 0.02,
            scale: modelObject.czmObject.scale,
            xbsjScale: [...modelObject.czmObject.xbsjScale],
            xbsjPosition: [...modelObject.czmObject.xbsjPosition],
            xbsjRotation: [...modelObject.czmObject.xbsjRotation],
            viewDistance: 150,
            distanceDisplayCondition: [1.0, 30000.0],
          },
        };
        const index = modelObject.parent.children.push(modelConfig);
        return index;
        // const model = new window.XE.Obj.Model(window.$earth)
        // model.xbsjFromJSON(modelConfig)
        // const leaf = new window.XE.SceneTree.Leaf(model)
        // window.$earth.sceneTree.root.push(leaf)
      } else {
        const objConfig3 = {
          ref: '',
          name: modelObject.name,
          czmObject: {
            customProp: modelObject.czmObject.customProp,
            name: modelObject.czmObject.name,
            xbsjType: modelObject.czmObject.xbsjType,
            imageUrl: modelObject.czmObject.imageUrl,
            position: [...modelObject.czmObject.position],
            scale: modelObject.czmObject.scale,
            pinBuilder: {
              extText: modelObject.czmObject.pinBuilder.extText,
              extTextFont: '30px 楷体',
              extTextPixelOffset: [30, -20],
              fillColor: [1, 1, 1, 0.9],
              outlineColor: [0, 0, 0, 0.9],
            },
            far: 1073741824,
          },
        };
        const index = modelObject.parent.children.push(objConfig3);
        return index;
      }

      // return model
    }
    cloneShamNode(oldRef, id, title) {
      const shamNode = window.$earth.sceneTree.$refs['node_' + oldRef];
      const newShamNode = {
        ref: 'node_' + id,
        title: title,
        expand: false,
        children: [],
      };
      // that.currentModel = response.result
      shamNode.parent.children.push(newShamNode);
    }
    getAreaCode(item) {
      const currentRef = item._inner.sn.ref;
      if (!this.areaByNodeId.has(currentRef)) {
        if (item.parent) {
          return this.getAreaCode(item.parent);
        }
      } else {
        return this.areaByNodeId.get(currentRef);
      }
    }
    setAllLabelStatus(selectRef, item, wbUnifiedResponse) {
      const that = this;
      //监控点
      if (selectRef.startsWith('monitor')) {
        let grandsons: any = [];
        const childs = item.children;
        for (const child of childs) {
          const grandson1 = child.children;
          if (grandson1 && grandson1.length > 0) {
            grandsons = grandsons.concat(grandson1);
          }
        }
        for (const grandson of grandsons) {
          const xbsjObject = grandson._inner.sn;
          const ref = xbsjObject.ref;
          if (ref.startsWith('camera_')) {
            const state = that.statusByNodeId.get(ref);
            if (state == 1) {
              that.statusByNodeId.set(ref, 0);
              const img = that.imgByRef.get(ref);
              img.src = require('@/assets/earthMap/circleDot1.png');
            } else if (state == 0) {
              that.statusByNodeId.set(ref, 1);
              const img = that.imgByRef.get(ref);
              img.src = require('@/assets/earthMap/circleDot1.png');
            }
          }
        }
      }
      //微波
      else if (selectRef.startsWith('wbList')) {
        const parentNode = item.parent;
        let areaCode = null;
        if (parentNode) {
          const falseNodeRef = item.parent._inner.sn.ref;
          const nodeRef = falseNodeRef.split('_')[1];
          const trueNode = window.$earth.sceneTree.$refs[nodeRef];
          areaCode = trueNode.czmObject.customProp;
        }
        const childs1 = item.children;
        if (!childs1 || childs1.length < 0) {
          return;
        }
        const length = childs1.length;
        let index = -1;
        for (const child of childs1) {
          index++;
          let xbsjObject = child._inner.sn;
          let jsonObj = JSON.parse(xbsjObject.czmObject.customProp);
          let deviceId = jsonObj.deviceId;
          let device = that.hostDeviceMapById.get(deviceId);
          if (!device) {
            console.error('主机设备为null');
            continue;
          }
          const args = {
            device: device,
            isDefence: wbUnifiedResponse,
            defenceArea: areaCode,
            detectorList: null,
          };
          defHttp
            .post(
              {
                url: this.url.setDefenseArea,
                params: args,
              },
              { isTransformResponse: false }
            )
            // postAction(this.url.setDefenseArea, args)
            .then((response) => {
              if (!response.success) {
                return;
              } else {
                for (let i = index; i < length; i++) {
                  const child1 = childs1[i];
                  const xbsjObject1 = child1._inner.sn;
                  const ref1 = xbsjObject1.ref;
                  if (ref1 && ref1.length > 0) {
                    const state1 = that.statusByNodeId.get(ref1);
                    if (state1 == 0 && wbUnifiedResponse) {
                      that.statusByNodeId.set(ref1, 1);
                      const img1 = that.imgByRef.get(ref1);
                      if (!img1) return;
                      img1.src = require('@/assets/earthMap/circleDot2.png');
                    } else if (state1 == 1 && !wbUnifiedResponse) {
                      that.statusByNodeId.set(ref1, 0);
                      const img1 = that.imgByRef.get(ref1);
                      if (!img1) return;
                      img1.src = require('@/assets/earthMap/circleDot1.png');
                    }
                  }
                }
              }
              console.log(response);
            });
          break;
        }
      } else if (selectRef.startsWith('nodeSecondary')) {
        const childs1 = item.children;
        if (!childs1 || childs1.length < 0) {
          return;
        }
        for (const child of childs1) {
          let xbsjObject = child._inner.sn;
          let jsonObj = JSON.parse(xbsjObject.czmObject.customProp);
          let deviceId = jsonObj.deviceId;
          let device = that.hostDeviceMapById.get(deviceId);
          if (!device) {
            console.error('主机设备为null');
            continue;
          }
          let regionIdList: any = [];
          if (item.children.length > 0) {
            item.children.forEach((element) => {
              regionIdList.push(element._inner.sn.ref);
            });
          }
          const args = {
            regionIdList: regionIdList, // 周界防区区域ID列表(雷达设备列表的ID)
            regionStatus: wbUnifiedResponse ? 1 : 0, // 布防状态 0 - 未布防 1 - 布防
            defenceRule: {
              // 布防规则
              startTime: 'yyyy-MM-dd HH:mm:ss', // 布防开始时间 每日循环情况下只包含时分秒,格式:"HH:mm:ss" 非每日循环情况下包含年月日、时分秒,格式:"yyyy-MM-dd HH:mm:ss"
              endTime: 'yyyy-MM-dd HH:mm:ss', // 布防结束时间 每日循环情况下只包含时分秒,格式:"HH:mm:ss" 非每日循环情况下包含年月日、时分秒,格式:"yyyy-MM-dd HH:mm:ss"
              dailyCycle: true, // 每日循环布防 true - 是 false - 否
            },
          };
          // putAction(this.url.perimeterControl,{})
          console.log(device, that.statusByNodeId, xbsjObject);
          let ref1 = xbsjObject.ref;
          let state1 = that.statusByNodeId.get(ref1);
          //一键布防撤防测试使用
          if (wbUnifiedResponse) {
            state1 = 0;
          } else {
            state1 = 1;
          }
          if (state1 == 0 && wbUnifiedResponse) {
            that.statusByNodeId.set(ref1, 1);
            const img1 = that.imgByRef.get(ref1);
            if (!img1) return;
            img1.src = require('@/assets/earthMap/circleDot2.png');
          } else if (state1 == 1 && !wbUnifiedResponse) {
            that.statusByNodeId.set(ref1, 0);
            const img1 = that.imgByRef.get(ref1);
            if (!img1) return;
            console.log(img1);
            img1.src = require('@/assets/earthMap/circleDot1.png');
          }
          //   break
        }
      }
    }

    // 图层管理-模型右键菜单
    sceneTreePopContextMenu({ item, vueObject }, earthUI) {
      let that: any = this;
      let earth = window.$earth;
      let XE = window.XE;
      let sceneTree = earthUI.tools.sceneTree;
      let sceneTreeComp = sceneTree._comp;
      // 转换方法
      let transform = window.Cesium.Math;
      //右键之后设置当前 node
      item._inner.sn.isSelected = true;
      const el = vueObject.$el;
      let baseItems = [
        {
          text: '克隆',
          keys: '',
          func: () => {
            let sn: any = null;
            if (item._inner.sn.ref.startsWith('node_')) {
              const objectId = item._inner.sn.ref.split('_')[1];
              sn = earth.sceneTree.$refs[objectId];
            } else {
              sn = item._inner.sn;
            }
            if (sn) {
              let newSn: any = null;
              let newSnData: any = null;
              let index = 0;
              if (sn.czmObject.xbsjType !== 'Polyline') {
                index = that.cloneModel(sn);
                newSn = sn.parent.children[index - 1];
                newSnData = newSn.czmObject;
                if (newSnData.xbsjType === 'Model') {
                  that.$nextTick(() => {
                    const divs = $('#earthContainer>div>div>div:nth-child(5)')
                      .children('div')
                      .eq(1)
                      .children()
                      .eq(0)
                      .children()
                      .eq(0)
                      .children()
                      .each((index, element) => {
                        if (index <= 1) {
                          return;
                        }
                        const paddingLeft = $(element).children().eq(0).css('padding-left');
                        if (paddingLeft === '10px') {
                          $(element).css('display', 'none');
                        }
                      });
                  });
                }
              }
              // 保存数据到数据库中
              that
                .handleNodeType(sn)
                // 传感器
                .sensor(() => {
                  // debugger
                  // 设置 ref 属性 防止数据库中 eventSerialNum 重复
                  newSn.ref += '_copy';
                  // 发送请求 保存到数据库中
                  let saveSensorModelParameter = {
                    eventSerialNum: newSn.ref,
                    lon: transform.toDegrees(newSnData.xbsjPosition[0]).toFixed(5),
                    lat: transform.toDegrees(newSnData.xbsjPosition[1]).toFixed(5),
                    height: newSnData.xbsjPosition[2].toFixed(2),
                    yaw: transform.toDegrees(newSnData.xbsjRotation[0]).toFixed(2),
                    pitch: transform.toDegrees(newSnData.xbsjRotation[1]).toFixed(2),
                    roll: transform.toDegrees(newSnData.xbsjRotation[2]).toFixed(2),
                    isShow: 1,
                    modelType: '11',
                    eventType: 1,
                  };
                  defHttp
                    .post(
                      {
                        url: this.url.SaveSensorModel,
                        params: saveSensorModelParameter,
                      },
                      { isTransformResponse: false }
                    )
                    // postAction(this.url.SaveSensorModel, saveSensorModelParameter)
                    .then((res) => {
                      if (res.success) {
                        that.$message.success('克隆成功');
                      } else {
                        newSn.parent.children.splice(index, 1);
                        that.$message.error('克隆失败: ', res.message ? res.message : '');
                      }
                    });
                })
                // 标志点 微波雷达回调
                .markerPosition(() => {
                  // debugger
                  newSn.title += '_copy';
                  let pinImage = newSnData.imageUrl;
                  const staticDomainURL = window._CONFIG['staticDomainURL'] + '/';
                  // 去除 image 地址中的 staticDomainURL 链接
                  let imageUri = pinImage.substring(pinImage.indexOf(staticDomainURL) + staticDomainURL.length, pinImage.length);
                  const jsonObj = JSON.parse(newSnData.customProp);
                  const labelAttr = jsonObj.labelAttr;
                  let savePinModelParameter = {
                    mapLabel: {
                      labelName: newSnData.name,
                      labelLon: transform.toDegrees(newSnData.position[0]).toFixed(5),
                      labelLat: transform.toDegrees(newSnData.position[1]).toFixed(5),
                      labelHeight: newSnData.position[2].toFixed(2),
                      labelImgUrl: imageUri,
                      // 1 启用, 0 禁用
                      labelStatus: 1,
                      // 标记属性-> 3: 标记位置
                      labelAttr: labelAttr,
                      labelCode: '',
                      lineId: newSn.name,
                    },
                    deviceId: jsonObj.deviceId,
                  };
                  defHttp
                    .post(
                      {
                        url: this.url.saveMapLabel,
                        params: savePinModelParameter,
                      },
                      { isTransformResponse: false }
                    )
                    // postAction(this.url.saveMapLabel, savePinModelParameter)
                    .then((res) => {
                      if (res.success) {
                        // 修改 ref 成 数据库返回的 id
                        newSn.ref = res.result;
                        that.setIconByRef(newSn.ref, newSn.ref);
                        newSn.czmObject.pinBuilder.extText = newSnData.name;
                        jsonObj.labelCode = '';
                        newSn.czmObject.customProp = JSON.stringify(jsonObj);
                        // 保存成功
                        that.$message.success('克隆成功');
                      } else {
                        newSn.parent.children.splice(index, 1);
                        that.$message.error('克隆失败: ', res.message ? res.message : '');
                      }
                    })
                    .catch((err) => {
                      newSn.parent.children.splice(index, 1);
                      that.$message.error('克隆失败');
                    });
                })
                //区域回调
                .polylineCallBack(() => {
                  // debugger
                  const currentModel = new window.XE.Obj.Polyline(window.$earth);
                  const submitData: any = {};
                  const poistions = sn.czmObject.positions;
                  if (poistions.length <= 0) {
                    return;
                  }
                  submitData.name = sn.czmObject.name + '_copy';
                  submitData.lineCode = currentModel.guid;
                  submitData.isLoop = Number(sn.czmObject.loop);
                  submitData.isDepthCheck = Number(sn.czmObject.depthTest);
                  submitData.width = sn.czmObject.width;
                  submitData.interpolation = sn.czmObject.arcType;
                  submitData.positions = JSON.stringify(poistions);
                  switch (sn.czmObject.material.type) {
                    // 实线
                    case 'XbsjColorMaterial':
                      submitData.materialType = 0;
                      submitData.color = JSON.stringify(sn.czmObject.material.XbsjColorMaterial.color);
                      submitData.intervalColor = null;
                      submitData.dashLength = 0;
                      submitData.dashStyle = 0;
                      break;
                    // 虚线
                    case 'XbsjPolylineDashMaterial':
                      submitData.materialType = 1;
                      submitData.color = JSON.stringify(sn.czmObject.material.XbsjPolylineDashMaterial.color);
                      submitData.intervalColor = JSON.stringify(sn.czmObject.material.XbsjPolylineDashMaterial.gapColor);
                      submitData.dashLength = sn.czmObject.material.XbsjPolylineDashMaterial.dashLength;
                      submitData.dashStyle = sn.czmObject.material.XbsjPolylineDashMaterial.dashPattern;
                      break;
                    // 箭头线
                    case 'XbsjPolylineArrowMaterial':
                      submitData.materialType = 2;
                      submitData.color = JSON.stringify(sn.czmObject.material.XbsjPolylineArrowMaterial.color);
                      submitData.intervalColor = null;
                      submitData.dashLength = 0;
                      submitData.dashStyle = 0;
                      break;
                    // 轨迹线
                    case 'XbsjODLineMaterial':
                      submitData.materialType = 3;
                      submitData.color = JSON.stringify(sn.czmObject.material.XbsjODLineMaterial.color);
                      submitData.intervalColor = null;
                      submitData.dashLength = 0;
                      submitData.dashStyle = 0;
                      submitData.cycleFrame = sn.czmObject.material.XbsjODLineMaterial.totoalFrameCount;
                      break;
                  }
                  defHttp
                    .post(
                      {
                        url: this.url.saveMapLine,
                        params: submitData,
                      },
                      { isTransformResponse: false }
                    )
                    // postAction(this.url.saveMapLine, submitData)
                    .then((response) => {
                      if (response.success) {
                        currentModel.name = submitData.name;
                        currentModel.loop = submitData.isLoop;
                        currentModel.depthTest = submitData.isDepthCheck;
                        currentModel.width = submitData.width;
                        currentModel.arcType = submitData.interpolation;
                        currentModel.positions = JSON.parse(submitData.positions);
                        switch (sn.czmObject.material.type) {
                          // 实线
                          case 'XbsjColorMaterial':
                            currentModel.material.type = 'XbsjColorMaterial';
                            currentModel.material.color = submitData.color;
                            break;
                          // 虚线
                          case 'XbsjPolylineDashMaterial':
                            currentModel.material.type = 'XbsjPolylineDashMaterial';
                            currentModel.material.color = submitData.color;
                            currentModel.material.XbsjPolylineDashMaterial.gapColor = submitData.intervalColor;
                            currentModel.material.XbsjPolylineDashMaterial.dashLength = submitData.dashLength;
                            currentModel.material.XbsjPolylineDashMaterial.dashPattern = submitData.dashStyle;
                            break;
                          // 箭头线
                          case 'XbsjPolylineArrowMaterial':
                            currentModel.material.type = 'XbsjPolylineArrowMaterial';
                            currentModel.material.XbsjPolylineArrowMaterial.color = submitData.color;
                            break;
                          // 轨迹线
                          case 'XbsjODLineMaterial':
                            currentModel.material.type = 'XbsjODLineMaterial';
                            currentModel.material.XbsjODLineMaterial.color = submitData.color;
                            currentModel.material.XbsjODLineMaterial.totoalFrameCount = submitData.cycleFrame;
                            break;
                        }
                        const leaf = new XE.SceneTree.Leaf(currentModel);
                        leaf.ref = response.result;
                        sn.parent.children.push(leaf);
                      } else {
                        throw '克隆区域数据出错';
                      }
                    })
                    .catch((e) => {
                      currentModel.destroy();
                      // $mitt.emit('openNotification', '克隆区域数据出错', 2, 'error', '50px')
                      $mitt.emit('openNotification', { msg: '克隆区域数据出错', dt: 2, type: 'error', top: '50px' });
                    });
                })
                //监控点
                .modelCallback(() => {
                  this.$message.warning('监控点不支持克隆');
                })
                .run();
            }
          },
        },
        {
          text: '删除',
          keys: '',
          func: () => {
            earthUI.confirm('确认删除图层?', () => {
              try {
                // debugger
                let sn: any = null;
                const ref = item._inner.sn.ref;
                // update:-- 判断方式要修改
                if (ref.startsWith('node_')) {
                  const objectId = item._inner.sn.ref.split('_')[1];
                  sn = earth.sceneTree.$refs[objectId];
                } else {
                  sn = item._inner.sn;
                }
                let id = sn.ref;
                // 删除数据库中的数据
                that
                  .handleNodeType(sn)
                  // 传感器
                  .sensor(() => {
                    // 发送请求 删除数据库中的数据
                    that.handlerModelDelete(this.url.deleteSensor, { eventSerialNum: id });
                  })
                  // 标志点
                  .markerPosition(() => {
                    if (sn.czmObject.addViewShedReturn) {
                      window.$earth.czm.viewer.entities.remove(sn.czmObject.addViewShedReturn);
                    }
                    if (sn.czmObject.customProp) {
                      let prop = JSON.parse(sn.czmObject.customProp);
                      if (prop.labelAttr == 4) {
                        defHttp.delete(
                          {
                            url: '/military/RadarConfig/deleteByRadarCode',
                            params: { radarCode: prop.labelCode },
                          },
                          { isTransformResponse: false, joinParamsToUrl: true }
                        );
                        // deleteAction("/military/RadarConfig/deleteByRadarCode", {radarCode: prop.labelCode}).then(res => {
                        //   // console.log(res,'delete');
                        // })
                      }
                    }
                    this.handlerModelDelete(this.url.deleteMapLabel, {
                      id: id,
                    });
                  })
                  // 线
                  .modelCallback(() => {
                    that.handlerModelDelete(this.url.deleteSite, { id: id }).then(() => {
                      sn.destroy();
                      const node = item._inner.sn;
                      const childList = node.parent.children;
                      childList.splice(childList.indexOf(node), 1);
                      node.destroy();
                    });
                  })
                  .polylineCallBack(() => {
                    const childList = item._inner.sn.children;

                    for (const child of childList) {
                      if (child.children.length > 0) {
                        this.$message.warning('存在下级数据无法删除');
                        throw '存在下级数据无法删除';
                      }
                    }
                    that.handlerModelDelete(this.url.deleteMapLine, { id: id }).then(() => {
                      const nodeRef = 'node_' + id;
                      const node = $earth.sceneTree.$refs[nodeRef];
                      const childList = node.parent.children;
                      childList.splice(childList.indexOf(node), 1);
                      node.destroy();
                    });
                  })
                  .run();
                const index = sn.parent.children.indexOf(sn);
                sn.parent.children.splice(index, 1);
              } catch (error) {}
            });
          },
        },
      ];
      const bf = {
        text: '布防/撤防',
        keys: '',
        func: () => {
          const xbsjObject = item._inner.sn;
          if (!xbsjObject || !xbsjObject.czmObject) return;
          const jsonObj = JSON.parse(xbsjObject.czmObject.customProp);
          const deviceId = jsonObj.deviceId;
          if (!deviceId) {
            console.error('主机设备为空');
            return;
          }
          const labelCode = jsonObj.labelCode;
          if (!labelCode) {
            console.error('设备编码为null');
            return;
          }
          const device = that.hostDeviceMapById.get(deviceId);
          const ref = xbsjObject.ref;
          if (device.deviceType_dictText.indexOf('微波探测器') > -1) {
            if (ref && ref.length > 0) {
              const state = that.statusByNodeId.get(ref);
              if (state == 1) {
                that.setLabelStatus(device, labelCode, ref, 0).then((response) => {
                  that.setIconByRef(ref, el);
                });
              } else if (state == 0) {
                that.setLabelStatus(device, labelCode, ref, 1).then((response) => {
                  that.setIconByRef(ref, el);
                });
              } else {
                that.$message.error('设备不在线');
              }
            }
          } else if (device.deviceType_dictText.indexOf('雷达') > -1) {
            // console.log("leida");
            //处理单个雷达布防撤防
            //参数
            // {
            //   "regionIdList": [
            // 2
            //   ], // 周界防区区域ID列表(雷达设备列表的ID)
            //   "regionStatus": 0, // 布防状态 0 - 未布防 1 - 布防
            //   "defenceRule": { // 布防规则
            // "startTime": "yyyy-MM-dd HH:mm:ss", // 布防开始时间 每日循环情况下只包含时分秒,格式:"HH:mm:ss" 非每日循环情况下包含年月日、时分秒,格式:"yyyy-MM-dd HH:mm:ss"
            // "endTime": "yyyy-MM-dd HH:mm:ss", // 布防结束时间 每日循环情况下只包含时分秒,格式:"HH:mm:ss" 非每日循环情况下包含年月日、时分秒,格式:"yyyy-MM-dd HH:mm:ss"
            // "dailyCycle": true // 每日循环布防 true - 是 false - 否
            //   }
            // }
            // putAction(this.url.perimeterControl,{})
          }
        },
      };
      const selectRef = item._inner.sn.ref;
      if (selectRef.startsWith('wbList') || selectRef.startsWith('nodeSecondary_')) {
        baseItems = [
          {
            text: '一键布防',
            keys: '',
            func: () => {
              that.setAllLabelStatus(selectRef, item, true);
            },
          },
          {
            text: '一键撤防',
            keys: '',
            func: () => {
              that.setAllLabelStatus(selectRef, item, false);
            },
          },
        ];
        earthUI.contextMenu.pop(baseItems);
        return;
      } else if (selectRef.startsWith('monitor') || selectRef.startsWith('ldList')) {
        earthUI.contextMenu.pop([]);
        return;
      } else if (item.level <= 2) {
        if (!item._inner.sn.ref.startsWith('node_')) {
          earthUI.contextMenu.pop([]);
          return;
        } else {
          baseItems.splice(0, 1);
        }
      } else {
        if (selectRef.startsWith('camera')) {
          //   baseItems = [bf]
          //   earthUI.contextMenu.pop(baseItems)
          return;
        } else if (!selectRef.startsWith('node_')) {
          //站点
          baseItems.unshift({
            type: 'divider',
          });
          baseItems.unshift(bf);
        }
      }
      let num = 2;
      //判断定位的位置
      if (
        item.level <= 2 ||
        selectRef.startsWith('monitor') ||
        selectRef.startsWith('wbList') ||
        selectRef.startsWith('ldList') ||
        //站点
        selectRef.startsWith('node_')
      )
        num = 0;
      baseItems.splice(num, 0, {
        text: '定位',
        keys: '',
        func: () => {
          // const czmObject = item._inner.sn.czmObject
          // czmObject.flyTo()
          const ref = item._inner.sn.ref;
          let czmObject: any = null;
          if (ref.startsWith('node_')) {
            const objectId = ref.split('_')[1];
            const sn = earth.sceneTree.$refs[objectId];
            czmObject = sn.czmObject;
          } else {
            const sn = item._inner.sn;
            czmObject = sn.czmObject;
          }

          czmObject.flyTo();
        },
      });
      baseItems.push(
        ...[
          {
            type: 'divider',
          },
          {
            text: '属性',
            func: () => {
              $mitt.emit('windowCancel');
              // 属性面板
              const mainUI = earthUI._vm.$refs.mainUI;
              const areaCode = that.getAreaCode(item);
              let sn: any = null;
              if (item._inner.sn.ref.startsWith('node_')) {
                const objectId = item._inner.sn.ref.split('_')[1];
                sn = earth.sceneTree.$refs[objectId];
                // window.XE.MVVM.watch(() => {
                //   item._inner.sn.title = sn.title
                // })

                sn.czmObject.distanceDisplayCondition = [1.0, 30000.0];
                if (sn.czmObject.xbsjType == 'Model') {
                  const lineId = item.parent.parent._inner.sn.ref.split('_')[1];

                  this.czmObject = sn.czmObject;
                  this.node = item;
                  this.type = 'jkd';
                  this.lineId = lineId;
                  this.areaCode = areaCode;
                  this.areaByNodeIdModel = that.areaByNodeId;
                  // this.addModelWinShow = true
                  this.$nextTick(() => {
                    this.addModelWinShow = true;
                  });

                  //////////////////////////
                  // 只有组件中有getBind属性才能传递属性
                  // this._earthUI.showPropertyWindow(
                  //   {
                  //     czmObject: sn.czmObject,
                  //     node: item,
                  //     type: 'jkd',
                  //     lineId: lineId,
                  //     areaCode: areaCode,
                  //     areaByNodeId: that.areaByNodeId,
                  //   },
                  //   {
                  //     // component: addModelModal,
                  //     component: addModelWin,
                  //   }
                  // )
                  return;
                }
              } else {
                sn = item._inner.sn;
                if (sn.czmObject.xbsjType == 'Pin') {
                  const jsonObj = JSON.parse(sn.czmObject.customProp);

                  const lineId = jsonObj.labelAttr == 4 ? item.parent._inner.sn.ref.split('_')[1] : item.parent.parent._inner.sn.ref.split('_')[1];

                  this.czmObject = sn.czmObject;
                  this.node = item;
                  this.type = jsonObj.labelAttr == 4 ? 'ld' : 'wb';
                  this.lineId = lineId;
                  this.areaCode = areaCode;
                  this.eidtId = sn.ref;
                  this.areaByNodeIdModel = that.areaByNodeId;
                  // setLabelStatus: that.setLabelStatus, 已经有了
                  //     setIconByRef: that.setIconByRef,
                  (this.el = el),
                    this.$nextTick(() => {
                      this.addModelWinShow = true;
                    });

                  // 只有组件中有getBind属性才能传递属性
                  // this._earthUI.showPropertyWindow(
                  //   {
                  //     czmObject: sn.czmObject,
                  //     node: item,
                  //     type: jsonObj.labelAttr == 4 ? 'ld' : 'wb',
                  //     lineId: lineId,
                  //     areaCode: areaCode,
                  //     areaByNodeId: that.areaByNodeId,
                  //     eidtId: sn.ref,
                  //     setLabelStatus: that.setLabelStatus,
                  //     setIconByRef: that.setIconByRef,
                  //     el: el,
                  //   },
                  //   {
                  //     // component: addModelModal,
                  //     component: addModelWin,
                  //   }
                  // )
                  return;
                }
              }
              let index = sn.parent.children.indexOf(sn);
              let tempData = sn.czmObject.toAllJSON();
              // 设置属性面板的确定按钮方法
              // 显示属性面板
              earthUI.showPropertyWindow(sn.czmObject);
              that.$nextTick(() => {
                // 模型窗口
                const windowsAttrList = Object.keys(mainUI.$refs);
                // 找到该模型设置属性窗口
                const modelToolKey = windowsAttrList.filter((f) => f.indexOf(sn.czmObject.guid || sn.guid) > -1)[0];
                const modelTool = mainUI.$refs[modelToolKey][0];
                // 对应处理方法
                that
                  .handleNodeType(sn)
                  // 感应器
                  .sensor(() => {
                    // 禁用模型名称编辑
                    modelTool.$el.getElementsByClassName('xbsj-flatten')[0].children[0].children[1].setAttribute('disabled', 'disabled');
                  })
                  .default(() => {
                    // 启用模型名称编辑
                    modelTool.$el.getElementsByClassName('xbsj-flatten')[0].children[0].children[1].removeAttribute('disabled');
                  })
                  .run();

                // modelTool
                modelTool.ok = () => {
                  // 确定时清除这个事件
                  $mitt.off('windowCancel');
                  // 保存前端数据
                  const modelToolObj = modelTool._czmObj;
                  if (!modelToolObj) {
                    return;
                  }
                  modelToolObj.positionEditing = false;
                  if (modelToolObj.isCreating) {
                    modelToolObj.isCreating = false;
                    const sceneObject = new XE.SceneTree.Leaf(modelToolObj);
                    earthUI.addSceneObject(sceneObject);
                  }

                  // 保存到数据库
                  that.propertiesWindowConfirm(modelTool, sn, index);
                  // 关闭属性面板
                  modelTool.close();
                };
                modelTool.cancel = () => {
                  // 清除这个事件
                  $mitt.off('windowCancel');
                  // 关闭属性面板
                  modelTool.close();
                  let t = modelTool._czmObj;
                  // 如果是创建的话,需要删除
                  t && t.positionEditing === false && t.isCreating && t.isCreating === false && t.destroy();
                  // 恢复之前的数据
                  t && t.xbsjFromJSON(tempData);
                };
                $mitt.on('windowCancel', modelTool.cancel);
                // 下面的代码,是切换属性面板里选项窗口, 必须
                // 否侧 ok cancel 等方法执行是原本的方法而不是已经修改的方法
                modelTool.tabShow = '3';
                modelTool.tabShow = '1';
              });
            },
          },
        ]
      );
      // 右键菜单-重命名
      // 先销毁之前的 on-change-title 事件
      vueObject.$off('on-change-title', that.handleChangeTitle);
      // 重命名时 on-change-title 事件
      vueObject.$on('on-change-title', that.handleChangeTitle);

      // 弹出右键菜单
      earthUI.contextMenu.pop(baseItems);
    }

    // 重命名 on-change-title 事件 使用 lodash.debounce 函数(防抖)
    handleChangeTitle = _.debounce(function (options) {
      const sn = options.item._inner.sn;
      const newTitle = options.title;

      // 修改模型属性后,提交到后台。先判断模型的节点,调用不同的接口
      this.handleNodeType(sn)
        // 感应器
        .sensor(() => {
          // 不支持修改名称
          this.$message.warning('不支持修改感应器的名称');
        })
        // 传感器标志线
        .modelCallback(() => {
          // 发送请求 保存模型属性
          let editCameraSiteModelParameter = {
            id: sn.ref,
            sitename: newTitle,
          };
          defHttp
            .put(
              {
                url: this.url.updateSite,
                params: editCameraSiteModelParameter,
              },
              { isTransformResponse: false }
            )
            // putAction(this.url.updateSite, editCameraSiteModelParameter)
            .then((res) => {
              if (res.success) {
                this.$message.success('修改成功');
              } else {
                this.$message.error('修改失败');
              }
            })
            .catch((error) => {
              this.$message.error('修改失败');
            });
        })
        .markerPosition(() => {
          // 发送请求 保存模型属性
          let editPinModelParameter = {
            id: sn.ref,
            labelName: newTitle,
          };
          defHttp
            .put(
              {
                url: this.url.updateMapLabel,
                params: editPinModelParameter,
              },
              { isTransformResponse: false }
            )
            // putAction(this.url.updateMapLabel, editPinModelParameter)
            .then((res) => {
              if (res.success) {
                // 修改扩展文本
                sn.czmObject.pinBuilder.extText = newTitle;
                this.$message.success('修改成功');
              } else {
                this.$message.error('修改失败');
              }
            })
            .catch((error) => {
              this.$message.error('修改失败');
            });
        })
        .run();
    }, 150);

    // 右键菜单删除按钮的删除方法
    handlerModelDelete(url, params) {
      // return deleteAction(url, params).then((res) => {
      return defHttp
        .delete(
          {
            url: url,
            params: params,
          },
          { isTransformResponse: false, joinParamsToUrl: true }
        )
        .then((res) => {
          if (res.success) {
            this.$message.success('删除成功');
          } else {
            this.$message.error('删除失败');
            console.log('asdasdasd');
          }
        });
    }

    // 属性面板确定按钮方法
    propertiesWindowConfirm(propertiesWindow, sn, index) {
      // 属性面板 所修改的模型
      let model: any = null;
      if (sn.ref && !sn.ref.startsWith('node_')) {
        model = sn;
      } else {
        model = sn.parent.children[index];
      }

      let modelData = model.czmObject;
      // 转换方法
      let transform = window.Cesium.Math;

      // 修改模型属性后,提交到后台。先判断模型的节点,调用不同的接口
      this.handleNodeType(sn)
        // 传感器
        .sensor(() => {
          // 发送请求 保存模型属性
          let editSensorParams = {
            eventSerialNum: model.ref,
            lon: transform.toDegrees(modelData.xbsjPosition[0]).toFixed(5),
            lat: transform.toDegrees(modelData.xbsjPosition[1]).toFixed(5),
            height: modelData.xbsjPosition[2].toFixed(2),
            yaw: transform.toDegrees(modelData.xbsjRotation[0]).toFixed(2),
            pitch: transform.toDegrees(modelData.xbsjRotation[1]).toFixed(2),
            roll: transform.toDegrees(modelData.xbsjRotation[2]).toFixed(2),
            isShow: 1,
            // 传感器类型
            modelType: '11',
            // 事件类型
            eventType: 1,
          };
          defHttp
            .put(
              {
                url: this.url.updateSensor,
                params: editSensorParams,
              },
              { isTransformResponse: false }
            )
            // putAction(this.url.updateSensor, editSensorParams)
            .then((res) => {
              if (res.success) {
                this.$message.success('修改成功');
              } else {
                this.$message.error('修改失败: ', res.message);
              }
            });
        })
        // 站点
        .modelCallback(() => {
          let startNum = modelData.url.lastIndexOf('/') + 1;
          let modelName = '';
          if (startNum > 0) {
            modelName = modelData.url.substring(startNum, modelData.url.length);
          }
          // 发送请求 保存模型属性
          let editCameraSiteModelParameter = {
            id: model.ref,
            longitude: transform.toDegrees(modelData.xbsjPosition[0]).toFixed(6),
            latitude: transform.toDegrees(modelData.xbsjPosition[1]).toFixed(6),
            height: modelData.xbsjPosition[2],
            yaw: transform.toDegrees(modelData.xbsjRotation[0]).toFixed(6),
            pitch: transform.toDegrees(modelData.xbsjRotation[1]).toFixed(6),
            roll: transform.toDegrees(modelData.xbsjRotation[2]).toFixed(6),
            modelUrl: modelName,
            sitename: modelData.name,
          };
          defHttp
            .put(
              {
                url: this.url.updateSite,
                params: editCameraSiteModelParameter,
              },
              { isTransformResponse: false }
            )
            // putAction(this.url.updateSite, editCameraSiteModelParameter)
            .then((res) => {
              if (res.success) {
                modelData.pinBuilder.extText = modelData.name;
                this.$message.success('修改成功');
              } else {
                this.$message.error('修改失败');
              }
            });
        })
        // 标志点
        .markerPosition(() => {
          let pinImage = modelData.imageUrl;
          const staticDomainURL = window._CONFIG['staticDomainURL'] + '/';
          // 去除 image 地址中的 staticDomainURL 链接
          let imageUri = pinImage.substring(pinImage.indexOf(staticDomainURL) + staticDomainURL.length, pinImage.length);
          let editPinModelParameter = {
            id: model.ref,
            labelName: modelData.name,
            labelLon: transform.toDegrees(modelData.position[0]).toFixed(5),
            labelLat: transform.toDegrees(modelData.position[1]).toFixed(5),
            labelHeight: modelData.position[2].toFixed(2),
            labelImgUrl: imageUri,
          };
          defHttp
            .put(
              {
                url: this.url.updateMapLabel,
                params: editPinModelParameter,
              },
              { isTransformResponse: false }
            )
            // putAction(this.url.updateMapLabel, editPinModelParameter)
            .then((res) => {
              if (res.success) {
                modelData.pinBuilder.extText = modelData.name;
                this.$message.success('修改成功');
              } else {
                this.$message.error('修改失败');
              }
            })
            .catch((error) => {
              this.$message.error('修改失败');
            });
        })
        .polylineCallBack(() => {
          const submitData: any = {};
          const poistions = modelData.positions;
          if (poistions.length <= 0) {
            return;
          }
          submitData.id = model.ref;
          submitData.name = modelData.name;
          if (!modelData.customProp) {
            submitData.lineCode = modelData.guid;
          }

          submitData.isLoop = Number(modelData.loop);
          submitData.isDepthCheck = Number(modelData.depthTest);
          submitData.width = modelData.width;
          submitData.interpolation = modelData.arcType;
          submitData.positions = JSON.stringify(poistions);
          switch (modelData.material.type) {
            // 实线
            case 'XbsjColorMaterial':
              submitData.materialType = 0;
              // material.XbsjColorMaterial = {}
              submitData.color = JSON.stringify(modelData.material.XbsjColorMaterial.color);
              submitData.intervalColor = null;
              submitData.dashLength = 0;
              submitData.dashStyle = 0;
              break;
            // 虚线
            case 'XbsjPolylineDashMaterial':
              submitData.materialType = 1;
              submitData.color = JSON.stringify(modelData.material.XbsjPolylineDashMaterial.color);
              submitData.intervalColor = JSON.stringify(modelData.material.XbsjPolylineDashMaterial.gapColor);
              submitData.dashLength = modelData.material.XbsjPolylineDashMaterial.dashLength;
              submitData.dashStyle = modelData.material.XbsjPolylineDashMaterial.dashPattern;
              // material.XbsjPolylineDashMaterial = {}
              // material.XbsjPolylineDashMaterial.dashLength = data.dashLength
              // material.XbsjPolylineDashMaterial.dashPattern = data.dashStyle
              break;
            // 箭头线
            case 'XbsjPolylineArrowMaterial':
              submitData.materialType = 2;
              // material.XbsjPolylineArrowMaterial = {}
              submitData.color = JSON.stringify(modelData.material.XbsjPolylineArrowMaterial.color);
              submitData.intervalColor = null;
              submitData.dashLength = 0;
              submitData.dashStyle = 0;
              break;
            // 轨迹线
            case 'XbsjODLineMaterial':
              submitData.materialType = 3;
              submitData.color = JSON.stringify(modelData.material.XbsjODLineMaterial.color);
              submitData.intervalColor = null;
              submitData.dashLength = 0;
              submitData.dashStyle = 0;
              submitData.cycleFrame = modelData.material.XbsjODLineMaterial.totoalFrameCount;

              // material.XbsjODLineMaterial = {}
              // material.XbsjODLineMaterial.color = JSON.parse(data.color)
              // material.XbsjODLineMaterial.totoalFrameCount = data.cycleFrame
              break;
          }
          defHttp
            .put(
              {
                url: this.url.updateMapLine,
                params: submitData,
              },
              { isTransformResponse: false }
            )
            // putAction(this.url.updateMapLine, submitData)
            .then((res) => {
              if (res.success) {
                // $mitt.emit('openNotification', '修改成功', 2, 'info')
                $mitt.emit('openNotification', { msg: '修改成功!', dt: 2, type: 'info', top: '50px' });
                sn.title = submitData.name;
                window.$earth.sceneTree.$refs['node_' + sn.ref].title = submitData.name;
              } else {
                // $mitt.emit('openNotification', '修改失败', 2, 'error', '50px')
                $mitt.emit('openNotification', { msg: '修改失败', dt: 2, type: 'error', top: '50px' });
              }
            })
            .catch((error) => {
              // $mitt.emit('openNotification', '修改失败', 2, 'error', '50px')
              $mitt.emit('openNotification', { msg: '修改失败', dt: 2, type: 'error', top: '50px' });
            });
        })
        .run();
    }

    /**
     * 保存更改的ref到模型和后台数据中;
     * @param {Object} model 当前模型
     * @param {string} newRef 新的ref
     * @param {string} oldRef 旧的ref
     */
    changeRef = _.debounce(function (model, newRef, oldRef) {
      // 当数值改变时且旧值不等于空时,更新模型的ref
      if (newRef !== oldRef && oldRef !== '') {
        // 修改后台的数据
        this.handleNodeType(model)
          .sensor(() => {
            defHttp
              .put(
                {
                  url: this.url.updateSensor + `?eventSerialNum=${oldRef}`,
                  params: { eventSerialNum: newRef },
                },
                { isTransformResponse: false }
              )
              // putAction(this.url.updateSensor + `?eventSerialNum=${oldRef}`, {eventSerialNum: newRef})
              .then((res) => {
                if (res.success) {
                  // 设置保存的 ref
                  this.sceneTreeOldRefValue = '';
                  // 更新模型的名称
                  model.title = newRef;
                  this.$message.success('修改成功');
                } else {
                  this.$message.error('修改失败: ' + res.message);
                }
              })
              .catch((err) => {
                this.$message.error('修改失败: ', err);
              });
          })
          .modelCallback(() => {
            // 传感器标志线不能修改ref,因为 ref 是后台数据库的ID;
            this.$message.warning('无法修改传感器标志线的ref');
          })
          .run();
      }
    }, 150);
    handleNodeType(sn) {
      return new HandleNodeType(sn);
    }
    radarAlarmTimeOutCheck() {
      const now = Date.now();
      const timeout = 5 * 60 * 1000;
      // 遍历报警数据
      this.alarmInfoMap.forEach((value, key) => {
        // 获取当前时间与报警时间的时间差
        const timeDiff = now - value.timestamp;
        // 如果时间差大于5分钟,则清除报警
        if (timeDiff > timeout) {
          // 清除报警,有雷达告警则清除雷达告警和雷达轨迹
          this.clearAlarmModel(key);
        }
      });
    }
    clearRadarAlarmModel(radarAlarmDataMap, eventNum) {
      if (radarAlarmDataMap.has(eventNum)) {
        let alarmData = radarAlarmDataMap.get(eventNum);
        for (let target of alarmData.target) {
          let pathModel = target.path;
          let groundImageModel = target.groundImage;
          // 销毁模型
          pathModel && pathModel.destroy();
          groundImageModel && groundImageModel.destroy();
        }
        radarAlarmDataMap.delete(eventNum);
      }
    }
    clearAlarmModel(eventNum) {
      let alarmInfoMap = this.alarmInfoMap;
      let radarAlarmDataMap = this.radarAlarmDataMap;
      if (alarmInfoMap.has(eventNum)) {
        let alarmData = alarmInfoMap.get(eventNum);
        // 清除报警
        alarmData.pin && alarmData.pin._div.remove();
        alarmData.pin && alarmData.pin.destroy();
        alarmData.scanline && alarmData.scanline.destroy();
        this.alarmInfoMap.delete(eventNum);
      }
      this.clearRadarAlarmModel(radarAlarmDataMap, eventNum);
    }
    // 获取当前实时时间
    getRealTime() {
      this.timer2 = setInterval(() => {
        this.realTime = getRealTime();
      }, 1000);
    }
    // 资源销毁
    beforeDestroy() {
      // vue程序销毁时,需要清理相关资源
      this._earth = this._earth && this._earth.destroy();
      this.websocketclose();
      //清除定时器
      clearInterval(this.timer);
      clearInterval(this.timer2);
      clearInterval(this.alarmTrackClearTimer);
    }
  }
</script>

<style>
  .xbsj-model-box,
  .detail-model,
  .xbsj-modal-box {
    background: linear-gradient(360deg, rgba(9, 39, 76, 0.9), rgba(9, 39, 76, 0.6)) !important;
    /* border: 1px solid #2c58a6; */
    box-shadow: 0 0 10px #2c58a6;
  }

  .xbsjSceneTreeBox {
    left: initial !important;
    width: 280px !important;
    height: 600px !important;
    right: 0 !important;
    top: 0 !important;
    background: -webkit-linear-gradient(270deg, RGBA(9, 39, 76, 0.9), RGBA(9, 39, 76, 0.1)) !important;
    background: -o-linear-gradient(270deg, RGBA(9, 39, 76, 0.9), RGBA(9, 39, 76, 0.1)) !important;
    background: -moz-linear-gradient(270deg, RGBA(9, 39, 76, 0.9), RGBA(9, 39, 76, 0.1)) !important;
    background: linear-gradient(270deg, RGBA(9, 39, 76, 0.9), RGBA(9, 39, 76, 0.1)) !important;
    box-shadow: none !important;
  }

  .xbsjSceneTreeBox .xbsj-model-close {
    display: none;
  }

  .xbsjcesium + div {
    background: -webkit-linear-gradient(360deg, RGBA(9, 39, 76, 0.9), RGBA(9, 39, 76, 0.1)) !important;
    background: -o-linear-gradient(360deg, RGBA(9, 39, 76, 0.9), RGBA(9, 39, 76, 0.1)) !important;
    background: -moz-linear-gradient(360deg, RGBA(9, 39, 76, 0.9), RGBA(9, 39, 76, 0.1)) !important;
    background: linear-gradient(360deg, RGBA(9, 39, 76, 0.9), RGBA(9, 39, 76, 0.1)) !important;
  }

  .distance-legend {
    background: RGBA(9, 39, 76, 0.8);
  }

  /* 标题 */
  .earthUI_header header {
    position: relative;
    top: -3px;
    height: 4rem;
    background: url(../../../assets/earthMap/head_bg.png) no-repeat top center;
    background-size: 100% 90%;
  }

  .earthUI_header p {
    font-family: 'Arial', 'Microsoft YaHei', '黑体', '宋体', sans-serif;
    color: #00ffe4;
    text-align: center;
    margin: 0;
    padding: 0;
  }

  .earthUI_header header > p:first-child {
    font-size: 1.1rem;
    line-height: 28px;
    padding-top: 0.5vh;
    /* 文字间隔 */
    letter-spacing: 5px;
  }

  .earthUI_header header > p:last-child {
    font-family: Microsoft YaHei;
    font-size: 0.8rem;
    font-weight: 400;
    /* 文字间隔 */
    letter-spacing: 0.5px;
  }

  .quitBtn {
    position: relative;
    text-align: center;
    font-size: 12px;
    min-width: 100px;
    width: 120px;
    height: 30px;
    padding: 0 7px;
    margin-left: 100px;
    line-height: 30px;
    border-radius: 100px;
    border: 1px solid #c9c9c9;
    background-color: #fff;
    color: #555;
    cursor: pointer;
    display: none;
  }

  /* 视频窗口 */
  .videos {
    display: none;
    border: 1px solid #080808;
    /*position: fixed;
   right: 0;
  bottom: 2px; */
    position: absolute;
    left: 0;
    top: 0;
    z-index: 100;
    width: 420px;
    height: 380px;
    -webkit-box-shadow: 0px 3px 3px #c8c8c8;
    -moz-box-shadow: 0px 3px 3px #c8c8c8;
    box-shadow: 0px 3px 3px #c8c8c8;
  }

  .vclose {
    position: absolute;
    right: 1%;
    top: 1%;
    border-radius: 100%;
    cursor: pointer;
  }

  .videosSpan1 {
    position: absolute;
    left: 1%;
    top: 1%;
    color: #000;
    font-size: 15px;
    font-weight: bold;
    font-family: 黑体;
    border-radius: 100%;
  }

  .videosSpan2 {
    position: absolute;
    right: 1%;
    bottom: 1%;
    color: #000;
    font-size: 16px;
    font-weight: bold;
    font-family: 黑体;
    border-radius: 100%;
  }

  /* 相机状态点 */
  .successStatus,
  .offlineStatus,
  .errorStatus {
    position: relative;
  }

  .successStatus::before {
    content: ' ';
    position: absolute;
    height: 7px;
    width: 7px;
    top: -60px;
    left: 0;
    /*transform: translateY(-50%);*/
    border-radius: 50%;
    background: rgb(0, 255, 0);
  }

  .offlineStatus::before {
    content: ' ';
    position: absolute;
    height: 7px;
    width: 7px;
    top: -60px;
    left: 0;
    /*transform: translateY(-50%);*/
    border-radius: 50%;
    background: rgb(170, 170, 170);
  }

  .errorStatus::before {
    content: ' ';
    position: absolute;
    height: 7px;
    width: 7px;
    top: -60px;
    left: 0;
    /*transform: translateY(-50%);*/
    border-radius: 50%;
    background: rgb(255, 0, 0);
  }

  /* 相机状态点 */

  /* 电线杆气泡窗 */
  .cameraModal {
    margin: 20px auto;
    position: absolute;
    left: 0;
    top: 0;
    width: auto;
    line-height: 25px;
    color: white;
    text-align: center;
    font-size: 14px;
    border: 1px solid rgb(255, 255, 255);
    opacity: 0.9;
    border-radius: 5px;
    background: rgb(255, 255, 255);
  }

  .cameraModal::after {
    /* 箭头靠下边 */
    content: '';
    position: absolute;
    width: 0;
    height: 0;
    left: 35px;
    bottom: -15px;
    border-left: 10px solid transparent;
    border-right: 10px solid transparent;
    border-top: 15px solid rgb(255, 255, 255);
  }

  .cameraModal ul {
    margin: 20px;
    padding: 0px;
    list-style: none;
  }

  .cameraModal li {
    float: left;
    list-style-type: none;
    display: inline;
    margin: 5px;
    width: 120px;
    border: 2px solid #fff;
  }

  .cameraModal li:hover {
    border-bottom-color: #00ffe4;
  }

  .cameraModal li > a {
    color: rgb(19, 15, 15);
    text-decoration: none;
    cursor: pointer;
  }

  .cameraModal img {
    width: 80px;
    height: 60px;
    display: block;
    margin: 0 auto;
  }

  .spinning {
    position: absolute;
    left: 50%;
    top: 35%;
    z-index: 999;
  }

  /* 电线杆气泡窗 */

  /* 地标气泡窗 */
  /*.poiModal {
  margin: 20px auto;
  padding: 5px;
  position: absolute;
  left: 0;
  top: 0;
  height: 160px;
  width: 300px;
  color: white;
  text-align: center;
  font-size: 14px;
  border: 1px solid RGBA(12, 177, 177, 0.8);
  border-radius: 5px;
  filter: alpha(opacity=50);
  background: RGBA(12, 177, 177, 0.9);
}

.poiModal::after {
  !* 箭头靠下边 *!
  content: '';
  position: absolute;
  width: 0;
  height: 0;
  left: 140px;
  bottom: -15px;
  border-left: 10px solid transparent;
  border-right: 10px solid transparent;
  border-top: 15px solid RGBA(12, 177, 177, 0.8);
}

.poiModal-content {
  width: 100%;
  height: 100%;
  box-shadow: 0 5px 8px 0 rgba(0, 0, 0, 0.2), 0 7px 20px 0 rgba(0, 0, 0, 0.2);
  animation-name: modalopen;
  animation-duration: 1s;
}

.poiModal-header h2 {
  margin: 0;
  color: white;
}

.poiModal-header {
  line-height: 40px;
}

.poiModal-body {
  text-align: left;
  font-size: 16px;
  padding-left: 5px;
}

.poiModal-body span {
  color: #ffeb3b;
}*/

  /* 地标气泡窗 */
  /* 地图切换按钮 */
  .radioBtn {
    position: absolute;
    bottom: 40px;
    right: 15px;
  }

  .radioBtn span {
    transition: color 0.3s linear;
  }

  .radioBtn span:hover {
    color: #00ffe4bb !important;
    transition: color 0.3s linear;
  }

  .ant-radio-button-wrapper-checked {
    background: #00ffe4bb !important;
    border-color: #00ffe4 !important;
  }

  .ant-radio-button-wrapper-checked:not(.ant-radio-button-wrapper-disabled)::before {
    background-color: #00ffe4 !important;
  }

  .earthChangeSpin {
    position: absolute;
    left: 45%;
    top: 35%;
  }

  .ant-spin {
    color: #00ffe4;
  }

  .ant-spin-dot-item {
    background-color: #00ffe4;
  }

  /* 地图切换按钮 */
  /* 比例尺和指南针属性 */
  #distanceLegendDiv .distance-legend {
    bottom: 80px !important;
    background-color: rgba(9, 39, 76, 0.7) !important;
  }

  #navigationDiv > div {
    top: unset !important;
    /*去掉已有的top值使bottom生效 */
    bottom: 120px !important;
    right: 40px !important;
  }

  .compass-outer-ring-background {
    border: 12px solid rgba(9, 39, 76, 0.7) !important;
  }

  .compass-gyro-background {
    background-color: rgba(9, 39, 76, 0.7) !important;
  }

  /* 比例尺和指南针属性 */

  body {
    user-select: none;
  }
</style>