<template>
  <div class="style_container bufferContent" v-if="isShow">
    <div class="container">
      <div class="title">
        缓冲区分析
        <p class="close" @click="close">×</p>
      </div>
      <div class="content">
        <el-row>
          <el-col :span="5" class="label">半径</el-col>
          <el-col :span="11">
            <el-input-number v-model="radius"></el-input-number>
          </el-col>
          <el-col :span="2"> 公里 </el-col>
        </el-row>
        <el-row>
          <el-col :span="5" class="label">图层</el-col>
          <el-col :span="17">
            <el-select
              v-model="selectedLayer"
              value-key="id"
              placeholder="请选择"
            >
              <el-option
                v-for="item in layerArrRenderEle"
                :key="item.id"
                :label="item.title"
                :value="item"
              >
              </el-option>
            </el-select>
          </el-col>
        </el-row>
      </div>
      <div class="result" v-show="resultArr.length > 0">
        <div class="title">
          共
          <span>{{ resultArr.length }}</span>
          个地点
        </div>
        <div class="content">
          <ul>
            <li
              v-for="(item, index) in resultArr"
              :key="index"
              @click="location(item)"
            >
              {{ item.title }}
            </li>
          </ul>
        </div>
      </div>
      <div class="footer">
        <el-button @click="getCenter" v-show="!drawCompleted">
          选定中心
        </el-button>
        <el-button @click="analysis" v-show="drawCompleted"> 分析 </el-button>
        <el-button @click="reset" v-show="drawCompleted"> 重置 </el-button>
      </div>
    </div>
  </div>
</template>

<script>
import VectorSource from "ol/source/Vector";
import VectorLayer from "ol/layer/Vector";
import Feature from "ol/Feature";
import Point from "ol/geom/Point";
import { transform } from "ol/proj";
import { Style, Fill, Stroke, Icon } from "ol/style";
import GeoJSON from "ol/format/GeoJSON";
import DrawTool from "@/utils/openlayer_plugins/draw";
import focusMaker from "../assets/images/poi/focus_maker.png";

export default {
  props: {
    isShow: {
      type: Boolean,
      default: false,
    },
    closeCallback: {
      type: Function,
      default: null,
    },
  },
  data() {
    return {
      radius: 5,
      selectedLayer: null,
      layerArrRenderEle: [],
      drawCompleted: false,
      centerPoint: null,
      circleGeojson: null,
      resultArr: [],
    };
  },
  mounted() {},
  methods: {
    // 选取缓冲区的中心点
    getCenter() {
      // 初始化标绘
      if (!this.draw)
        this.draw = new DrawTool(
          globalVariable.map,
          this.drawCenterCompleteCallback
        );
      this.draw.start("Point");
    },
    // 得到中心点
    drawCenterCompleteCallback(geometry) {
      this.centerPoint = transform(
        geometry.getCoordinates(),
        "EPSG:3857",
        "EPSG:4326"
      );
      this.generateCircle();
    },
    // 绘制缓冲区
    generateCircle() {
      this.resetLayer();
      let options = {
        steps: 60,
        units: "kilometers",
      };
      this.circleGeojson = turf.circle(this.centerPoint, this.radius, options);
      this.drawing_source.addFeatures(
        new GeoJSON().readFeatures(this.circleGeojson, {
          dataProjection: "EPSG:4326",
          featureProjection: "EPSG:3857",
        })
      );
      globalVariable.map.getView().fit(this.drawing_source.getExtent());
      this.drawCompleted = true;
    },

    // 缓冲区分析
    analysis() {
      let that = this;
      if (this.selectedLayer) {
        let pointArr = this.selectedLayer.layer
          .getSource()
          .getFeatures()
          .map(function (item) {
            return item.getProperties().properties;
            // return item
            //   .getGeometry()
            //   .clone()
            //   .transform("EPSG:3857", "EPSG:4326")
            //   .getCoordinates();
          });
        this.resultArr = pointArr.filter(function (item) {
          return turf.booleanPointInPolygon(
            turf.point([item.centerLon, item.centerLat]),
            that.circleGeojson
          );
        });
      } else {
        this.$message({
          type: "warning",
          message: "未选择需要分析的图层，请选择后分析！",
        });
      }
    },

    location(item) {
      let that = this;
      let view = globalVariable.map.getView();
      let point = transform(
        [item.centerLon, item.centerLat],
        "EPSG:4326",
        "EPSG:3857"
      );
      view.animate({
        center: point,
        zoom: 17,
        duration: 2000,
      });
      this.clearFocusSource();
      this.focusFeature = new Feature({
        geometry: new Point(point),
        callback: function (feature, selectSingleClickFeatures) {
          let properties = feature.values_.properties;
          that.setPopup(properties, feature.getGeometry().getCoordinates());
        },
        properties: item,
      });
      this.focusFeature.setStyle(
        new Style({
          image: new Icon({
            anchor: [0.5, 1],
            crossOrigin: "anonymous",
            src: focusMaker,
          }),
        })
      );
      this.focusSource.addFeature(this.focusFeature);
    },

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

    // 重置
    reset() {
      this.radius = 5;
      this.resetLayer();
      this.resultArr = [];
      this.clearFocusSource();
    },
    // 重置图层
    resetLayer() {
      if (this.drawing_source)
        this.drawing_source.getFeatures().forEach((element) => {
          this.drawing_source.removeFeature(element);
        });
      this.drawCompleted = false;
    },
    // 添加高亮图层
    addFocusLayerToMap() {
      this.focusLayer = new VectorLayer({
        source: null,
        style: null,
        zIndex: 1001,
      });
      this.focusSource = new VectorSource(); // 创建矢量图
      this.focusLayer.setSource(this.focusSource); //设置图源
      globalVariable.map.addLayer(this.focusLayer);
    },
    // 移除高亮图层+source
    removeFocusLayer() {
      if (this.focusLayer) globalVariable.map.removeLayer(this.focusLayer);
    },
    // 清空定位高亮 source
    clearFocusSource() {
      if (!this.focusSource) return;
      let features = this.focusSource.getFeatures();
      for (let i = 0; i < features.length; i++) {
        this.focusSource.removeFeature(features[i]);
      }
    },
    // 关闭模块
    close() {
      this.radius = 5;
      this.resetLayer();
      this.resultArr = [];
      this.closeCallback();
      this.clearFocusSource();
      this.removeFocusLayer();
    },
    // 停止绘制
    stop() {
      if (this.draw) this.draw.stop();
    },
  },
  computed: {
    layerArr() {
      return this.$store.state.layers;
    },
  },
  watch: {
    layerArr(newVal) {
      let that = this;
      this.layerArrRenderEle = newVal.filter(function (item, index) {
        return item.layerType == "singlepoint";
      });
      if (this.selectedLayer != null) {
        if (
          !newVal.some(function (item, index) {
            return item.id == that.selectedLayer.id;
          })
        ) {
          this.selectedLayer = null;
        }
      }
    },
    isShow(newVal) {
      if (newVal) {
        this.drawing_source = new VectorSource({
          projection: "EPSG:4326",
        });
        this.drawing_layer = new VectorLayer({
          source: this.drawing_source,
          zIndex: 1000,
          style: new Style({
            stroke: new Stroke({
              color: "#ff9900",
              width: 3,
            }),
            fill: new Fill({
              color: "rgb(255 153 0 / 60%)",
            }),
          }),
        });
        this.addFocusLayerToMap();
        globalVariable.map.addLayer(this.drawing_layer);
      } else {
        this.removeFocusLayer();
        globalVariable.map.removeLayer(this.drawing_layer);
      }
    },
  },
};
</script>

