小程序结合腾讯地图(QQMapWX)SDK做位置周边搜索在地图上展示气泡点,点击气泡展示不同状态

1.背景:

在微信小程序中,地图上展示一个坐标点周边的医院学校等周边设施,通过地图上气泡的方式。点击气泡展示不同的气泡状态,点击导航跳转到对应气泡点所在的坐标位置。

2.实现思路:

2.1布局:

地图全屏展示,地图上的位置tablist展示在地图底部,跳转导航按钮位于地图右上角。因为map属于原生标签,而且层级比较高,所以tablist和按钮都需要通过cover-view和cover-image来提高层级。官网传送门

2.2map部分:

需要在地图上做标记,通过marks进行标记点(cover即将废弃,点击跳转官网);

地图上气泡点的点击事件是通过给map添加bindcallouttap来实现的,点击去官网查看;

获取当前点击的气泡是通过  bindcallouttap的  “点击标记点对应的气泡时触发e.detail = {markerId}”,官网中也有说明;

map跳转导航,通过wx.openLocation的api来实现的,点击去官网;

2.3 腾讯地图SDK:

需要通过坐标点来获取周边的位置,肯定需要用到第三方的SDK来查找,点击官网传送门,比较简单明了,大概看一下就会用了:

几点说明:

① 需要申请密匙;

② 加入合法域名;

③ 下载 qqmap-wx-jssdk.min.js 包并且引入;

④ 这个地方主要使用 qqmapsdk.search 查找方法(传入关键词,写入一个需要几条(不写默认10条),传入经纬度(用逗号拼接),然后对获取的数据进行处理为自己所需要的格式);

⑤ 当然了,对于接口所返回的distance如果感觉不准确的话可以使用距离计算的方法 qqmapsdk.calculateDistance,传入起始点的坐标位置,传入终点位置(终点可以是一个点页可以是多个点,通过坐标的方式可以计算的,具体使用可以参考官网,写的也比较详细);

3.代码实现:

3.1wxml


	
	
	
		
			
			{{item.name}}
		
	

	
	

3.2 css

/*弹性布局*/
.flex {
  display: -webkit-box;
  display: -moz-box;
  display: -ms-flexbox;
  display: -webkit-flex;
  display: flex;
  display: box;
  flex-wrap:wrap;
}
.noWarp{
    flex-wrap:nowrap; 
}
/*元素居中*/
.alignC{
  align-items: center;
  -webkit-box-align: center;
  -webkit-align-items: center;
  -moz-align-items: center;
  -ms-align-items: center;
  -o-align-items: center;
}
/*水平排列*/
.flexH{
  -webkit-box-orient: horizontal;
  -webkit-flex-direction: row;
  -moz-flex-direction: row;
  -ms-flex-direction: row;
  -o-flex-direction: row;
  flex-direction: row;
}
/*垂直排列*/
.flexV {
  -webkit-box-orient: vertical;
  -webkit-flex-direction: column;
  -moz-flex-direction: column;
  -ms-flex-direction: column;
  -o-flex-direction: column;
  flex-direction: column;
}
/*两端对齐*/
.flexSa {
  -webkit-box-pack: justify;
  justify-content: space-around;
  -webkit-justify-content: space-around;
  -moz-justify-content: space-around;
  -ms-justify-content: space-around;
  -o-justify-content: space-around;
}
/*居中对齐*/
.flexC {
  -webkit-box-pack: center;
  justify-content: center;
  -webkit-justify-content: center;
  -moz-justify-content: center;
  -ms-justify-content: center;
  -o-justify-content: center;
}
.flexSb {
  justify-content: space-between;
  -webkit-justify-content: space-between;
  -moz-justify-content: space-between;
  -ms-justify-content: space-between;
  -o-justify-content: space-between;
}
.flexS {
  -webkit-box-pack: start;
  justify-content: flex-start;
  -webkit-justify-content: flex-start;
  -moz-justify-content: flex-start;
  -ms-justify-content: flex-start;
  -o-justify-content: flex-start;
}
.flexE {
  -webkit-box-pack: end;
  justify-content: flex-end;
  -webkit-justify-content: flex-end;
  -moz-justify-content: flex-end;
  -ms-justify-content: flex-end;
  -o-justify-content: flex-end;
}

