<template>
    <div id="map">
        <div class="search">
            <el-input placeholder="请输入内容"
                      v-model="input"
                      clearable
                      size="medium">
                <template slot="append">
                    <span style="cursor: pointer;"
                          @click="goSearch">搜索</span>
                </template>
            </el-input>
        </div>
        <div id="mapContent"
             style="width: 100%;height: 100%;">
            <div id="popup">
                <a href="#"
                   id="popup-closer"></a>
                <div id="popup-title">
                    场所信息
                </div>
                <div>
                    <div>
                        <span>场所名称：{{featureInfo.place_name||"--"}}</span>
                    </div>
                    <div style="margin: 12px 0;">
                        <span>场所类型：{{featureInfo.place_type||"--"}}</span>
                    </div>
                    <div>
                        <span>场所地址：{{featureInfo.place_address||"--"}}</span>
                    </div>
                    <div class="moreInfo"
                         @click="ifShowDetails=true">更多信息</div>
                </div>
            </div>
        </div>
        <el-dialog :visible.sync="ifShowDetails"
                   width="60%"
                   :modal="false">
            <span slot="title"
                  style="font-size:20px;font-weight:700">
                {{ featureInfo.place_name }}的更多信息
            </span>
            <Dialog :info="featureInfo"></Dialog>
            <div slot="footer"
                 style="display: flex;justify-content: space-evenly;">
                <el-button @click="ifShowDetails = false">取 消</el-button>
                <el-button type="primary"
                           @click="ifShowDetails = false">确 定</el-button>
            </div>
        </el-dialog>
    </div>
</template>
<script>

