阅读 610

Vue + 高德地图画矢量图

功能需求

  • 引入并创建地图
  • 支持鼠标工具
  • 鼠标画矢量图(线、圆、矩形、多边形)
  • 支持矢量图编辑、获取各点经纬度及求面积等操作
  • 自定义鼠标右键事件

一图胜千言,效果图如下

创建地图对象

    //DOM加载后动态引入地图脚本并map初始化
    
    //template
    <div id="map"></div>
    //mounted
    this.$nextTick(function() {
        this.initMap();
    });
    
    initMap() {
            var url = 'https://webapi.amap.com/maps?v=1.4.15&key=秘钥;
            var jsapi = document.createElement('script');
            jsapi.charset = 'utf-8';
            jsapi.src = url;
            document.head.appendChild(jsapi);
            setTimeout(() => {//一秒延迟,等待脚本加载
                let that = this;
                let map = new AMap.Map('map', {
                    zoom: 13, //级别
                    center: [117.226737, 31.820066], //中心点坐标
                    pitch: 30, // 地图俯仰角度,有效范围 0 度- 83 度
                    viewMode: '2D' // 地图模式
                });
                this.MAP = map;//将map挂载到组件data,后续交互需要用到
            }, 1000);
        },
    
复制代码

插件介绍(plugin)

map众多功能需要插件的支持官方文档

使用步奏

//1、引入插件,支持按需异步加载和同步加载,可同时引入多个插件
AMap.plugin(
            [
                'AMap.InfoWindow',
                'AMap.ContextMenu',
                'AMap.Heatmap',
                'AMap.MouseTool',
                'AMap.RangingTool',
                'AMap.CircleEditor',
                'AMap.PolyEditor',
                'AMap.ToolBar',
                'AMap.Scale',
                'AMap.OverView',
                'AMap.MapType',
                'AMap.Geolocation'
            ],
            function() {
                //插件引入回调事件,可添加工具控件,也可创建插件实例
                map.addControl(new AMap.ToolBar({ position: 'RT' }));// 在图面添加比例尺控件,展示地图在当前层级和纬度下的比例尺
                map.addControl(new AMap.Scale());// 在图面添加鹰眼控件,在地图右下角显示地图的缩略图
                map.addControl(new AMap.OverView({ isOpen: true }));// 在图面添加类别切换控件,实现默认图层与卫星图、实施交通图层之间切换的控制
            }
);
2、创建插件实例,非特殊情况需避免重复创建多个实例,复用同一个实例即可,vue中可将实例保存到data中;
    //插件实例可在任何地方创建,例如鼠标工具实例创建如下:
    //注意:实例的创建过程需要放到plugin的回调函数中执行,防止创建实例前没有获取到map实例
    this.mouseTool = new AMap.MouseTool(map);
    //this.mouseTool 实例挂载到data,方便全局使用
    //AMap.MouseTool 插件名
    //map 初始化的地图对象
    
    //监听鼠标工具出发的事件
    this.mouseTool.on('draw', function(e) {
        //做些什么
    });
    
    //自定义交互事件,当事件被dom触发后可以被mouseTool监听到
    <div class="m" @click="draw('circle')">画圆</div> 
    draw(type) {
            switch (type) {
                
                case 'polygon': {
                    ......
                    break;
                }
                case 'circle': {
                    ......
                    break;
                }
            }
            
        },
    
3、调用实例的方法,使用相关功能。
    <!--以测量工具插件为例-->
    this.ruler = new AMap.RangingTool(map); //创建测量工具实例
    <!--调用实例方法-->
    this.ruler.turnOn();
复制代码

