小程序实现附近三公里搜索和地图路线导航(改版)

##本片博客主要介绍的是小程序利用地图搜索附近三公里信息并导航路线或者复制路线打开地图导航。可以直接在微信内置打开导航。

开篇先提一下,网上有很多关于小程序搜索框的,地图地点信息检索的,路线导航的,以及一个找事吧APP模仿的小程序。我也看过这些内容,整理一下,就是我今天要展示的。

惯例,先上整体效果图:
在这里插入图片描述
这是点击药店,搜索附近20个药店信息。
这里写图片描述
可以打印出20条信息数据,自己可根据实际情况展示。同时点击搜索出来的地址信息,可以复制到手机粘贴板,方便在自己手机地图中导航,因为腾讯自带的多数人不习惯用。
附上小程序的复制文字的方法:

wx.showModal({
      title: '确定复制地址信息吗?',
      content: e.currentTarget.dataset.text,
      success: function (res) {
        if(res.confirm == true){
          wx.setClipboardData({
            data: e.currentTarget.dataset.text,
            success: function (res) {
              wx.getClipboardData({
                success: function (res) {
                  //console.log(res)
                }
              })
            }
          })
        }else{
          wx.showModal({
            title: '抱歉',
            content: '你取消了复制信息',
            showCancel: false
          })
        }
        
      }
    })

在这里插入图片描述
虽然腾讯自带的不咋地,但是我还是加上地图导航功能吧,看看效果图。
在这里插入图片描述
在这里插入图片描述
在开发工具中不能进行点击,但是在真机上点击就会显示导航按钮以及导航地图选择。直接使用内置地图导航,微信官方也有api,这里奉上代码:

copyText: function (e) {
    var that = this,info_detail = e.currentTarget.dataset;
    wx.getLocation({//获取当前经纬度
      type: 'wgs84', //返回可以用于wx.openLocation的经纬度,官方提示bug: iOS 6.3.30 type 参数不生效,只会返回 wgs84 类型的坐标信息  
      success: function (res) {
        wx.openLocation({//​使用微信内置地图查看位置。
          latitude: info_detail.latitude,//要去的纬度-地址
          longitude: info_detail.longitude,//要去的经度-地址
          name: info_detail.title,
          address: info_detail.text
        })
      }
    })
  },

前端代码:

<view class="cu-item" wx:for="{{dataArray}}" wx:for-item="item" wx:key>
   <view class='content padding-tb-sm' bindtap='copyText' data-text="{{item.address}}" data-index="{{item}}" data-latitude="{{item.latitude}}" data-longitude="{{item.longitude}}" data-tile="{{item.title}}">
     <view>
       <text class='icon-activityfill text-blue'></text> {{item.id+1}}:{{item.title}}</view>
     <view class='text-gray text-sm'>
       <text class='icon-locationfill'></text> {{item.address}}</view>
   </view>
 </view>

##下面介绍主要方法步骤:
1.引入百度地图的js,添加个人AK
2.书写自己的wxSearch方法包
3.页面布局和JS写入
4.最终效果展示

##第一步:百度地图JS引入

在我的第一篇博客中我已经介绍过关于百度地图开发者信息如何获取,AK是个人小程序应用专用的ak.

