高德地图的使用

layui.define(['jquery', 'notice'], function (exports) {
    let $ = layui.jquery;
    let notice = layui.notice;

    /**
     * 模拟请求,判断网络
     * @param {function} callback 回调
     */
    function onLine(callback) {
        let img = new Image();
        img.src = 'https://www.baidu.com/favicon.ico?_t=' + Date.now();
        img.onload = function () {
            if (callback) callback(true)
        };
        img.onerror = function () {
            if (callback) callback(false)
        };
    }

    function gaodeMap() {
        let that = this;

        this.map;

        let defaultOpt = {
            domID: 'container',
            zoom: 16,
            mapCenter: [121.503144, 31.235309]
        }

        this.opt = defaultOpt

        this.render = function (option) {
            // 根据网络情况,加载地图
            onLine(function (flag) {
                if (flag) {
                    window.onLoad = function () {
                        that.opt = $.extend({}, defaultOpt, option);
                        that.init();

                        if (typeof option.done === 'function') {
                            option.done();
                        }
                    };

                    let url = 'https://webapi.amap.com/maps?v=1.4.15&key=d57b9f334d35402807617176c660f1c3&callback=onLoad&plugin=AMap.MouseTool,AMap.PolyEditor,AMap.Autocomplete,AMap.PlaceSearch,AMap.Geocoder,AMap.CitySearch,AMap.PolyEditor,AMap.CircleEditor';
                    let jsapi = document.createElement('script');
                    jsapi.charset = 'utf-8';
                    jsapi.src = url;
                    document.head.appendChild(jsapi);
                } else {
                    option.done();
                    console.log('网络故障,禁止使用地图');
                }
            });
        }
    }

    /*
     * @method
     * @desc 卫星地图
     */
    gaodeMap.prototype.SatelliteLayer;

    gaodeMap.prototype.TileLayer;

    /*
     * @method
     * @param {object} lnglat 高德经纬度对象或者经纬度数组
     * @desc 初始化地图对象
     */
    gaodeMap.prototype.init = function () {
        let that = this;

        this.SatelliteLayer = new AMap.TileLayer.Satellite();
        this.TileLayer = new AMap.TileLayer();

        this.map = new AMap.Map(that.opt.domID, {
            zoom: that.opt.zoom,
            zooms: [5, 18],
            center: that.opt.mapCenter,
            viewMode: '3D',
            pitch: 60,
            resizeEnable: true,
        });

        if (this.SatelliteLayerBuildings) {
            this.map.add(this.SatelliteLayerBuildings)
        }

        // 3D地图
        this.add3DCompass();

        // 鼠标工具
        this.mouseTool = new AMap.MouseTool(that.map);
    }

    gaodeMap.prototype.checkMap = function () {
        if (!this.map) {
            notice.error('地图未加载或正在加载,请稍后再试')
            return true;
        }
    }

    /**
     * 当你不想每个函数都检查地图是否已加载时,可以使用以下方式执行函数
     */
    /**
     * 
    gaodeMap.prototype.ExcuteFunction = function (funcName,...params) {
        if (that.checkMap()) {
            return;
        }

        this[funcName].apply(this,params);
    }
     */

    /*
     * @method
     * @desc 添加3D地图
     */
    gaodeMap.prototype.add3DCompass = function () {
        let that = this;

        if (that.checkMap()) {
            return;
        }

        AMap.plugin([
            'AMap.ControlBar',
        ], function () {
            // 添加 3D 罗盘控制
            that.map.addControl(new AMap.ControlBar({
                position: { top: '50px', right: '20px' }
            }));
        });
    }

    /*
     * @method
     * @desc 添加卫星地图
     */
    gaodeMap.prototype.addSatelliteLayer = function () {
        if (this.checkMap()) {
            return;
        }

        if (this.SatelliteLayer) {
            this.map.add(this.SatelliteLayer);
        }
    }

    /*
     * @method
     * @desc 移除卫星地图
     */
    gaodeMap.prototype.removeSatelliteLayer = function () {
        if (this.checkMap()) {
            return;
        }

        this.map.remove(this.SatelliteLayer);
    }

    /*
     * @method
     * @desc 添加卫星地图
     */
    gaodeMap.prototype.addTileLayer = function () {
        if (this.checkMap()) {
            return;
        }
        this.map.add(this.TileLayer);
    }

    /*
     * @method
     * @desc 移除卫星地图
     */
    gaodeMap.prototype.removeTileLayer = function () {
        if (this.checkMap()) {
            return;
        }
        this.map.remove(this.TileLayer);
    }

    /*
     * @method
     * @param {object} option
     * @param {object} option.lnglat 高德经纬度对象或者经纬度数组
     * @param {object} option.type 移动方式
     * @desc 设置地图中心位置
     */
    gaodeMap.prototype.setCenter = function (option) {
        if (this.checkMap()) {
            return;
        }

        if (!option) {
            return;
        }

        if (!option.lnglat) {
            return;
        }

        option.type = option.type || 1;

        if (option.type == 1) {
            this.map.setCenter(option.lnglat);
        } else {
            this.map.panTo(option.lnglat);
        }
    }

    /*
     * @method
     * @desc 标记点集合
     */
    gaodeMap.prototype.markers = {};

    /*
     * @method
     * @param {object} option
     * @param {object} option.lnglat 高德经纬度对象或者经纬度数组
     * @param {object} option.size 图片大小,图片地址无时,此项无效
     * @param {object} option.imageUrl 图片地址
     * @param {object} option.extData 自定义数据
     * @param {object} option.click 点的单击事件
     * @desc 设置地图中心位置
     */
    gaodeMap.prototype.addMarker = function (option) {
        if (this.checkMap()) {
            return;
        }

        var defaultOption = {
            //lnglat
            size: [32, 32],
            imageUrl: undefined
        };

        var tempOpt = $.extend({}, defaultOption, option);

        var markerOpt = {
            map: this.map
        };

        // 经纬度
        if (!tempOpt.lnglat) {
            return;
        }

        markerOpt.position = tempOpt.lnglat;

        // 自定义图片
        if (tempOpt.imageUrl) {
            markerOpt.icon = new AMap.Icon({
                size: new AMap.Size(tempOpt.size[0], tempOpt.size[1]),
                image: tempOpt.imageUrl,
                imageSize: new AMap.Size(tempOpt.size[0], tempOpt.size[1])
            })

            markerOpt.offset = new AMap.Pixel(-(tempOpt.size[0] / 2), -tempOpt.size[1])
        }

        // 鼠标滑过时的显示
        markerOpt.title = tempOpt.title || '';

        // 自定义参数
        markerOpt.extData = tempOpt.extData;
        markerOpt.key = tempOpt.key;

        var marker = new AMap.Marker(markerOpt);

        if (option.isPanTo) {
            this.map.panTo(tempOpt.lnglat);
        }

        if (!markerOpt.key) {
            markerOpt.key = this.newGuid();
        }

        this.markers[markerOpt.key] = marker;

        if (tempOpt.click) {
            marker.on('click', function (e) {
                tempOpt.click(e, marker.getExtData());
            })
        }

        if (typeof tempOpt.clickAfter === 'function') {
            tempOpt.clickAfter(tempOpt.extData);
        }

        // 文本标注
        if (tempOpt.labelText) {
            this.addMarkerLabel(marker, tempOpt.labelText)
        }

        return marker;
    }

    gaodeMap.prototype.addMarkerLabel = function (marker, label) {
        marker.setLabel({
            offset: new AMap.Pixel(0, -30),  //设置文本标注偏移量
            content: '<div class="map-label"><div>' + label + '<div> </div></div></div>', //设置文本标注内容
            direction: 'top' //设置文本标注方位
        });
    }

    /*
     * @method
     * @param {bool} type true:清除点  false:清除地图
     * @desc 清除地图上的标记
     */
    gaodeMap.prototype.clearMarkers = function (type, callback) {
        if (this.checkMap()) {
            return;
        }

        if (type) {
            $.each(this.markers, function (key, value) {
                value.setMap(null);
            })
        } else {
            this.map.clearMap();
        }

        this.markers = {};

        if (this.clusterer) {
            this.clusterer.setMap(null);
            this.clusterer = undefined;
        }

        if (typeof callback == 'function') {
            callback()
        }
    }

    /*
     * @method
     * @param {bool} key object:marker的指定唯一标识
     * @param {bool} isExclude bool:指定删除内容,true:删除不包含key的所有内容,false:删除包含可以的marker
     * @desc 清除地图上的标记
     */
    gaodeMap.prototype.clearMarker = function (key, isExclude) {
        if (this.checkMap()) {
            return;
        }

        if (isExclude == undefined) {
            isExclude = false;
        }

        var that = this;

        if (!isExclude) {
            if (key) {
                if (this.markers[key]) {
                    var marker = this.markers[key];

                    marker.setMap(null);

                    delete this.markers[key]
                }
            }
            //this.markers = {};

            if (this.clusterer) {
                this.clusterer.setMap(null);
                this.clusterer = undefined;
            }
        }
        else {
            $.each(that.markers, function (k, v) {
                if (k != key) {
                    v.setMap(null);

                    delete that.markers[k]
                }
            })
        }
    }

    /*
     * @method
     * @param {bool} key object:marker的指定唯一标识的一部分
     * @desc 清除地图上的标记
     */
    gaodeMap.prototype.clearAssignMarkers = function (key) {
        if (this.checkMap()) {
            return;
        }

        var that = this

        var keys = [];

        $.each(that.markers, function (k, v) {
            if (k.indexOf(key) > -1) {
                keys.push(k);
                v.setMap(null);
            }
        })

        $.each(keys, function (i, item) {
            delete that.markers[item];
        })
    }

    /*
     * @method
     * @param {bool} key object:marker的指定唯一标识
     * @desc 根据key获取marker对象
     */
    gaodeMap.prototype.getMarker = function (key) {
        if (this.checkMap()) {
            return;
        }

        if (key) {
            return this.markers[key]
        }
        return undefined;
    }

    /*
     * @method
     * @param {bool} key object:marker的指定唯一标识的一部分
     * @desc 根据key获取marker对象集合
     */
    gaodeMap.prototype.getMarkers = function (key) {
        if (this.checkMap()) {
            return;
        }

        var mrks = [];

        $.each(that.markers, function (k, v) {
            if (k.indexOf(key) > -1) {
                mrks.push(v);
            }
        })

        return mrks;
    }

    /*
     * @method
     * @param {bool} key object:marker的指定唯一标识
     * @param {array} size array:图标大小,默认值[60,60]
     * @desc 根据key设置图标大小
     */
    gaodeMap.prototype.setMarkerIcon = function (key, size) {
        if (this.checkMap()) {
            return;
        }

        var marker = this.markers[key]

        if (marker) {
            var _size = [60, 60];

            if (size) {
                _size = size;
            }

            var icon = marker.getIcon()

            marker.setIcon(new AMap.Icon({
                size: new AMap.Size(_size[0], _size[1]),
                image: icon.w.image,
                imageSize: new AMap.Size(_size[0], _size[1])
            }))

            marker.setOffset(new AMap.Pixel(-(_size[0] / 2), -_size[1]))
        }
    }

    /*
     * @method
     * @param {bool} key object:marker的指定唯一标识
     * @desc 选中时的图标大小
     */
    gaodeMap.prototype.checkedMarker = function (key) {
        if (this.checkMap()) {
            return;
        }

        this.setMarkerIcon(key, [45, 45]);
    }

    /*
     * @method
     * @param {bool} key object:marker的指定唯一标识
     * @desc 反选时的图标大小
     */
    gaodeMap.prototype.uncheckedMarker = function (key) {
        if (this.checkMap()) {
            return;
        }

        this.setMarkerIcon(key, [32, 32]);
    }

    /*
     * @method
     * @param {bool} key object:marker的指定唯一标识
     * @desc 设置所有图标,按反选时的图标大小设置
     */
    gaodeMap.prototype.setAllMarkersIcon = function () {
        if (this.checkMap()) {
            return;
        }

        var that = this;

        $.each(that.markers, function (k, v) {
            that.uncheckedMarker(k);
        })
    }

    /*
     * @method
     * @param {bool} key object:marker的指定唯一标识
     * @desc 设置所有图标,按反选时的图标大小设置
     */
    gaodeMap.prototype.setUncheckedMarkersIcon = function (key) {
        if (this.checkMap()) {
            return;
        }

        var that = this;

        $.each(that.markers, function (k, v) {
            if (k.indexOf(key) > -1) {
                that.uncheckedMarker(k);
            }
        })
    }

    /*
     * @method
     * @param {bool} key object:marker的指定唯一标识的一部分
     * @desc 设置选中的marker的图标大小
     */
    gaodeMap.prototype.setCheckedMarkersIcon = function (key) {
        if (this.checkMap()) {
            return;
        }

        var that = this;

        $.each(that.markers, function (k, v) {
            if (k.indexOf(key) > -1) {
                that.checkedMarker(k);
            }
        })
    }

    /*
     * @method
     * @desc 弹框对象
     */
    gaodeMap.prototype.infoWindow = undefined;

    /*
     * @method
     * @desc 关闭弹框
     */
    gaodeMap.prototype.addInfoWindow = function (option) {
        if (this.checkMap()) {
            return;
        }

        if (!option) {
            return
        }
        var html;
        if (option.content) {
            html = $(option.content)
        }

        this.infoWindow = new AMap.InfoWindow({
            offset: option.offset || new AMap.Pixel(0, -34),
            isCustom: true,// 自定义窗体  默认false
            closeWhenClickMap: option.closeWhenClickMap == undefined ? false : option.closeWhenClickMap, // 点击地图关闭信息窗,默认不关闭
            content: html.get(0)  //使用默认信息窗体框样式,显示信息内容
        });

        this.infoWindow.open(this.map, option.lnglat);

        this.bindCloseInfoWindow(html, option);

        if (typeof option.addFinish === 'function') {
            option.addFinish(html, option.extData);
        }
    }

    /*
     * @method
     * @desc 绑定关闭弹框事件
     */
    gaodeMap.prototype.bindCloseInfoWindow = function (html, option) {
        var that = this;

        html.find('.close-window').on('click', function () {
            that.infoWindow.close();

            if (typeof option.closeAfter === 'function') {
                option.closeAfter(option.extData);
            }
        })
    }

    /*
     * @method
     * @desc 绑定关闭弹框事件
     */
    gaodeMap.prototype.closeInfoWindow = function () {
        if (this.infoWindow) {
            this.infoWindow.close();
        }
    }

    /*
     * @method
     * @desc 点聚合对象
     */
    gaodeMap.prototype.clusterer = undefined;

    /*
     * @method
     * @desc 添加点聚合效果
     */
    gaodeMap.prototype.addClusterer = function (keys, clickCallBack) {
        if (this.checkMap()) {
            return;
        }

        var tempMarkers = [];
        var that = this;

        for (var key in this.markers) {
            if (keys) {
                $.each(keys, function (i, item) {
                    if (key.indexOf(item) > -1) {
                        tempMarkers.push(that.markers[key]);
                    }
                })
            }
            else {
                tempMarkers.push(that.markers[key]);
            }
        }

        if (!this.clusterer) {
            this.clusterer = new AMap.MarkerClusterer(this.map, tempMarkers, { gridSize: 80, maxZoom: 50, zoomOnClick: false });

            if (typeof clickCallBack === 'function') {
                this.clusterer.on('click', function (cluster) {
                    clickCallBack(cluster)
                })
            }
        } else {
            this.clusterer.clearMarkers();
            this.clusterer.setMarkers(tempMarkers);
        }
    }

    /*
     * @method
     * @desc 生成guid
     */
    gaodeMap.prototype.newGuid = function () {
        return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
            var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
            return v.toString(16);
        });
    }

    /*
     * @method
     * @desc 覆盖物数组
     */
    gaodeMap.prototype.overlay = [];

    /*
     * @method
     * @desc 删除覆盖物
     */
    gaodeMap.prototype.removeOverlay = function (key) {
        if (this.checkMap()) {
            return;
        }

        if (key) {
            if (this.overlay[key]) {
                var overlay = this.overlay[key];
                this.map.remove(overlay);
                delete this.overlay[key]
            }
        }
    }

    /*
     * @method
     * @desc 添加圆
     */
    gaodeMap.prototype.addCircle = function (opt) {
        if (this.checkMap()) {
            return;
        }

        if (!opt.center) {
            console.error('未提供中心点坐标');
            return
        }

        if (!opt.radius || opt.radius == 0) {
            console.error('未提供半径');
            return
        }

        var _defaultOpt = {
            //center: coor,
            //radius: radius, //半径
            strokeColor: "#008ad8",//线条颜色
            strokeOpacity: 0.4,//透明度
            strokeWeight: 3,
            // 线样式还支持 'dashed'
            fillColor: '#00b0ff',
            fillOpacity: 0.4,//填充透明度
            bubble: true,//允许冒泡到地图
            map: this.map
        }

        var circleOpt = $.extend({}, _defaultOpt, opt)

        var circle = new AMap.Circle(circleOpt)

        if (typeof circleOpt.click === 'function') {
            circle.on('click', function (e) {
                var data = circle.getExtData()

                circleOpt.click(e, data);
            })
        }

        if (circleOpt.text) {
            var center = this.getLonAndLat(circleOpt.center.getLng(), circleOpt.center.getLat(), 180, circleOpt.radius)

            this.addText({
                text: circleOpt.text,
                offset: new AMap.Pixel(0, 10),
                coor: new AMap.LngLat(center.lng, center.lat) //circleOpt.center
            })
        }

        if (!circleOpt.key) {
            circleOpt.key = this.newGuid();
        }

        this.overlay[circleOpt.key] = circle;
    }

    /*
     * @method
     * @desc 画圆
     */
    gaodeMap.prototype.drawCircle = function (callback) {
        if (this.checkMap()) {
            return;
        }

        let that = this;
        let option = {
            strokeColor: "#80d8ff",
            strokeWeight: 6,
            strokeOpacity: 0.2,
            fillColor: '#00b0ff',
            fillOpacity: 0.4,
            strokeStyle: 'solid',
        }

        that.mouseTool.close();

        that.mouseTool = new AMap.MouseTool(that.map);

        that.map.clearMap();

        that.mouseTool.circle(option)

        // 无法移除
        // that.mouseTool.off('draw');

        that.mouseTool.on('draw', function (event) {
            let radius = event.obj.getRadius()
            let center = event.obj.getCenter()
            callback && callback(radius, center)

            // 编辑
            that.editCircle({
                callback: callback,
                radius: radius,
                center: center
            });
        });
    }

    /*
     * @method
     * @desc 编辑圆
     */
    gaodeMap.prototype.editCircle = function (option) {
        if (this.checkMap()) {
            return;
        }

        let that = this;

        let editOption = {
            strokeColor: "#008ad8",
            strokeWeight: 3,
            strokeOpacity: 0.4,
            fillColor: '#00b0ff',
            fillOpacity: 0.4,
            strokeStyle: 'solid',
            center: option.center,
            radius: option.radius, //半径
            borderWeight: 3,
            strokeDasharray: [10, 10],
            zIndex: 50,
            map: that.map
        }

        that.map.clearMap();

        // 编辑前,先删除图层
        let circle = new AMap.Circle(editOption);

        let circleEditor = new AMap.CircleEditor(that.map, circle);

        circleEditor.on('adjust', function (e) {
            option.callback && option.callback(e.radius, option.center)
        })

        circleEditor.on('move', function (e) {
            option.callback && option.callback(option.radius, e.lnglat)
        })

        circleEditor.open();    //打开圆形编辑器

        that.map.setFitView();
    }

    /**
    * 根据一个经纬度及距离角度,算出另外一个经纬度
    * @param {float} lng 经度 113.3960698
    * @param {float} lat 纬度 22.941386
    * @param {int} brng 方位角 45 ---- 正北方:000°或360° 正东方:090° 正南方:180° 正西方:270°
    * @param {int} dist 90000距离(米)
    *
    * 1、角度转换为弧度公式:弧度=角度×(π ÷度180 )
    * 2、弧度转换为角度公式: 角度=弧度×(180÷π)
    */
    gaodeMap.prototype.getLonAndLat = function (lng, lat, brng, dist) {
        //大地坐标系资料WGS-84 长半径a=6378137 短半径b=6356752.3142 扁率f=1/298.2572236
        var a = 6378137;
        var b = 6356752.3142;
        var f = 1 / 298.257223563;

        var lon1 = lng * 1;
        var lat1 = lat * 1;
        var s = dist;
        var alpha1 = brng * (Math.PI / 180)//mapNumberUtil.rad(brng);
        var sinAlpha1 = Math.sin(alpha1);
        var cosAlpha1 = Math.cos(alpha1);

        //var tanU1 = (1 - f) * Math.tan(mapNumberUtil.rad(lat1));
        var tanU1 = (1 - f) * Math.tan(lat1 * (Math.PI / 180));
        var cosU1 = 1 / Math.sqrt((1 + tanU1 * tanU1)), sinU1 = tanU1 * cosU1;
        var sigma1 = Math.atan2(tanU1, cosAlpha1);
        var sinAlpha = cosU1 * sinAlpha1;
        var cosSqAlpha = 1 - sinAlpha * sinAlpha;
        var uSq = cosSqAlpha * (a * a - b * b) / (b * b);
        var A = 1 + uSq / 16384 * (4096 + uSq * (-768 + uSq * (320 - 175 * uSq)));
        var B = uSq / 1024 * (256 + uSq * (-128 + uSq * (74 - 47 * uSq)));

        var sigma = s / (b * A), sigmaP = 2 * Math.PI;
        while (Math.abs(sigma - sigmaP) > 1e-12) {
            var cos2SigmaM = Math.cos(2 * sigma1 + sigma);
            var sinSigma = Math.sin(sigma);
            var cosSigma = Math.cos(sigma);
            var deltaSigma = B * sinSigma * (cos2SigmaM + B / 4 * (cosSigma * (-1 + 2 * cos2SigmaM * cos2SigmaM) -
                B / 6 * cos2SigmaM * (-3 + 4 * sinSigma * sinSigma) * (-3 + 4 * cos2SigmaM * cos2SigmaM)));
            sigmaP = sigma;
            sigma = s / (b * A) + deltaSigma;
        }

        var tmp = sinU1 * sinSigma - cosU1 * cosSigma * cosAlpha1;
        var lat2 = Math.atan2(sinU1 * cosSigma + cosU1 * sinSigma * cosAlpha1,
            (1 - f) * Math.sqrt(sinAlpha * sinAlpha + tmp * tmp));
        var lambda = Math.atan2(sinSigma * sinAlpha1, cosU1 * cosSigma - sinU1 * sinSigma * cosAlpha1);
        var C = f / 16 * cosSqAlpha * (4 + f * (4 - 3 * cosSqAlpha));
        var L = lambda - (1 - C) * f * sinAlpha *
            (sigma + C * sinSigma * (cos2SigmaM + C * cosSigma * (-1 + 2 * cos2SigmaM * cos2SigmaM)));

        var revAz = Math.atan2(sinAlpha, -tmp); // final bearing

        var lngLatObj = { lng: lon1 + L * (180 / Math.PI), lat: lat2 * (180 / Math.PI) }
        return lngLatObj;
    }

    /*
     * @method
     * @desc 添加多边形
     */
    gaodeMap.prototype.addPolygon = function (opt) {
        if (this.checkMap()) {
            return;
        }

        if (!opt.path || opt.path.length < 3) {
            console.error('未提供坐标')
            return
        }

        var _defaultOpt = {
            strokeColor: "#008ad8",//线条颜色
            strokeOpacity: 0.4,//透明度
            strokeWeight: 3,
            // 线样式还支持 'dashed'
            fillColor: '#00b0ff',
            fillOpacity: 0.4,//填充透明度
            bubble: true,//允许冒泡到地图
            map: this.map
        };

        var polygonOpt = $.extend({}, _defaultOpt, opt);

        var polygon = new AMap.Polygon(polygonOpt);

        if (typeof polygonOpt.click === 'function') {
            polygon.on('click', function (e) {
                var data = polygon.getExtData()

                polygonOpt.click(e, data);
            })
        }

        if (polygonOpt.text) {
            var point = this.getMinLatPoint(polygonOpt.path)

            this.addText({
                text: polygonOpt.text,
                offset: new AMap.Pixel(0, 10),
                coor: point//polygonOpt.path
            })
        }

        if (!polygonOpt.key) {
            polygonOpt.key = this.newGuid();
        }

        this.overlay[polygonOpt.key] = polygon;
    }

    gaodeMap.prototype.getMinLatPoint = function (points) {
        var point = {};

        $.each(points, function (i, item) {
            if (item.getLat() < (point.lat || 999)) {
                point = item;
            }
        })

        return point;
    }

    gaodeMap.prototype.addText = function (opt) {
        if (this.checkMap()) {
            return;
        }

        if (!opt.text) {
            console.error('添加文本标记失败,文本标记内容为空')
            return;
        }

        if (!opt.coor) {
            console.error('添加文本标记失败,文本标记坐标不确定')
            return;
        }

        var lnglat;

        if (opt.coor.length > 2) {
            lnglat = this.getCenterPoint(opt.coor);
        } else {
            lnglat = opt.coor;
        }

        var txt = new AMap.Text({
            text: opt.text,
            offset: opt.offset || new AMap.Pixel(0, 0),
            map: this.map,
            position: lnglat
        });

        txt.setStyle({ 'font-size': '10px' });
    }

    /**
     * 画多边形
     */
    gaodeMap.prototype.drawPolygon = function (callback) {
        if (this.checkMap()) {
            return;
        }

        let that = this;
        let option = {
            strokeColor: "#008ad8",
            strokeWeight: 3,
            strokeOpacity: 0.4,
            fillColor: '#00b0ff',
            fillOpacity: 0.4,
            strokeStyle: 'solid'
        }
        that.mouseTool.close();

        that.mouseTool = new AMap.MouseTool(that.map);

        that.map.clearMap();

        that.mouseTool.polygon(option)

        // 无法移除
        // that.mouseTool.off('draw');

        that.mouseTool.on('draw', function (event) {
            event.obj.getPath()

            callback && callback(event.obj.getPath())

            that.editPolygon({
                paths: event.obj.getPath(),
                callback
            })
        });
    }

    /**
     * 编辑多边形
     */
    gaodeMap.prototype.editPolygon = function (option) {
        if (this.checkMap()) {
            return;
        }

        let that = this;

        that.map.clearMap();

        let polygon = new AMap.Polygon({
            path: option.paths,
            isOutline: true,
            strokeColor: "#008ad8",
            strokeWeight: 3,
            strokeOpacity: 0.4,
            fillColor: '#00b0ff',
            fillOpacity: 0.4,
            strokeStyle: 'solid',
            map: that.map
        })

        let polyEditor = new AMap.PolyEditor(that.map, polygon);//创建多边形编辑器

        polyEditor.open();

        polyEditor.on('adjust', function (e) {
            option.callback && option.callback(polygon.getPath())
        })

        polyEditor.open();    //打开圆形编辑器

        that.map.setFitView();
    }

    /*
     * @method
     * @desc 获取中心坐标
     */
    gaodeMap.prototype.getCenterPoint = function (coor) {
        if (this.checkMap()) {
            return;
        }

        if (coor) {
            var total = coor.length;
            var lat = 0, lng = 0;

            $.each(coor, function (i, item) {
                lat += (item.getLat() || item.lat) * Math.PI / 180;
                lng += (item.getLng() || item.lng) * Math.PI / 180;
            })

            lat /= total;
            lng /= total;

            return new AMap.LngLat(lng * 180 / Math.PI, lat * 180 / Math.PI);
        }
    }

    gaodeMap.prototype.massMarks = undefined;

    /*
     * @method
     * @desc 设置海量点
     */
    gaodeMap.prototype.setMassMarkers = function (opt) {
        if (this.checkMap()) {
            return;
        }

        if (!opt) {
            return;
        }

        if (!opt.data) {
            return;
        }
        // 示例数据
        // {"lnglat":[116.258446,37.686622],"name":"景县","style":2}

        this.map.clearMap();

        if (!this.massMarks) {
            this.massMarks = new AMap.MassMarks(
                opt.data,
                {
                    //map: this.map,
                    opacity: 0.9,
                    zIndex: 99999,
                    alwaysRender: opt.alwaysRender || false,//是否在地图缩放时重绘
                    style: [{
                        anchor: new AMap.Pixel(0, 0),
                        url: '/images/green.png',
                        size: new AMap.Size(20, 20)
                    },
                    {
                        anchor: new AMap.Pixel(0, 0),
                        url: '/images/red.png',
                        size: new AMap.Size(20, 20)
                    }]
                })
        }
        else {
            this.massMarks.setData(opt.data)
        }

        this.massMarks.setMap(this.map);

        var marker = new AMap.Marker({ content: ' ', map: this.map });

        this.massMarks.on('mouseover', function (e) {
            marker.setPosition(e.data.lnglat);
            marker.setLabel({ content: e.data.name })
        });

        this.massMarks.on('mouseout', function (e) {
            marker.setLabel({ content: "" })
        });

        this.map.setZoom(5);
        this.map.setCenter([102.342785, 35.312316])
    }

    /*
     * @method
     * @desc 清除海量点
     */
    gaodeMap.prototype.clearMassMarkers = function () {
        if (this.checkMap()) {
            return;
        }

        if (this.massMarks) {
            this.massMarks.clear();
        }
        this.map.clearMap();
    }

    /*
     * @method
     * @desc 添加行政范围
     */
    gaodeMap.prototype.addAreaRang = function (opt) {
        if (this.checkMap()) {
            return;
        }

        var _map = this.map;
        var that = this;
        (new AMap.Geocoder()).getAddress(opt.lnglat, function (status, result) {
            console.log(JSON.stringify(result))
            if (status === 'complete' && result.regeocode) {
                // 获取区域编码
                var adcode = result.regeocode.addressComponent.adcode;

                // 设置显示范围
                new AMap.DistrictSearch({
                    extensions: 'all',
                    subdistrict: 0
                }).search(adcode, function (status, result) {
                    // 外多边形坐标数组和内多边形坐标数组
                    var outer = [
                        new AMap.LngLat(-360, 90, true),
                        new AMap.LngLat(-360, -90, true),
                        new AMap.LngLat(360, -90, true),
                        new AMap.LngLat(360, 90, true),
                    ];

                    var holes = result.districtList[0].boundaries

                    var pathArray = [
                        outer
                    ];

                    var centerPoint = that.getCenterPoint(holes[0])

                    pathArray.push.apply(pathArray, holes);

                    var polygon = new AMap.Polygon({
                        pathL: pathArray,
                        strokeColor: '#000000',
                        strokeWeight: 1,
                        fillColor: '#000000',
                        fillOpacity: 0.9
                    });
                    polygon.setPath(pathArray);
                    _map.add(polygon)
                    //_map.panTo(opt.lnglat);
                    _map.panTo(centerPoint)
                    _map.setZoom(opt.zoom || 12);
                })
            } else {
                console.log('经纬度查询失败')
            }
        });
    }

    gaodeMap.prototype.mapClick;

    /**
     * 绑定地图点击
     * @param {boolean} opt.isclearMap 是否清除地图
     * @param {string} opt.key 清除指定key的覆盖物
     * @param {Function} opt.callback 点击回调
     */
    gaodeMap.prototype.bindMapClick = function (opt) {
        if (this.checkMap()) {
            return;
        }

        let that = this;

        let _map = this.map;

        if (!that.mapClick) {
            that.mapClick = function (e) {
                if (opt.isclearMap) {
                    if (opt.key) {
                        that.clearMarker(opt.key);
                    }
                    else {
                        that.clearMarkers();
                    }
                }

                let address;
                (new AMap.Geocoder()).getAddress(e.lnglat, function (status, result) {
                    if (status === 'complete' && result.regeocode) {
                        address = {
                            address: result.regeocode.formattedAddress,
                            //lnglat: e.lnglat
                            lng: e.lnglat.getLng(),
                            lat: e.lnglat.getLat()
                        }

                        if (typeof opt.callback === 'function') {
                            opt.callback(e, address);
                        }
                    }
                });
            }
        }

        _map.on('click', that.mapClick);
    }

    gaodeMap.prototype.cancleMapClick = function () {
        if (this.checkMap()) {
            return;
        }

        let _map = this.map;

        _map.off('click', this.mapClick);
        //this.map.clearEvents('click');
    }

    /*
     * @method
     * @desc 绑定地图搜索
     */
    gaodeMap.prototype.bindSearch = function (opt) {
        if (this.checkMap()) {
            return;
        }

        let _map = this.map;

        if (opt.isclearMap) {
            this.clearMarkers();
        }

        let auto = new AMap.Autocomplete({
            input: opt.inputID || "tipinput"
        });

        let placeSearch = new AMap.PlaceSearch({ map: _map });

        AMap.event.addListener(auto, "select", select);

        function select(e) {
            //placeSearch.setCity(e.poi.adcode);
            placeSearch.search(e.poi.name, function (status, result) {
                // 查询成功时,result即对应匹配的POI信息
                let pois = result.poiList.pois;
                let address;
                //return false;
                if (pois.length > 0) {
                    (new AMap.Geocoder()).getAddress(pois[0].location, function (status, result) {
                        if (status === 'complete' && result.regeocode) {
                            address = {
                                address: result.regeocode.formattedAddress,
                                //lnglat: pois[0].location
                                lng: pois[0].location.lng,
                                lat: pois[0].location.lat
                            }

                            if (typeof opt.success === 'function') {
                                opt.success(address);
                            }
                        }
                    });
                }
            })
        }
    }

    /*
     * @method
     * @desc 获取地址
     */
    gaodeMap.prototype.getAddress = function (lnglat, callback) {
        if (this.checkMap()) {
            return;
        }

        (new AMap.Geocoder()).getAddress(lnglat, function (status, result) {
            if (status === 'complete' && result.regeocode) {
                callback && callback(result.regeocode.formattedAddress);
            }
        })
    }

    exports('gdmap', new gaodeMap());
})

  

岁月无情催人老,请珍爱生命,远离代码!!!
原文地址:https://www.cnblogs.com/zhoushangwu/p/15006430.html