当前位置:   article > 正文

vue+高德地图写地图选址组件_center search

center search

前言

现在做这个移动端的项目中有一个地图选址的功能,本来高德地图中有一个现成的选址组件,但是有两个问题,因为他是用iframe引用的,第一改不了样式,这点还勉强能接受;第二他的左上角有一个返回键,在搜索的时候可以返回到地图界面,但是在地图界面时点返回没有用,试了半天也没搞明白怎么监听到那个返回键的点击事件,所以趁这两天项目基本结束自己写一个把这个功能优化一下,也方便以后使用。

开整

vue的安装使用啥的我在这就不说了,直接开始地图选址组件。
首先上高德开放平台弄一个key,然后在index.html引入

<script src="https://webapi.amap.com/maps?v=1.4.14&key=yourKey"></script>
  • 1

然后写样式
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
css我就不贴了,大概就是上面一个搜索框,中间是地图,然后下面是一个地址列表,然后一个搜索结果的列表。有一点值得注意一下,就是地图中心的定位图标,这个自己弄一个定位图标使用绝对定位,上下左右外边距为auto的方法定位到中间,但是这时地图的中心点是在图标的中心,我们的图标不是一般都是下面是尖的嘛,选址的时候都会用尖的部分指到目标位置,那这样就会有一点偏差,怎么办呢,比如我们的图标是30*30的,我们就把bottom的值设为图标的高度的一半15,或者是把top设为-15,就ok了,另外注意在切图的时候靠着图标边切,不要留空白。
data里定义的值:

data(){
   return{
       center: [106.532357,29.57212],//经度+纬度
       search_key: '',               //搜索值
       lists: [],							//地点列表
       search_list: [],              //搜索结果列表
       noSearchShow: false   //无搜索结果提示,无搜索结果时会显示暂无搜索结果
   }
 },
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

然后在mounted中调取第一个方法------初始化地图:

adMap(){
	//初始化地图
    var map = new AMap.Map('container',{
        zoom: 14,            //缩放级别
        center: this.center,  //设置地图中心点
        //resizeEnable: true,  //地图初始化加载定位到当前城市
    });
    //获取初始中心点并赋值
    var currentCenter = map.getCenter();//此方法是获取当前地图的中心点
    this.center = [currentCenter.lng,currentCenter.lat];//将获取到的中心点的纬度经度赋值给data的center
    //根据地图中心点查附近地点,此方法在下方
    this.centerSearch();
    //监听地图移动事件,并在移动结束后获取地图中心点并更新地点列表
    var moveendFun = (e) => {
        // 获取地图中心点
        currentCenter = map.getCenter();
        this.center = [currentCenter.lng,currentCenter.lat]
        //根据地图中心点查附近地点
        this.centerSearch();
    }
    // 绑定事件移动地图事件
    map.on('moveend', moveendFun);
},
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

根据中心点查询附近地点

centerSearch(){
    AMap.service(["AMap.PlaceSearch"], () => {
        //构造地点查询类
        var placeSearch = new AMap.PlaceSearch({ 
            type: '汽车服务|餐饮服务|购物服务|生活服务|体育休闲服务|医疗保健服务|住宿服务|风景名胜|商务住宅|政府机构及社会团体|科教文化服务|交通设施服务|金融保险服务|公司企业|地名地址信息', // 兴趣点类别
            pageSize: 30, // 单页显示结果条数
            pageIndex: 1, // 页码
            city: "全国", // 兴趣点城市
            autoFitView: false // 是否自动调整地图视野使绘制的 Marker点都处于视口的可见范围
        });
        //根据地图中心点查附近地点
        placeSearch.searchNearBy('', [this.center[0],this.center[1]], 200, (status, result) => {
            if(status == 'complete'){
                this.lists = result.poiList.pois//将查询到的地点赋值
            }
        });
    });
 },
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

这个方法没什么好说的,就是高德地图的方法,copy过来就行了,要注意的几个点:
1.type,需要查找的地点的分类,这个可以按需添加减少;
2.这里可以传条数和页码,如果需要做上拉加载的都可以使用这个;
3.placeSearch.searchNearBy(),这个方法的第二个参数就是经纬度,是一个数组,这里要注意lng是经度,lat是纬度;
4.然后是返回值status是状态,result是结果,具体的请参考:
https://lbs.amap.com/api/javascript-api/reference/search#m_AMap.PlaceSearch

到这里我们一个地点展示的功能就可以使用了,接下来就是搜索
首先我使用了watch监听了用户输入的搜索值,当search_key(用户输入的值)不为空时:

