<template>
  <div class='coord' v-drag="'.coord .ant-card-head'">
    <a-card v-show='value' title='定位' style='width: 350px; box-shadow: 0 0 5px #1890ff;'>
      <a-icon slot='extra' type='close' class='panelClose' @click="$emit('input',false)" />
      <a-form-model ref='ruleForm' :model='form' :rules='rules' :label-col='labelCol' :wrapper-col='wrapperCol'>
<!--        <a-form-model-item style='margin-bottom: 1em' ref='locate' label='输入坐标' prop='locate'>
          <a-input v-model.trim='form.locate' @pressEnter='onSubmit' placeholder='请输入坐标' allow-clear @blur='
		                () => {
		                  $refs.locate.onFieldBlur();
		                }
		              ' />
        </a-form-model-item>-->
        <a-form-model-item  style="margin-bottom: 10px" label="x" prop="lng">
          <a-input v-model="form.lng" placeholder="请输入横坐标" />
        </a-form-model-item>
        <a-form-model-item style="margin-bottom: 10px" label="y" prop="lat">
          <a-input v-model="form.lat" placeholder="请输入纵坐标" />
        </a-form-model-item>
        <a-form-model-item style='margin-bottom: 5px' v-show='!isGeodetic&&coordsArr.length>0' label='经纬度:'>
					<span class='ant-form-text text'>
						{{ form.geodetic }}
					</span>
        </a-form-model-item>
        <a-form-model-item style='margin-bottom: 5px' v-show='!isDegree&&coordsArr.length>0' label='度分秒:'>
					<span class='ant-form-text text'>
						{{ form.degree }}
					</span>
        </a-form-model-item>
        <a-form-model-item style='margin-bottom: 10px' v-show='!isProjCoord&&coordsArr.length>0' label='投影坐标:'>
					<span class='ant-form-text text'>
						{{ form.projCoord }}
					</span>
        </a-form-model-item>
        <a-form-model-item :wrapper-col='{ span: 20, offset: 3 }'>
          <a-space>
            <a-button @click='pickCoordsOnMap'>
              拾 取
            </a-button>
            <a-button type='primary' @click='onSubmit'>
              定 位
            </a-button>
            <a-button @click='resetForm'>
              重 置
            </a-button>
            <a-button type='link' @click='handleHistory'>
              历史记录
            </a-button>
          </a-space>

        </a-form-model-item>
      </a-form-model>
      <a-list v-show='history' style='margin-top: 10px;border-top: 1px solid #8a8af4;  max-height: 550px '
              item-layout='horizontal' :data-source='historyList' :pagination='pagination'>
        <a-list-item slot='renderItem' style='display:block;cursor: auto' slot-scope='item, index' :key='item.id'>
          <a-list-item-meta :description='item.inputval'>
            <span style=' display: inline-block; word-break: break-all;white-space: normal; cursor: text; color: #333'
                  slot='title'>{{ item.name || '未命名' }}</span>
          </a-list-item-meta>
          <a slot='actions' @click='handleHistoryLocate(item)'>定位</a>
          <a slot='actions' @click='showModal(item,index)'>编辑</a>
          <a-popconfirm slot='actions' title='确定删除吗?' @confirm='() => handleRemove(item.id,index)'>
            <a>删除</a>
          </a-popconfirm>
        </a-list-item>
      </a-list>
      <a-modal
        title='编辑'
        :visible='visible'
        :confirm-loading='confirmLoading'
        @ok='handleOk'
        @cancel='handleCancel'
      >
        <a-form-model>
          <a-row>
            <a-col :span='24'>
              <a-form-model-item label='名称' :labelCol='labelCol' :wrapperCol='wrapperCol'>
                <a-input v-model='model.name'></a-input>
              </a-form-model-item>
            </a-col>
            <a-col :span='24'>
              <a-form-model-item label='坐标' :labelCol='labelCol' :wrapperCol='wrapperCol'>
                <a-input v-model='model.inputval' disabled rows='4' />
              </a-form-model-item>
            </a-col>
          </a-row>
        </a-form-model>
      </a-modal>
    </a-card>
  </div>
</template>

<script>
import Point from '@arcgis/core/geometry/Point';
import * as projection from '@arcgis/core/geometry/projection';
import SpatialReference from '@arcgis/core/geometry/SpatialReference';
import { deleteAction, getAction, postAction } from '@/api/manage';
import Graphic from '@arcgis/core/Graphic';


