##本片博客主要介紹的是小程序利用百度地圖搜索附近三公里信息
開篇先提一下,網上有很多關於小程序搜索框的,地圖地點信息檢索的,路線導航的,以及一個找事吧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.init和WxSearch.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則直接輸出商家電話未展示,否則就輸出原內容。
##最后結果展示

由於樣式表個人喜好不同,所以不做展示了。頁面非常簡單,祝各位開發愉快。
如果有不明之處,請評論區回復。


