<template>
<<<<<<< HEAD
    <div class="map-container">
      <div id="mapContainer" class="map-box"></div>
  
      <!-- 图层控制 -->
      <div class="layer-control-center" v-if="false">
        <a-collapse v-model:activeKey="activeKey" accordion expandIconPosition="end" expandIcon="">
          <a-collapse-panel key="1" header="图层">
            <p v-for="(item, index) in props.mapConfig.layers" class="layer-item">
              <a-checkbox v-model:checked="item.checked" @change="handlerCheckboxChange(item)">{{
                item.name
              }}</a-checkbox>
            </p>
            <p v-for="(item, index) in props.mapConfig.baseLayers" class="layer-item">
              <a-checkbox v-model:checked="item.checked" @change="handlerCheckboxChange(item)">{{
                item.name
              }}</a-checkbox>
            </p>
          </a-collapse-panel>
        </a-collapse>
      </div>
=======
  <div class="map-container">
    <div id="mapContainer" class="map-box"></div>
>>>>>>> 666e8282d20e63d6618652a83ba0b8f126f74646

    <!-- 图层控制 -->
    <div class="layer-control-center">
      <a-collapse v-model:activeKey="activeKey" accordion expandIconPosition="end" expandIcon="">
        <a-collapse-panel key="1" header="图层">
          <p v-for="(item, index) in props.mapConfig.layers" :key="index">
            <a-checkbox v-model:checked="item.checked" @change="handlerCheckboxChange(item)">{{
              item.name
            }}</a-checkbox>
          </p>
          <p v-for="(item, index) in props.mapConfig.baseLayers" :key="index">
            <a-checkbox v-model:checked="item.checked" @change="handlerCheckboxChange(item)">{{
              item.name
            }}</a-checkbox>
          </p>
        </a-collapse-panel>
      </a-collapse>
    </div>

    <!-- 绘图控制 -->
    <div class="draw-control-center" v-show="drawing">
      <div class="draw-btn" @click="handlerCancleDraw"> 取消 </div>
      <div class="draw-btn" @click="handlerDrawComplete"> 保存 </div>
    </div>
  </div>
</template>

<script lang="ts" setup>
  import {
    onMounted,
    onUnmounted,
    defineProps,
    defineEmits,
    reactive,
    ref,
    defineExpose,
  } from 'vue';

<<<<<<< HEAD
    // 测量工具
    import { SwitchLayerControl,MeasureControl,SwitchMapControl } from 'mapbox-extensions'
    import 'mapbox-extensions/dist/index.css'
=======
  import { useMessage } from '@/hooks/web/useMessage';
>>>>>>> 666e8282d20e63d6618652a83ba0b8f126f74646

  import mapboxgl, { Map, Popup } from 'mapbox-gl';

  // 图形绘制工具类
  import MapboxDraw from '@mapbox/mapbox-gl-draw';

  import { generateUUID, getGeometryCenter } from './src/tool';

  // 测量工具
  import { SwitchLayerControl, MeasureControl } from 'mapbox-extensions';
  import 'mapbox-extensions/dist/index.css';

  import U from 'mapbox-gl-utils';
  import 'mapbox-gl/dist/mapbox-gl.css';
  import './src/index.less';
  import { MapboxConfig, MapboxDefaultStyle, MapControlConfig } from './src/config';
  import { MP } from './src/MP';
  import { DrawingType } from '@/enums/mapEnum';

