Vue + 高德地图整理了几点

2020年01月07日作者:井井客来源:井井客原创

高德地图上面做的小需求,根据字符串地址标记一片区域,将这一片区域中的人员列出来,然后点击人员可以进行派工操作。

Vue + 高德地图整理了几点

只是一个小需求,用到的点不多,只稍微整理了一下(建议先稍微了解一下API)。

高德地图API地址:https://lbs.amap.com/api/javascript-api/summary

1、使用高德地图

在项目根目录下 index.html 中引入(head标签之间添加,key值和版本号可以看API):

  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <title>eslink-atm</title>
    <script type="text/javascript" src="https:/ /webapi.amap.com/maps?v=1.4.15&key=值"></script>
  </head>

在webpack.base.conf.js文件中module.exports中间添加externals:

module.exports = {
    context: path.resolve(__dirname, '../'),
    entry: {
        app: './src/main.js'
    },
    externals: {
        AMap: 'AMap'
    },
    ...
};

在需要使用高德地图的文件,引入:

import AMap from 'AMap';

最后通过new AMap.XXX()即可使用相关功能,列了几个我将要用到的方法:

new AMap.Map()            // 创建地图对象
new AMap.LngLat()         // 返回经纬度标准写法
new AMap.Marker()         // 创建点标记
new AMap.Circle()         // 创建圆形区域
new AMap.OverlayGroup()   // 创建覆盖物群组(将点、面放入集中管理)

2、地址描述信息转换成地理坐标

AMap.plugin('AMap.Geocoder', () => {
    var geocoder = new AMap.Geocoder({
        city: '全国'
    });
    geocoder.getLocation('地址描述内容', (status, result) => {
        if (status === 'complete' && result.info === 'OK') {
            // 成功,通过result.geocodes去获取经纬度
        } else {
            // 不成功,通过IP地址定位
        }
    });
});

如果地址描述内容不是很清晰,有可能没办法转换成功,这时可以通过IP地址所在城市中心点获取大致经纬度:

AMap.plugin('AMap.CitySearch', () => {
    var citySearch = new AMap.CitySearch();
    citySearch.getLocalCity((status, result) => {
        if (status === 'complete' && result.info === 'OK') {
            // let nc = result.bounds.nc;
            // let wc = result.bounds.wc;
            // let lng = (nc.lng + wc.lng) / 2;
            // let lat = (nc.lat + wc.lat) / 2;
        }
    });
});

因为获取的结果中没有具体的中心点值,我是用左上角和右下角地址中间值作为中心点。

3、圆形区域及移动

我的设想:圆形区域有可移动和不可移动状态,不可移动时,用蓝色透明区域显示,可移动时用红色区域显示,并且可移动时将中心点标红。

在这里我使用了AMap.Circle和AMap.CircleMarker,其中CircleMarker是中心点标红用的,因为Circle会随着地图放大缩小而变化,但CircleMarker却不会变化,这样做可以在地图非常小时,通过中心点依然可以发现这块圆形区域。

