import "ol/ol.css";
import {
    Map,
    View
} from "ol";
import {
    OverviewMap,
    defaults
} from "ol/control";
import TileLayer from "ol/layer/Tile";
import XYZ from "ol/source/XYZ";
import LayerGroup from "ol/layer/Group";

import { fromLonLat, toLonLat, transform, get} from "ol/proj";
import Feature from "ol/Feature";
import { Icon, Style, Text, Fill, Stroke } from "ol/style";
import { Vector as VectorLayer } from "ol/layer";
import { Vector as VectorSource } from 'ol/source';
import Point from "ol/geom/Point";
import Overlay from 'ol/Overlay';
import Select from 'ol/interaction/Select'

import Draw from 'ol/interaction/Draw';
import GeoJSON from 'ol/format/GeoJSON';
import Snap from 'ol/interaction/Snap';

import { toSize } from 'ol/size';

import axios from "axios";

export default class Mutil {
    constructor(divId, option = {}) {
        this.divId = divId;
        this.option = option;
        this.MAP = this.initMap()
    }
    //初始化地图
    initMap() {
        /*  天地图 */
        let  MAP,tianSlA = new TileLayer({
            className: "mapTypeC",
            source: new XYZ({
                // url:
                //       "http://t{0-7}.tianditu.gov.cn/img_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=img&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=c8df739f047ce17cfe41b63cbeae6997",
                //url: "https://t{0-7}.tianditu.gov.cn/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=c8df739f047ce17cfe41b63cbeae6997",
                url: "http://wprd0{1-4}.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scl=1&style=6"
            }),
            visible: true,
            name: "天地图矢量底图影像",
        });
        let tianSlB = new TileLayer({
            className: "mapTypeC",
            source: new XYZ({
                //url: "https://t{0-7}.tianditu.gov.cn/DataServer?T=cva_w&x={x}&y={y}&l={z}&tk=c8df739f047ce17cfe41b63cbeae6997",
                url: " http://wprd0{1-4}.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scl=1&style=7",
            }),
            visible: false,
            name: "天地图标注(不含路网)",
        });
        let tianSlC = new TileLayer({
            className: "mapTypeC",
            source: new XYZ({
                //url: "https://t{0-7}.tianditu.gov.cn/DataServer?T=cia_w&x={x}&y={y}&l={z}&tk=c8df739f047ce17cfe41b63cbeae6997",
                url: "http://webst0{1-4}.is.autonavi.com/appmaptile?style=8&x={x}&y={y}&z={z}",
            }),
            visible: true,
            name: "天地图标注",
        });
        let that = this;
        const ShiJiaZhuang = fromLonLat([114.514793, 38.042225]);
        const BeiJing = fromLonLat([116.322056, 39.89491]);
        const VIEW = new View({
            center: ShiJiaZhuang,
            zoom: 12,
            maxZoom: 18,
        });
        /*
                    鹰眼
                    */
        // const overiewControl = new OverviewMap({
        // 	className: "ol-overviewmap ol-custom-overviewmap",
        // 	layers: [tianSlC, tianSlB, tianSlA],
        // 	collapseLabel: "\u00BB",
        // 	label: "\u00AB",
        // 	collapsed: false,
        // });
        MAP = new Map({
            projection: "EPSG:4326",
            target: that.divId,
            layers: [],
            view: VIEW,
        });
        MAP.setLayerGroup(
            new LayerGroup({
                id: 'mapGroup',
                layers: [tianSlA, tianSlB, tianSlC],
            })
        );
        MAP.on("pointermove", function (evt) {
            MAP.getTargetElement().style.cursor = that.MAP.hasFeatureAtPixel(
                evt.pixel
            ) ?
                "pointer" :
                "";
        });
        return MAP
    }
    //设置地图view
    setViewF(option) {
        let that = this, view = that.MAP.getView();
        if (option.center) view.setCenter(fromLonLat(option.center));
        if (option.zoom) view.setZoom(option.zoom);
    }
    /*标注到地图
    * type为是标注类型 在设备标注中为标注类型- layClassName
    * scale, id可以为空
    */
    addMarkerToMap(type, name, imgageUrl, lnglat, scale, id) {
        let that = this, feature = new Feature({
            geometry: new Point(fromLonLat(lnglat)),
        });
        let style = new Style({
            image: new Icon({
                anchor: [.5, 1],
                src: imgageUrl,
                scale: scale ? scale : 1,
            }),
            text: new Text({
                textAlign: "center", //位置
                textBaseline: "bottom", //基准线
                offsetY: -44,
                font: "normal 14px 微软雅黑", //文字样式
                text: name, //文本内容
                placement: "point",
                fill: new Fill({
                    color: "#efeb54",
                }),
                backgroundFill: new Fill({
                    color: "#5f636a",
                }),
                padding: [2, 2, 2, 2],
            }),
        });
        let iconFeatureArr = [];
        feature.setStyle(style);
        if (id) feature.set('did', id);
        iconFeatureArr.push(feature);
        var vectorSource = new VectorSource({
            features: iconFeatureArr,
        });
        var vectorLayer = new VectorLayer({
            source: vectorSource,
        });
        vectorLayer.set('layClassName', type)
        if (["1", "2", "3", "4", "5", "6"].indexOf(type) > -1) {
            vectorLayer.set('layClassMark', 'Maker');
            if (id) vectorLayer.set('did', id);
        }
        that.MAP.addLayer(vectorLayer)

    }
    /*
    *获取layer根据-layClassName 属性移除
    */
    getLayerByClass( ClassName ){
        let that = this, layerarr = that.MAP.getLayers().getArray(),
            formerLayer = layerarr.filter((e) => e.get("layClassName") == ClassName);
        return formerLayer
    }
    /*
    *移除某类型标注 根据-layClassName 属性移除
    */
    removeSearchm(type) {
        let that = this, layerarr = that.MAP.getLayers().getArray(),
            formerLayer = layerarr.filter((e) => e.get("layClassName") == type);
        if (formerLayer) {
            formerLayer.forEach((ele) => {
                that.MAP.removeLayer(ele);
            });
        }
    }
    //隐藏显示某类型标注 type：Boolean 是否显示
    visibleMarks(type, datatype) {
        let that = this, layerarr = that.MAP.getLayers().getArray(),
            formerLayer = layerarr.filter((e) => e.get("layClassName") == datatype);
        if (formerLayer) {
            formerLayer.forEach((ele) => {
                ele.setVisible(type)
            });
        }
    }
    //增加标注弹窗
    addPopup(popConHtml, id, longitude, latitude) {
        let that = this;
        let newDiv = document.createElement('div');
        newDiv.setAttribute('id', `popup${id}`);
        newDiv.setAttribute('class', `popup`);
        newDiv.innerHTML = `<div class="pop-con"></div>${popConHtml}<div class="pop-close" id="pop-close${id}" data-id="${id}">×</div>`
        let mapdiv = document.getElementById('mapbox');
        mapdiv.appendChild(newDiv);
        let hei = newDiv.offsetHeight, kuan = newDiv.offsetWidth;
        let overlay = new Overlay({
            id: id,
            element: document.getElementById(`popup${id}`),
            autoPan: true,
            offset: [- (kuan / 2 + 10), -(hei + 50)],
            position: fromLonLat([longitude, latitude]),
            autoPanAnimation: {
                duration: 250,
            },
        })
        that.MAP.addOverlay(overlay);
        document.getElementById(`pop-close${id}`).onclick = function () {
            overlay.setPosition(undefined)
        }
    }
    mapSelectBind(callbcak) {//地图绑定选中feature事件
        let se = new Select({
            style: null,
            hitTolerance: 0,
            multi: false,
        });
        se.on("select", function (evt) {
            if (evt.selected.length > 0) {
                callbcak( evt )
            }
        })
        this.MAP.addInteraction(se)
    }
    /*
    *绘制多边形 callbcak-drawend触发事件 mapView:Object
    */
    drawPloygon(mapView, callbcak) {
        let that = this;
        let obj = {
            type: 'Feature',
            geometry: {
                type: 'MultiPolygon',
                coordinates: mapView ? mapView.polygoncoorArr : null
            }
        }
        let source = mapView ? new VectorSource({ wrapX: false, features: new GeoJSON().readFeatures(obj) }) : new VectorSource({ wrapX: false });
        let vector = new VectorLayer({
            source: source,
            style: new Style({
                fill: new Fill({
                    color: 'rgba(212, 220, 29, 0.1)'
                }),
                stroke: new Stroke({
                    color: '#ec0d0d',
                    width: 2
                })
            })
        });
        vector.set('layClassName', 'boundary')
        //已有图形填充到地图
        if (mapView) {
            let view = that.MAP.getView();
            view.setCenter(mapView.center);
            view.setZoom(mapView.zoom);
            that.MAP.addLayer(vector)
            return
        }
        //绘制
        let drawPoly = new Draw({
                source: source,
                type: 'Polygon'
            }),
            drawPoint = new Draw({
                source: source,
                type: 'Point',
                style: new Style({
                    stroke: new Stroke({
                        color: '#08d527',
                        width: 2
                    })
                })
            });
        that.MAP.addLayer(vector)
        that.MAP.addInteraction(drawPoly)
        drawPoly.on('drawend', function (evt) {
            callbcak(evt.feature, evt.target)
            that.MAP.removeInteraction(drawPoly);
        })
    }