<<<<<<< HEAD
            },
            measureLineStringOptions:{ 
            },
            measurePolygonOptions:{    
            }
        }),"top-right")

        let applicationLayers = []
        let baseLayers = [];
        props.mapConfig.layers?.forEach((item,index)=>{
          let style = JSON.parse(item.style)
          let layers = {
            name:item.name,   
            layer:style,     
            fixed:true,    
            zoom:-100,   
            easeToOptions:{},   
            mutex:true,          
            mutexIdentity:"t1",  
            active:false,         
            backgroundImage:"",  
            backgroundImageActive:"",

            onVisibleChange:(visible:boolean)=>{}
          }
          applicationLayers.push(layers)
        })

        props.mapConfig.baseLayers?.forEach((item,index)=>{
          let layers = {
            name:item.name,   
            layer: item.layer,     
            fixed:true,    
            zoom:-100,   
            easeToOptions:{},   
            mutex:true,          
            mutexIdentity:index,  
            active:false,         
            backgroundImage:"http://lbs.tianditu.gov.cn/images/cia_c.png",  
            backgroundImageActive:"",
            onVisibleChange:(visible:boolean)=>{}
          }
          baseLayers.push(layers)
        })

        map.addControl(new SwitchLayerControl({
              name:"图层管理" ,       
              position:"top-left",     
              selectAndClearAll:true, 
              selectAllLabel:"select all",   
              clearAllLabel:"clear all",    
              showToTop:true,         
              topLayerId:"",          
              layerGroups:{           
                  "应用图层":{
                      mutex:true,         
                      collapse:true,      
                      uiType:"SwitchBtn", 
                      layers:applicationLayers
                  },
                  "地图底图":{
                      mutex:true,         
                      collapse:true,      
                      uiType:"ImgTxtBtn", 
                      layers:baseLayers
                  },
              }
          }),"top-left");


      });
    });
    // 销毁地图
=======
  import {
    SnapPolygonMode,
    SnapPointMode,
    SnapLineMode,
    SnapModeDrawStyles,
    SnapDirectSelect,
  } from 'mapbox-gl-draw-snap-mode';