<style lang="less" scoped>
.bufferContent {
  position: absolute;
  top: -60px;
  left: calc(100% - 70px - 400px);
}
.bufferContent {
  border-radius: 4px;
  width: 400px;
  height: fit-content;
  .title {
    width: 100%;
    height: 39px;
    line-height: 40px;
    position: relative;
    text-indent: 10px;
    font-size: 16px;
    border-bottom: 1px solid #eeeeee;
    .close {
      width: 20px;
      height: 20px;
      line-height: 20px;
      text-align: center;
      margin: 10px 10px;
      font-size: 20px;
      float: right;
      cursor: pointer;
      text-indent: 0px;
      vertical-align: top;
    }
  }
  .header {
    border-bottom: 1px solid #eeeeee;
    padding: 10px 0px;
    text-align: center;
  }
  .content {
    position: relative;
    height: fit-content;
    max-height: 600px;
    overflow: hidden;
    overflow-y: auto;
    .el-row:first-child {
      margin-top: 15px;
    }
    .el-row {
      height: fit-content;
      margin-bottom: 15px;
    }
    .el-col.label {
      font-size: 16px;
      text-align: right;
      line-height: 40px;
      padding-right: 10px;
    }
    .el-col {
      line-height: 40px;
    }
    .picture_store {
      width: 272px;
      height: 300px;
      border: 1px solid #eeeeee;
      padding: 5px 10px;
      overflow: hidden;
      overflow-y: auto;
      li {
        float: left;
        width: 34px;
        height: 42px;
        background-position-x: center;
        background-position-y: center;
        background-repeat: no-repeat;
        margin: 0px 5px;
        margin-top: 10px;
      }
    }
  }
  .result {
    box-sizing: border-box;
    border-top: 1px solid #eeeeee;
    .title {
      padding: 0 20px;
      box-sizing: border-box;
      border-bottom: 1px solid #eeeeee;
      span {
        color: dodgerblue;
      }
    }
    .content {
      max-height: 300px;
      overflow: hidden;
      overflow-y: auto;
      padding: 0 20px;
    }
    li {
      line-height: 40px;
      font-size: 16px;
      cursor: pointer;
      border-bottom: 1px solid #eeeeee;
      &:last-child {
        border-bottom: 0px solid #eeeeee;
      }
    }
  }
  .footer {
    border-top: 1px solid #eeeeee;
    padding: 10px 0px;
    text-align: center;
  }
}
</style>