<template>
  <div class="app-container home">
    <!-- Cesium地图容器 -->
    <div id="cesiumContainer" class="cesium-container"></div>
  </div>
</template>

<script>
import { getTokenApi } from "@/api/token";
import { localStg } from "@/utils/storage";
export default {
  name: "Index",
  data() {
    return {
      // 版本号
      version: "3.8.9",
      // Cesium查看器实例
      viewer: null,
      tileset: null,
      personnelList: [
        {
          longitude: 121.70710830038986,
          latitude: 36.853636402927986,
          height: 100,
          name: "张三",
          status: "online", // 在线
          avatar: "/static/images/avatars/zhangsan.png", // 头像
        },
        {
          longitude: 121.70810830038986,
          latitude: 36.854636402927986,
          height: 100,
          name: "李四",
          status: "offline", // 离线
          avatar: "/static/images/avatars/lisi.png", // 头像
        },
        // 其他人员数据...
      ],
      personModelInterval: null,
      bgEntities: {}, // 所有的key都对应一个实体对象。而人员的实体对应的key不是数字。
    };
  },
  mounted() {
    // 组件挂载后初始化地图
    this.initCesium();
  },
  beforeMount() {
    localStg.set("token", 222233);

    if (localStg.get("token")) {
      return;
    }
    // 组件挂载前获取token
    getTokenApi().then((res) => {
      console.log("token", res);
      localStg.set("token", res.data.data);
    });
  },
  beforeDestroy() {
    // 组件销毁前清理地图资源
    if (this.viewer) {
      this.viewer.destroy();
      this.viewer = null;
    }
  },
  methods: {
    createPersonModel() {
      // 批次号管理（每次定时器触发时生成一个新的批次号）
      // var currentBatch = 0;
      // const batchMap = {};

      if (!this.personModelInterval) {
        this.personModelInterval = setInterval(() => {
          console.log("开始获取实时数据");
          // currentBatch++; // 每次定时器触发，生成新的批次号
          if (this.bgEntities) {
            for (let key in this.bgEntities) {
              if (isNaN(parseFloat(key))) {
                // 非数字键名的是人员实体
                this.viewer.entities.remove(this.bgEntities[key]);
                delete this.bgEntities[key];
              }
            }
          }

          // 从API获取最新的人员定位数据
          this.personCardList((list) => {
            // let perList = list; // 使用全部人员数据
            console.log("人员数据", this.personnelList);
            // 创建新实体
            for (let item of this.personnelList) {
              let lng = Number(item.lng);
              let lat = Number(item.lat);
              let height = Number(item.height);
              let position = Cesium.Cartesian3.fromDegrees(lng, lat, height);
              console.log(item.perName, position);
              // 创建人员标记
              let entity = this.viewer.entities.add({
                position: position,
                label: {
                  text: item.perName,
                  font: "16px",
                  backgroundColor: Cesium.Color.fromCssColorString("#173349"),
                  showBackground: true,
                  fillColor: Cesium.Color.YELLOW,
                  depthTestAgainstTerrain: false, // 禁用地形深度测试
                  // text: "高区管委",
                  // font: "16px",
                  // // scale: 0.5,
                  // backgroundColor: Cesium.Color.fromCssColorString("#173349"),
                  // color: Cesium.Color.WHITE,
                  // showBackground: true,
                  // horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
                  // verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
                  // distanceDisplayCondition: new Cesium.DistanceDisplayCondition(
                  //   1.0,
                  //   8000.0
                  // ),
                  pixelOffset: new Cesium.Cartesian2(0, -35),
                  // fillColor: Cesium.Color.WHITE,
                  // backgroundColor: new Cesium.Color(0.0, 0.486, 0.65, 0.8),
                  // disableDepthTestDistance: 5,
                  // heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
                },
                billboard: {
                  image: "/poi-marker-default.png",
                  scale: 0.5,
                  // heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
                  // disableDepthTestDistance: 5,
                  // distanceDisplayCondition: new Cesium.DistanceDisplayCondition(
                  //   1.0,
                  //   8000.0
                  // ),
                  // horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
                  // verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
                },
                description: `<div><h4>${item.perName}${item.status}</h4></div>`,
                fixedFrame: Cesium.Transforms.eastNorthUpToFixedFrame(position),
              });
              entity.info = item; // 添加 info 属性
              // entity.batch = currentBatch; // 标记当前批次
              this.bgEntities[item.perName] = entity; // 存储新实体
            }
          });
        }, 10000); // 每10秒刷新一次
      }
    },
    personCardList(fn) {
      console.log("人员定位数据", this.personnelList);
      // 将笛卡尔坐标转换为经纬度坐标
      const cartographic = Cesium.Cartographic.fromCartesian({
        x: -2686273.730145489,
        y: 4293961.185794622,
        z: 3863430.5618300107,
      });
      const baseLongitude = Cesium.Math.toDegrees(cartographic.longitude);
      const baseLatitude = Cesium.Math.toDegrees(cartographic.latitude);
      const baseHeight = cartographic.height + 1;

      console.log("人员经纬度基准点:", {
        longitude: baseLongitude,
        latitude: baseLatitude,
        height: baseHeight,
      });

      // 清除现有的人员列表
      this.personnelList = [];

      // 生成10个不同的经纬度坐标，确保它们之间的距离不超过100米
      // 在经纬度上，约0.00001度的变化大约对应1米（赤道附近）
      // 为了确保不超过100米，我们使用±0.00005度的随机偏移
      const maxOffset = 0.00005;

      for (let index = 0; index < 10; index++) {
        // 生成随机偏移量，确保每个点都不同但距离不远
        const lngOffset = (Math.random() - 0.5) * 2 * maxOffset;
        const latOffset = (Math.random() - 0.5) * 2 * maxOffset;

        this.personnelList.push({
          lng: baseLongitude + lngOffset,
          lat: baseLatitude + latOffset,
          height: baseHeight, // 高度略有不同，便于区分
          perName: "张三" + index,
          status: "online", // 在线
          avatar: "/static/images/avatars/zhangsan.png", // 头像
        });
      }

      fn(this.personnelList);
    },
    showPersonInfo(description) {
      // 使用 Cesium 的 InfoBox 显示信息
      this.viewer.selectedEntity = this.viewer.entities.add({
        description: description,
      });
      this.viewer.infoBox.frame.sandbox =
        "allow-same-origin allow-top-navigation allow-pointer-lock allow-popups allow-forms allow-scripts";
      this.viewer.infoBox.frame.src = "about:blank";
      this.viewer.infoBox.frame.contentDocument.write(description);
      this.viewer.infoBox.frame.contentDocument.close();
      this.viewer.infoBox.viewModel.showInfo = true;
      this.viewer.scene.globe.depthTestAgainstTerrain = true;
    },
    goTarget(href) {
      window.open(href, "_blank");
    },

    /**
     * 初始化Cesium地图
     */
    async initCesium() {
      Cesium.Ion.defaultAccessToken =
        "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI0ZDAxZGFhYy02MjJlLTRiNzktODNhZi00N2VjZGY0NTk4YmIiLCJpZCI6Mjc0NDAxLCJpYXQiOjE3NjMzNDYwNTR9.ZQW2DZ4KaMGbHuwrtIbyI6EdSSvgMJUHmmD74eZW7PQ";
      try {
        // 创建Cesium Viewer实例
        this.viewer = new Cesium.Viewer("cesiumContainer", {
          // 设置地图提供者，这里使用默认的Bing Maps
          imageryProvider: new Cesium.BingMapsImageryProvider({
            url: "https://dev.virtualearth.net",
            key: "AgcbDCAOb9zMfquaT4Z-MdHfx--9wUNrLRiiS7rIElFx8f-4lLulxZ0QnhqX5Lm6",
            mapStyle: Cesium.BingMapsStyle.AERIAL,
          }),
          // 配置是否显示各种控件
          animation: false, // 动画控件
          baseLayerPicker: true, // 底图选择器
          fullscreenButton: true, // 全屏按钮
          geocoder: true, // 地址搜索
          homeButton: true, // 主页按钮
          infoBox: true, // 信息框
          sceneModePicker: true, // 场景模式选择器
          selectionIndicator: true, // 选择指示器
          timeline: false, // 时间线
          navigationHelpButton: false, // 导航帮助按钮
          navigationInstructionsInitiallyVisible: false,
          // 设置初始视图位置（中国区域）
          center: Cesium.Cartesian3.fromDegrees(104.06, 30.67, 10000000),
        });

        // 设置相机视图
        // this.viewer.camera.setView({
        //   destination: Cesium.Cartesian3.fromDegrees(104.06, 30.67, 10000000), // 经度、纬度、高度
        //   orientation: {
        //     heading: Cesium.Math.toRadians(0.0), // 方向
        //     pitch: Cesium.Math.toRadians(-90.0), // 倾斜角度
        //     roll: 0.0, // 翻滚角度
        //   },
        // });

        this.viewer.scene.camera.setView({
          // 视角-环翠
          duration: 1,
          destination: {
            x: -2739843.563038797,
            y: 4357442.794747324,
            z: 3880768.3292693933,
          },
          orientation: {
            heading: 6.037000745578596,
            pitch: -1.2499586064720978,
            roll: 0.000005306352659495417,
          },
        });

        // 隐藏Cesium logo
        this.viewer._cesiumWidget._creditContainer.style.display = "none";

        const VUE_APP_GIS =
          "http://192.168.2.11:8080/Apps/assets/media/gaoquyingji";
        try {
          const tileset = await Cesium.Cesium3DTileset.fromUrl(
            VUE_APP_GIS + "/tiles/01_guanwei/tileset.json"
          );
          this.viewer.scene.primitives.add(tileset);

          console.log("倾斜摄影模型加载成功tileset", tileset);

          if (tileset) {
            this.tileset = tileset;
            this.locateToTileset();
          }
        } catch (error) {
          console.error(`加载倾斜摄影模型失败: ${error}`);
        }

        console.log("Cesium地图初始化成功");
      } catch (error) {
        console.error("Cesium地图初始化失败:", error);
      }
    },
    /**
     * 获取倾斜摄影模型的经纬度并将摄像机视角转向模型上方
     */
    locateToTileset() {
      if (!this.tileset || !this.viewer) {
        console.error("模型或视图未准备就绪");
        return;
      }

      try {
        // 获取模型的边界球
        const boundingSphere = this.tileset.boundingSphere;

        if (!boundingSphere) {
          console.error("无法获取模型边界");
          return;
        }

        // 获取模型中心点的笛卡尔坐标
        const center = boundingSphere.center;

        // 将笛卡尔坐标转换为经纬度坐标
        const cartographic = Cesium.Cartographic.fromCartesian(center);
        const longitude = Cesium.Math.toDegrees(cartographic.longitude);
        const latitude = Cesium.Math.toDegrees(cartographic.latitude);
        const height = cartographic.height;

        console.log("倾斜摄影模型中心点经纬度:", {
          longitude: longitude,
          latitude: latitude,
          height: height,
        });

        // 计算合适的观察距离 - 基于模型半径的倍数
        const distance = boundingSphere.radius * 2.5; // 可以根据需要调整倍数

        // 设置相机位置在模型上方
        const cameraPosition = Cesium.Cartesian3.fromRadians(
          cartographic.longitude,
          cartographic.latitude,
          height + distance // 相机高度为模型最高点加上观察距离
        );

        // 计算相机看向模型中心的方向
        const heading = Cesium.Math.toRadians(0); // 方向角
        const pitch = Cesium.Math.toRadians(-90); // 俯仰角 - 负数表示向下看
        const roll = Cesium.Math.toRadians(0); // 翻滚角

        // 使用flyTo方法平滑过渡到目标位置
        this.viewer.camera.flyTo({
          destination: cameraPosition,
          orientation: {
            heading: heading,
            pitch: pitch,
            roll: roll,
          },
          duration: 2, // 过渡时间2秒
          complete: () => {
            console.log("相机已成功定位到模型上方");
            this.createPersonModel(); // 定位后创建人员模型
          },
        });
      } catch (error) {
        console.error("定位到模型上方失败:", error);
      }
    },
  },
};
</script>