>>>>>>> 666e8282d20e63d6618652a83ba0b8f126f74646

  import { customDrawStyles } from './Styles/Styles';
  import Drawtool from '@/views/datamaintenance/components/drawtool.vue';
  import { WktToGeojson, GeojsonToWkt } from './src/WktGeojsonTransform';
  import { features } from 'process';

  const openModal = ref(false);
  const insertShpModal = ref(false);
  const changeOpenModal = (value) => {
    openModal.value = value;
  };
  const changeOpenInsertShpModal = (value) => {
    insertShpModal.value = value;
  };

  // map参数类型
  interface MapboxOptionsInterface {
    mapOptions: mapboxgl.MapboxOptions;
    control: DrawingType[];
  }

  const props = defineProps({
    mapConfig: {
      type: Object,
      default: {},
    },
    layers: {
      type: Array,
      default: [],
    },
    location: {
      type: Array,
      default: [],
    },
    type: {
      type: String,
      default: '',
    },
    feature: {
      type: String,
      default: '',
    },
  });

  console.log('mapConfig', props.mapConfig);

  let nextMapControl: Array<any> = reactive([]);
  nextMapControl = props.control
    ? props.control.map((item) => {
        return MapControlConfig[item];
      })
    : [];

  // 定义地图容器
  let map: Map;
  let drawTool: any;
  let popup: Popup;
  let clickPoisition: Array<number> = [];
  let selectFeature: Object = {};
  let mp: any = null;
  let geojson = reactive({
    geojson: {},
  });
  let drawing = ref(false);

  let drawGeojson = reactive({
    geojson: {
      type: 'FeatureCollection',
      features: [],
    },
  });

  const { createConfirm, createMessage } = useMessage();

  // 定义地图回调emit
  // 地图加载完成回调
  const emit = defineEmits(['mapOnLoad', 'mapDraw', 'handlerDrawComplete']);

  onMounted(() => {
    mapboxgl.accessToken = MapboxConfig.ACCESS_TOKEN;
    map = initMap();
    map.on('load', () => {
      // 根据地图配置信息加载地形数据
      if (props.mapConfig.mode == '3D') {
        handlerLoadTerrain();
      }

      // 初始化绘图空间
      // handlerInitDrawTool(null);

      map.on('click', (e) => {
        // handlerPreviewFeatureInfo(e);
        clickPoisition = e.lngLat;
      });

      map.on('draw.selectionchange', (e) => {
        // handlerCopyToTargetLayer(e);
      });
      emit('mapOnLoad', map);

      // 设置绘图监听事件
      map.on('draw.create', function (e) {
        drawGeojson.geojson.features = e.features;
        handlerDealFeature(e.features[0]);
      });

      map.on('draw.update', function (e) {
        drawGeojson.geojson = e.features;
        handlerDealFeature(e.features[0]);
      });

      map.on('draw.delete', function (e) {
        handlerDeleteFeature(e.features[0]);
      });

      window.handlerCopyFeature = handlerCopyFeature;

      // 测量工具
      map.addControl(
        new MeasureControl({
          horizontal: true, //default false
          btnBgColor: '#ffffff', //default '#ffffff'
          btnActiveColor: '#ddd', //default '#ddd'
          geometryClick: true, //defualt false
          enableModes: ['Point', 'LineString', 'Polygon'], //default all
          onStart: () => {},
          onStop: () => {},
          measurePointOptions: {},
          measureLineStringOptions: {},
          measurePolygonOptions: {},
        }),
        'top-right',
      );
    });
  });
  // 销毁地图

  // 加载地形
  const handlerLoadTerrain = () => {
    map.addSource('mapbox-dem', {
      type: 'raster-dem',
      url: 'mapbox://mapbox.mapbox-terrain-dem-v1',
      tileSize: 512,
      maxzoom: 14,
    });

    map.setTerrain({ source: 'mapbox-dem', exaggeration: 1.5 });
  };
  // 移除地图实例
  onUnmounted(() => {
    map ? map.remove() : null;
  });

  // 数据绘制完成判断
  const handlerDealFeature = (feature) => {
    let existFeature = geojson.geojson.features.find((item, index) => {
      return item.id == feature.id;
    });

    if (existFeature) {
      // 如果查找到了 则替换数据
      for (let i = 0; i < geojson.geojson.features.length; i++) {
        if (geojson.geojson.features[i].id == feature.id) {
          geojson.geojson.features[i] = feature;
        }
      }
    } else {
      // 如果没找到数据则添加到数组
      geojson.geojson.features.push(feature);
    }
    // 自动将数据返回给父组件
    handlerDrawComplete();
  };

  // 删除数据
  const handlerDeleteFeature = (feature) => {
    for (let i = 0; i < geojson.geojson.features.length; i++) {
      if (geojson.geojson.features[i].id == feature.id) {
        geojson.geojson.features.splice(i, 1);
      }
    }
    // handlerDrawComplete();
  };

  // 初始化地图 返回地图实例
  const initMap = () => {
    return new mapboxgl.Map({
      container: 'mapContainer',
      language: 'zh-cmn',
      projection: 'equirectangular', // wgs84参考系
      style: MapboxDefaultStyle,
      maxZoom: props.mapConfig.maxZoom ? props.mapConfig.maxZoom : 18,
      minZoom: props.mapConfig.minZoom ? props.mapConfig.minZoom : 1,
      zoom: props.mapConfig.zoom ? props.mapConfig.zoom : 12,
      pitch: props.mapConfig.angle ? props.mapConfig.angle : 0,
      center: props.mapConfig.center?.split(','),
    });
  };

  const handlerMapControlClick = (handler: string) => {
    handler === 'handlerDrawPoint' && handlerDrawPoint();
    handler === 'handlerDrawLineString' && handlerDrawLineString();
    handler === 'handlerDrawPolygon' && handlerDrawPolygon();
  };
  //绘制点
  const handlerDrawPoint = () => {
    mp.draw('Point');
    mp.on('Point', function (e) {
      emit('mapDraw', 'Point', e);
    });
  };
  //绘制线
  const handlerDrawLineString = () => {
    mp.draw('LineString');
    mp.on('LineString', function (e) {
      emit('mapDraw', 'LineString', e);
    });
  };
  //绘制面
  const handlerDrawPolygon = () => {
    mp.draw('Polygon');
    mp.on('Polygon', function (e) {
      emit('mapDraw', 'Polygon', e);
    });
  };
  //删除标记
  const handlerUnDraw = () => {
    mp.deleteDraw();
    emit('mapDraw', 'cancel');
  };

  // 初始化绘图空间
  const handlerInitDrawTool = (feature, bool) => {
    // if (feature.features.length > 0) {

    //     feature.features.forEach((item) => {

    //         if (item.geometry.type == 'MultiPolygon') {
    //             let arr: any = ref([]);
    //             item.geometry.coordinates.forEach((val) => {
    //                 arr.value.push(val[0]);
    //             });
    //             item.geometry.coordinates = arr.value;
    //             item.geometry.type = 'Polygon';
    //         }
    //     });

    // }

    geojson.geojson = feature;

    if (drawTool) {
      drawTool.deleteAll();
      if (feature.features) {
        drawTool.set(geojson.geojson);
      }
    } else {
      drawTool = new MapboxDraw({
        modes: {
          ...MapboxDraw.modes,
          draw_point: SnapPointMode,
          draw_polygon: SnapPolygonMode,
          draw_line_string: SnapLineMode,
          direct_select: SnapDirectSelect,
        },
        styles: customDrawStyles,
        userProperties: true,
        snap: true,
        snapOptions: {
          snapPx: 12, // defaults to 15
          snapToMidPoints: true, // defaults to false
          snapVertexPriorityDistance: 0.0025, // defaults to 1.25
        },
        guides: false,
      });

      map.addControl(drawTool, 'top-right');

      if (feature.features) {
        drawTool.set(geojson.geojson);
      }
    }

    // 正在绘制
    // if (bool) {
    //     drawing.value = true;
    // } else {
    //     drawing.value = false;
    // }

    drawing.value = true;
  };

  // 将图斑复制到指定图层
  const handlerCopyToTargetLayer = (e) => {
    if (e.features.length > 0) {
      if (popup) {
        popup.remove();
        popup = null;
      }

      selectFeature = e.features[0];

      popup = new mapboxgl.Popup({
        closeButton: false,
        closeOnClick: false,
      });

      // 设置 popup 的位置和内容
      popup
        .setLngLat(clickPoisition)
        .setHTML(
          `
                    <div style="color:#333;padding:3px 12px;cursor:pointer;" type="primary" icon="el-icon-search" onclick="handlerCopyFeature();">复制当前图斑</div>`,
        )
        .addTo(map);
    } else {
      popup.remove();
    }
  };

  const handlerCopyFeature = () => {
    popup.remove();
    createMessage.success('复制成功！');
  };

  // 添加到图层
  const handlerAddToLayerList = (layer) => {
    handlerCheckLayerExist(layer);
  };

  // 判断图层列表中是否一定添加
  const handlerCheckLayerExist = (layer) => {
    for (let i = 0; i < layerList.length; i++) {
      if (layerList[i] == layer.id) {
        return;
      }
    }
    layerList.push(layer);
  };

  const handlerCheckboxChange = (item) => {
    console.log('itemitemitem', item);
    handlerPreviewLayer(item);
  };

  // 控制图层是否显示
  const handlerPreviewLayer = (layer) => {
    console.log('layersss', layer);
    handlerLayerControler(layer);
  };

  // 图层控制中心
  const handlerLayerControler = (layerInfo) => {
    layerInfo.layer = layerInfo.layer ? layerInfo.layer : JSON.parse(layerInfo.style);

    if (map.getSource(layerInfo.layer.id)) {
      if (layerInfo.checked) {
        map.setLayoutProperty(layerInfo.layer.id, 'visibility', 'visible');
      } else {
        map.setLayoutProperty(layerInfo.layer.id, 'visibility', 'none');
      }
    } else {
      map.addLayer(layerInfo.layer);
      map.on('click', layerInfo.layer.id, function (e) {
        handlerPreviewFeatureInfo(e);
      });
    }
  };

  // 查看列表数据
  const handlerDataList = () => {};

  // 图斑属性查看
  const handlerPreviewFeatureInfo = (e) => {
    if (e.features) {
      isOpen.value = true;
    }
  };

  const handlerClose = (e) => {
    isOpen.value = e;
  };

  // 图斑定位
  const handlerLocation = (lngLat) => {
    map.flyTo({
      center: lngLat,
      zoom: 17,
      speed: 10, // 飞行速度
      curve: 1, // 飞行曲线
      easing(t) {
        // 飞行动画函数
        return t;
      },
    });
  };

  // 编辑图斑
  const handlerEdit = (info) => {
    initDraw(info);
  };

  const initDraw = (layerInfo) => {
    // 实例化绘图工具
    drawTool = new MapboxDraw({
      modes: {
        ...MapboxDraw.modes,
        draw_point: SnapPointMode,
        // draw_polygon: SnapPolygonMode,
        // draw_line_string: SnapLineMode,
        direct_select: SnapDirectSelect,
      },
      styles: customDrawStyles,
      userProperties: true,
      snap: true,
      snapOptions: {
        snapPx: 15, // defaults to 15
        snapToMidPoints: true, // defaults to false
        snapVertexPriorityDistance: 0.0025, // defaults to 1.25
      },
      guides: false,
    });

    map.addControl(drawTool, 'top-right');

    // let geojson:Object = {};
    // if (layerInfo.dataType == "面") {
    //     geojson.type = "Polygon";
    //     geojson.coordinates = geojson.coordinates[0];
    // } else if (layerInfo.dataType == "点") {
    //     geojson.type = "Point";
    //     geojson.coordinates = geojson.coordinates;
    // } else if (layerInfo.dataType == "线") {
    //   geojson.type = "LineString";
    //   geojson.coordinates = geojson.coordinates[0];
    // }
    // if (formData.lat && formData.lng) {
    //   formData.lat = geojson.coordinates[1];
    //   formData.lng = geojson.coordinates[0];
    // }
    // geojson = {
    //   type: "FeatureCollection",
    //   features: [
    //     {
    //       type: "Feature",
    //       geometry: geojson,
    //     },
    //   ],
    // };
    // map.setLayoutProperty("pbfLayer", "visibility", "none");
    // drawTool.set(geojson);
  };

  const handlerDrawComplete = () => {
    let arr = [];
    geojson.geojson.features.forEach((item, index) => {
      let wktStr = GeojsonToWkt(item.geometry);
      let obj = {
        columnName: 'mapgeom',
        value: wktStr,
      };
      arr.push(obj);
    });
    console.log('aaaa', arr);
    emit('handlerDrawComplete', arr);
  };

  const handlerCancleDraw = () => {
    map.removeControl(drawTool);
    drawTool = null;
    drawing.value = false;

    // 清空详情图层
    if (map.getSource('detailsSource')) {
      map.getSource('detailsSource').setData({
        type: 'FeatureCollection',
        features: [],
      });
    }
  };

  /**
   *
   * 查看图斑
   *
   * 添加图斑
   *
   * 编辑图斑
   *
   * status 操作类型
   *
   * features 空间数据
   *
   * [
   *  {id:"8448048304dofhaofh0af0q4",geom:""}
   * ]
   * */
  const handlerDraw = (status: string, features = null, bool = false) => {
    let geo = {
      type: 'FeatureCollection',
      features: [],
    };
    // 清空详情图斑
    if (map.getSource('detailsSource')) {
      map.getSource('detailsSource').setData({
        type: 'FeatureCollection',
        features: [],
      });
    }
    if (features == null) {
      bool = true;
    } else {
      if (features.length > 0) {
        for (let i = 0; i < features.length; i++) {
          try {
            let featureTemp = WktToGeojson(features[i]?.mapgeom);
            let feature = {
              id: generateUUID(),
              type: 'Feature',
              properties: {},
              geometry: featureTemp,
            };
            geo.features.push(feature);

            // 获取第一个图斑的中心点跳转定位
            if (i == 0) {
              let lngLat = getGeometryCenter(feature);
              handlerLocation(lngLat);
            }
          } catch (e) {
            createMessage.error('WKT数据格式解析错误，请检查WKT数据格式是否有误！');
          }
        }
      }
    }
    switch (status) {
      case 'Add':
        handlerInitDrawTool(geo, bool);
        break;
      case 'Edit':
        handlerInitDrawTool(geo, bool);
        break;
      case 'Details':
        handlerDetails(geo);
        break;
      default:
        createMessage.error('请传入操作类型！');
    }
  };

  // 查看图斑详情
  const handlerDetails = (geojson) => {
    if (map.getSource('detailsSource')) {
      map.getSource('detailsSource').setData(geojson);
    } else {
      map.addSource('detailsSource', {
        type: 'geojson',
        data: geojson,
      });
      map.addLayer({
        id: 'detailsLayer',
        type: 'fill',
        source: 'detailsSource',
        layout: {},
        paint: {
          //填充颜色
          'fill-color': '#3badc9',
          //透明度设置
          'fill-opacity': 0.4,
        },
      });

      map.addLayer({
        id: 'detailsLayerLine',
        type: 'line',
        source: 'detailsSource',
        layout: {},
        paint: {
          'line-color': '#3badc9',
          'line-width': 2,
        },
      });
    }
  };

  // 创建查看图斑图层

  defineExpose({
    handlerDraw,
    handlerLocation,
    handlerCancleDraw,
  });