<!--搜索列表-->
<div class="search-list" v-if="!!search_key">
    <ul>
        <li v-for="(item, index) in search_list" :key="index" @click="onSearchLi(item.location)">
            <span>{{item.name}}</span>
            <p>{{item.address}}</p>
        </li>
        <li v-if="noSearchShow"><p>暂无搜索结果</p></li>
    </ul>
</div>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

我们使用v-if判断当search_key不为空时就显示搜索列表,这里的双感叹号就是强制转换为布尔值,不写也可以的,具体为啥我在这就不多说了;这里的search-list就是定位在页面上的,把地图给它覆盖了,css相信大家都会。

然后我们来看一看搜索的方法:

keySearch(){
     AMap.service(["AMap.PlaceSearch"], () => {
         //构造地点查询类
         var placeSearch = new AMap.PlaceSearch({
             type: '汽车服务|餐饮服务|购物服务|生活服务|体育休闲服务|医疗保健服务|住宿服务|风景名胜|商务住宅|政府机构及社会团体|科教文化服务|交通设施服务|金融保险服务|公司企业|地名地址信息', // 兴趣点类别
             pageSize: 30, // 单页显示结果条数
             pageIndex: 1, // 页码
             city: "全国", // 兴趣点城市
             citylimit: false,  //是否强制限制在设置的城市内搜索
             autoFitView: false // 是否自动调整地图视野使绘制的 Marker点都处于视口的可见范围
         });
         //关键字查询
         placeSearch.search(this.search_key,(status, result) => {
             if(status == 'complete'){
                 if(result.poiList.count === 0){
                     this.noSearchShow = true;
                 }else{
                     this.search_list = result.poiList.pois//将查询到的地点赋值
                     this.noSearchShow = false;
                 }
             }else{
                 this.search_list = [];
                 this.noSearchShow = true;
             }
         });
     });
 },
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

还是copy高德的方法过来,然后进行配置,主要说一下这里返回结果的处理:
1.status为complete的时候是完成查询,其中完成后有一个count 参数是代表查到的总条数,如果总条数为0时,我们就this.noSearchShow = true,这个我们上面说了,当noSearchShow 为true的时候会显示‘暂无搜索结果’;如果count不为0的时候,也就是else中的内容,那就将我们查询到的值赋给this.search_list,然后遍历出来,然后记得this.noSearchShow = false;
2.另外我是将status不为complete的情况统统视为没有搜索结果,这时候我们就清空this.search_list,然后this.noSearchShow = true。

这时候搜索也完成了,接下来如果我们不想搜索了,清空了搜索框,这是点×的清空方法:

<span class="clear" v-if="search_key" @click="search_key = ''"></span>
  • 1

直接@click="search_key = ‘’"就行了,当然我们也可以用输入键盘退格删除,这时要注意清空input之后我们要把search_list也清空并且this.noSearchShow = false,这里我是使用了watch来监控search_key:

watch: {
     search_key(newv,oldv){
         if(newv == ''){
             this.search_list = [];
             this.noSearchShow = false;
         }
     }
 },
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

至于为什么要清空呢?因为如果我们第一次进行了搜索,这时search_list就有值了,如果下次在进入搜索状态,就会直接显示上次的搜索列表,所以我们要清空一下。

上面是说的放弃了搜索,这里是说如果搜索到了我们想要的结果,那我们会去点击我们想要的结果:

//这里我们遍历search_list的时候将location传进来
onSearchLi(location){
    this.center = [location.lng,location.lat];
    this.adMap();
    this.search_key = '';
},
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

这里的步骤是:
1.先给this.center赋值,这里注意纬度在前,经度在后!
2.调取上面的this.adMap()查询一次新的lists;
3.清空search_key,清空search_key后搜索列表就会自动隐藏了,另外因为我们用watch监控了search_key ,所以在这里清空search_key 的同时也会清空search_list并将noSearchShow设为false。

这里基本上就差不多完成了,还有就是最后一步,我们点击地址列表的时候获取地址信息:

//html
<li v-for="(item, index) in lists" :key="index" @click="onResLi(item)">
             <span>{{item.name}}</span>
             <p>{{item.address}}</p>
</li>

//js   
onResLi(e){
     console.log(e)
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

这里e打印出来就是选择的地点信息。
在这里我们组件就完成了,另外可能还需要一个回到当前位置的方法,我说下思路,就不在写出来了:
1.在地图上写一个图标,给一个点击事件;
2.点击的时候使用高德的定位方法获取当前位置的坐标,然后赋值给this.center;
3.再调一次adMap()方法就会回到当前位置了。

欢迎大佬批评指正优化,小弟献丑了~

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop】
推荐阅读
相关标签
  

闽ICP备14008679号