<style scoped lang="scss">
.home {
  width: 100%;
  height: 100vh;
  position: relative;
  overflow: hidden;

  blockquote {
    padding: 10px 20px;
    margin: 0 0 20px;
    font-size: 17.5px;
    border-left: 5px solid #eee;
  }
  hr {
    margin-top: 20px;
    margin-bottom: 20px;
    border: 0;
    border-top: 1px solid #eee;
  }
  .col-item {
    margin-bottom: 20px;
  }

  ul {
    padding: 0;
    margin: 0;
  }

  font-family: "open sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 13px;
  color: #676a6c;
  overflow-x: hidden;

  ul {
    list-style-type: none;
  }

  h4 {
    margin-top: 0px;
  }

  h2 {
    margin-top: 10px;
    font-size: 26px;
    font-weight: 100;
  }

  p {
    margin-top: 10px;

    b {
      font-weight: 700;
    }
  }

  .update-log {
    ol {
      display: block;
      list-style-type: decimal;
      margin-block-start: 1em;
      margin-block-end: 1em;
      margin-inline-start: 0;
      margin-inline-end: 0;
      padding-inline-start: 40px;
    }
  }

  // Cesium容器样式
  .cesium-container {
    // width: 100vw;
    // height: 100vh;
    width: 87vw;
    height: 87vh;
    position: absolute;
    top: 0;
    left: 0;
    z-index: 1;
  }
}
</style>