<template>
  <div id="map">
    <div id="popup" class="style_container ol-popup">
      <div class="container">
        <div class="close_func">
          <a href="#" id="popup-closer" class="ol-popup-closer">×</a>
        </div>
        <div id="popup-title" class="popup-title"></div>
        <div id="popup-content" class="popup-content"></div>
      </div>
    </div>
    <div class="style_container changeBaseMap">
      <div class="container">
        <p
          :class="[
            'bg',
            {
              active: mapChangeIsShow,
            },
          ]"
          @click="mapChangeIsShow = !mapChangeIsShow"
        ></p>
        <div class="style_container mapChangeIsShow" v-if="mapChangeIsShow">
          <div class="container">
            <ul>
              <li v-for="(item, index) in mapList" :key="index">
                <p :class="['bg', item.class, { active: item.active }]" @click="changeMap(item)">
                  <span>{{ item.title }}</span>
                </p>
              </li>
            </ul>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import api from "@/api/menu";

import Map from "ol/Map";
import View from "ol/View";
import Tile from "ol/layer/Tile";
import XYZ from "ol/source/XYZ";
import { defaults } from "ol/control";
import { transform } from "ol/proj";
import { Zoom, ScaleLine, Rotate, FullScreen, MousePosition } from "ol/control";
import { createStringXY } from "ol/coordinate";
import GeoJSON from "ol/format/GeoJSON";
import VectorSource from "ol/source/Vector";
import VectorLayer from "ol/layer/Vector";
import Overlay from "ol/Overlay";

import { Fill, Stroke, Text, Style } from "ol/style";

import Select from "ol/interaction/Select";

import { getLayerData } from "@/utils/getLayerDataAndCreateFeatures";
import { createLayer } from "@/utils/openlayer_plugins/layer_control";