鼠标画矢量图

    <div class="m" @click="draw('polyline')">划线</div>
    <div class="m" @click="draw('circle')">画圆</div>
    <div class="m" @click="draw('rectangle')">矩形</div>
    <div class="m" @click="draw('polygon')">多边形</div>
    draw(type) {
        //mouseTool是鼠标工具实例
        switch (type) {
            case 'marker': {//画点
                mouseTool.marker({
                    //同Marker的Option设置
                });
                break;
            }
            case 'polyline': {//划线
                mouseTool.polyline({
                    strokeColor: '#80d8ff'
                    //同Polyline的Option设置
                });
                break;
            }
            case 'polygon': {//画多边形
                mouseTool.polygon({
                    strokeColor: '#f7797d',
                    strokeOpacity: 1,
                    strokeWeight: 2,
                    strokeOpacity: 1,
                    strokeStyle: 'solid',
                    fillOpacity: 0.1,
                    fillColor: '#69AC8F',
                    zIndex: 100
                });
                break;
            }
            case 'rectangle': {//画矩形
                mouseTool.rectangle({
                    strokeColor: '#f7797d',
                    strokeOpacity: 1,
                    strokeWeight: 2,
                    strokeOpacity: 1,
                    strokeStyle: 'solid',
                    fillOpacity: 0.1,
                    fillColor: '#69AC8F',
                    zIndex: 100
                });
                break;
            }
            case 'circle': {//画圆
                mouseTool.circle({
                    strokeColor: '#f7797d',
                    strokeOpacity: 1,
                    strokeWeight: 2,
                    strokeOpacity: 1,
                    strokeStyle: 'solid',
                    fillOpacity: 0.1,
                    fillColor: '#69AC8F',
                    zIndex: 100
                });
                break;
            }
        }
    }
复制代码

支持矢量图编辑、获取各点经纬度及求面积等工具插件

    //编辑各种矢量图形需要对应的插件
    1、引入
    2、创建实例
    3、使用:调用方法、监听事件
    
    let circleEditor = new AMap.CircleEditor(map, e.obj);//创建圆实例,e.obj是mouseTool事件回调函数返回的数据对象
    circleEditor.open(); //打开编辑状态
    监听圆编辑过程中的事件
    circleEditor.on('move', function(event) {
        // event.target 即为编辑后的图形对象,包含图形的相关数据和方法
        event.target.getCenter().lat.toFixed(7)//获取圆心经度
        
    });
    circleEditor.on('adjust', function(event) {
        
    });
    circleEditor.on('end', function(event) {
        
    });
复制代码

自定义鼠标右键事件

        //地图绑定鼠标右击事件——弹出右键菜单
        //地图对象监听右键事件(这里监听的是地图上的右键事件,如果是监听绘画的矢量图右键,
        则把监听对象改成绘画的矢量图)
        map.on('rightclick', function(e) {
            that.rightclickObj(); //定义右键内容
            that.contextMenu.open(map, e.lnglat);
            that.contextMenuPositon = e.lnglat; //右键菜单位置
        });
        
        //定义右键内容
        rightclickObj() {
            let that = this;
            //定义内容
            let content = [];
            content.push("<div class='context_menu'>");
            content.push(
                "<p class='menu-list menu-list-edit-start' >启用编辑</p>"
            );
            content.push(
                "<p class='menu-list menu-list-edit-end' >结束编辑</p>"
            );
            content.push(
                "<p class='menu-list menu-list-get-area' >计算面积</p>"
            );
            content.push(
                "<p class='menu-list menu-list-remove' >移除图形</p>"
            );
            if (that.circleEditor) {
                content.push(
                    "<p class='menu-list menu-list-radius'>半径</p>"
                );
            }
            content.push('</div>');
            //创建右键实例并添加自定义的内容
            
            that.contextMenu = new AMap.ContextMenu({
                isCustom: true,
                content: content.join('')
            });  
        }
        //强调说明:自定义的dom是基于地图对象生成的,并不能像vue一样绑定事件,这里采用jQuery的方式出发的事件。如下
        
        mounted() {
            this.$nextTick(function() {
                this.initMap();
            });
    
            $('body').on('click', '.menu-list-edit-start', () => {//这里采用箭头函数,为了this指向vue
                //调用定义的dom交互
                this.rightMenuu(0);
            });
            $('body').on('click', '.menu-list-edit-end', () => {
                this.rightMenuu(1);
            });
            $('body').on('click', '.menu-list-get-area', () => {
                this.rightMenuu(2);
            });
            $('body').on('click', '.menu-list-remove', () => {
                this.rightMenuu(3);
            });
            $('body').on('click', '.menu-list-radius', () => {
                this.rightMenuu(4);
            });
        }
复制代码

总结

仔细对比会发现,地图无非就是自身API和引入插件实现相应功能

  • 事件监听通过 .on('支持的事件名',function)
  • 事件插件需要引入并创建实例,实例也包含方法和事件,方法直接调用,事件用.on监听,事件的回调函数会返回图形的相关数据以及方法
  • 最后,地图的所有功能都是由一个或多个API或插件组合而成,好在官方文档足够详细且每个功能点都有demo,所以当遇到一个功能不知如何下手时,试着把功能拆成更小的步奏或单元

初次使用地图,以上所述如有不足之处或者你有更好的方法,欢迎留言指出