<template>
  <div class="mapBox">
    <div id="cesiumContainer" style="width: 100%; height: 100vh"></div>
    <div class="menuBox" :class="allyShow ? '' : 'switch'">
      <el-button type="primary" @click="resetViewport()">初始化视角</el-button>
      <el-button
        :type="windLayer ? 'danger' : 'primary'"
        @click="switchWindLayer"
        >{{ windLayer ? "关闭" : "显示" }}风场图</el-button
      >
      <el-button
        :type="cloudLayer ? 'danger' : 'primary'"
        @click="switchCloudLayer"
        >{{ cloudLayer ? "关闭" : "显示" }}云图</el-button
      >
      <el-button
        :type="rainLayer ? 'danger' : 'primary'"
        @click="switchRainLayer"
        >{{ rainLayer ? "关闭" : "显示" }}降雨图</el-button
      >
      <el-tooltip
        class="box-item"
        effect="dark"
        :content="`点击${allyShow ? '隐藏' : '常显'}菜单栏`"
        placement="bottom-end"
      >
        <el-icon
          style="margin-left: 20px"
          size="20px"
          :color="allyShow ? '#1890ff' : '#f25656'"
          @click="allyShow = !allyShow"
        >
          <House
            :style="`transform: rotate(${
              allyShow ? -45 : 45
            }deg); transition: 0.2s; cursor: pointer;`"
          />
        </el-icon>
      </el-tooltip>
    </div>
  </div>
</template>

<script>
import * as Cesium from "../Cesium";
import "../Cesium/Widgets/widgets.css";
import Windy from "../assets/wind/Windy_source.js";
import SingleImageProvider from "../assets/wind/SingleImageProvider";

import basicGeoJson from "../assets/geoJson/basic.json";
import windLineJson from "../assets/geoJson/windLine_2017121300.json";

import axios from "axios";
export default {
  name: "CesiumMap",
  data() {
    return {
      allyShow: false,
      viewer: null,
      windLayer: null, // 风场图
      windLayerTimmer: null, // 风场图计时器
      cloudLayer: null, // 卫星云图
      rainLayer: null, //
    };
  },

  mounted() {
    this.initCesium();
  },

  unmounted() {
    if (this.windLayer !== null) {
      clearInterval(this.windLayerTimmer);
      this.windLayer.removeLines();
      this.windLayer = null;
    }
  },

  methods: {
    initCesium() {
      // 需要从 https://cesium.com/ion/signup 获取
      Cesium.Ion.defaultAccessToken =
        "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiIwYTQwNDk3MC05YTZkLTQ2ZTEtODc0MS1lZTFkYjFlOTFmNmQiLCJpZCI6MTcyNDQ1LCJpYXQiOjE3NTQ4ODA4MzF9.KnhENYiHxNwTkhTWRA-lHqG59coLVT2FsIyOru2TV3E";
      const viewer = new Cesium.Viewer("cesiumContainer", {
        baseLayerPicker: false,
        animation: false,
        vrButton: false,
        geocoder: false,
        homeButton: false,
        infoBox: false,
        sceneModePicker: false,
        selectionIndicator: false,
        timeline: false,
        fullscreenButton: false,
        navigationHelpButton: false,
        shouldAnimate: true,
      });

      // 隐藏logo
      // this.$nextTick(() => {
      //   document.querySelector(".cesium-viewer-bottom")?.remove();
      // });

      // 隐藏logo
      viewer.cesiumWidget.creditContainer.style.display = "none";

      // 添加中文底图
      const imageryProvider = new Cesium.UrlTemplateImageryProvider({
        url: "https://webst02.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}",
        credit: "高德地图",
      });

      viewer.imageryLayers.addImageryProvider(imageryProvider);

      // 添加一些3D模型
      //   const addModel = (name, lon, lat, height) => {
      //     viewer.entities.add({
      //       name: name,
      //       position: Cesium.Cartesian3.fromDegrees(lon, lat, height),
      //       model: {
      //         uri: "/sample-data/models/CesiumAir/Cesium_Air.glb",
      //         scale: 50000.0,
      //       },
      //     });
      //   };

      //   addModel("模型1", 116.4, 39.9, 1000);
      //   addModel("模型2", 121.47, 31.23, 1000);

      // 添加点击事件显示坐标
      viewer.screenSpaceEventHandler.setInputAction((movement) => {
        const cartesian = viewer.camera.pickEllipsoid(
          movement.position,
          viewer.scene.globe.ellipsoid
        );
        if (cartesian) {
          const cartographic = Cesium.Cartographic.fromCartesian(cartesian);
          const lon = Cesium.Math.toDegrees(cartographic.longitude).toFixed(5);
          const lat = Cesium.Math.toDegrees(cartographic.latitude).toFixed(5);

          viewer.entities.removeAll();
          viewer.entities.add({
            position: cartesian,
            point: {
              pixelSize: 10,
              color: Cesium.Color.RED,
            },
            label: {
              text: `经度: ${lon}°, 纬度: ${lat}°`,
              font: '16px "Microsoft YaHei"',
              fillColor: Cesium.Color.WHITE,
              outlineColor: Cesium.Color.BLACK,
              outlineWidth: 2,
              style: Cesium.LabelStyle.FILL_AND_OUTLINE,
              pixelOffset: new Cesium.Cartesian2(0, -30),
            },
          });
        }
      }, Cesium.ScreenSpaceEventType.LEFT_CLICK);

      this.viewer = viewer;

      this.initGeoJsonData();
    },

    // 初始化 geoJson 数据
    async initGeoJsonData() {
      // 创建GeoJSON数据源
      await new Cesium.GeoJsonDataSource.load(basicGeoJson, {
        stroke: Cesium.Color.WHITE, // 边界线颜色
        fill: Cesium.Color.BLACK.withAlpha(0.1), // 填充颜色
        strokeWidth: 1, // 边界线宽度
        markerSymbol: "?", // 点要素的符号
      }).then((dataSource) => {
        // 添加到视图
        this.viewer.dataSources.add(dataSource);
        var entities = dataSource.entities.values;
        for (let i = 0; i < entities.length; i++) {
          let entity = entities[i];

          let polyPositions = entity.polygon.hierarchy.getValue(
            Cesium.JulianDate.now()
          ).positions;
          //单独设置线条样式
          var positions = entity.polygon.hierarchy._value.positions;

          entity.polyline = {
            positions: positions,
            width: 1,
            outline: false,
          };
        }

        // 添加中文标签图层
        const labelLayer = new Cesium.LabelCollection();
        this.viewer.scene.primitives.add(labelLayer);
        const cities = [];
        basicGeoJson?.features?.forEach((ele) => {
          if (Array.isArray(ele.properties.centroid)) {
            const name = ele.properties.name;
            const lon = ele.properties.centroid[0];
            const lat = ele.properties.centroid[1];
            cities.push({ name, lon, lat });
          }
        });

        cities.forEach((city) => {
          labelLayer.add({
            position: Cesium.Cartesian3.fromDegrees(city.lon, city.lat),
            text: city.name,
            font: 'bold 16px "Microsoft YaHei", sans-serif',
            fillColor: Cesium.Color.YELLOW,
            outlineColor: Cesium.Color.BLACK,
            outlineWidth: 2,
            style: Cesium.LabelStyle.FILL_AND_OUTLINE,
            pixelOffset: new Cesium.Cartesian2(0, 0), // 设置为0
            horizontalOrigin: Cesium.HorizontalOrigin.CENTER, // 水平居中
            verticalOrigin: Cesium.VerticalOrigin.CENTER, // 垂直居中
          });
        });

        this.resetViewport();
      });
    },

    // 重置视角
    resetViewport(height = 0) {
      // 设置初始视图为宁夏
      this.viewer.camera.flyTo({
        destination: Cesium.Cartesian3.fromDegrees(
          106.169866,
          38.46637,
          height || 8000000
        ),
        orientation: {
          heading: Cesium.Math.toRadians(0),
          pitch: Cesium.Math.toRadians(-90),
          roll: 0.0,
        },
        duration: 1.0,
      });
    },

    // 添加风场图
    showWindLayer() {
      if (!this.windLayer) {
        this.resetViewport(20000000);
        this.windLayer = new Windy(windLineJson, this.viewer);
        this.windLayerTimmer = setInterval(() => {
          this.windLayer.animate();
        }, 200);
      }
    },

    // 将风向角度数据转换为矢量坐标
    windToVector(speed, direction) {
      // 转换为弧度（气象角度：0°=北风，90°=东风）
      const rad = Cesium.Math.toRadians(direction);
      // 计算UV分量（U: 东西方向，V: 南北方向）
      return {
        u: -speed * Math.sin(rad), // 东正西负
        v: -speed * Math.cos(rad), // 北正南负
      };
    },

    // 显示云图
    showCloudLayer() {
      // 设置云图位置（示例：覆盖中国区域）
      // const rectangle = Cesium.Rectangle.fromDegrees(
      //   73.66, // 西经
      //   18.16, // 南纬
      //   135.05, // 东经
      //   53.55 // 北纬
      // );

      const now = new Date();
      const year = now.getFullYear();
      const month = String(now.getMonth() + 1).padStart(2, "0");
      const day = String(now.getDate()).padStart(2, "0");
      const hour = String(Math.floor(now.getHours() / 3) * 3).padStart(2, "0"); // 每3小时更新

      // 创建云图图层
      const cloudLayer = this.viewer.imageryLayers.addImageryProvider(
        new Cesium.UrlTemplateImageryProvider({
          url: `https://data.ventusky.com/${year}/${month}/${day}/icon/whole_world/hour_${hour}/icon_oblacnost_${year}${month}${day}_${hour}.jpg`,
          rectangle: Cesium.Rectangle.fromDegrees(-180, -90, 180, 90),
          credit: "实时卫星云图",
        })
      );

      // 设置蓝色调效果
      cloudLayer.alpha = 0.75; // 透明度
      cloudLayer.brightness = 1; // 亮度
      cloudLayer.contrast = 1; // 对比度

      this.cloudLayer = cloudLayer;
    },

    // 移除风场图
    removeWindLayer() {
      if (this.windLayer) {
        clearInterval(this.windLayerTimmer);
        this.windLayer.removeLines();
        this.viewer.imageryLayers.remove(this.windLayer);
        this.windLayer = null;
      }
    },

    // 移除卫星云图
    removeCloudLayer() {
      if (this.cloudLayer) {
        this.viewer.imageryLayers.remove(this.cloudLayer);
        this.cloudLayer = null;
      }
    },

    // 切换风场图显隐
    switchWindLayer() {
      if (this.windLayer) {
        this.removeWindLayer();
      } else {
        this.showWindLayer();
      }
    },

    // 切换微星图显隐
    switchCloudLayer() {
      if (this.cloudLayer) {
        this.removeCloudLayer();
      } else {
        this.showCloudLayer();
      }
    },

    switchRainLayer() {
      this.$router.push({
        path: "/satellitecloudchart",
      });
    },
  },
};
</script>

<style lang="less" scoped>
.mapBox {
  width: 100%;
  height: 100%;
  position: relative;
  box-sizing: content-box;

  .menuBox {
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    background: #fff;
    display: flex;
    justify-content: flex-end;
    align-items: center;
    padding: 10px;

    &.switch {
      opacity: 0;
      transition: 0.2s;

      &:hover {
        opacity: 1;
        transition: 0.2s;
      }
    }
  }
}
</style>