    tianSlA() {
        this.MAP.getLayers().getArray()[0].setVisible(true);
        this.MAP.getLayers().getArray()[1].setVisible(false);
        this.MAP.getLayers().getArray()[2].setVisible(true);
    };
    tianSlB() {
        this.MAP.getLayers().getArray()[0].setVisible(false);
        this.MAP.getLayers().getArray()[1].setVisible(true);
        this.MAP.getLayers().getArray()[2].setVisible(false);
    };
    tianSlC() {
        this.MAP.getLayers().getArray()[0].setVisible(false);
        this.MAP.getLayers().getArray()[1].setVisible(false);
        this.MAP.getLayers().getArray()[2].setVisible(true);
    }

    drawArea(json) {
        let pointsz = [];   //存储点坐标
        let points = json.polyline.split(";");  //获取点坐标
        //对获取的点坐标数据进行处理，重构，得到我们需要的数据结构
        for (let i = 0; i < points.length; i++) {
            let region = points[i];   //单个面
            let pArr = region.split(',');
            let pos = fromLonLat(pArr);  //将坐标转为默认投影，默认投影是EPSG：3857
            //let hdms = transform(pos, 'EPSG:3857', 'EPSG:4326');   //坐标系间坐标转换，由前面的坐标转为后面坐标系坐标
            pointsz.push(pos)    //将转化格式后的点坐标存储起来
        };
        //自己造的地图数据（GeoJSON数据）
        let geojsonObject = this.structureGeojson(pointsz);
        let vectorSource = new VectorSource({   //提供矢量图层的数据
            features: (new GeoJSON().readFeatures(geojsonObject))
        });
        let vectorLayer = new VectorLayer({
            source: vectorSource,   //来源
            style: new Style({
                stroke: new Stroke({
                    color: '#08d527',
                    width: 4
                }),
                fill: new Fill({
                    color: 'rgba(212, 220, 29, 0.1)'
                })
            })
        });
        if (this.tempLayer != ' ') {
            this.MAP.removeLayer(this.tempLayer);
        }

        this.MAP.addLayer(vectorLayer);
        this.tempLayer = vectorLayer;
    }
    structureGeojson(pointsz){
        let geojsonObject = {
            'type': 'FeatureCollection',    //要素集合
            'crs': {
                'type': 'name',
                'properties': {  //特性
                    'name': 'EPSG:3857'
                }
            },
            'features': [{  //要素
                'type': 'Feature',
                'geometry': {  //几何图形
                    'type': 'GeometryCollection',   //几何图形集合
                    'geometries': [{   //几何形状
                        'type': 'Polygon',   //多边形
                        'coordinates': [pointsz]    //坐标
                    }]
                }
            }]
        };
        return geojsonObject;
    }

    getBoundaries(name) {  //根据name传参
        axios.get('https://restapi.amap.com/v3/config/district?key=cb087c0fb3b8bc56a4af064630495bb9&subdistrict=0&extensions=all&keywords='+name).then(res => {
            let local = res.data.districts[0].center.split(",");
            let view = this.MAP.getView();
            view.setCenter(fromLonLat(local));
            view.setZoom(10);
            this.drawArea(res.data.districts[0])
        })
    }
}
