全面解析小程序之百度地图附近三公里信息检索

##本片博客主要介绍的是小程序利用百度地图搜索附近三公里信息

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

惯例,先上整体效果图:
这里写图片描述
这是点击药店,搜索附近20个药店信息。
这里写图片描述
可以打印出20个药店的信息数据,自己可根据实际情况展示。
这里写图片描述
搜索附近营业厅信息。同样是打印20个。
这里写图片描述

以上只是两个例子,列表中的10个信息都是可以检索的。点击任意一个块都能准确搜出你附近的地点信息。

##下面介绍主要方法步骤:
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信息检索默认是输出地点的,但是这并不是我们想要的结果。我们需要根据需求,设计自己想要的检索功能,诸如这样的:
这里写图片描述
点击各个模块,搜索对应的信息;你也可以来个更简洁的放个搜索输入框,让用户自己来输入搜索。不过,我坚信用户更倾向于点击搜索,这样更一目了然,不是吗。

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

<template name="wxSearch">
  <view class="wxSearch" bindtap="wxSearchTap"  style="display:{{wxSearchData.view.isShow ? 'block':'none'}};height:{{wxSearchData.view.seachHeight}}px;top:{{wxSearchData.view.barHeight}}px;">
    <view  class="wxSearchInner">
        <view class="wxSearchMindKey">
            <view class="wxSearchMindKeyList">
                <block wx:for="{{wxSearchData.mindKeys}}" wx:key='' >
                    <view class="wxSearchMindKeyItem" bindtap="wxSearchKeyTap" data-key="{{item}}">{{item}}</view>
                </block>
            </view>
        </view>
    </view>
  </view>
</template>

对,不需要多么的华丽,只要放入一个简单的搜索模块调起即可,因为我们要用的是点击搜索,所以这块可以省略不写。
那就剩下wxSearch.js最重要了对不对。wxSearchTap和wxSearchData这些内容我们都必须在JS中有方法写进,毕竟是要用到的。
wxSearch.js:

// 定义数据格式

/***
 * 
 * "wxSearchData":{
 *  configconfig:{
 *    style: "wxSearchNormal"
 *  },
 *  view:{
 *    hidden: true,
 *    searchbarHeght: 20
 *  }
 *  keys:[],//自定义热门搜索
 *  his:[]//历史搜索关键字
 *  value
 * }
 * 
 * 
 */
var __keysColor = [];

var __mindKeys = [];

function initColors(colors){
    __keysColor = colors;
}

function initMindKeys(keys){
    __mindKeys = keys;
}

function init(that, barHeight, keys, isShowKey, isShowHis, callBack) {
    var temData = {};
    var view = {
        barHeight: barHeight,
        isShow: false
    }
    
    if(typeof(isShowKey) == 'undefined'){
        view.isShowSearchKey = true;
    }else{
        view.isShowSearchKey = isShowKey;
    }

    if(typeof(isShowHis) == 'undefined'){
        view.isShowSearchHistory = true;
    }else{
        view.isShowSearchHistory = isShowHis;
    }
    temData.keys = keys;
    wx.getSystemInfo({
        success: function(res) {
            var wHeight = res.windowHeight;
            view.seachHeight = wHeight-barHeight;
            temData.view = view;
            that.setData({
                wxSearchData: temData
            });
        }
    })
    
    if (typeof (callBack) == "function") {
        callBack();
    }
    
    getHisKeys(that);
}

function wxSearchInput(e, that, callBack){
    var temData = that.data.wxSearchData;
    var text = e.detail.value;
    var mindKeys = [];
    if(typeof(text) == "undefined" || text.length == 0){
        
    }else{
        for(var i = 0; i < __mindKeys.length; i++){
            var mindKey = __mindKeys[i];
            if(mindKey.indexOf(text) > -1){
                mindKeys.push(mindKey);
            }
        }
    }
    temData.value = text;
    temData.mindKeys = mindKeys;
    that.setData({
        wxSearchData: temData
    });
}

function wxSearchFocus(e, that, callBack) {
    var temData = that.data.wxSearchData;
    temData.view.isShow = true;
    that.setData({
        wxSearchData: temData
    });
    //回调
    if (typeof (callBack) == "function") {
        callBack();
    }
    // if(typeof(temData) != "undefined"){
    //   temData.view.hidden= false;
    //   that.setData({
    //     wxSearchData:temData
    //   });
    // }else{

    // }
}
function wxSearchBlur(e, that, callBack) {
    var temData = that.data.wxSearchData;
    temData.value = e.detail.value;
    that.setData({
        wxSearchData: temData
    });
    if (typeof (callBack) == "function") {
        callBack();
    }
}