</script>

<style>
  .map-container {
    width: 100%;
    height: 100%;
  }

  .map-box {
    width: 100%;
    height: 100%;
  }

  .layer-control-center {
    position: absolute;
    top: 15px;
    left: 15px;
    background: #fff;
    border-radius: 8px;
  }

  .layer-control-center p {
    margin: 0px;
  }

  .layer-control-center .ant-checkbox-wrapper {
  }

  .draw-control-center {
    position: absolute;
    padding: 8px;
    top: 15px;
    right: 15px;
    background: #ffffff;
    border-radius: 12px;
  }

  .draw-control-center .draw-btn {
    float: left;
    margin: 0px 7px;
    padding: 5px;
    border-radius: 5px;
  }

  .draw-control-center .draw-btn:hover {
    background-color: rgb(0 0 0/5%);
    cursor: pointer;
  }

<<<<<<< HEAD
    .mapboxgl-ctrl-group {
      padding: 6px;
      border-radius: 12px;
      top: 5px;
    }
    .mapbox-gl-draw_ctrl-draw-btn {
      width: 20px !important;
      height: 20px !important;
      float: left;
    }
=======
  .mapboxgl-ctrl-group:not(:empty) {
    box-shadow: none;
  }
>>>>>>> 666e8282d20e63d6618652a83ba0b8f126f74646

  .mapboxgl-ctrl-group {
    padding: 10px;
    border-radius: 12px;
    position: relative;
    right: 140px;
    top: 5px;
  }
  .mapbox-gl-draw_ctrl-draw-btn {
    width: 20px !important;
    height: 20px !important;
    float: left;
  }

  .mapboxgl-ctrl-top-right {
  }

  .mapboxgl-ctrl-group button + button {
    border: 0px;
    margin: 0px 6px;
  }

  .mapbox-gl-draw_ctrl-draw-btn:hover {
    transform: scale(1.2);
  }