bmap-wx.min.js。这是百度提供给小程序的开发JS。放上下载链接(http://lbsyun.baidu.com/index.php?title=wxjsapi/wxjs-download)。
当然你也可以花点时间,在深入了解一下百度地图信息检索开发文档。

var bmap = require('../../utils/bmap-wx.min.js');

在index.js中引入你存放起来的百度地图JS。
强调一点在百度地图开发文档中有详细的说明,这里我只说一下在JS中的各个参数代表:

var e={query:t.query||"生活服务$美食&酒店",scope:t.scope||1,filter:t.filter||"",coord_type:t.coord_type||2,page_size:t.page_size||20,page_num:t.page_num||0,output:t.output||"json",ak:a.ak,sn:t.sn||"",timestamp:t.timestamp||"",radius:t.radius||2e3,ret_coordtype:"gcj02ll"}

这一段代码是百度地图JS中默认的各个参数存放处,找到这段代码,你可以根据自己实际需要来修改各个参数的值,界面展示的信息结果也会不一样的。此处的t.query默认请求的是生活服务美食酒店,也可根据个人喜好修改。

##第二步:给页面添加一个搜索功能

百度地图的POI信息检索默认是输出地点的,但是这并不是我们想要的结果。我们需要根据需求,设计自己想要的检索功能,诸如这样的:
这里写图片描述
点击各个模块,搜索对应的信息;你也可以来个更简洁的放个搜索输入框,让用户自己来输入搜索。不过,我坚信用户更倾向于点击搜索,这样更一目了然,不是吗。

好了我们来看看这个搜索方法如何写入:

这里的内容是小程序整个搜索事件的所有可能用到的事件。我们在地图展示中也会用到的,最基础的就是wxSearchInput,wxSearchFocus,wxSearchKeyTap,wxSearchAddHisKey,init。将这些方法写起来,区别于util文件夹。方便其他页面的调用。

##第三步:编写我们的主要内容
这就是正文内容了。先写wxml内容吧:

<!--index.wxml-->
<view class="map_container">
  <map class="map" id="map" circles='{{circles}}' longitude="{{longitude}}" latitude="{{latitude}}" scale="15" show-location="true" markers="{{markers}}" bindmarkertap="makertap"></map>
</view>
<!--nearby.wxml-->
<view style="overflow:hidden;">
  <view class="items" wx:for="{{array}}" wx:key="" wx:for-item="item" bindtap="wxSearchFn" bindinput="wxSearchInput" bindfocus="wxSerchFocus" value="{{wxSearchData.value}}" bindblur="wxSearchBlur" data-code="{{item.code}}" data-text="{{item.text}}">
    <image class="item-img" mode="aspectFit" src="{{item.src}}"></image>
    <view class="item-text">{{item.text}}</view>
  </view>
</view>

<!-- 测试地图选点如下 -->
<view class="cu-bar bg-white solid-bottom margin-top">
  <view class='action'>
    <text class='icon-titles text-orange '></text>{{title}}
  </view>
</view>
<view class="cu-list menu margin-top  margin-indexbottom">
  <view class="cu-item" wx:for="{{dataArray}}" wx:for-item="item" wx:key>
    <view class='content padding-tb-sm' bindtap='copyText' data-text="{{item.address}}" data-index="{{item}}" data-latitude="{{item.latitude}}" data-longitude="{{item.longitude}}" data-tile="{{item.title}}">
      <view>
        <text class='icon-activityfill text-blue'></text> {{item.id+1}}:{{item.title}}</view>
      <view class='text-gray text-sm'>
        <text class='icon-locationfill'></text> {{item.address}}</view>
    </view>
  </view>
</view>
<!--  -->
<include src="../../template/footBar.wxml"></include>
 

想要搜索的名称列表我们用wx:for="{{array}}"来循环这个item的内容,array的内容存储在JS的data中就可以了。节省页面空间。
由于我们将搜索框替换为卡片点击形式,所以还要在该
item
上来绑定搜索框的属性:bindtap=“wxSearchFn” bindinput=“wxSearchInput” bindfocus=“wxSerchFocus” bindblur=“wxSearchBlur”,以及点击卡片传入搜索对应的值value="{{wxSearchData.value}}" 。这样就可以确保每个卡片单独点击都只会显示对应的内容,不会乱码搜索。

那么在JS中是什么样子呢?JS部分现在做了一些调整修改,所以放上最新的。
下面,写JS内容:

//获取应用实例
var App = getApp();
var bmap = require('../../utils/bmap-wx.min.js');
var wxMarkerData = [];
var WxSearch = require('../../wxSearch/wxSearch.js');
var count = 10;
var total = 0;
var code = "2";
Page({
  data: {
    aslect: false,
    bslect: true,
    cslect: true,
    dslect: true,
    eslect: true,
    title: "周边信息查询结果",
    indicatorDots: true,
    vertical: false,
    autoplay: true,
    markers: [],
    latitude: '',
    longitude: '',
    rgcData: {},
    telephone: {},
    test: '',
    interval: 3000,
    duration: 1000,
    array: [{
      code: '1',
      id: 'icon_1',
      src: '../../images/homework.png',
      text: '家政'
    }, {
      code: '2',
      id: 'icon_2',
      src: '../../images/ill.png',
      text: '药店'
    }, {
      code: '3',
      id: 'icon_3',
      src: '../../images/bank.png',
      text: '银行'
    }, {
      code: '4',
      id: 'icon_4',
      src: '../../images/dis.png',
      text: '维修'
    }, {
      code: '5',
      id: 'icon_5',
      src: '../../images/wc.png',
      text: '公厕'
    }, {
      code: '6',
      id: 'icon_6',
      src: '../../images/hospital.png',
      text: '医院'
    }, {
      code: '7',
      id: 'icon_7',
      src: '../../images/addyou.png',
      text: '加油站'
    }, {
      code: '8',
      id: 'icon_8',
      src: '../../images/food.png',
      text: '饭店'
    }, {
      code: '9',
      id: 'icon_9',
      src: '../../images/weed.png',
      text: '营业厅'
    }, {
      code: '10',
      id: 'icon_10',
      src: '../../images/park.png',
      text: '停车场'
    }],
    dataArray: []
  },

  //分类存储
  makertap: function(e) {
    var that = this;
    var id = e.markerId;
    that.showSearchInfo(wxMarkerData, id);
    that.setData({
      index_id: e.markerId,
    })
    console.log(e)
    this.showSearchInfo(e);
  },
  openPage: function (a) {
    var e = a.currentTarget.dataset.url;
    console.log(e)
    wx.reLaunch({
      url: e,
    })
  },
  onLoad: function(options) {
    var that = this;
    if (options.scene) {
      console.log("has scene");
      var scene = decodeURIComponent(options.scene);
      console.log("scene is ", scene);
      var arrPara = scene.split("&");
      var arr = [];
      for (var i in arrPara) {
        arr = arrPara[i].split("=");
        wx.setStorageSync(arr[0], arr[1]);
        console.log("setStorageSync:", arr[0], "=", arr[1]);
      }
    } else {
      console.log("no scene");
    }

    //初始化的时候渲染wxSearchdata
    WxSearch.init(that, 400, ['家政', '药店', '公厕', '银行', '营业厅', '医院', '超市', '地铁站', '停车场', '维修', '美食', '饭店']);
    WxSearch.initMindKeys(['家政公司', '保洁公司', '大药房', '药店', '免费公厕', '营业厅', '银行ATM', '三甲医院', '地下停车场', '地铁口', '汽车美容', '饭店', '美食广场', '中石化加油站', '中石油加油站']);
    // 新建百度地图对象 
    var BMap = new bmap.BMapWX({
      ak: 'jXYZ2cjB0lwQYiI8einLVGGEv7Q0zfDz'
    });
    var fail = function(data) {
      console.log(data)
    };
    var success = function(data) {
      wxMarkerData = data.wxMarkerData;
      that.setData({
        markers: wxMarkerData,
        latitude: wxMarkerData[0].latitude,
        longitude: wxMarkerData[0].longitude,
        dataArray: data.wxMarkerData
      });
    };

    // 发起POI检索请求 
    BMap.search({
      "query": "",
      fail: fail,
      success: success,
      // 此处需要在相应路径放置图片文件 
      iconPath: '../../images/marker_red.png',
      // 此处需要在相应路径放置图片文件 
      iconTapPath: '../../images/marker_red.png'
    });
  },

  //点击事件
  wxSearchFn: function(e) {
    var that = this;
    total = 0;
    code = e.currentTarget.dataset.code + "";
    var name = e.currentTarget.dataset.text + "";
    this.data.dataArray = [];
    //显示选择结果
    this.setData({
      title: "周边信息: " + name
    })

    WxSearch.wxSearchAddHisKey(that);

    // 新建百度地图对象 
    var BMap = new bmap.BMapWX({
      ak: 'jXYZ2cjB0lwQYiI8einLVGGEv7Q0zfDz'
    });

    var fail = function(data) {
      console.log(data)
    };
    var success = function(data) {
      wxMarkerData = data.wxMarkerData;
      that.setData({
        markers: wxMarkerData,
        latitude: wxMarkerData[0].latitude,
        longitude: wxMarkerData[0].longitude,
        dataArray: data.wxMarkerData
      });
    };
    // 发起POI检索请求 
    BMap.search({
      query: name,
      fail: fail,
      success: success,
      // 此处需要在相应路径放置图片文件 
      iconPath: '../../images/marker_red.png',
      // 此处需要在相应路径放置图片文件 
      iconTapPath: '../../images/marker_red.png'
    });
  },
  wxSerchFocus: function(e) {
    var that = this
    WxSearch.wxSearchFocus(e, that);
  },
  wxSearchBlur: function(e) {
    var that = this
    WxSearch.wxSearchBlur(e, that);
  },
  wxSearchKeyTap: function(e) {
    var that = this
    WxSearch.wxSearchKeyTap(e, that);
  },
  wxSearchDeleteKey: function(e) {
    var that = this
    WxSearch.wxSearchDeleteKey(e, that);
  },
  wxSearchDeleteAll: function(e) {
    var that = this;
    WxSearch.wxSearchDeleteAll(that);
  },
  wxSearchTap: function(e) {
    var that = this
    WxSearch.wxSearchHiddenPancel(that);
  },
  showSearchInfo: function(data, i) {
    console.log("------------", data[i])
    var that = this;
    var Otitle = data[i].title;
    var Oaddress = data[i].address;
    wx.getLocation({//获取当前经纬度
      type: 'wgs84', //返回可以用于wx.openLocation的经纬度,官方提示bug: iOS 6.3.30 type 参数不生效,只会返回 wgs84 类型的坐标信息  
      success: function (res) {
        wx.openLocation({//​使用微信内置地图查看位置。
          latitude: data[i].latitude,//要去的纬度-地址
          longitude: data[i].longitude,//要去的经度-地址
          name: Otitle,
          address: Oaddress
        })
      }
    })
  },
  changeMarkerColor: function(data, i) {
    var that = this;
    var markers = [];
    for (var j = 0; j < data.length; j++) {
      if (j == i) {
        // 此处需要在相应路径放置图片文件 
        data[j].iconPath = "../../images/marker_yellow.png";
      } else {
        // 此处需要在相应路径放置图片文件 
        data[j].iconPath = "../../images/marker_red.png";
      }
      markers[j](data[j]);
    }
    that.setData({
      markers: markers
    });
  },
  goTolocate:function(){
   
  },
  copyText: function (e) {
    var that = this,info_detail = e.currentTarget.dataset;
    wx.getLocation({//获取当前经纬度
      type: 'wgs84', //返回可以用于wx.openLocation的经纬度,官方提示bug: iOS 6.3.30 type 参数不生效,只会返回 wgs84 类型的坐标信息  
      success: function (res) {
        wx.openLocation({//​使用微信内置地图查看位置。
          latitude: info_detail.latitude,//要去的纬度-地址
          longitude: info_detail.longitude,//要去的经度-地址
          name: info_detail.title,
          address: info_detail.text
        })
      }
    })
  },
  onShareAppMessage: function (res) {
    //console.log("用户点击了确定", res)
    if (res.from === 'button') {
      // 来自页面内转发按钮
      console.log(res.target)
    }
    return {
      title: '美丽生活帮-看看周围有什么',
      path: 'pages/index/index',
      success: function (res) {
        // 转发成功
        
        wx.showShareMenu({
          // 要求小程序返回分享目标信息
          withShareTicket: true
        });
      },
      fail: function (res) {
        // 转发失败
        console.log("用户点击了取消",res)
      }
    }
  }

})

这里我们主要就是引入JS后,在data中配置各个数组数据,然后就是地图要搜所结果。这里你可能注意到我用了两次地图POI检索。说明一下,第一次在onload中,是页面首次加载默认显示的检索信息,所以默认值无需点击,我就存储在WxSearch.initWxSearch.initMindKeys来进行模糊搜索匹配。

wxSearchFn来详细配置我们的搜索内容和结果,var name = e.currentTarget.dataset.text + “”;,name是我们主要要用的参数,在query:name中进行精确搜索。

这个搜索功能可以直接下载工具包,也可以自己封装。下面是搜索框的部分属性。若果是在下载不到或者不会写的可以看我其他的博文,有介绍分类搜索功能的。

wxSearch EventHandle 键盘输入时触发,event.detail = {value, cursor, keyCode},keyCode 为键值,2.1.0 起支持,处理函数可以直接 return 一个字符串,将替换输入框的内容。
wxSerchFocus EventHandle 输入框聚焦时触发,event.detail = { value, height },height 为键盘高度,在基础库 1.9.90 起支持

附上页面样式表:

/**index.wxss**/
@import "/wxSearch/wxSearch.wxss";

.items {
  float: left;
  width: 20%;
  background-color: #fff;
}

.item-img {
  width: 100%;
  height: 50rpx;
  margin-top: 10rpx;
}

.item-text {
  width: 100%;
  height: 50rpx;
  font-size: 25rpx;
  line-height: 50rpx;
  text-align: center;
}

.map_container {
  height: 300px;
  width: 100%;
}

.map {
  height: 100%;
  width: 100%;
}
.margin-indexbottom{
  padding-bottom:150rpx;
}

如果有不理解或者想要源码的,请评论区回复。

  • 10
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 33
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 33
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值