function wxSearchHiddenPancel(that){
    var temData = that.data.wxSearchData;
    temData.view.isShow = false;
    that.setData({
        wxSearchData: temData
    });
}

function wxSearchKeyTap(e, that, callBack) {
    //回调
    var temData = that.data.wxSearchData;
    temData.value = e.target.dataset.key;
    that.setData({
        wxSearchData: temData
    });
    if (typeof (callBack) == "function") {
        callBack();
    }
}
function getHisKeys(that) {
    var value = [];
    try {
        value = wx.getStorageSync('wxSearchHisKeys')
        if (value) {
            // Do something with return value
            var temData = that.data.wxSearchData;
            temData.his = value;
            that.setData({
                wxSearchData: temData
            });
        }
    } catch (e) {
        // Do something when catch error
    }
    
}
function wxSearchAddHisKey(that) {
    wxSearchHiddenPancel(that);
    var text = that.data.wxSearchData.value;
    if(typeof(text) == "undefined" || text.length == 0){return;}
    var value = wx.getStorageSync('wxSearchHisKeys');
    if(value){
        if(value.indexOf(text) < 0){
            value.unshift(text);
        }
        wx.setStorage({
            key:"wxSearchHisKeys",
            data:value,
            success: function(){
                getHisKeys(that);
            }
        })
    }else{
        value = [];
        value.push(text);
        wx.setStorage({
            key:"wxSearchHisKeys",
            data:value,
            success: function(){
                getHisKeys(that);
            }
        })
    }
    
    
}
function wxSearchDeleteKey(e,that) {
    var text = e.target.dataset.key;
    var value = wx.getStorageSync('wxSearchHisKeys');
    value.splice(value.indexOf(text),1);
    wx.setStorage({
        key:"wxSearchHisKeys",
        data:value,
        success: function(){
            getHisKeys(that);
        }
    })
}
function wxSearchDeleteAll(that){
    wx.removeStorage({
        key: 'wxSearchHisKeys',
        success: function(res) {
            var value = [];
            var temData = that.data.wxSearchData;
            temData.his = value;
            that.setData({
                wxSearchData: temData
            });
        } 
    })
}



module.exports = {
    init: init,
    initColor: initColors,
    initMindKeys: initMindKeys,
    wxSearchInput: wxSearchInput,
    wxSearchFocus: wxSearchFocus,
    wxSearchBlur: wxSearchBlur,
    wxSearchKeyTap: wxSearchKeyTap,
    wxSearchAddHisKey:wxSearchAddHisKey,
    wxSearchDeleteKey:wxSearchDeleteKey,
    wxSearchDeleteAll:wxSearchDeleteAll,
    wxSearchHiddenPancel:wxSearchHiddenPancel
}

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

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

<!--index.wxml-->
<view class='banner'> 
    <image src="../../image/banner.png"></image>
</view>

<!--nearby.wxml-->
<scroll-view class="sv" scroll-y="true">
    <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=" place_info"> 
      <view><text>{{placeData.title}}</text></view>
      <view><text>{{placeData.address}}</text> </view>
      <view><text>{{placeData.telephone}}</text></view>
    </view> 
    <!-- 测试地图选点如下 -->
    <view class="data">
      <view class="data-title"><text >{{title}}</text></view>
        <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>   
    </view>
  </scroll-view>
  <!-- 导航 -->
 

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

当然我们也要输出地图选点后的信息结果:

<view class=" place_info"> 
 <view><text>{{placeData.title}}</text></view>
  <view><text>{{placeData.address}}</text> </view>
  <view><text>{{placeData.telephone}}</text></view>
</view> 

地点的商户名称,地址信息,商家电话。商家电话不是每个地点都会有的,有的商家未填写,所以我们在JS中进行区分。

那么在JS中是什么样子呢?
下面,写JS内容:

//index.js
//获取应用实例
var app = getApp()
var count = 10;
var total = 0;
var code = "2";
var bmap = require('../../utils/bmap-wx.min.js');
var wxMarkerData = [];
var WxSearch = require('../../wxSearch/wxSearch.js');
Page({
  data: {
    title: "附近三公里",
    indicatorDots: true,
    vertical: false,
    autoplay: true,
    interval: 3000,
    duration: 1000,
    markers: [],
    latitude: '',
    longitude: '',
    rgcData: {},
    telephone: {},
    test: '', 
    loadingHidden: false,  // loading
    array: [{
      code: '1',
      id: 'icon_1',
      src: '../../image/img1.png',
      text: '家政'
    }, {
      code: '2',
      id: 'icon_2',
      src: '../../image/img2.png',
      text: '药店'
    }, {
      code: '3',
      id: 'icon_3',
      src: '../../image/img3.png',
      text: '银行'
    }, {
      code: '4',
      id: 'icon_4',
      src: '../../image/img4.png',
      text: '维修'
    }, {
      code: '5',
      id: 'icon_5',
      src: '../../image/img5.png',
      text: '公厕'
    }, {
      code: '6',
      id: 'icon_6',
      src: '../../image/img6.png',
      text: '医院'
    }, {
      code: '7',
      id: 'icon_7',
      src: '../../image/img7.png',
      text: '加油站'
    }, {
      code: '8',
      id: 'icon_8',
      src: '../../image/img8.png',
      text: '美食'
    }, {
      code: '9',
      id: 'icon_9',
      src: '../../image/img9.png',
      text: '营业厅'
    }, {
      code: '10',
      id: 'icon_10',
      src: '../../image/img10.png',
      text: '停车场'
    }],
    dataArray: []
  },

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

    // 发起POI检索请求 
    BMap.search({
      "query": "",
      fail: fail,
      success: success,
      // 此处需要在相应路径放置图片文件 
      iconPath: '../../image/marker_red.png',
      // 此处需要在相应路径放置图片文件 
      iconTapPath: '../../image/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: '个人ak'
    });
    
    var fail = function (data) {
      console.log(data)
    };
    var success = function (data) {
      wxMarkerData = data.wxMarkerData;
      that.setData({
        markers: wxMarkerData
      }); that.setData({
        latitude: wxMarkerData[0].latitude
      });
      that.setData({
        longitude: wxMarkerData[0].longitude
      })
     
    };
    // 发起POI检索请求 
    console.log("当前点击", name)
    BMap.search({
      query: name,
      fail: fail,
      success: success,
      // 此处需要在相应路径放置图片文件 
      iconPath: '../../image/marker_red.png',
      // 此处需要在相应路径放置图片文件 
      iconTapPath: '../../image/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)
    var that = this;
    var Otitle = data[i].title;
    var Oaddress =data[i].address;
    var Otel = data[i].telephone;
    if (Otel == "" || Otel == undefined){
      that.setData({
        placeData: {
          title: '名称:' + Otitle + '\n',
          address: '地址:' + Oaddress + '\n',
          telephone: '电话:' + "商家暂未登记"

        }
      });
    }else{
      that.setData({
        placeData: {
          title: '名称:' + Otitle + '\n',
          address: '地址:' + Oaddress + '\n',
          telephone: '电话:' + Otel

        }
      });
    }
    
  },
  changeMarkerColor: function (data, i) {
    var that = this;
    var markers = [];
    for (var j = 0; j < data.length; j++) {
      if (j == i) {
        // 此处需要在相应路径放置图片文件 
        data[j].iconPath = "../../image/marker_yellow.png";
      } else {
        // 此处需要在相应路径放置图片文件 
        data[j].iconPath = "../../image/marker_red.png";
      }
      markers[j](data[j]);
    }
    that.setData({
      markers: markers
    });
  }
})

这里我们主要就是引入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 起支持

对点击结果进行展示:

var that = this;
    var Otitle = data[i].title;
    var Oaddress =data[i].address;
    var Otel = data[i].telephone;
    if (Otel == "" || Otel == undefined){
      that.setData({
        placeData: {
          title: '名称:' + Otitle + '\n',
          address: '地址:' + Oaddress + '\n',
          telephone: '电话:' + "商家暂未登记"

        }
      });
    }else{
      that.setData({
        placeData: {
          title: '名称:' + Otitle + '\n',
          address: '地址:' + Oaddress + '\n',
          telephone: '电话:' + Otel

        }
      });
    }

如果电话号码为空或者undefined则直接输出商家电话未展示,否则就输出原内容。

##最后结果展示
这里写图片描述
由于样式表个人喜好不同,所以不做展示了。页面非常简单,祝各位开发愉快。

如果有不明之处,请评论区回复。
在这里插入图片描述在这里插入图片描述

posted @ 2018-08-01 10:08  沉默的小猴子  阅读(2297)  评论(0编辑  收藏  举报