<<<<<<< HEAD
    .jas-ctrl-measure-item{
        height:22px;
        color: rgb(255, 255, 255);
    }

    .layer-item{
      padding:8px 16px;

    }

    .layer-item:hover{
      background:#c7dcf580;

    }

    

    ::v-deep .ant-collapse-content-box{
      padding:0px!important;
    }



  </style>
  
=======
  .mapbox-gl-draw_polygon {
    background-image: url(/polygon.png);
    background-size: 100% 100%;
    width: 100px;
    height: 100px;
  }
  .mapbox-gl-draw_point {
    background-image: url(/point.png);
    background-size: 100% 100%;
    width: 100px;
    height: 100px;
  }
  .mapbox-gl-draw_line {
    background-image: url(/line.png);
    background-size: 100% 100%;
    width: 100px;
    height: 100px;
    margin: 0px 6px;
  }

  .mapbox-gl-draw_trash {
    background-image: url(/del.png);
    background-size: 100% 100%;
    width: 100px;
    height: 100px;
  }

  .mapbox-gl-draw_combine {
    background-image: url(/combine.png);
    background-size: 100% 100%;
    width: 100px;
    height: 100px;
  }

  .mapbox-gl-draw_uncombine {
    background-image: url(/uncombine.png);
    background-size: 100% 100%;
    width: 100px;
    height: 100px;
  }

  .jas-ctrl-measure {
    position: relative;
    top: 6px;
    right: 10px;
  }

  .jas-ctrl-measure-item {
    height: 22px;
    color: #fff;
  }
</style>
>>>>>>> 666e8282d20e63d6618652a83ba0b8f126f74646