export default {
  data() {
    return {
      TDT_Mercator: {
        vector_layer: { id: "vec_w", layer_id: "vec" },
        vector_layer_annotation: { id: "cva_w", layer_id: "cva" },
        raster_layer: { id: "img_w", layer_id: "img" },
        raster_layer_annotation: { id: "cia_w", layer_id: "cia" },
        topography_layer: { id: "ter_w", layer_id: "ter" },
        topography_layer_annotation: { id: "cta_w", layer_id: "cta" },
        national_boundary: { id: "ibo_w", layer_id: "ibo" },
      },

      TDT_lnglat: {
        vector_layer: { id: "vec_c", layer_id: "vec" },
        vector_layer_annotation: { id: "cva_c", layer_id: "cva" },
        raster_layer: { id: "img_c", layer_id: "img" },
        raster_layer_annotation: { id: "cia_c", layer_id: "cia" },
        topography_layer: { id: "ter_c", layer_id: "ter" },
        topography_layer_annotation: { id: "cta_c", layer_id: "cta" },
        national_boundary: { id: "ibo_c", layer_id: "ibo" },
      },

      TDT_layer_common_config: {
        SERVICE: "WMTS",
        REQUEST: "GetTile",
        VERSION: "1.0.0",
        STYLE: "default",
        TILEMATRIXSET: "w",
        TILEMATRIX: "{z}",
        TILEROW: "{y}",
        TILECOL: "{x}",
        FORMAT: "tiles",
      },

      TDT_Mercator_common_config:
        "&SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&STYLE=default&TILEMATRIXSET=w&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&FORMAT=tiles",

      TDT_lnglat_common_config:
        "&SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&STYLE=default&TILEMATRIXSET=c&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&FORMAT=tiles",

      keyword: "",

      mapList: [
        {
          title: "地图",
          class: "vector",
          active: true,
        },

        {
          title: "影像",
          class: "raster",
          active: false,
        },
        {
          title: "地形",
          class: "dixing",
          active: false,
        },
      ],

      mapChangeIsShow: false,

      base_layer: null,
      base_layer_annotation: null,
      national_boundary: null,
    };
  },
  components: {},
  created() { },

  mounted() {
    let that = this;
    var mousePositionControl = new MousePosition({
      coordinateFormat: createStringXY(6),
      projection: "EPSG:4326",
      className: "custom-mouse-position",
      target: document.getElementById("mouse-position"),
      undefinedHTML: "&nbsp;",
    });
    let rotate = new Rotate({
      autoHide: true,
      label: "N",
    });
    let zoom = new Zoom({ target: undefined, delta: 1 });
    let scaleLine = new ScaleLine();
    let fullScreen = new FullScreen();

    // e90d56e5a09d1767899ad45846b0cefd

    let center = transform(
      [systemConfig.mapDefault.center.lng, systemConfig.mapDefault.center.lat],
      "EPSG:4326",
      "EPSG:3857"
    );

    let view = new View({
      center: center,
      zoom: systemConfig.mapDefault.zoom,
      constrainResolution: true, // 以整数级别缩放地图
    });

    that.$store.commit("setMouseLocation", [
      systemConfig.mapDefault.center.lng,
      systemConfig.mapDefault.center.lat,
    ]);
    that.$store.commit("setZoom", systemConfig.mapDefault.zoom);

    let map = new Map({
      target: "map", //地图标签id
      logo: false,
      controls: defaults({
        attribution: false,
        zoom: false,
        rotate: false,
      }).extend([scaleLine, fullScreen]),
      // .extend([zoom, scaleLine, fullScreen]),
      view: view,
    });
    globalVariable.map = map;
    globalVariable.map.getLayerById = function (id) {
      let arr = this.getLayers()
        .getArray()
        .filter(function (layer) {
          return layer.id == id || layer.values_.id == id;
        });
      if (arr.length == 0) {
        return null;
      } else if (arr.length < 2) {
        return arr[0];
      } else {
        throw "Layer ID repeat";
      }
    };
    // // 监听鼠标经纬度
    // map.on("pointermove", function (e) {
    //   let lonlat = transform(e.coordinate, "EPSG:3857", "EPSG:4326");
    //   that.$store.commit("setMouseLocation", [
    //     Number(lonlat[0].toFixed(6)),
    //     Number(lonlat[1].toFixed(6)),
    //   ]);
    // });
    // 监听地图变化时，缩放级别
    map.getView().on("change:center", function (e) {
      let lonlat = transform(globalVariable.map.getView().getCenter(), "EPSG:3857", "EPSG:4326");
      that.$store.commit("setMouseLocation", [
        Number(lonlat[0].toFixed(6)),
        Number(lonlat[1].toFixed(6)),
      ]);
    });
    map.getView().on("change", function (e) {
      that.$store.commit("setZoom", e.target.getZoom());
    });
    // 图层选中事件
    this.selectSingleClick = new Select();
    globalVariable.map.addInteraction(this.selectSingleClick);
    this.selectSingleClick.on("select", function (selectEvent) {
      let selectSingleClickFeatures = that.selectSingleClick.getFeatures();
      let selected = selectEvent.selected[0];
      if (!selected) return;
      if (selectEvent.target.getLayer(selectEvent.selected[0]) != null) {
        switch (selectEvent.target.getLayer(selectEvent.selected[0]).values_.name) {
          case "singlepoint":
            if (selected.values_.callback) {
              selected.values_.callback(selected, selectSingleClickFeatures);
              return;
            }
            selectSingleClickFeatures.clear();
            break;
          case "cluster":
            if (!selected.values_.features) {
              selectSingleClickFeatures.clear();
              break;
            }
            if (selected.values_.features.length == 1) {
              let newFeature = selected.values_.features[0];
              if (newFeature.values_.callback) {
                newFeature.values_.callback(
                  newFeature,
                  selectSingleClickFeatures
                );
              } else {
                selectSingleClickFeatures.clear();
                return;
              }
            } else {
              // TODO 缩放级别
              globalVariable.map.getView().fit(
                new VectorSource({
                  features: selected.values_.features,
                }).getExtent()
              );
              selectSingleClickFeatures.clear();
              return;
            }
            break;
          case "heatmap":
            return;
            break;

          default:
            if (selected.values_.callback) {
              selected.values_.callback(selected, selectSingleClickFeatures);
            }
            selectSingleClickFeatures.clear();
            break;
        }
      } else {
        selectSingleClickFeatures.clear();
      }
    });

    this.changeMap(this.mapList[0]);
    this.loadRegionBoundary();
    if (!this.$root.popup) {
      this.$root.popup_container = $("#popup");
      this.$root.popup_content = $("#popup-content");
      this.$root.popup_title = $("#popup-title");
      this.$root.popup_closer = $("#popup-closer");
      this.$root.popup_closer.bind("click", this.popupcloseEvent);
      this.$root.popup = new Overlay({
        element: this.$root.popup_container[0],
        autoPan: true,
        autoPanMargin: 100,
        positioning: "center-right",
      });
      globalVariable.map.addOverlay(this.$root.popup);
      this.$root.popup_setPositionAndRelocation = function (position) {
        that.$root.popup.setPosition(position);
        let height = 0 - 70 - that.$root.popup_content.height();
        that.$root.popup_container.css({
          transform: " translate(-50%, " + height + "px)",
        });
      };
      // 初始化
      this.$root.popup.setPosition(undefined);
      // 地图点击事件
      map.on("click", function (e) {
        that.$root.popup.setPosition(undefined);
      });
    }
  },
  methods: {
    // overlay 关闭
    popupcloseEvent() {
      this.$root.popup.setPosition(undefined);
      return false;
    },
    getCompleteUrl(param) {
      let url =
        systemConfig.tdt_url +
        "/" +
        param.id +
        "/wmts?" +
        "tk=" +
        systemConfig.tdt_tk +
        "&LAYER=" +
        param.layer_id +
        this.TDT_Mercator_common_config;
      return url;
    },
    addLayerToMap(url, title) {
      let layer = new Tile({
        title: title,
        source: new XYZ({ url: url }),
        zIndex: 0,
      });
      globalVariable.map.addLayer(layer);
      return layer;
    },
    removeLayerToMap(layer) {
      globalVariable.map.removeLayer(layer);
    },
    changeMap(item) {
      this.mapList = this.mapList.map(function name(item_) {
        if (item_.class != item.class) {
          item_.active = false;
        } else {
          item_.active = true;
        }
        return item_;
      });
      this.addBaseLayer(item);
    },
    addBaseLayer(item) {
      if (this.base_layer) {
        this.removeLayerToMap(this.base_layer);
      }
      if (this.base_layer_annotation) {
        this.removeLayerToMap(this.base_layer_annotation);
      }
      if (this.national_boundary) {
        this.removeLayerToMap(this.national_boundary);
      }
      switch (item.class) {
        case "vector":
          this.base_layer = this.addLayerToMap(
            this.getCompleteUrl(this.TDT_Mercator.vector_layer)
          ); // 天地图 底图
          this.base_layer_annotation = this.addLayerToMap(
            this.getCompleteUrl(this.TDT_Mercator.vector_layer_annotation)
          ); // 天地图 国境线
          this.national_boundary = this.addLayerToMap(
            this.getCompleteUrl(this.TDT_Mercator.national_boundary)
          ); // 天地图 底图对应注记
          globalVariable.map.getView().setMaxZoom(18);
          break;
        case "raster":
          this.base_layer = this.addLayerToMap(
            this.getCompleteUrl(this.TDT_Mercator.raster_layer)
          ); // 天地图 底图
          this.base_layer_annotation = this.addLayerToMap(
            this.getCompleteUrl(this.TDT_Mercator.raster_layer_annotation)
          ); // 天地图 国境线
          this.national_boundary = this.addLayerToMap(
            this.getCompleteUrl(this.TDT_Mercator.national_boundary)
          ); // 天地图 底图对应注记
          globalVariable.map.getView().setMaxZoom(18);
          break;
        case "dixing":
          this.base_layer = this.addLayerToMap(
            this.getCompleteUrl(this.TDT_Mercator.topography_layer)
          ); // 天地图 底图
          this.base_layer_annotation = this.addLayerToMap(
            this.getCompleteUrl(this.TDT_Mercator.topography_layer_annotation)
          ); // 天地图 国境线
          this.national_boundary = this.addLayerToMap(
            this.getCompleteUrl(this.TDT_Mercator.national_boundary)
          ); // 天地图 底图对应注记
          globalVariable.map.getView().setMaxZoom(14);
          break;

        default:
          break;
      }
    },
    loadRegionBoundary() {
      const boundary_style = function (feature) {
        let default_style = new Style({
          stroke: new Stroke({
            color: "rgba(50, 164, 220, 1)",
            width: 3,
          }),
          fill: new Fill({
            color: "rgba(50, 164, 220, 0.1)",
          }),
        });
        return default_style;
      };

      const diming_textStyle = new Style({
        text: new Text({
          // 字体与大小
          font: "16px Microsoft YaHei",
          //文字填充色
          fill: new Fill({
            color: "rgba(50, 164, 220, 1)",
          }),
          //文字边界宽度与颜色
          stroke: new Stroke({
            color: "#fff",
            width: 2,
          }),
          // 显示文本，数字需要转换为文本string类型！
          /*text: "" + vectorSource.features.values_.limitvalue + "",*/
          offsetX: 0,
          offsetY: 0,
        }),
      });
      let that = this;
      const styleCallback = function (feature) {
        const limitvalue = feature.values_.Name;
        if (
          limitvalue != null &&
          limitvalue != undefined &&
          limitvalue.length > 0
        ) {
          diming_textStyle.getText().setText("" + limitvalue + "");
        }
        return diming_textStyle;
      };
      let province_boundary = this.geojsonSource(
        "../static/data/sheng.geojson"
      );
      let province_text = this.geojsonSource("../static/data/shengD.geojson");
      let city_boundary = this.geojsonSource("../static/data/shi.geojson");
      let city_text = this.geojsonSource("../static/data/shiD.geojson");
      let country_boundary = this.geojsonSource("../static/data/xian.geojson");
      let country_text = this.geojsonSource("../static/data/xianD.geojson");

      let province_boundary_layer = this.geojsonLayer(
        "province_boundary",
        province_boundary,
        boundary_style,
        1,
        7
      );
      let province_text_layer = this.geojsonLayer(
        "province_text",
        province_text,
        styleCallback,
        1,
        7
      );
      let city_boundary_layer = this.geojsonLayer(
        "city_boundary",
        city_boundary,
        boundary_style,
        7,
        9
      );
      let city_text_layer = this.geojsonLayer(
        "city_text",
        city_text,
        styleCallback,
        7,
        9
      );
      let country_boundary_layer = this.geojsonLayer(
        "country_boundary",
        country_boundary,
        boundary_style,
        9,
        18
      );
      let country_text_layer = this.geojsonLayer(
        "country_text",
        country_text,
        styleCallback,
        9,
        18
      );
      globalVariable.map.addLayer(province_boundary_layer);
      globalVariable.map.addLayer(province_text_layer);
      globalVariable.map.addLayer(city_boundary_layer);
      globalVariable.map.addLayer(city_text_layer);
      globalVariable.map.addLayer(country_boundary_layer);
      globalVariable.map.addLayer(country_text_layer);
    },
    geojsonSource(url) {
      return new VectorSource({
        projection: "EPSG:4326",
        url: url,
        format: new GeoJSON(),
      });
    },
    geojsonLayer(id, source, style, minZoom, maxZoom) {
      return new VectorLayer({
        id: id,
        source: source,
        style: style,
        minZoom: minZoom,
        maxZoom: maxZoom,
        zIndex: 1,
      });
    },
    loadDefaultLayer() {
      let that = this,
        type = 0;
      if (
        this.urlParam.modelId == "" ||
        this.urlParam.modelId == null ||
        this.urlParam.modelId == undefined
      ) {
        return;
      }
      if (!isNaN(Number(this.urlParam.showType))) {
        if (
          Number(this.urlParam.showType) < 0 ||
          Number(this.urlParam.showType) > 3
        ) {
          type = 0;
        } else {
          type = Number(this.urlParam.showType);
        }
      } else {
        type = 0;
      }
      let layerType = "singlepoint";
      switch (type) {
        case 0:
          layerType = "singlepoint";
          break;
        case 1:
          layerType = "aggregation";
          break;
        case 2:
          layerType = "heatmap";
          break;

        default:
          break;
      }
      // 根据类型加载;
      api
        .getModelByID({ id: this.urlParam.modelId })
        .then((result) => {
          if (result.code == 200) {
            that.searchData(result.content, layerType);
          } else {
            that.$message({
              type: "warning",
              message: result.message,
            });
          }
        })
        .catch((err) => {
          that.$message({
            type: "warning",
            message: "服务器异常，请稍后重试！",
          });
        });
    },

    searchData(content, layerType) {
      let that = this;
      // 上传loading
      const loading = this.$loading({
        customClass: "allPageLoading",
        lock: true,
        text: "数据获取中，请稍后！",
        spinner: "el-icon-loading",
        background: "rgba(0, 0, 0, 0.7)",
      });
      getLayerData(content, this.setPopup, loading)
        .then((result) => {
          let source = new VectorSource();
          source.addFeatures(result);
          that.addDifferentLayer(content, layerType, source);
        })
        .catch((err) => {
          that.$message({
            type: "warning",
            message: err,
          });
        });
    },

    // 设置 popup
    setPopup(properties, position) {
      let that = this;
      that.$root.popup_content.html(
        `<div>名称：${properties.title}</div>
         <div>类别：${properties.classify}</div>
         <div>详情：${properties.content}</div>
        `
      );
      that.$root.popup_setPositionAndRelocation(position);
    },

    // 地图 加载 不同图层
    addDifferentLayer(item, layerType, source) {
      let layer = createLayer(item, layerType, source, this.$store.state.token);
      globalVariable.map.addLayer(layer);
      globalVariable.map.getView().fit(source.getExtent());
    },
  },
  computed: {
    urlParam() {
      return this.$store.state.urlParams;
    },
  },
  watch: {},
};
</script>