import Map from 'ol/Map';
import { XYZ } from 'ol/source';
import View from 'ol/View';
import { defaults as defaultControls } from 'ol/control.js';
import { Icon, Style, Fill, Stroke, Text } from 'ol/style';
import { Tile as TileLayer, Vector as VectorLayer } from 'ol/layer';
import education from '@/assets/images/fifteen/education.png'
import xz from '@/assets/images/fifteen/xz.png'
import jr from '@/assets/images/fifteen/jr.png'
import qt from '@/assets/images/fifteen/qt.png'
import sy from '@/assets/images/fifteen/sy.png'
import sz from '@/assets/images/fifteen/sz.png'
import wt from '@/assets/images/fifteen/wt.png'
import yl from '@/assets/images/fifteen/yl.png'
import dy from '@/assets/images/fifteen/dy.png'
import { Vector as VectorSource } from 'ol/source';
import { Feature, Overlay } from 'ol'
import { Point, Polygon, Circle } from 'ol/geom'
import { requestPostBi } from "@/js/dai/request-bipass";
import { getPointResolution } from 'ol/proj'
import { METERS_PER_UNIT } from 'ol/proj/Units'
import Dialog from "./dialog.vue"
export default {
    components: {
        Dialog
    },
    data() {
        return {
            map: null,
            vectorSource: null,
            vectorLayer: null,
            rangeSource: null,
            rangeLayer: null,
            positionSource: null,
            positionLayer: null,
            circleSource: null,
            circleLayer: null,
            featureInfo: {},
            overlay: null,
            input: "",
            ifShowDetails: false,
            dialogTitle: ""
        }
    },
    mounted() {
        this.init();

    },
    methods: {
        init() {
            //高德地图也是一种瓦片图层，是通过行列号与层级(zoom)关系加载的
            let gaodeMapLayer = new TileLayer({
                title: "高德地图",
                source: new XYZ({
                    url: 'http://wprd0{1-4}.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scl=1&style=7',
                    wrapX: true
                })
            });

            this.map = new Map({
                layers: [gaodeMapLayer],
                view: new View({
                    center: [120.38140448734, 36.09344959486],
                    projection: 'EPSG:4326',
                    zoom: 14,
                    maxZoom: 18
                }),
                controls: defaultControls({
                    zoom: false,//禁用缩放控件
                    rotate: false,
                }),
                target: 'mapContent'
            });

            this.getRange()

            let container = document.getElementById('popup');
            //构建一个覆盖标注
            this.overlay = new Overlay({
                element: container,//将最外面的div容器放在覆盖标注中
                autoPan: {
                    animation: {
                        duration: 250,//拖动动画的效果
                    },
                },
            });
            //添加标注
            this.map.addOverlay(this.overlay);
            const _this = this;
            _this.map.on("click", function (e) {
                _this.featureInfo = {}
                let feature = _this.map.forEachFeatureAtPixel(e.pixel, function (feature) {
                    return feature
                });
                if (feature && Object.keys(feature.values_).length > 1) {
                    container.style.display = "inline-block"
                    _this.featureInfo = feature.values_ || {}
                    if (_this.featureInfo && Object.keys(_this.featureInfo).length > 0) {
                        _this.initPop(e)
                    }
                } else {
                    container.style.display = "none"
                }

            })

        },
        initPop(e) {
            let coordinate = e.coordinate;//单击事件的坐标
            this.overlay.setPosition(coordinate);//设置覆盖标注位置
            //将视口的中心位置设置为鼠标点击的位置
            // this.map.getView().setCenter(coordinate);  
        },
        goMarker(data) {
            document.getElementById('popup').style.display = "none"
            if (this.positionLayer) {
                this.map.removeLayer(this.positionLayer)
                this.positionLayer = null
            }
            if (Array.isArray(data) && data.length > 1) {
                if (this.vectorLayer) {
                    this.map.removeLayer(this.vectorLayer)
                    this.vectorLayer = null
                }
                //矢量标注的数据源
                this.vectorSource = new VectorSource();
                //矢量标注图层
                this.vectorLayer = new VectorLayer({
                    source: this.vectorSource
                });
                this.map.addLayer(this.vectorLayer);
                data.forEach(f => {
                    if (f.longitude && f.latitude) {
                        this.addImageVectorLabel(f)
                    }
                })
            }
            if (Array.isArray(data) && data.length == 1) {
                //矢量标注的数据源
                this.positionSource = new VectorSource();
                //矢量标注图层
                this.positionLayer = new VectorLayer({
                    source: this.positionSource
                });
                this.map.addLayer(this.positionLayer);
                this.addImageVectorLabel(data[0], "listClick")
                if (data[0]['longitude'] && data[0]['latitude']) {
                    this.map.getView().setCenter([data[0]['longitude'], data[0]['latitude']]);
                }
            }
        },
        //添加图片标注
        addImageVectorLabel(data, type) {
            //新建一个点要素 ol.Feature
            let newFeature = new Feature({
                //几何信息
                geometry: new Point([Number(data.longitude), Number(data.latitude)]),
            });
            newFeature.setProperties(data);
            //设置要素的样式
            data.place_type_code
            if (type == "listClick") {
                data.place_type_code = "listClick"
                newFeature.setStyle(this.createImageLabelStyle(data.place_type_code));
                //将新要素添加到数据源中
                this.positionSource.addFeature(newFeature);
            } else {
                newFeature.setStyle(this.createImageLabelStyle(data.place_type_code));
                //将新要素添加到数据源中
                this.vectorSource.addFeature(newFeature);
            }
        },
        createImageLabelStyle(type) {
            let url
            switch (type) {
                case "commerce_service":
                    url = sy
                    break;
                case "edu":
                    url = education
                    break;
                case "finance_post":
                    url = jr
                    break;
                case "medical":
                    url = yl
                    break;
                case "administration":
                    url = xz
                    break;
                case "culture_sport":
                    url = wt
                    break;
                case "municipal":
                    url = sz
                    break;
                case "others":
                    url = qt
                    break;
                case "listClick":
                    url = dy

                    break;
                default:

                    break;
            }
            return new Style({
                image: new Icon(//返回一个图片标注
                    ({
                        // anchor: [0.5, 60],
                        // anchorOrigin: 'top-right',
                        // anchorXUnits: 'fraction',
                        // anchorYUnits: 'pixels',
                        // offsetOrigin: 'top-right',
                        // offset:[0,10],
                        //图标缩放比例
                        scale: 1,
                        //透明度
                        opacity: 1,
                        //图标的url
                        src: url
                    })
                )
            });
        },
        async getRange() {
            const url = "regional_scope";
            const param = {
                "org_id": localStorage.getItem("agencyId") || "",
            }
            const { data, code, msg } = await requestPostBi(
                url,
                {
                    queryParam: param
                }
            );
            if (code == 0) {
                data.forEach((f, i) => {
                    this.addPolygon(f, i)

                })
            }
        },
        addPolygon(value, index) {
            if (this.rangeLayer) {
                this.map.removeLayer(this.rangeLayer)
            }
            //矢量标注的数据源
            this.rangeSource = new VectorSource();
            //矢量标注图层
            this.rangeLayer = new VectorLayer({
                source: this.rangeSource
            });
            let arr = value.community_coordinates.split(",") || []
            let res = [];
            for (let index = 0; index < arr.length; index += 2) {
                res.push([arr[index], arr[index + 1]]);
            }
            let polygon = new Feature({
                geometry: new Polygon([res]),
            });

            let pointsCenter = this.getPointsCenter(res)
            let point = new Feature({
                geometry: new Point(pointsCenter),
            });
            if (index == 0) {
                this.map.getView().setCenter(pointsCenter);

            }
            //设置区样式信息
            polygon.setStyle(
                new Style({
                    //填充色
                    fill: new Fill({
                        color: 'rgba(255, 255, 255, 0)',
                    }),
                    //边线颜色
                    stroke: new Stroke({
                        color: '#4095e5',
                        width: 4,
                        lineDash: [6],
                    }),
                }),
            );
            point.setStyle(
                new Style({
                    text: new Text({
                        //位置
                        textAlign: 'center',
                        //基准线
                        textBaseline: 'middle',
                        //文字样式
                        font: 'normal 14px 微软雅黑',
                        scale: 1.2,
                        //文本内容
                        text: value.grid_name,
                        //文本填充样式（即文字颜色）
                        fill: new Fill({ color: '#fff' }),
                        backgroundFill: new Fill({//背景设置必须是placement为point的形式
                            color: "#36a3ff"
                        }),
                        padding: [5, 5, 5, 5]
                    })
                })
            );
            this.rangeSource.addFeature(polygon);
            this.rangeSource.addFeature(point);
            this.map.addLayer(this.rangeLayer);
        },
        async goSearch() {
            if (!this.input) {
                this.$parent.getClassify()
                this.$parent.getTableList()
                if (this.circleLayer) {
                    this.map.removeLayer(this.circleLayer)
                }
                return
            }
            const url = "search_all";
            const param = {
                "org_id": localStorage.getItem("agencyId") || "",
                "name": this.input
            }
            const { data, code, msg } = await requestPostBi(
                url,
                {
                    queryParam: param
                }
            );
            if (code == 0) {
                if (data.length == 0) {
                    this.$message({
                        message: '未搜索到数据',
                        type: 'warning'
                    });
                    return
                }
                this.loadCircleLayer(data[0])
            }
        },
        loadCircleLayer(data) {
            if (!Number(data.longitude) || !Number(data.latitude)) {
                this.$message({
                    message: '缺失坐标！',
                    type: 'warning'
                });
                return
            }
            if (this.circleLayer) {
                this.map.removeLayer(this.circleLayer)
            }
            this.circleSource = new VectorSource();
            //矢量标注图层
            this.circleLayer = new VectorLayer({
                source: this.circleSource
            });
            let center = [Number(data.longitude), Number(data.latitude)]
            this.$parent.getTableList(center)
            this.$parent.getClassify(center)
            const view = this.map.getView()
            const resolutionAtEquator = view.getResolution()
            const pointResolution = getPointResolution('EPSG:4326', resolutionAtEquator, center, METERS_PER_UNIT.m)
            const resolutionFactor = resolutionAtEquator / pointResolution
            let radius = (100 / METERS_PER_UNIT.m) * resolutionFactor
            let circle = new Circle(center, radius);// 新建圆对象 
            let newFeature = new Feature(circle);// 新建Feature对象 并将circle传入
            newFeature.setStyle(
                new Style({
                    //填充色
                    fill: new Fill({
                        color: 'rgba(127, 131, 247, 0.5)',
                    }),
                })
            );
            this.map.addLayer(this.circleLayer);
            this.circleSource.addFeature(newFeature);
            view.animate(
                { zoom: 16, duration: 1000 },
                { center: center, duration: 1000 });
        },
        getPointsCenter(points) {
            points.forEach((f, i, arr) => {
                arr[i] = f.join(",")
            })
            let point_num = points.length; //坐标点个数
            let X = 0, Y = 0, Z = 0;
            for (let i = 0; i < points.length; i++) {
                if (points[i] == '') {
                    continue;
                }
                let point = points[i].split(',');
                let lat, lng, x, y, z;
                lat = parseFloat(point[1]) * Math.PI / 180;
                lng = parseFloat(point[0]) * Math.PI / 180;
                x = Math.cos(lat) * Math.cos(lng);
                y = Math.cos(lat) * Math.sin(lng);
                z = Math.sin(lat);
                X += x;
                Y += y;
                Z += z;
            }
            X = X / point_num;
            Y = Y / point_num;
            Z = Z / point_num;

            let tmp_lng = Math.atan2(Y, X);
            let tmp_lat = Math.atan2(Z, Math.sqrt(X * X + Y * Y));

            return [tmp_lng * 180 / Math.PI, tmp_lat * 180 / Math.PI];
        }
    }
}
</script>

<style scoped lang="scss">
#map {
    position: relative;
    #popup {
        background-color: #0e2849;
        color: #fff;
        padding: 16px;
        border-radius: 8px;
        font-size: 18px;
        .moreInfo {
            margin: 12px 0;
            padding: 4px;
            background-color: #fff;
            color: #000;
            border-radius: 2px;
            width: 80px;
            cursor: pointer;
        }
    }
    #popup-title {
        color: #4090db;
        margin-bottom: 12px;
    }
    .search {
        position: absolute;
        left: 50px;
        top: 50px;
        z-index: 99;
    }
    ::v-deep {
        .el-input-group__append {
            background-color: #0e2849;
        }
        .el-input--medium {
            font-size: 22px;
        }
        .el-input--medium .el-input__inner {
            height: 45px;
            line-height: 45px;
        }
    }
}
</style>