<template>
  <div class="cesium-page-css">
    <basis-cesium ref="basisCesium" :access-token="this.$setting.cesiumSetting.defaultAccessToken" />
    <div class="cesiumContainer2d">
      <div ref="cesiumRef2D" id="cesium2d"></div>
    </div>
    <main-view ref="mainView" :speed="speed" :heading="heading2" :v2xname="v2xname" :driveMode="driveMode"
      :endTime="endTime" :rsiChange="rsiChange" :infowindowChange="infowindowChange" />
    <div class="showBuildingBtn">
      <el-switch active-text="建筑物" v-model="showBuilding" active-color="rgb(99, 122, 190)"
        @change="setBuildingVisibility">
      </el-switch>
    </div>
    <div class="videoBox">
      <video controls>
        <source src="" type="video/mp4">
      </video>
    </div>
  </div>
</template>

<script>
import Worker from "@/assets/js/bessel.worker.js";
import basisCesium from "@/components/cesium/basis-cesium.vue";
import mainView from "@/components/other/main-view.vue";
import websocket from "@/utils/ws/websocket.js";
import axios from "axios";
import SpaceData from "@/assets/SpaceJSON.json";
import CarJSON from "@/assets/CarJSON.json";
// import * as Cesium from "cesium/Cesium";
import * as turf from "@turf/turf";
import cesiumMainIns from "@/utils/cesiumMain";

import carpng_src from "@/assets/img/car.png";

let v2xdata = {
  v2xArray: [],
};
let baseData = {
  mainCarID: "",
  mainLocation: {
    lon: 116.50304817785404,
    lat: 39.80882415169232,
  },
};

let carArr = []
let lineArr = []
window.carArr = carArr
window.lineArr = lineArr
window.bblineArr = []

window.recordData = {};
window.needRecord = false;

// 记录rsi高亮的感知物数组
let rsiHighlightArr = [];
// 记录rsi数组
let rsiEventArr = [];

// 感知目标物topic对象，主要用于记录感知目标物什么时候结束，以及结束后的操作
let dataMergeTopicObj = {
  timer: null, // 计时器
  lastSecond: null, // 最新记录的秒数
};

// 停车位编码
let spaceCode = "";

let worker = null;
let postData = [];
let AllTingCheChang = [];

let viewer2d; // 二维视图
let car2d; // 二维车辆
let polyine2d = {}; // 二维路线
let billboardCollection2d; // 二维图标集合
let primitiveCollection3d;  // 三维primitive集合
let polylineCollection2d; // 二维poliline集合
let singleLinePathPosition = []; // 整体路径的坐标
let highlightSpaceEntity = null;

// basis-cesium 中已经算好了路径，就不需要重复计算，直接使用
window.beforePath = [] // 车辆前面还没走的路径
window.afterPath = [] // 车辆前面还没走的路径
window.leftPath = [] // 倒车入库左边的路径
window.rightPath = [] // 倒车入库右边的路径

