<!--
 * @Author: SunTao 328867980@qq.com
 * @Date: 2025-01-02 11:56:20
 * @LastEditors: SunTao 328867980@qq.com
 * @LastEditTime: 2025-01-02 15:54:11
 * @FilePath: \znxjxt-ui\src\views\xj\inspection\task-management\components\task-map.vue
 * @Description: 巡检任务-地图弹窗
-->
<template>
  <div class="content">
    <!-- 多选框切换坐标类型 -->
    <div class="check-box">
      <el-cascader
        ref="screenCascader"
        v-model="mapCareSelect"
        placeholder="病害类型筛选"
        :options="defectCascaderList"
        collapse-tags
        :props="{
          multiple: true,
          emitPath: false,
          children: 'subTypes',
        }"
        @change="changeMapCareSelect"
        clearable
      ></el-cascader>
    </div>
    <fssm-map ref="taskMap"></fssm-map>
  </div>
</template>

<script>
// 接口
import { getDefectPoint } from "@/api/xj/task";
import FssmMap from "@/components/map/fssm-map.vue";
import { Feature } from "ol";
import { Point } from "ol/geom";
import VectorSource from "ol/source/Vector";
import VectorLayer from "ol/layer/Vector";
import { Style, Icon } from "ol/style";
export default {
  name: "TaskMap",
  components: {
    FssmMap,
  },
  props: {
    // 弹窗传的数据
    dialogItem: {
      type: Object,
      default: () => {},
    },
    // 病害类型筛选下拉数据
    defectCascaderList: {
      type: Array,
      default: () => [],
    },
  },
  data() {
    return {
      // 病害类型筛选绑定
      mapCareSelect: [],
      // 地图打点图层
      markLayerPoints: null,
      // 中心点集合(过滤后得点位)
      centerPiont: [],
      // 中心点集合（所有点位）
      drawPointList: [],
    };
  },
  mounted() {
    this.getMapPoint();
  },
  methods: {
    /**
     * @description: 病害类型筛选改变事件
     * @return {void}
     */
    changeMapCareSelect(value) {
      if (value.length > 0) {
        this.centerPiont = this.drawPointList.filter((item) => {
          return value.includes(item.iconType);
        });
      } else {
        this.centerPiont = this.drawPointList;
      }
      this.drawPoint();
    },

    /**
     * @description: 获取地图点位的方法
     * @return {void}
     */
    getMapPoint() {
      getDefectPoint({ id: this.dialogItem.extId }).then(({ code, data }) => {
        if (code === 200) {
          this.drawPointList = data.map((item) => {
            if (item.geometry) {
              return {
                ...item,
                geometry: [item.geometry[0], item.geometry[1]],
              };
            }
            return [];
          });
          this.centerPiont = data.map((item) => {
            if (item.geometry) {
              return {
                ...item,
                geometry: [item.geometry[0], item.geometry[1]],
              };
            }
            return [];
          });
          // 如果不是病害巡检，则绘制点位
          // 如果图片弹窗打开，则绘制点位
          // if (!this.shouldLoadClusters) {
          // 修改地图中心点位
          const pointArray = data.map((item) => {
            if (item.geometry) {
              return [item.geometry[0], item.geometry[1]];
            }
            return [];
          });
          this.fitMapToPoints(pointArray);
          this.drawPoint();
          // }
        }
      });
    },

    /**
     * @description: 根据点位计算地图中心点
     * @return {void}
     */
    fitMapToPoints(points) {
      if (points.length > 0) {
        // 创建一个空的 extent
        let extent = [Infinity, Infinity, -Infinity, -Infinity];
        // 计算所有点的边界框（extent）
        points.forEach((point) => {
          extent = [
            Math.min(extent[0], point[0]),
            Math.min(extent[1], point[1]),
            Math.max(extent[2], point[0]),
            Math.max(extent[3], point[1]),
          ];
        });
        this.$nextTick(() => {
          // 获取地图实例
          const map = this.$refs.taskMap.instance.get("map");

          // 使用 fit 方法根据边界框计算最佳缩放级别
          map.getView().fit(extent, {
            duration: 500, // 动画持续时间
            padding: [10, 10, 10, 10], // 边缘填充
          });
        });
      }
    },

    /**
     * @description: 绘制地图点位
     * @return {void}
     */
    drawPoint() {
      const features = [];
      this.centerPiont.forEach((element) => {
        // 修改坐标样式
        const point = new Point(element.geometry);
        const feature = new Feature({
          geometry: point,
          data: element,
          // 自己设置一个标识
          type: "icon",
        });
        // 设置点位样式
        feature.setStyle([
          new Style({
            image: new Icon({
              crossOrigin: "anonymous",
              src: require(`@/assets/screen/index/${element.iconTypeName}.png`),
              // size: [40, 40],
              scale: 0.5, // 图标缩放比例
              displacement: [0, 30],
            }),
          }),
        ]);
        features.push(feature);
      });
      //设置地图的数据源
      const pointSource = new VectorSource({
        features,
      });
      if (!this.markLayerPoints) {
        this.markLayerPoints = new VectorLayer({
          source: pointSource,
          properties: {
            type: "point",
          },
        });
        this.$nextTick(() => {
          const map = this.$refs.taskMap.instance.get("map");
          map.addLayer(this.markLayerPoints);
        });
      } else {
        this.markLayerPoints.setSource(pointSource);
      }
    },
  },
};
</script>

<style lang="scss" scoped>
.content {
  width: 100%;
  height: 45rem;
  position: relative;

  .check-box {
    position: absolute;
    z-index: 1;
  }
}
</style>