.tfLine1 {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* 页面内容 */

.xmwzB{
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  background-color: rgba(255, 255, 255, 0.6);
  box-sizing: border-box;
  padding: 20rpx 25rpx;
}

.xmwzBLi{
  background-size:48rpx 48rpx;
  background-repeat: no-repeat;
  background-position:top center;
  padding-top: 72rpx;
  text-align: center;
  font-size: 30rpx;
  color: #333333;
  padding-bottom: 30rpx;
  position: relative;
}

.xmwzBLi:before{
  position: absolute;
  width: 100%;
  height: 10rpx;
  background-color: transparent;
  left: 0;
  bottom: 0;
  display: block;
  content:'';
}

.xmwzBLi.on::before{
  background-color: #3072f6;
}

.xmwzBLi .img{
  position: absolute;
  left: 50%;
  top: 5rpx;
  margin-left: -24rpx;
  width: 48rpx;
  height: 48rpx;

}

.xmwzUl{
  padding: 15rpx 0 50rpx;
}

.xmwzUl-li{
  height: 60rpx;
  line-height: 60rpx;
}

.xmwzUl-li-name{
  font-size: 30rpx;
  color: #666666;
}

.xmwzUl-li-add{
  background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAeCAMAAAAB8C7XAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyZpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTM4IDc5LjE1OTgyNCwgMjAxNi8wOS8xNC0wMTowOTowMSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTcgKFdpbmRvd3MpIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOkY5QTYwM0Y5NzhBNDExRUE4RUQ0Q0YzMkJFMDVDRjRGIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOkY5QTYwM0ZBNzhBNDExRUE4RUQ0Q0YzMkJFMDVDRjRGIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6RjlBNjAzRjc3OEE0MTFFQThFRDRDRjMyQkUwNUNGNEYiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6RjlBNjAzRjg3OEE0MTFFQThFRDRDRjMyQkUwNUNGNEYiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz7eVhRAAAAAGFBMVEX19fX9/f3k5OTt7e3l5eX////Z2dkAAADwxi4GAAAACHRSTlP/////////AN6DvVkAAAB3SURBVHjajNJREoAgCATQJTPuf+PKRFHYmfhrX6UoUKur1XiET70h5F0Q80+Q5E2Q5a8gzR+ZcEAER4RSW5UB9n7tZd8YwAAbiIH8BfqruDjd7mjw3BukZ8WBHju/KA70zvmUeFnnaoruQCbRRDNQny+gHm4BBgBoDxEM+vumxAAAAABJRU5ErkJggg==);
  background-size:24rpx 30rpx;
  background-repeat: no-repeat;
  background-position: left center;
  padding-left:36rpx;
  font-size: 30rpx;
  color: #aaaaaa;
}

.navigation_btn{
  width:76rpx;
  height:76rpx;
  position: absolute;
  right:30rpx;
  top:50rpx;
}

3.3js

var QQMapWX = require('../../lib/qqmap-wx-jssdk.min.js');
var qqmapsdk;
qqmapsdk = new QQMapWX({
  key: 'RAMBZ-UKXW6-FZOSO-M6ENO-RCTTE-THFBQ'
});
Page({

  /**
   * 页面的初始数据
   */
  data: {
    // 获取的经纬度
    t_lat: '32.00335',
    t_lng: '118.73145',
    // 地图的markers
    markers: [],
    // 当前选中第几个
    xmwzB_index: 0,
    // tab列表
    tabs: [{
        ico: '../../images/around/icon1.png',
        ico_active: '../../images/around/icon1_1.png',
        name: '交通'
      },
      {
        ico: '../../images/around/icon2.png',
        ico_active: '../../images/around/icon2_1.png',
        name: '学校'
      },
      {
        ico: '../../images/around/icon3.png',
        ico_active: '../../images/around/icon3_1.png',
        name: '医疗'
      },
      {
        ico: '../../images/around/icon4.png',
        ico_active: '../../images/around/icon4_1.png',
        name: '购物'
      },
      {
        ico: '../../images/around/icon5.png',
        ico_active: '../../images/around/icon5_1.png',
        name: '餐饮'
      },
    ],
    // 把从腾讯地图SDK获取的位置存起来,以后每次点击就不用请求了。
    arrlist: [
      [],
      [],
      [],
      [],
      []
    ],
    // 记录当前地图选中的icon点
    location: ['', '', '', '', ''],
    // 是否展示地图跳转导航按钮
    navigation: false,
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    var that = this;
    var marks = [];
    // 地图上的icon图标
    marks.push({ // 获取返回结果,放到mks数组中
      latitude: that.data.t_lat,
      longitude: that.data.t_lng,
      iconPath: '../../images/around/address.png', //图标路径
      width: 20,
      height: 20,
    });
    // 地图上的气泡点
    that.setData({
      markers: marks
    });

    // 进页面先请求一波(第一个tab下对应的列表内容)
    that.nearby_search(that.data.tabs[0].name);

  },
  // 点击tab切换
  xmwzB_click(e) {
    var that = this;
    var index = e.currentTarget.dataset.index;
    that.setData({
      xmwzB_index: index
    }, () => {
      var name = that.data.tabs[index].name;
      that.nearby_search(name);
    });
  },
  // 通过关键字调用地图SDK,搜索获取结果列表
  nearby_search(key) {
    var that = this;
    var xmwzB_index = that.data.xmwzB_index;
    var list_c = that.data.arrlist[xmwzB_index];
    // 判断是否请求过了,如果没请求过则请求;请求过了就直接赋值
    if (list_c && list_c.length) {
      that.setData({
        markers: list_c
      });
    } else {
      wx.showToast({
        title: '请稍后',
        icon: 'loading',
        duration: 2000
      })
      qqmapsdk.search({
        keyword: key, // 搜索关键词
        page_size: 5, // 一页展示几个
        location: that.data.t_lat + ',' + that.data.t_lng, //设置周边搜索中心点
        success: function (res) { //搜索成功后的回调
          wx.hideToast({});

          var marks = [];
          marks.push({ // 获取返回结果,放到mks数组中
            latitude: that.data.latitude,
            longitude: that.data.longitude,
            iconPath: '../../images/around/address.png', //图标路径
            width: 20,
            height: 20,
          });

          for (var i = 0; i < res.data.length; i++) {
            marks.push({ // 获取返回结果,放到mks数组中
              title: res.data[i].title,
              id: res.data[i].id,
              latitude: res.data[i].location.lat,
              longitude: res.data[i].location.lng,
              iconPath: '../../images/around/cover_1.png', //图标路径
              width: 20,
              height: 20,
              address: res.data[i].address,
              callout: {
                content: res.data[i].title,
                color: '#404040',
                bgColor: '#ffffff',
                borderWidth: 1,
                borderColor: '#8a8a8a',
                fontSize: 14,
                padding: 10,
                borderRadius: 10,
                display: 'ALWAYS'
              }
            });
          }
          // 只赋值当前tab下的内容,其他tab下的不用管
          var arrlist_key = 'arrlist[' + xmwzB_index + ']';
          that.setData({ //设置markers属性,将搜索结果显示在地图中
            [arrlist_key]: marks,
            markers: marks
          });
        },
        fail: function (res) {
          console.log(res);
        },
        complete: function (res) {
          //console.log(res.data);
        }
      });
    }
  },
  // 地图上的气泡点击事件绑定,具体详情可参考微信小程序地图api
  callouttap(e) {
    var that = this;
    var marks = that.data.markers;

    // 点击某个tab下的某个气泡,其他气泡恢复为初始状态,点击的气泡变为选中状态
    // 同时把选中的状态的气泡信息存入到location对应位置(给点击跳转导航做准备)
    for (var i = 0; i < marks.length; i++) {
      if (marks[i].callout == undefined) {
        continue
      }
      marks[i].callout.bgColor = '#ffffff';
      marks[i].callout.color = '#404040'
      marks[i].callout.borderColor = '#8a8a8a'
    }

    that.setData({
      markers: marks,
      navigation: true,
      ['markers[' + that.data.markers.findIndex((n) => n.id == e.markerId) + '].callout.bgColor']: '#558ef9',
      ['markers[' + that.data.markers.findIndex((n) => n.id == e.markerId) + '].callout.color']: '#ffffff',
      ['markers[' + that.data.markers.findIndex((n) => n.id == e.markerId) + '].callout.borderColor']: '#558ef9',
      ['location[' + that.data.xmwzB_index + ']']: that.data.markers[that.data.markers.findIndex((n) => n.id == e.markerId)]
    });

  },
  // 小程序地图api,跳转大地图
  show_big_map: function () {
    var that = this;
    var location_c = that.data.location[that.data.xmwzB_index];
    var lat_c = location_c.latitude ? location_c.latitude : '';
    var lng_c = location_c.longitude ? location_c.longitude : '';
    var name_c = location_c.title ? location_c.title : '';
    var address_c = location_c.address ? location_c.address : '';

    if (location_c && lat_c && lng_c && name_c && address_c) {
      wx.getLocation({ //获取当前经纬度
        type: 'wgs84', //返回可以用于wx.openLocation的经纬度,官方提示bug: iOS 6.3.30 type 参数不生效,只会返回 wgs84 类型的坐标信息  
        success: function (res) {
          wx.openLocation({ //​使用微信内置地图查看位置。
            latitude: lat_c, //要去的纬度-地址
            longitude: lng_c, //要去的经度-地址
            name: name_c,
            address: address_c
          });
        }
      })
    }
  }

})

3.4效果

小程序结合腾讯地图(QQMapWX)SDK做位置周边搜索在地图上展示气泡点,点击气泡展示不同状态_第1张图片

4.说明

4.1 之前也写过一个比较简单的,只是展示列表的,如果需要也可以去瞅瞅,点击传送门;

4.2 也可以去百度云盘下载完整代码:

链接:https://pan.baidu.com/s/19Lx3PDsysSbYvYOUJmyLaA 
提取码:blmx

4.3 也可去Git下载实例:https://github.com/hangGe110305/Wechat-applet-search-around-of-the-map

你可能感兴趣的:(微信小程序)