// 渲染地图(主要是中心点及圆形区域)
initMap(lng, lat) {
    let blue = '#2d8cf0';
    let red = '#fc363b';
    // 初始地图对象
    this.map = new AMap.Map('container', {
        center: [lng, lat],
        resizeEnable: true,
        zoom: 14
    });
    // 圆形区域中心点初始化(默认隐藏)
    let circleMarker = new AMap.CircleMarker({
        center: new AMap.LngLat(lng, lat),
        radius: 5,
        fillColor: red,
        strokeColor: red,
        strokeWeight: 1,
        fillOpacity: 1
    });
    circleMarker.hide();
    // 圆形区域(默认蓝色)
    let lnglat = new AMap.LngLat(lng, lat);
    this.center = [lnglat.lng, lnglat.lat];
    this.circle = new AMap.Circle({
        center: lnglat,
        fillColor: blue,
        strokeColor: blue,
        strokeWeight: 1,
        fillOpacity: 0.1
    });
    // 点击切换--蓝色与红色切换--是否可移动切换(红色时显示中心点且可以移动)
    this.circle.on('click', () => {
        // 切换圆形区域状态值
        this.circleType = !this.circleType;

        this.circle.setOptions({
            fillColor: this.circleType ? red : blue,
            strokeColor: this.circleType ? red : blue,
            draggable: this.circleType,
            cursor: this.circleType ? 'move' : ''
        });
        this.circleType ? circleMarker.show() : circleMarker.hide();
        let getCenter = this.circle.getCenter();

        if (this.circleType) {
            this.center = [getCenter.lng, getCenter.lat];
        } else if (
            (this.center[0] && this.center[0] !== getCenter.lng) ||
            this.center[1] !== getCenter.lat
        ) {
            // 中心点有变化则重新请求外勤人员
            this.getAcceptPersonList();
        }
    });
    // 圆形区域变化位置时,中心点也需跟着变
    this.circle.on('change', data => {
        let center = this.circle.getCenter();
        circleMarker.setCenter(new AMap.LngLat(center.lng, center.lat));
    });

    // 初时化覆盖物群组
    this.overlayGroups = new AMap.OverlayGroup([]);

    // 初时化信息弹窗
    this.infoWindow = new AMap.InfoWindow({
        offset: new AMap.Pixel(0, -30)
    });

    // (圆形区域+中心点+覆盖物群组)添加到地图上
    this.map.add(circleMarker);
    this.map.add(this.circle);
    this.map.add(this.overlayGroups);

    AMap.plugin(['AMap.Scale'], () => {
        this.map.addControl(new AMap.Scale());
    });

    // 初时化时获取周边外勤人员
    this.getAcceptPersonList();
}

上面这段代码不太好分离,所以我就一起贴出来了。主要实现的就是初始化地图对象、圆形区域及中心点、当圆形区域点击时触发状态变更、当圆形区域变化(移动)时将中心点跟着移动。

另外还初始了两个东西:覆盖物群组、信息弹窗。下面就说~

4、覆盖物群组、自定义信息弹窗

覆盖物群组就是标记这片区域的所有人员,当我们中心点变化时,必然需要先清空群组,再重新标记,而覆盖物群组自带清空方法,反正很方便。

简化的getAcceptPersonList方法如下:

// 先清空覆盖物群组
this.overlayGroups.clearOverlays();
// 假设一条数据
let info = {
    id: 1,
    longitude: 30,
    latitude: 120,
    userName: '张三',
    userPhone: '15012345678',
    number: 5

};
// 创建一个点标记
let marker = new AMap.Marker({
    position: new AMap.LngLat(
        info.longitude,
        info.latitude
    ),
    icon: require('@/assets/img/personnel.png'),
    extData: {
        id: info.id
    }
});
marker.content = '<button class="info-submit" type="submit">确定</button>';
marker.setLabel({
    offset: new AMap.Pixel(0, 20),
    content: `<div class="info-address2">${info.userName}(${info.number || 0})</div>`,
    direction: 'center'
});
// 点击时将内容放入信息弹窗并显示
marker.on('click', e => {
    this.infoWindow.setContent(e.target.content);
    this.infoWindow.open(
        this.map,
        e.target.getPosition()
    );
});
// 将点标记添加覆盖物群组
this.overlayGroups.addOverlay(marker);

这里面如果自定义信息弹窗需要绑定事件的话,marker.content内容需要使用Vue.extend生成(Vue.extend是帮我们动态生成模板,在里面我们可以定义事件)。

5、自定义信息弹窗绑定事件

将marker.content这一行替换成下面这一段代码:

var Popup = Vue.extend({
    render(createElement) {
        return createElement('div', {
            domProps: {
                innerHTML: `<div class="info-btns"><button class="info-submit" type='submit'>确定</button></div>`
            },
            on: {
                click: e => {
                    if (e.target.type === 'submit') {
                        // 点击确定按钮时触发
                    }
                }
            }
        });
    }
});
marker.content = new Popup().$mount('').$el;

在点击事件时,我们通过返回的target对象中类型为submit来判断是不是确定按钮。

差不多整理的就是这些了~我想下次再做高德地图相关的需求时,应该可以轻松一点了~

文章TAG:Vue

本文标题:Vue + 高德地图整理了几点
本文链接:http://www.jingjingke.com/c/07363.html

上一篇:IndexedDB快速入门
下一篇:Animate CC之canvas动画玩耍篇