export default {
  name: "HomeView",
  components: {
    basisCesium,
    mainView,
  },
  //L
  data() {
    return {
      heading2: "—— ——", //航向角显示
      v2xname: "-", //预警事件名称
      driveMode: "—— ——", //驾驶模式
      driveModeCode: -1, //驾驶模式
      speed: 0, //速度
      endTime: false, //用于判断预警事件是否展示完毕，false为没有预警事件
      // 是否是车内视角
      firstPerspective: false,
      audioSrc: "@/assets/11582.mp3",
      rsiChange: {}, // rsi改变，界面弹窗
      infowindowChange: {}, // 弹窗信息改变，界面弹窗
      showBuilding: true, // 是否显示停车场外围建筑物
    };
  },

  //A
  mounted() {
    this.initMap();
    this.initViewer2d(); // 初始化二维场景

    // todo 采用测试数据 todo 暂时注释
    this.websocketClient();
    // this.addTestCar()

    // 采用worker的目的是，当websoket推送频率降低，两帧数据之间的点位距离较大，在这两个点之间做插值，使路线平滑
    worker = new Worker();
    worker.onmessage = (e) => {
      let lon = e.data[0];
      let lat = e.data[1];
      let alt = e.data[2];

      if (this.needDealPath) {
        // 根据车辆位置计算已经走过的点
        this.$refs.basisCesium.updatePathPlanLine(lon, lat);

        // 小地图中路径
        cesiumMainIns.updateLinePosition2D(polyine2d, {
          before: window.beforePath,
          after: window.afterPath,
          left: window.leftPath,
          right: window.rightPath,
        });
        // console.log('window.leftPath', window.leftPath)
      }

      // 移动车辆位置
      this.moveCar(lon, lat, alt);

      // carArr.push([lon, lat, alt])
    };

    // 延时5秒查询车位信息
    setTimeout(this.getSpaceData, 5000);

    // 每隔20s查询一次车位信息
    setInterval(this.getSpaceData, 20000);

    // todo 测试代码
    // this.addTest()
  },
  methods: {
    /**
     * 模拟入库
     */
    addTest() {
      let gui = new dat.GUI();
      let param = {
        mockCar: () => {
          spaceCode = "C002";
          let index = 50;
          setInterval(() => {
            let bodyData = CarJSON[index];
            this.topicVehicle(bodyData);

            index++;
            if (index == CarJSON.length) {
              index = 50;
            }
          }, 300);
        },
        startParking: () => {
          this.needDealPath = true;
          spaceCode = "1D-005";
          this.setAvpStatus(true);
        },
        changeParking: () => {
          spaceCode = "C004";
          let parkingSpot = this.getParkingSpot(spaceCode);
          this.$refs.basisCesium.updateParkingSpace(parkingSpot);
        },
        startAvoidance: () => {
          let obj = {
            objectData: [
              {
                taskType: 1,
                vehiclePlate: "吉AC242",
                lineName: "",
                pointStr: "[]",
                tenantCode: "VL961",
                type: 2, // 1避障 2倒车入库
              },
            ],
            wsTime: 1720253314196,
          };

          this.topicPartLine(obj);
        },
        endAvoidance: () => {
          this.$refs.basisCesium.removeAvoidanceEffect();
        },
        backPath: () => {
          this.$refs.basisCesium.addBackParkingEffect({
            spaceInfo: {
              spaceCode: "1D-005",
              coordinates: [
                [
                  125.14352243,
                  43.8387679
                ],
                [
                  125.14349542,
                  43.83875615
                ],
                [
                  125.14346121,
                  43.83879796
                ],
                [
                  125.14348784,
                  43.83880941
                ],
                [
                  125.14352243,
                  43.8387679
                ]
              ],
              type: "car",
              heading: 130,
              center: [120.70663029752453, 31.32409853737599],
            },
          });
        },
        endParking: () => {
          this.$refs.basisCesium.removeParkingEffect();
        },
        startV2x1: () => {
          this.topicv2xStart({
            v2xStartData: [
              {
                id: "111",
                name: "弱势交通参与者碰撞预警",
                priority: 2,
              },
            ],
          });
        },
        startV2x2: () => {
          this.topicv2xStart({
            v2xStartData: [
              {
                id: "222",
                name: "弱势交通参与者碰撞预警",
                priority: 3,
              },
            ],
          });
        },
        endV2x1: () => {
          this.topicv2xEnd({
            v2xEndData: [
              {
                id: "111",
              },
            ],
          });
        },
        endV2x2: () => {
          this.topicv2xEnd({
            v2xEndData: [
              {
                id: "222",
              },
            ],
          });
        },
        addMerge: () => {
          let bodyData = {
            objectData: [
              {
                participant: [
                  {
                    ptcId: "7113",
                    ptcType: "pedestrian",
                    heading: 90,
                    longitude: 120.70653432313952,
                    latitude: 31.32399543429305,
                  },
                ],
                deviceCode: "merge111deviceCode",
              },
            ],
          };
          this.topicDataMerge(bodyData);
        },
        highlightMerge: () => {
          this.$refs.basisCesium.highlightPerceive("1363547912");
        },
        cancleHighlightMerge: () => {
          this.$refs.basisCesium.cancleHighlightPerceive("1363547912");
        },
        startCongestion: () => {
          this.$refs.basisCesium.addCongestionEffect({
            eventId: "707",
            eventPosition: {
              lon: 120.70650368953218,
              lat: 31.32387012500568,
            },
            eventRadius: 25,
          });
        },
        startCongestion2: () => {
          this.$refs.basisCesium.addCongestionEffect({
            eventId: "707",
            eventPosition: {
              lon: 120.70627736888751,
              lat: 31.324424454655308,
            },
            eventRadius: 15,
          });
        },
        startCongestion3: () => {
          this.$refs.basisCesium.addCongestionEffect({
            eventId: "707",
            eventPosition: {
              lon: 120.7064005384187,
              lat: 31.324587955182743,
            },
            eventRadius: 15,
          });
        },
        startCongestion4: () => {
          this.$refs.basisCesium.addCongestionEffect({
            eventId: "707",
            eventPosition: {
              lon: 120.70640680679377,
              lat: 31.324612419581705,
            },
            eventRadius: 15,
          });
        },
        endCongestion: () => {
          this.$refs.basisCesium.removeCongestionEffect("707");
        },
        startRoadConstruction: () => {
          this.$refs.basisCesium.addRoadConstructionEffect({
            eventId: "38",
            eventPosition: {
              lon: 120.70640680679377,
              lat: 31.324612419581705,
            },
            eventRadius: 15,
          });
        },
        endRoadConstruction: () => {
          this.$refs.basisCesium.removeRoadConstructionEffect("38");
        },
        startRsi: () => {
          let obj = {
            objectData: [
              {
                reportData: [
                  {
                    eventId: "100",
                    eventType: "707",
                    eventPosition: {
                      lon: 120.70575286803157,
                      lat: 31.32438408479422,
                    },
                  },
                ],
                tenantCode: "VL961",
              },
            ],
            wsTime: 1720059537473,
          };

          this.topicRsiEvent(obj);
        },
        startRsi2: () => {
          let obj = {
            objectData: [
              {
                reportData: [
                  {
                    eventId: "901-2",
                    eventRadius: 1,
                    referencePaths: [
                      {
                        activePath: [
                          {
                            lon: 120.1234567,
                            lat: 30.7654321,
                          },
                        ],
                      },
                    ],
                    eventSource: "3",
                    eventDescription: "3",
                    eventObjId: ["119951397"],
                    eventType: "901",
                    eventPriority: "17",
                    referenceLinkList: [
                      {
                        upstreamNodeId: 63880,
                        downstreamNodeId: 63880,
                      },
                    ],
                    eventPosition: {
                      lon: 120.70575286803157,
                      lat: 31.32438408479422,
                    },
                  },
                ],
                tenantCode: "VL961",
              },
            ],
            wsTime: 1720059537473,
          };

          this.topicRsiEvent(obj);
        },
        endRsi: () => {
          this.topicRsiEvent({
            objectData: [],
          });
        },
        startRecord: () => {
          window.needRecord = true;
          window.recordData = {
            vehicle: [],
            vehicleStatus: [],
            dataMerge: [],
            v2xStart: [],
            v2xEnd: [],
            points: [],
            linePlaning: [],
            linePlaningHttp: [],
            partLine: [],
            rsiEvent: [],
            getOrderParkingInfoForPlate: [],
            spaceNo: [],
          };
        },
        endRecord: () => {
          needRecord = false;
        },
        linePlaningInfowindow: () => {
          // 弹窗显示
          this.infowindowChange = {
            time: new Date().getTime(),
            type: "linePlaning",
            text: "已重新规划路线",
          };
        },
        mockGetSpaceData: () => {
          let response = {
            code: "0",
            msg: "pgs.common.msg.success",
            data: {
              total: 85,
              pageNo: 1,
              pageSize: 1000,
              totalPage: 1,
              list: [
                {
                  spaceSyscode: "fe3960ce3dd9420d915785d5a7b2255f",
                  spaceNo: "1C-033",
                  // "spaceNo": "1A-053",
                  parkSyscode: "8abec9a2db5f442a86ba563b40c41f00",
                  parkName: "博览中心",
                  floorSyscode: "2a6452b0a9fb4d1fa02bcf7e1dc16817",
                  floorName: "负1",
                  longitude: "946.0",
                  latitude: "657.0",
                  state: 1,
                  inTime: "2024-10-28T11:29:27+08:00",
                  spacePicUri:
                    "/pic?0d2500=d580ip-beo621-f67*1o5=2503*7l0=0106078763t0=912**ps==810b*=22a0*3b4250a17-82375e-0*l10aod04952=004",
                  plateNoPicUri: null,
                  aswSyscode: "f52ac7d7-b3f9-4a5e-8844-c999b1bd76aa",
                  plateNos: "苏A2T9C7,苏EAVP002,吉AC242",
                  alarmPlateNos: null,
                  spaceTypeKey: "1",
                  spaceType: "允许停放车位",
                  plateNo: "苏EFP9932",
                  spacePicUrl:
                    "http://10.16.14.20:6120/pic?0d2500=d580ip-beo621-f67*1o5=2503*7l0=0106078763t0=912**ps==810b*=22a0*3b4250a17-82375e-0*l10aod04952=004&AccessKeyId=sdY2KWVe/wHUcN0P&Expires=1730709991&Signature=OjTzwM3ZwMnA4eiszgd6SBXX+IY=",
                  plateNoPicUrl: null,
                },
              ],
            },
          };

          AllTingCheChang = [];
          const newData = response.data.list;
          postData = newData;
          // 遍历新数据，根据state值添加或移除模型
          postData.forEach((car) => {
            const parkingSpot = SpaceData.find(
              (spot) => spot.spaceCode === car.spaceNo
            );
            if (parkingSpot) {
              // 检查该车位是否已经添加模型
              if (car.state === 1) {
                //将车位信息添加到已添加模型的数据中;
                const name = parkingSpot.spaceCode;
                const latlon = [parkingSpot.center[0], parkingSpot.center[1]];
                let distance = this.getDistance(
                  baseData.mainLocation.lon,
                  baseData.mainLocation.lat,
                  latlon[0],
                  latlon[1]
                );
                if (distance > 2) {
                  AllTingCheChang.push({
                    id: name,
                    longitude: latlon[0],
                    latitude: latlon[1],
                    heading: parkingSpot.heading,
                  });
                }
              }
            }
          });
          this.$refs.basisCesium.beginParkingLot(AllTingCheChang);

          if (needRecord) {
            window.recordData.spaceNo.push(response);
          }
        },
      };
      gui.add(param, "mockCar").name("模拟跑车");
      gui.add(param, "startParking").name("开始泊车");
      gui.add(param, "changeParking").name("切换车位");
      gui.add(param, "startAvoidance").name("开始避让");
      gui.add(param, "endAvoidance").name("结束避让");
      gui.add(param, "backPath").name("倒车入库");
      gui.add(param, "endParking").name("结束自主泊车");
      gui.add(param, "startV2x1").name("开始v2x1");
      gui.add(param, "endV2x1").name("结束v2x1");
      gui.add(param, "startV2x2").name("开始v2x2");
      gui.add(param, "endV2x2").name("结束v2x2");
      gui.add(param, "addMerge").name("添加感知物");
      gui.add(param, "highlightMerge").name("高亮感知物");
      gui.add(param, "cancleHighlightMerge").name("取消高亮感知物");
      gui.add(param, "startCongestion").name("发生拥堵");
      gui.add(param, "startCongestion2").name("发生拥堵2");
      gui.add(param, "startCongestion3").name("发生拥堵3");
      gui.add(param, "startCongestion4").name("发生拥堵4");
      gui.add(param, "endCongestion").name("拥堵结束");
      gui.add(param, "startRoadConstruction").name("发生道路施工");
      gui.add(param, "endRoadConstruction").name("结束道路施工");
      gui.add(param, "startRsi").name("开始rsi");
      gui.add(param, "startRsi2").name("结束rsi1");
      gui.add(param, "startRsi2").name("开始rsi2");
      gui.add(param, "startRsi").name("结束rsi2");
      gui.add(param, "endRsi").name("结束所有rsi");
      gui.add(param, "startRecord").name("开始记录");
      gui.add(param, "endRecord").name("结束记录");
      gui.add(param, "linePlaningInfowindow").name("切换路径弹窗");
      gui.add(param, "mockGetSpaceData").name("停车位信息");
    },

    addTestCar() {
      const res = pathRes
      this.$refs.basisCesium.findPathPlanning(res);

      // 高亮车位
      spaceCode = "1D-005";
      this.highlightSpaceEntity(spaceCode)

      setTimeout(() => {
        spaceCode = "1D-004";
        this.highlightSpaceEntity(spaceCode)
      }, 5000)

      setTimeout(() => {
        spaceCode = "";
        this.highlightSpaceEntity(spaceCode)
      }, 8000)

      let index = 0
      const timer = setInterval(() => {
        if (index == pathCar.length) {
          clearInterval(timer)
          return
        }
        const ele = pathCar[index]
        const bodyData = {
          "vehicleData": [
            {
              "altitude": 0,
              "brake": 30,
              "gasPedal": 20,
              "gear": 1,
              "heading": 0,
              "latitude": ele[1],
              "longitude": ele[0],
              "obuCode": "O-HK-2687",
              "reportTime": 1748411699632,
              "speed": 0,
              "vehicleId": "1694264612474306561",
              "vehiclePlate": "吉AC242",
              "vehiclePurpose": "avp",
              "vehiclePurposeName": "AVP车辆",
              "wheelAngle": 2
            }
          ],
          "wsTime": 1748411699632
        }
        this.topicVehicle(bodyData);
        index++
      }, 1)
    },

    // 设置停车场外围建筑物的显示和隐藏
    setBuildingVisibility(value) {
      this.$refs.basisCesium.setBuildingVisibility(value);
    },

    initMap() {
      this.$refs.basisCesium.buildCesiumWorld();
      this.$refs.basisCesium.inject3DtilesMapByUrl("unit/tileset.json"); // 停车场外部建筑
      // this.$refs.basisCesium.inject3DtilesMapByUrl_two("garage/tileset.json");  // 停车场内部建筑
      this.$refs.basisCesium.addWmsDT(); // 低精地图
      this.$refs.basisCesium.addWmsGQDT(); // 高精地图
      this.$refs.basisCesium.cesiumCameraflyTo(
        125.142191,
        43.829754,
        600,
        356,
        -33,
        0
      );
    },

    async websocketClient() {
      await websocket.connectSocket();

      // 2.2. 联网车辆位姿数据topic
      websocket.stompClient.subscribe(
        this.$setting.webSocket.dic["/topic/vehicle"],
        (message) => {
          let bodyData = JSON.parse(message.body);
          this.topicVehicle(bodyData);
          // console.log('车辆', bodyData)

          if (needRecord) {
            window.recordData.vehicle.push(bodyData);
          }
        }
      );
      // 2.3. 联网车辆状态数据topic
      websocket.stompClient.subscribe(
        this.$setting.webSocket.dic["/topic/vehicleStatus"],
        (message) => {
          var bodyData = JSON.parse(message.body);
          this.topicVehicleStatus(bodyData);

          if (needRecord) {
            window.recordData.vehicleStatus.push(bodyData);
          }
        }
      );
      // 2.4. 感知目标物数据topic
      websocket.stompClient.subscribe(
        this.$setting.webSocket.dic["/topic/dataMerge"],
        (message) => {
          var bodyData = JSON.parse(message.body);
          this.topicDataMerge(bodyData);

          if (needRecord) {
            window.recordData.dataMerge.push(bodyData);
          }

          // 2秒没有消息推过来，则需要清除所有感知目标物了
          dataMergeTopicObj.lastSecond = new Date().getTime();
          if (dataMergeTopicObj.timer) {
            return;
          }
          dataMergeTopicObj.timer = setInterval(() => {
            let newSecond = new Date().getTime();
            if (newSecond - dataMergeTopicObj.lastSecond > 2000) {
              // 清除所有感知目标物
              this.removeDataMerge();

              clearInterval(dataMergeTopicObj.timer);
              dataMergeTopicObj.timer = null;
              console.log("2s接收不到感知目标物，清除感知目标物");
            }
          }, 500);

          // console.log(bodyData)
        }
      );

      // 2.5. V2X预警开始topic
      websocket.stompClient.subscribe(
        this.$setting.webSocket.dic["/topic/v2xStart"],
        (message) => {
          var bodyData = JSON.parse(message.body);
          this.topicv2xStart(bodyData);

          if (needRecord) {
            window.recordData.v2xStart.push(bodyData);
          }
        }
      );
      // 2.6. V2X预警结束topic
      websocket.stompClient.subscribe(
        this.$setting.webSocket.dic["/topic/v2xEnd"],
        (message) => {
          var bodyData = JSON.parse(message.body);
          this.topicv2xEnd(bodyData);

          if (needRecord) {
            window.recordData.v2xEnd.push(bodyData);
          }
        }
      );
      websocket.stompClient.subscribe(
        this.$setting.webSocket.dic["/topic/points"],
        (message) => {
          var bodyData = JSON.parse(message.body);
          this.topicvPoints(bodyData);

          if (needRecord) {
            window.recordData.points.push(bodyData);
          }
        }
      );

      // 全局路径发生切换
      websocket.stompClient.subscribe(
        this.$setting.webSocket.dic["/topic/linePlaning"],
        (message) => {
          var bodyData = JSON.parse(message.body);
          this.topicLinePlaning(bodyData);

          if (needRecord) {
            window.recordData.linePlaning.push(bodyData);
          }

          // console.log('/topic/linePlaning', bodyData)
        }
      );

      // 局部路径
      websocket.stompClient.subscribe(
        this.$setting.webSocket.dic["/topic/partLine"],
        (message) => {
          var bodyData = JSON.parse(message.body);
          this.topicPartLine(bodyData);

          if (needRecord) {
            window.recordData.partLine.push(bodyData);
          }

          // console.log('局部路径', bodyData)
        }
      );

      // rsi事件
      websocket.stompClient.subscribe(
        this.$setting.webSocket.dic["/topic/rsiEvent"],
        (message) => {
          var bodyData = JSON.parse(message.body);
          this.topicRsiEvent(bodyData);

          if (needRecord) {
            window.recordData.rsiEvent.push(bodyData);
          }

          // console.log(bodyData)
        }
      );
    },

    /**
     * 车辆驾驶模式
     * @param {*} msg
     */
    topicVehicleStatus(msg) {
      if (msg.vehicleStatusList.length != 0) {
        let driveMode1 = msg.vehicleStatusList[0].driveMode;
        this.driveModeCode = driveMode1;
        switch (driveMode1) {
          case 0:
            this.driveMode = "自动驾驶";

            // 如果有全局路径，那么显示全局路径
            this.$refs.basisCesium.organizePathLine({
              type: "driveMode0",
            });
            break;
          case 1:
            this.driveMode = "人工驾驶";

            // 如果有全局路径，那么隐藏全局路径
            this.$refs.basisCesium.organizePathLine({
              path: [],
              type: "driveMode1",
            });
            break;
          case 2:
            this.driveMode = "远程驾驶";
            break;
          default:
            this.driveMode = "—— ——";
            break;
        }
      }
    },

    /**
     * v2x开始
     * @param {*} msg
     */
    topicv2xStart(msg) {
      let v2xStartName = msg.v2xStartData[0].name;
      if (
        v2xStartName == "异常车辆预警" ||
        v2xStartName == "车辆入场预警" ||
        v2xStartName == "前向碰撞预警" ||
        v2xStartName == "盲区/变道预警" ||
        v2xStartName == "交叉路口碰撞预警" ||
        v2xStartName == "弱势交通参与者碰撞预警"
      ) {
        v2xdata.v2xArray.push({
          id: msg.v2xStartData[0].id,
          name: msg.v2xStartData[0].name,
          priority: msg.v2xStartData[0].priority,
          no: msg.v2xStartData[0].no,
        });
        //通过冒泡排序对插入在v2xArray的数组按照priority优先级由低到高进行排序
        const n = v2xdata.v2xArray.length;
        if (n > 1) {
          for (let i = 0; i < n - 1; i++) {
            let swapped = false; // 优化：如果某一轮没有进行交换，则说明数组已经有序，可以提前结束循环
            for (let j = 0; j < n - 1 - i; j++) {
              if (
                parseInt(v2xdata.v2xArray[j].priority) >
                parseInt(v2xdata.v2xArray[j + 1].priority)
              ) {
                // 交换位置
                const temp = v2xdata.v2xArray[j];
                v2xdata.v2xArray[j] = v2xdata.v2xArray[j + 1];
                v2xdata.v2xArray[j + 1] = temp;
                swapped = true;
              }
            }
            if (!swapped) {
              break; // 优化：如果没有进行交换，则说明数组已经有序，可以提前结束排序
            }
          }
        }
        this.v2xname = v2xdata.v2xArray[n - 1].name;
        this.endTime = true;
      }

      // 高亮目标物
      if (
        msg.v2xStartData[0] &&
        msg.v2xStartData[0].mec &&
        msg.v2xStartData[0].mec.length
      ) {
        console.log(msg.v2xStartData[0]);

        let needHighIds = msg.v2xStartData[0].mec;
        for (let i = 0; i < needHighIds.length; i++) {
          let nendId = needHighIds[i].id;
          let eventType = needHighIds[i].type;
          this.$refs.basisCesium.highlightPerceive({
            nendId,
            eventType,
            iconType: "v2xicon",
            mainCarID: baseData.mainCarID,
          });
        }
      }
    },

    /**
     * v2x结束
     * @param {*} msg
     */
    topicv2xEnd(msg) {
      v2xdata.v2xArray.forEach((item, index) => {
        if (item.id === msg.v2xEndData[0].id) {
          v2xdata.v2xArray.splice(index, 1); // 如果找到匹配的id，则删除该数组
        }
      });
      const n = v2xdata.v2xArray.length;
      if (n == 0) {
        //如果数组为空，则将endTime变为false，表示预警事件全部结束，隐藏预警
        this.endTime = false;
      } else {
        this.v2xname = v2xdata.v2xArray[n - 1].name;
        this.endTime = true;
        //否则会将优先级最高的事件进行展示
      }

      // 取消高亮目标物
      if (
        msg.v2xEndData[0] &&
        msg.v2xEndData[0].mec &&
        msg.v2xEndData[0].mec.length
      ) {
        console.log(msg.v2xEndData[0]);

        let needHighIds = msg.v2xEndData[0].mec;
        for (let i = 0; i < needHighIds.length; i++) {
          let nendId = needHighIds[i].id;
          this.$refs.basisCesium.cancleHighlightPerceive(nendId);
        }
      }
    },

    /**
     * 车辆实时位置、航向角等信息
     * @param {*} msg
     */
    topicVehicle(msg) {
      if (!msg || !msg.vehicleData || !msg.vehicleData.length) {
        return;
      }

      let vehicleData = msg.vehicleData[0];
      let { speed, heading, longitude, latitude } = vehicleData;
      let curHeading = heading - 90;
      this.speed = speed;

      // 设置界面上显示的角度
      this.setUIHeading(heading);

      if (baseData.mainCarID == "") {
        let id = msg.vehicleData[0].vehicleId;
        let url = "./cesium/yqcar.glb";
        this.$refs.basisCesium.addOneModelById({
          id,
          url,
          longitude,
          latitude,
          angle: curHeading,
          scale: 0.8,
        });
        baseData.mainCarID = id;
      } else {
        // 采用多线程插值
        worker.postMessage([longitude, latitude, curHeading]);

        // 如果不采用多线程插值，就需要在这里移动车辆位置
        // this.moveCar(longitude, latitude, heading);
      }

      // 记录车辆位置
      baseData.mainLocation.lon = longitude;
      baseData.mainLocation.lat = latitude;
    },

    /**
     * 设置界面上显示的角度
     * @param {*} heading
     */
    setUIHeading(heading) {
      let heading1 = Math.floor(heading);
      if (heading1 < 0) {
        heading1 += 360;
      }
      switch (true) {
        case heading1 === 0:
          this.heading2 = "正北";
          break;
        case heading1 === 90:
          this.heading2 = "正东";
          break;
        case heading1 === 180:
          this.heading2 = "正南";
          break;
        case heading1 === 270:
          this.heading2 = "正西";
          break;
        case heading1 > 0 && heading1 <= 45:
          this.heading2 = "北偏东 " + heading1 + "°";
          break;
        case heading1 > 45 && heading1 < 90:
          this.heading2 = "东偏北 " + (90 - heading1) + "°";
          break;
        case heading1 > 90 && heading1 <= 135:
          this.heading2 = "东偏南 " + (heading1 - 90) + "°";
          break;
        case heading1 > 135 && heading1 < 180:
          this.heading2 = "南偏东 " + (180 - heading1) + "°";
          break;
        case heading1 > 180 && heading1 <= 225:
          this.heading2 = "南偏西 " + (heading1 - 180) + "°";
          break;
        case heading1 > 225 && heading1 < 270:
          this.heading2 = "西偏南 " + (270 - heading1) + "°";
          break;
        case heading1 > 270 && heading1 <= 315:
          this.heading2 = "西偏北 " + (heading1 - 270) + "°";
          break;
        case heading1 > 315 && heading1 < 360:
          this.heading2 = "北偏西 " + (360 - heading1) + "°";
          break;
        default:
          break;
      }
    },

    /**
     * 停车位变更
     * @param {*} msg
     */
    topicvPoints(msg) {
      let curValue = msg.parkingSpace;

      if (spaceCode) {
        // 更新停车位的信息
        let parkingSpot = this.getParkingSpot(curValue);
        this.$refs.basisCesium.updateParkingSpace(parkingSpot);
      } else {
        // 第一次需要添加停车位的效果
        let carPostion = [baseData.mainLocation.lon, baseData.mainLocation.lat];
        // 开启前进自主泊车效果
        let parkingSpot = this.getParkingSpot(curValue);
        this.$refs.basisCesium.addForwardParkingEffect({
          id: baseData.mainCarID,
          carPostion: carPostion,
          spaceInfo: parkingSpot,
        });
      }

      // 记录 spaceCode 给倒车入库的时候用
      spaceCode = curValue;

      this.highlightSpaceEntity(spaceCode)
    },

    /**
     * 全局路径规划切换
     * @param {*} msg
     */
    topicLinePlaning(msg) {
      if (msg.objectData && msg.objectData[0] && msg.objectData[0].line) {
        this.$refs.basisCesium.organizePathLine({
          path: msg.objectData[0].line,
          type: "linePlaning",
        });

        // 弹窗显示
        this.infowindowChange = {
          time: new Date().getTime(),
          type: "linePlaning",
          text: "已重新规划路线",
        };
      }
    },

    /**
     * 局部路径发生改变
     * @param {*} msg
     */
    topicPartLine(msg) {
      // 先判断类型
      if (msg.objectData && msg.objectData[0] && msg.objectData[0]) {
        let objectData = msg.objectData[0];
        let { type, pointStr, globalPath } = objectData;

        let pointArr = JSON.parse(pointStr);
        if (pointArr) {
          if (type == 1) {
            // 避障
            this.$refs.basisCesium.addAvoidanceEffect({
              line: pointArr,
              globalPath,
            });

            // 更新全局路径
            this.$refs.basisCesium.organizePathLine({
              path: globalPath,
              partLine: pointArr,
              type: "partLine",
            });

            // singleLinePathPosition = [...pointArr, ...globalPath]

            // 记录前后路径
            // window.beforePath = [...globalPath]
            // window.afterPath = [...pointArr]

            // 避障需要前端判断结束，持续5s没有收到避障的topic，则任务避障结束
            clearInterval(this.addAvoidanceTimer);
            let voidanceLastSecond = new Date().getTime();
            this.addAvoidanceTimer = setInterval(() => {
              let newSecond = new Date().getTime();
              if (newSecond - voidanceLastSecond > 2000) {
                // 清除避障效果
                this.$refs.basisCesium.removeAvoidanceEffect();

                // 清除全局路径
                this.$refs.basisCesium.organizePathLine({
                  type: "partLine",
                });

                // 清除定时器
                clearInterval(this.addAvoidanceTimer);
                this.addAvoidanceTimer = null;
              }
            }, 1000);
          } else {
            if (!spaceCode) {
              return;
            }

            // lineArr.push(pointArr)

            // 开始后退，不需要再跳转视角了，因此用 singleLinePathPosition 长度控制
            // singleLinePathPosition = []

            let parkingSpot = this.getParkingSpot(spaceCode);
            this.$refs.basisCesium.addBackParkingEffect({
              carPos: baseData.mainLocation,
              line: pointArr,
              spaceInfo: parkingSpot,
            });
          }
        }
      }
    },

    /**
     * 根据停车位编号，获取停车位的具体信息
     * @param {*} parkingValue
     */
    getParkingSpot(parkingValue) {
      // 查询倒车入库的车位
      const parkingSpot = SpaceData.find(
        (spot) => spot.spaceCode === parkingValue
      );
      return parkingSpot;
    },

    /**
     * 获取路径规划
     */
    async findPathPlanning(ifParking = true) {
      await this.request
        .post("/avp/linePlaning/get", { vehiclePlate: "吉AC242" })
        .then((res) => {
          if (res.line && res.line.length) {
            this.$refs.basisCesium.findPathPlanning(res);

            // 泊车需要高亮车位，召车不高亮
            if (ifParking) {
              spaceCode = res.spaceCode
            } else {
              spaceCode = ''
            }
            this.highlightSpaceEntity(spaceCode)
          } else {
            console.log(res);
          }
        });
    },

    /**
     * rsi事件
     * 感知物高亮:如果eventObjId有值，那么就高亮对应的感知物，当连续几帧（比如3帧）没有某个感知物的id，则取消这个感知物的高亮
     * 道路面高亮：当eventType为拥堵时，需要高亮道路面，当连续几帧（比如3帧）不拥堵，则取消这个道路面的高亮
     * 事件优先级展示
     * @param {*} msg
     */
    topicRsiEvent(msg) {
      // 先得到所有需要高亮的感知物id
      let needHighIds = []; // 把所有rsi感知到的所有感知物id放在一个数组中，用于判断感知物高亮的结束
      let needRsiIds = []; // 把所有rsi的id放在一个数组中，用于判断rsi的结束
      for (let i = 0; i < msg.objectData.length; i++) {
        for (let j = 0; j < msg.objectData[i].reportData.length; j++) {
          let curData = msg.objectData[i].reportData[j];
          let eventId = curData.eventId;
          let eventType = curData.eventType;

          // console.log(eventId, eventType)

          // console.log(eventType)

          // 这一步的目的是把所有的事件id放到一个数组
          needRsiIds.push(eventId);

          // 设置当前rsi事件在rsiEventArr数组中的状态
          let obj = rsiEventArr.find((rs) => {
            return rs.eventId == eventId;
          });
          if (obj) {
            obj.number = 1;
          } else {
            let eventPriority = curData.eventPriority;

            rsiEventArr.push({
              eventId: eventId,
              priority: eventPriority,
              type: eventType,
              number: 1,
            });

            // 添加这个事件对应的弹窗
            this.rsiChange = {
              type: "add",
              eventId,
              eventType,
            };
          }

          if (eventType == "707") {
            // 如果当前是拥堵事件，则添加道路面，或者根据eventDescriptionI字段更新道路面的颜色
            this.$refs.basisCesium.addCongestionEffect({
              ...curData,
              eventId,
            });
          } else if (eventType == "38") {
            // 如果当前事件是道路施工，则根据传过来的经纬度添加施工图标
            // console.log('道路施工：接收到推送消息' + eventId)
            this.$refs.basisCesium.addRoadConstructionEffect({
              ...curData,
              eventId,
            });
          }

          // 这一步的目的是把所有的感知物id放到一个数组
          let curRsi = msg.objectData[i].reportData[j];
          if (curRsi.eventObjId) {
            if (Array.isArray(curRsi.eventObjId)) {
              curRsi.eventObjId.forEach((tr) => {
                needHighIds.push({
                  id: tr,
                  eventType: curRsi.eventType,
                });
                // console.log('交通事件', '事件id:' + eventId, '事件type:' + eventType, '参与者id:' + tr)
              });
            } else {
              // console.log('交通事件', '事件id:' + eventId, '事件type:' + eventType, '参与者id:' + curRsi.eventObjId)
              needHighIds.push({
                id: curRsi.eventObjId,
                eventType: curRsi.eventType,
              });
            }
          }
        }
      }

      // 高亮感知物
      this.dealHighlightRsi(needHighIds);

      // 事件优先级展示
      this.dealUIShow(needRsiIds);
    },

    /**
     * 处理感知物的高亮，包括高亮当前感知物 + 取消前面几帧高亮的感知物
     * @param {*} needHighIds
     */
    dealHighlightRsi(needHighIds) {
      // 高亮感知物
      for (let i = 0; i < needHighIds.length; i++) {
        let nendId = needHighIds[i].id;
        let eventType = needHighIds[i].eventType;
        let obj = rsiHighlightArr.find((rs) => {
          return rs.id == nendId;
        });
        if (obj) {
          obj.number = 1;
        } else {
          rsiHighlightArr.push({
            id: nendId,
            number: 1,
          });
        }

        // 高亮感知物
        this.$refs.basisCesium.highlightPerceive({
          nendId,
          eventType,
          iconType: "rsiicon",
          mainCarID: baseData.mainCarID,
        });
      }

      // 取消连续5帧不存在的感知物高亮
      for (let i = rsiHighlightArr.length - 1; i >= 0; i--) {
        let curRsi = rsiHighlightArr[i];
        let deleteObject = needHighIds.find((ni) => ni.id == curRsi.id);
        if (!deleteObject) {
          curRsi.number += 1;
          if (curRsi.number > 5) {
            this.$refs.basisCesium.cancleHighlightPerceive(curRsi.id);
            rsiHighlightArr.splice(i, 1);
          }
        }
      }
    },

    /**
     * 处理界面上的弹窗显示，按照优先级高低
     * @param {*} needRsiIds
     */
    dealUIShow(needRsiIds) {
      // 连续5帧没有同一个eventId的事件，则认为这个事件结束了
      for (let i = rsiEventArr.length - 1; i >= 0; i--) {
        let curRsi = rsiEventArr[i];
        let deleteObject = needRsiIds.find((ni) => ni == curRsi.eventId);
        if (!deleteObject) {
          curRsi.number += 1;
          if (curRsi.number > 5) {
            rsiEventArr.splice(i, 1);

            if (curRsi.type == "707") {
              // 删除这个事件对应的道路面高亮
              this.$refs.basisCesium.removeCongestionEffect(curRsi.eventId);
            } else if (curRsi.type == "38") {
              // 删除这个事件对应的道路施工图标
              // console.log('道路施工：连续5帧没有' + curRsi.eventId)
              this.$refs.basisCesium.removeRoadConstructionEffect(
                curRsi.eventId
              );
            }

            // 删除这个事件对应的弹窗
            this.rsiChange = {
              type: "remove",
              eventId: curRsi.eventId,
              eventType: curRsi.type,
            };
          }
        }
      }
    },

    /**
     * 移动车辆位置
     * @param {*} longitude
     * @param {*} latitude
     * @param {*} heading
     */
    moveCar(longitude, latitude, heading) {
      if (this.firstPerspective) {
        this.$refs.basisCesium.moveModelById({
          id: baseData.mainCarID,
          longitude,
          latitude,
          angle: heading,
          follow: true,
          offset: [-1, 0, 0],
          firstPer: true,
        });
      } else {
        this.$refs.basisCesium.moveModelById({
          id: baseData.mainCarID,
          longitude,
          latitude,
          angle: heading,
          follow: true,
          offset: [-31.5, 0, 9],
        });
      }

      // 更新2d车辆位置，需要跟随视角
      cesiumMainIns.updateBillboard(car2d, {
        viewer: viewer2d,
        position: [longitude, latitude],
        heading: heading - 60,
      });
      // if (car2d) {
      //   cesiumMainIns.updateGlbModelPrimitive(car2d, {
      //     position: [longitude, latitude],
      //     heading: heading + 90,
      //   })
      // }
    },

    /**
     * 两点之间的距离
     * @param {*} lng1
     * @param {*} lat1
     * @param {*} lng2
     * @param {*} lat2
     */
    getDistance(lng1, lat1, lng2, lat2) {
      let radLat1 = (lat1 * Math.PI) / 180.0;
      let radLat2 = (lat2 * Math.PI) / 180.0;
      let a = radLat1 - radLat2;
      let b = (lng1 * Math.PI) / 180.0 - (lng2 * Math.PI) / 180.0;
      let s =
        2 *
        Math.asin(
          Math.sqrt(
            Math.pow(Math.sin(a / 2), 2) +
            Math.cos(radLat1) *
            Math.cos(radLat2) *
            Math.pow(Math.sin(b / 2), 2)
          )
        );
      s = s * 6378137;
      s = Math.round(s * 10000) / 10000;
      return s;
    },

    /**
     * 感知目标物
     * @param {*} msg
     */
    topicDataMerge(msg) {
      for (let i = 0; i < msg.objectData.length; i++) {
        let allPerceive = [];
        for (let j = 0; j < msg.objectData[i].participant.length; j++) {
          let participant = msg.objectData[i].participant[j];
          let { longitude, latitude, ptcId, ptcType, heading } = participant;

          // 计算主车辆和感知目标物的距离
          let distance = this.getDistance(
            baseData.mainLocation.lon,
            baseData.mainLocation.lat,
            longitude,
            latitude
          );

          // 距离小于100米才显示感知目标物
          // if (distance < 100) {
          allPerceive.push({
            id: ptcId,
            type: ptcType,
            longitude: longitude,
            latitude: latitude,
            heading: heading,
          });
          // }
        }

        let deviceCode = msg.objectData[i].deviceCode;
        this.$refs.basisCesium.beginPerceive(deviceCode, allPerceive);
      }
    },

    /**
     * 清除所有感知目标物
     */
    removeDataMerge() {
      this.$refs.basisCesium.removeDataMerge();
    },

    /**
     * 开始泊车
     */
    startParkingVehicle() {
      // worker中处理路径规划显示的路径
      this.needDealPath = true;

      // 获取规划好的路径
      this.findPathPlanning();
    },

    /**
     * 结束泊车
     */
    endParkingVehicle() {
      // 移除自主泊车所有效果
      this.$refs.basisCesium.removeParkingEffect();

      // 停车位信息重置
      spaceCode = "";
      this.highlightSpaceEntity(spaceCode)

      // 是否处理路径规划显示的路径
      this.needDealPath = false;

      // 小地图上不显示线
      cesiumMainIns.updateLinePosition2D(polyine2d, {
        before: [],
        after: [],
        left: [],
        right: []
      });
      // console.log('window.leftPath', window.leftPath)
    },

    /**
     * 开始招车，显示路径规划路径
     */
    startRecruitmentVehicle() {
      // worker不处理路径规划显示的路径
      this.needDealPath = true;

      // 获取规划好的路径
      this.findPathPlanning(false);

      // 开始招车的时候就开始记录了
      // window.needRecord = true;
      // window.recordData = {
      //   vehicle: [],
      //   vehicleStatus: [],
      //   dataMerge: [],
      //   v2xStart: [],
      //   v2xEnd: [],
      //   points: [],
      //   linePlaning: [],
      //   linePlaningHttp: [],
      //   partLine: [],
      //   rsiEvent: [],
      // }
    },

    /**
     * 由招车转为其他状态，移除路径规划路线
     */
    endRecruitmentVehicle() {
      // worker中不处理路径规划显示的路径
      this.needDealPath = false;

      // 移除路面上的路线
      this.$refs.basisCesium.removePathPlanLine();

      // 小地图上不显示线
      cesiumMainIns.updateLinePosition2D(polyine2d, {
        before: [],
        after: [],
        left: [],
        right: []
      });
    },

    /**
     * 查询车位信息
     */
    async getSpaceData() {
      let data = JSON.stringify({
        pageNo: 20,
        pageSize: 1000,
      });
      await axios
        .post(
          "https://faw.cuscavp.cn:8443/hkapi/pms/v1/parkingSpace/spaceNo",
          data,
          {
            headers: {
              "Content-Type": "application/json",
            },
          }
        )
        .then((response) => {
          AllTingCheChang = [];
          const newData = response.data.data.list;
          postData = newData;
          // 遍历新数据，根据state值添加或移除模型
          postData.forEach((car) => {
            const parkingSpot = SpaceData.find(
              (spot) => spot.spaceCode === car.spaceNo
            );
            if (parkingSpot) {
              // 检查该车位是否已经添加模型
              if (car.state === 1) {
                //将车位信息添加到已添加模型的数据中;
                const name = parkingSpot.spaceCode;
                const latlon = [parkingSpot.center[0], parkingSpot.center[1]];
                let distance = this.getDistance(
                  baseData.mainLocation.lon,
                  baseData.mainLocation.lat,
                  latlon[0],
                  latlon[1]
                );
                if (distance > 2) {
                  AllTingCheChang.push({
                    id: name,
                    longitude: latlon[0],
                    latitude: latlon[1],
                    heading: parkingSpot.heading,
                  });
                }
              }
            }
          });
          this.$refs.basisCesium.beginParkingLot(AllTingCheChang);

          if (needRecord) {
            window.recordData.spaceNo.push(response);
          }
        });
    },

    // 添加二维内容
    async initViewer2d() {
      // 初始化二维场景
      viewer2d = cesiumMainIns.initScene(this.$refs.cesiumRef2D, {
        // sceneMode: Cesium.SceneMode.SCENE2D,
      });
      window.viewer2d = viewer2d;
      window.getCurrentCameraView = cesiumMainIns.getCurrentCameraView;

      // 设置二维视角
      cesiumMainIns.setView(viewer2d, {
        "longitude": 125.143565,
        "latitude": 43.838348,
        "height": 89.988899,
        "heading": 330,
        "pitch": -88.630968,
        "roll": 0
      });

      cesiumMainIns.addWmsLayer(viewer2d, {
        url: "https://faw.cuscavp.cn:8443/geoserver/changchun/wms?SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&FORMAT=image/png&TRANSPARENT=true",
        layers: "changchun:HMI_AVP_BASE",
      });
      cesiumMainIns.addWmsLayer(viewer2d, {
        url: "https://faw.cuscavp.cn:8443/geoserver/changchun/wms?service=WMS&version=1.1.0&request=GetMap&srs=EPSG:4326&styles=",
        layers: "changchun:CHANGCHUN_HMI_AVP_GJDT",
      });

      // 加载车位
      // cesiumMainIns.addGeojson(viewer2d, {
      //   url: "cesium/Parking.geojson",
      //   alpha: 0.5,
      //   strokeAlpha: 1,
      //   fill: "#BEDDFF",
      //   strokeColor: "#BEDDFF",
      // });

      // 添加二维poliline集合
      polylineCollection2d = cesiumMainIns.addPolylineCollection(viewer2d);
      // 二维路径
      polyine2d.before = cesiumMainIns.addPolyline(polylineCollection2d, {
        path: [],
        width: 5,
        type: "color",
        color: "#5b81f6",
      });
      polyine2d.after = cesiumMainIns.addPolyline(polylineCollection2d, {
        path: [],
        width: 5,
        type: "color",
        color: "#54B19B",
      });
      polyine2d.left = cesiumMainIns.addPolyline(polylineCollection2d, {
        path: [],
        width: 3,
        type: "gradientPolylineDash",
        color: "#fff",
      });
      polyine2d.right = cesiumMainIns.addPolyline(polylineCollection2d, {
        path: [],
        width: 3,
        type: "gradientPolylineDash",
        color: "#fff",
      });

      // 添加二维图标集合
      billboardCollection2d = cesiumMainIns.addBillboardCollection(viewer2d);
      car2d = cesiumMainIns.addBillboard(billboardCollection2d, {
        position: [baseData.mainLocation.lon, baseData.mainLocation.lat],
        heading: 0,
        scale: 1,
        // image: "./cesium/car.png",
        image: carpng_src,
        nearFarScalar: [50, 0.5, 300, 0.3]
      });
      console.log('加载car.png', car2d)


      // 三维primitive集合
      // primitiveCollection3d = cesiumMainIns.addPrimitiveCollection(viewer2d)
      // let url = "cesium/XC60.glb";
      // car2d = await cesiumMainIns.addGlbModelPrimitive(primitiveCollection3d, {
      //   url: url,
      //   position: [125.143684, 43.838424],
      //   heading: 0,
      //   follow: false,
      //   scale: 0.5,
      //   viewer: viewer2d,
      //   lightingFactor: 2
      // });

      setInterval(() => {
        if (!window.leftPath.length && [...window.afterPath, ...window.beforePath].length) {
          this.flyToRect([...window.afterPath, ...window.beforePath], {
            scale: 1.5
          })
        } else {
          cesiumMainIns.flyToPoint(viewer2d, {
            position: [baseData.mainLocation.lon, baseData.mainLocation.lat, 30],
            orientation: {
              heading: 330,
              pitch: -89,
              roll: 0
            }
          })
        }
      }, 3000)
    },

    flyToRect(lineCoors, options = {}) {
      const { scale = 1.5 } = options

      // 设置二维地图的视角
      const line = turf.lineString(lineCoors); // 得到路径

      const length = turf.length(line, { units: "kilometers" }) * 1000;
      // console.log(length)
      if (length < 18) return

      const bbox = turf.bbox(line); // 计算路径的边界框
      var poly = turf.bboxPolygon(bbox);  // 计算路径的边界多边形
      let result = turf.transformScale(poly, scale);  // 缩放1.2倍，主要是为了让地图边界留点空间
      const bbox2 = turf.bbox(result); // 需要跳转的矩形
      cesiumMainIns.flyToRect(viewer2d, bbox2, {
        orientation: {
          heading: 330,
          pitch: -89,
          roll: 0
        }
      })
    },

    highlightSpaceEntity(spaceCode) {
      if (spaceCode) {
        const parkingSpot = this.getParkingSpot(spaceCode);
        const coordinates = parkingSpot.coordinates
        if (highlightSpaceEntity) {
          cesiumMainIns.updatePolygonEntity(highlightSpaceEntity, {
            coordinates
          })
        } else {
          highlightSpaceEntity = cesiumMainIns.addPolygon(viewer2d, {
            coordinates,
            fill: '#72f8f4',
            alpha: 0.6
          })
        }
      } else {
        if (highlightSpaceEntity) {
          cesiumMainIns.updatePolygonEntity(highlightSpaceEntity, {
            coordinates: []
          })
        }
      }
    }
  },

  destroyed() {
    if (window.viewer) {
      if (window.viewer.primitive) {
        window.viewer.primitives.removeAll();
      }

      window.viewer.destroy();
      Cesium.CameraEventAggregator.prototype.removeInputAction;
      Cesium.Texture.prototype.destroy;
      delete window.viewer;
    }
    worker.postMessage("线程关闭");
    worker.terminate();
  },
};
</script>
<style scoped>
#cesium-page-css {
  position: absolute;
  height: 100%;
  width: 100%;
}

.showBuildingBtn {
  position: absolute;
  right: 1%;
  top: 13%;
}

.cesiumContainer2d {
  position: absolute;
  width: 20vw;
  height: 40vh;
  bottom: 4vh;
  right: 1vw;
  /* width: 300px;
  height: 380px;
  right: 20px;
  bottom: 20px; */

  &::before {
    content: "";
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    pointer-events: none;
    z-index: 1;
    box-shadow: 0rem 0rem 0.5rem 0.5rem rgb(191 206 233);
  }

  #cesium2d {
    position: absolute;
    width: 100%;
    height: 100%;
  }
}

.videoBox {
  position: absolute;
  width: 22vw;
  height: 30vh;
  top: 20vh;
  right: 1vw;

  /* width: 330px;
  height: 280px;
  right: 20px;
  top: 160px; */
  >video {
    width: 100%;
    height: 100%;
  }

  &::before {
    content: "";
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    pointer-events: none;
    z-index: 1;
    box-shadow: 0rem 0rem 0.5rem 0.5rem rgb(191 206 233);
  }
}
</style>
<style>
.cesium-widget-credits {
  display: none !important;
}
</style>