<style lang="less" scoped>
#map {
  width: 100%;
  height: 100%;
  position: absolute;
  /deep/ .ol-zoom {
    top: inherit;
    left: inherit;
    bottom: 60px;
    right: 20px;
    .ol-zoom-in,
    .ol-zoom-out {
      width: 30px;
      height: 30px;
      font-size: 24px;
    }
  }
  /deep/ .ol-scale-line {
    top: unset;
    left: unset;
    // bottom: 60px;
    left: 20px;
  }
  .changeBaseMap {
    position: absolute;
    top: 90px;
    right: 20px;
    z-index: 2;
  }
  .changeBaseMap > .container {
    width: 40px;
    height: 40px;
    cursor: pointer;
    border-radius: 4px;
    overflow: hidden;
    > p {
      width: 30px;
      height: 30px;
      margin: 5px 5px;
      background-position-x: center;
      background-position-y: center;
      background-repeat: no-repeat;
      background-image: url(../assets/images/tool/mapchange1.png);
      &:hover,
      &.active {
        background-image: url(../assets/images/tool/mapchange_active1.png);
      }
    }
    .mapChangeIsShow {
      position: absolute;
      top: -5px;
      left: calc(-234px - 10px - 12px - 10px);
    }
    .mapChangeIsShow > .container {
      width: calc(234px + 12px);
      height: 100%;
      border-radius: 4px;
      ul {
        width: fit-content;
        height: fit-content;
      }
      li {
        position: relative;
        display: inline-block;
        .bg {
          width: 68px;
          height: 63px;
          margin: 5px 5px;
          border: 2px solid #ffffff;
          background-position-x: center;
          background-position-y: center;
          background-size: 100% 100%;
          background-repeat: no-repeat;
          &:hover {
            border: 2px solid #c9c9c9;
          }
          &.active {
            border: 2px solid #00a9f9;
            span {
              background: #00a9f9b3;
            }
          }
          &.vector {
            background-image: url(../assets/images/maptype/xianhua.png);
          }
          &.raster {
            background-image: url(../assets/images/maptype/raster.png);
          }
          &.dixing {
            background-image: url(../assets/images/maptype/dixing.png);
          }
        }
        span {
          position: absolute;
          bottom: 5px;
          padding: 2px 5px;
          text-align: center;
          color: #ffffff;
          background: #00000080;
        }
      }
    }
  }
}
</style>