export default {
  name: 'CoordsLocate',
  beforeCreate() {

  },
  data() {
    //校验
    let validateLocate = (rule, value, callback) => {
      if (value === '') {
        callback(new Error('请输入坐标！'));
      } else {
        // let reg1 = /[^\d\,\,\°\′\″\ \t]/g
        let reg2 = /^(\-|\+)?\d+(\.\d+)?[\uff0c\,\ \t](\-|\+)?\d+(\.\d+)?$/;//4180693.903 541105.228
        // let reg2 = /^[\-\+]?(180|1?[0-7]?\d)*([.][0-9]+)?[\uff0c\,\ \t][\-\+]?(90|[0-8]?\d)([.][0-9]+)?$/;
        let reg3 = this.reg3;
        if (value.indexOf(';') !== -1 || value.indexOf('；') !== -1) {
          value.replace('；', ';');
          this.coordsArr = value.split(';');
          this.coordsArr.forEach((item, index) => {
            if (reg2.test(item) || reg3.test(item)) {
            } else {
              callback(new Error('请输入规范的坐标(只允许输入数字，空格，逗号，与度分秒)！多个坐标请用分号(;)分隔'));
            }
          });
          callback();
        } else {
          if (reg2.test(value) || reg3.test(value)) {
            if (reg3.test(value)) {
              this.isDegree = true;
            } else {
              this.isDegree = false;
            }
            callback();
          } else {
            callback(new Error('请输入规范的坐标(只允许输入数字，空格，逗号，与度分秒)！多个坐标请用分号(;)分隔'));
          }
        }
      }
    };
    return {
      pcs_Z39: {},
      pcs_117E: {},
      gcs_2000: {},
      model: {},
      labelCol: { span: 6 },
      wrapperCol: { span: 17 },
      visible: false,
      confirmLoading: false,
      currentIndex: '',
      form: {
        locate: '',
        geodetic: '',
        projCoord: '',
        degree: '',
        lng:'',
        lat: '',
      },
      pagination: {
        onChange: page => {
          this.pagination.current = page;
          this.getHistory();
        },
        disabled: false,
        pageSize: 10,
        total: 0,
        size: 'small',
        current: 1
      },
      reg3: /^[\-\+]?(180|1?[0-7]?\d)°([1-5]?[0-9]?\d)′([1-5]?[0-9]?\d(\.\d+)?)″[\uff0c\,\ \t][\-\+]?(90|[0-8]?\d)°([1-5]?[0-9]?\d)′([1-5]?[0-9]?\d(\.\d+)?)″$/,
      coordsArr: [],
      coords: '',
      data: [],
      isDegree: true,
      isGeodetic: true,
      isProjCoord: true,
      history: false,
      historyList: [],
      rules: {
        locate: [{
          validator: validateLocate,
          trigger: 'blur'
        }],
        lng:[{required:true,message:'请输入经度',trigger: 'blur'},
          {pattern:/^(\-|\+)?\d+(\.\d+)?$/,message:'请输入正确的坐标', trigger:'blur'}],
        lat:[{required:true,message:'请输入纬度',trigger: 'blur'},
          {pattern:/^(\-|\+)?\d+(\.\d+)??$/,message:'请输入正确的坐标',trigger:'blur'}],
      }
    };
  },
  props: {
    value: {
      type: Boolean,
      default: false,
      required: true
    }
  },
  mounted() {
    this.pcs_Z39 = new SpatialReference({
      wkid: 4527
    });
    this.pcs_117E = new SpatialReference({
      wkid: 4548
    });
    this.gcs_2000 = new SpatialReference({
      wkid: 4490
    });
    this.projectionLoad = projection.load();
  },
  watch: {
    value: function(newValue) {
      if (newValue === false) {
        // this.resetForm();
        this.history = false;
        this.basicMap.locate_GraphicsLayer.removeAll();
      }
    }
  },
  inject: ['basicMap'],
  methods: {
    pickCoordsOnMap() {
      let that = this;
      this.pickCoordsHandler = this.basicMap.mapView.on('click', (evt)=> {
        let lng = evt.mapPoint.longitude.toFixed(6);
        let lat = evt.mapPoint.latitude.toFixed(6);
        this.form.lng=lng;
        this.form.lat=lat;
      });
    },
    handleHistoryLocate(item) {
      this.form.locate = item.inputval;
      item = item.inputval.split(',');
      // this.form.locate= item.inputval;
      this.form.lng=item[0];
      this.form.lat=item[1];
      this.onSubmit();
    },
    onSubmit() {
      this.coordsArr = [];
      let m_this = this;
      this.$refs.ruleForm.validate((valid) => {
        if (valid) {
          let arrLo;
          if (m_this.coordsArr.length !== 0) {
            m_this.coordsArr.forEach((item, index) => {
              m_this.coordsArr[index] = m_this.replaceLocate(item);
            });
          } else {
            arrLo = [this.form.lng,this.form.lat]
            m_this.coordsArr.push(arrLo);
          }
          if (m_this.coordsArr.length > 10) {
            m_this.$message.error('最多支持同时查询十个点！');
            return;
          }
          this.data = this.coordsArr.slice(0);
          m_this.coordsArr.forEach((item, index) => {
            if (m_this.reg3.test(item)) {
              m_this.isGeodetic = false;
              m_this.isDegree = true;
              m_this.isProjCoord = false;
              item.forEach((itemA, index) => {
                itemA = itemA.replace('°', ',');
                itemA = itemA.replace('′', ',');
                itemA = itemA.replace('″', ',');
                itemA = m_this.changeDegree(itemA);
                item[index] = itemA;
              });
            } else {
              m_this.isGeodetic = true;
              m_this.isDegree = false;
              m_this.isProjCoord = false;
            }
            // 将字符串类型转换为数字类型
            item.forEach((itemB, index) => {
              item[index] = parseFloat(itemB);
            });
            // 默认按从大到小排
            item.sort((a, b) => {
              return b - a;
            });
            let projCoord;
            if (item[0] > 39000000&&item[1]>180) {
              m_this.isGeodetic = false;
              m_this.isDegree = false;
              m_this.isProjCoord = true;
              item.forEach((itemC, index) => {
                item[index] = parseFloat(itemC).toFixed(3);
              });
              m_this.form.projCoord = item.join(',');
              item = m_this.transform(item, m_this.pcs_Z39, m_this.gcs_2000);
            } else if (item[0] > 180&&item[1]>180) {
              m_this.isGeodetic = false;
              m_this.isDegree = false;
              m_this.isProjCoord = true;
              item.forEach((itemD, index) => {
                item[index] = parseFloat(itemD).toFixed(3);
              });
              m_this.form.projCoord = item.join(',');
              item.reverse();
              item = m_this.transform(item, m_this.pcs_117E, m_this.gcs_2000);
            } else if (item[0] <180&&item[0]>0&&item[1]>0&&item[1]<90) {
              projCoord = m_this.transform(item, m_this.gcs_2000, m_this.pcs_Z39);
              projCoord.forEach((item, index) => {
                projCoord[index] = parseFloat(item).toFixed(3);
              });
              m_this.form.projCoord = projCoord.join(',');
            }else {
              m_this.$message.error('输入数据有误！');
              m_this.isGeodetic = true;
              m_this.isDegree = true;
              m_this.isProjCoord = true;
              return;
            }
            m_this.coordsArr[index] = item;
            m_this.form.geodetic = item.map((item, index) => {
              return item = parseFloat(item).toFixed(6);
            }).join(',');
            m_this.form.degree = item.map((item) => {
              return item = m_this.formatDegree(item);
            }).join(',');
            if (item[0] > 180 || item[1] > 90) {
              m_this.$message.error('输入数据有误！');
              m_this.isGeodetic = true;
              m_this.isDegree = true;
              m_this.isProjCoord = true;
              return
            }
          });
          if(m_this.isGeodetic&&m_this.isDegree&&m_this.isProjCoord&&this.coordsArr.length===1){return }
          m_this.locateByCoords();
        } else {
          return false;
        }
      });
      if (this.pickCoordsHandler) {
        this.pickCoordsHandler.remove();
      }
    },
    transform(coords, inSpatialReference, outSpatialReference) {
      let point = new Point({
        x: coords[0],
        y: coords[1],
        spatialReference: inSpatialReference
      });
      let transPoint = projection.project(point, outSpatialReference);
      return [transPoint.x, transPoint.y];
    },
    replaceLocate(loc) {
      // 将英文空格转换为,
      let locate = loc;
      if (loc.includes(' ')) {
        locate = loc.replace(' ', ',');
      } else if (loc.includes('，')) {
        locate = loc.replace('，', ',');
      } else if (loc.includes('	')) {
        locate = loc.replace('	', ',');
      } else if (loc.includes('\t')) {
        locate = loc.replace('\t', ',');
      }
      let it = locate.split(',');
      return it;
    },
    //度分秒转换为度
    changeDegree(coord) {
      let arr = coord.split(',');
      let miao = arr[2];
      let fen = arr[1];
      let du = arr[0];
      var mFen = 0;
      if (miao != null && miao !== '') {
        mFen = Number(miao / 60);
      }
      var fDu = 0;
      if (fen != null && fen != '') {
        fDu = (Number(fen) + mFen) / 60;
      } else {
        fDu = mFen;
      }
      var lDu = 0;
      if (du != null && du != '') {
        lDu = (Number(du) + fDu).toFixed(6);
      } else {
        lDu = fDu.toFixed(6);
      }

      return lDu;
    },
    formatDegree(value) {
      if (value != null && value != '') {
        ///<summary>将度转换成为度分秒</summary>
        value = Math.abs(value); //返回数的绝对值
        var v1 = Math.floor(value); //度   //对数进行下舍入
        var v2 = Math.floor((value - v1) * 60); //分
        var v3 = Math.round((value - v1) * 3600 % 60); //秒  //把数四舍五入为最接近的整数
        return v1 + '°' + v2 + '′' + v3 + '″';
      } else {
        return '' + ';' + '' + ';' + '' + ';';
      }
    },
    async locateByCoords() {
      if (this.coords.toString() === this.coordsArr.toString()) {
        this.locateFit();
        return;
      }
      this.coords = this.coordsArr;

      let { success, message } = await postAction('gis.lochistory/locHistory/add', { inputval: this.coords[0].join() });
      if (!success) {
        this.$message.error(message);
        return;
      }
      this.locateFit();
    },
    locateFit() {
      let lng = [];
      let lat = [];
      this.coords.forEach((item, index) => {
        lng.push(item[0]);
        lat.push(item[1]);
      });
      this.basicMap.locate_GraphicsLayer.removeAll();
      let point_symbol = {
        type: 'picture-marker',
        url: require('../static/locate-red.png'),
        width: '48px',
        height: '48px',
        yoffset: '24px'      //图片默认定位在中心，所以Y方向需要设置一下偏移量
      };
      let point = {
        type: 'point',
        longitude: lng[0],
        latitude: lat[0]
      };
      let pointGraphic = new Graphic({
        geometry: point,
        symbol: point_symbol
      });
      this.basicMap.locate_GraphicsLayer.add(pointGraphic);
      let scale = this.basicMap.mapView.scale * 2;
      this.basicMap.mapView.goTo({
        scale: scale
      }, {
        duration: 600
      });
      let coords = [lng[0],lat[0]];
      setTimeout(() => {
        this.basicMap.mapView.goTo({
          center: coords,
          scale: 2000
        }, {
          duration: 1400
        });
      }, 500);
    },
    showModal(item, index) {
      this.visible = true;
      this.model.name = item.name;
      this.model.inputval = item.inputval;
      this.model.id = item.id;
      this.currentIndex = index;
    },
    async handleOk(e) {
      this.confirmLoading = true;
      let { success, result, message } = await postAction('gis.lochistory/locHistory/edit', { ...this.model });
      if (success) {
        this.visible = false;
        this.confirmLoading = false;
        this.historyList[this.currentIndex].name = this.model.name;
      } else {
        this.$message.error(message);
      }
    },
    handleCancel(e) {
      this.visible = false;
    },
    async handleRemove(id, index) {
      let { success, result, message } = await deleteAction('gis.lochistory/locHistory/delete', { id });
      if (success) {
        this.$message.success('删除成功');
        this.historyList.splice(index, 1);
      } else {
        this.$message.error(message);
      }

    },
    resetForm() {
      this.$refs.ruleForm.resetFields();
      this.isDegree = true;
      this.isGeodetic = true;
      this.isProjCoord = true;
      this.coordsArr = [];
      this.data=[];
      this.coords = '';
      this.basicMap.locate_GraphicsLayer.removeAll();
      if (this.pickCoordsHandler) {
        this.pickCoordsHandler.remove();
      }
    },
    handleHistory() {
      if (this.history) {
        this.history = false;
      } else {
        this.history = true;
        this.getHistory();
      }
    },
    async getHistory() {
      let {
        success,
        result,
        message
      } = await getAction('gis.lochistory/locHistory/list', {
        createBy: this.$store.state.user.info.username,
        pageNo: this.pagination.current,
        column: 'createTime',
        order: 'desc',
        field: 'id,,,createBy,createTime,name,inputval,action'
      });
      if (success) {
        this.historyList = result.records;
        this.pagination.total = parseInt(result.total);
      } else {
        this.$message.error(message);
      }
    }
  }

};
</script>

<style>
.coord {

}

.coord .ant-list-item-meta-description {
  word-break: break-all;
  white-space: normal;
  cursor: text;
  user-select: text;
}

.coord .ant-spin-nested-loading {
  max-height: 200px;
  overflow-y: auto;

}

.coord .ant-card-body {
  padding: 1em;
}

.coord .ant-list-item-action {
  text-align: end;
}

.coord .ant-form-item-children {
  display: flex;
  justify-content: space-around;
  align-items: center;
}

.coord .text {
  cursor: text;
  color: rgba(0, 0, 0, .65);
  font-weight: 400;
  font-size: 14px;
  padding: 4px 11px;
  background-color: #fafafa;
  border: 1px solid #d9d9d9;
  border-radius: 4px;
  transition: all .3s;
  width: 100%;
  height: 32px;
  line-height: 1.5;
  display: inline-block;
  user-select: text;
}

</style>
