溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

小程序開(kāi)發(fā)中如何使用定位地圖模塊

發(fā)布時(shí)間:2020-11-25 14:46:26 來(lái)源:億速云 閱讀:189 作者:Leah 欄目:開(kāi)發(fā)技術(shù)

小程序開(kāi)發(fā)中如何使用定位地圖模塊?針對(duì)這個(gè)問(wèn)題,這篇文章詳細(xì)介紹了相對(duì)應(yīng)的分析和解答,希望可以幫助更多想解決這個(gè)問(wèn)題的小伙伴找到更簡(jiǎn)單易行的方法。

1.定位系統(tǒng)使用場(chǎng)景及概述

如美團(tuán)外賣(mài)小程序

小程序開(kāi)發(fā)中如何使用定位地圖模塊

點(diǎn)定位

小程序開(kāi)發(fā)中如何使用定位地圖模塊

點(diǎn)搜索

小程序開(kāi)發(fā)中如何使用定位地圖模塊

顯而易見(jiàn),隨便一個(gè)電商小程序都需要用到定位服務(wù),那么今天我們做一個(gè)類似的定位模塊
定位模塊總覽
外部頁(yè)面

小程序開(kāi)發(fā)中如何使用定位地圖模塊

內(nèi)部頁(yè)面(下文說(shuō)的內(nèi)外部頁(yè)面就是指這兩個(gè))

小程序開(kāi)發(fā)中如何使用定位地圖模塊

好了接下來(lái)我們開(kāi)始動(dòng)手

2.定位外部模塊樣式

效果

小程序開(kāi)發(fā)中如何使用定位地圖模塊

代碼

//wxml
<view bindtap="getLocation" class="location">
 <image src="../../img/location.png"></image>
 <view>{{location}}</view>
</view>
//wxss
.location{
 font-size: 17px;
 width: 100%;
 background:rgb(196, 228, 123);
 display: flex;
 /* 對(duì)于兩個(gè)塊元素 */
 /* 垂直居中 */
 align-items: center;
 /* 水平居中 */
 justify-content: center;
}
.location image{
 width: 23px;
 height: 23px;
}

先不用管上面的{{location}},它是我們之后要從全局變量傳過(guò)來(lái)的位置信息,定位符號(hào)是用image圖片放進(jìn)去的,我們用flex布局讓圖片和文字在同一行居中顯示(見(jiàn)注釋)

3.定位模塊內(nèi)部樣式

效果

小程序開(kāi)發(fā)中如何使用定位地圖模塊

代碼(分五個(gè)小模塊,見(jiàn)注釋)

//wxml
//搜索模塊
<view class="header">
 <view class="search">
<image src="../../img/sousuo.png"></image>
 </view>
 <view class="input">
<input type="text" placeholder=" 請(qǐng)輸入你想要的內(nèi)容" placeholder-class="placeholder" bindinput="bindInput" bindfocus="bindFocus" auto-focus="{{autoFocus}}"></input>
 </view>
</view>
//定位模塊
<view class="dw">
<button size="mini" bindtap="getCity">
 <image src='../../img/location.png'></image>
 <text>定位</text>
 </button>
</view>
//當(dāng)前位置模塊
<view >當(dāng)前所在位置</view>
<button size="mini" bindtap="nowCity" class='nowcity'>{{city}}</button>
//熱門(mén)城市模塊
<view class="hotcity">熱門(mén)城市</view>
<view wx:for="{{hotcity}}" wx:key='index' class="hotcity1">
 <!-- 用了view循環(huán)之后要把view設(shè)置為inline元素,不然5個(gè)view會(huì)分成5行顯示 -->
<button size="mini" bindtap="hotCity" data-hotcityindex='{{index}}'>{{item.cityName}}</button>
</view>
//地圖模塊
<view class="map">
<map longitude="{{longitude}}" latitude="{{latitude}}" scale="14"></map>
</view>

由于我的搜索框是用了自定義組件里面的搜索組件,我是在組件的基礎(chǔ)上改出來(lái)的,原組件是這樣的

小程序開(kāi)發(fā)中如何使用定位地圖模塊

我們需要把搜索圖標(biāo)隱藏,我們直接設(shè)置它的透明度為0,然后把我們的定位文字跟圖標(biāo)通過(guò)定位直接定位到搜索框的左邊,所以樣式的代碼如下(代碼太多不好找的話可以Ctrl+F直接搜索)

//wxss
.dw{
 color:rgb(0, 0, 0);
 position: absolute;
 top: 14px;
 left: -2px;
}
.dw button{
 background: white;
 padding-right: 0;
 display: flex;
 align-items: center;
 font-weight: 600 !important;
}
.nowcity{
 font-weight: normal;
}
.dw image{
 width: 23px;
 height: 23px;
}
page{
 padding: 10px;
}
.hotcity1 button{
 margin: 10px;
 margin-bottom: 0;
 font-weight: 500 !important;
  border-radius: 10px !important;
}
.hotcity{
 margin-top: 6px;
 
}
.map_container{
 position: absolute;
 top: 0;
 bottom: 0;
 left: 0;
 right: 0;
}
.header{
 display: flex;
}
.search{
flex:1;
height: 40px;
text-align: center;
background: #fff;
}
.input{
 flex:9;
 height: 40px;
 background: #fff;
}
.input input{
 background: #f1f1f1;
height: 30px;
margin-top: 5px;
margin-bottom: 5px;
margin-right: 8px;
border-radius: 10px;
}
.search image{
 width: 70%;
 height: 25px;
 padding-top: 9px;
 padding-left: 5px;
}
.placeholder{
 font-size: 14px;
}
.search image{
 opacity: 0;
}
.input{
 flex:4;
}
.input input{
position: relative;
right: 0px;
}
.hotcity1{
 display: inline;
}
.map{
 position: relative;
}
map{
 border:5px solid green;
 text-align: center;
 margin: 10px auto;
position: relative;
right: 10px;
 width: 90%;
 height: 150px;
}

然后我們的搜索里面點(diǎn)擊搜索還會(huì)跳轉(zhuǎn)到新的搜索頁(yè)面,效果如下

小程序開(kāi)發(fā)中如何使用定位地圖模塊

這里我們可以直接復(fù)用上面的搜索組件,樣式代碼就不再貼出來(lái)了,這個(gè)模塊要將搜索自動(dòng)匹配的地點(diǎn)名稱用循環(huán)的方式顯示出來(lái),代碼如下

//wxml
<import src="../templates/search/search" />
<template is="search"></template>
<view bindtouchstart="bindSearch" data-keywords="{{i.name}}"
 class="text_box" wx:for="{{tips}}" wx:for-item="i" wx:key='index'>
 {{i.name}}
</view>
//wxss
@import '../templates/search/search.wxss';
.text_box{
 margin: 10px 25px;
 border-bottom:1px solid #c3c3c3;
 padding-bottom:10px
}

4.外部跳轉(zhuǎn)

當(dāng)我們點(diǎn)擊外部的位置信息,就跳轉(zhuǎn)到內(nèi)部的定位模塊,剛剛我們?cè)谏厦娼o外部的標(biāo)簽設(shè)置了觸摸事件getLocation,接下來(lái)只要到j(luò)s里面設(shè)置點(diǎn)擊跳轉(zhuǎn)(navigateTo)就可以了,但由于我們的位置信息是用全局變量賦值的,所以我們要在app.js設(shè)置一個(gè)全局變量,代碼如下

//app.js
App({
 globalData: {
  city:'暫未定位',
  userInfo:'無(wú)'
 },
 )}
//外部js
// 引入app.js
const app=getApp()
const appG=app.globalData
 data: {
//這里要初始化location,并將全局變量賦值給它
aboutList:'',
location:appG.city
 },
 Page({
 //定義觸摸事件
 getLocation(){
 wx.navigateTo({
 //跳轉(zhuǎn)到內(nèi)部定位頁(yè)面
  url: '../location/location',
 }) 
},
)}

5.點(diǎn)擊定位

做這個(gè)功能之前我們需要先考慮用什么地圖接口,常用的有百度地圖,騰訊地圖,高德地圖,本文選用高德地圖接口作為演示,搜索https://lbs.amap.com/,注冊(cè),進(jìn)入控制臺(tái),創(chuàng)建新應(yīng)用,

小程序開(kāi)發(fā)中如何使用定位地圖模塊

再添加key

小程序開(kāi)發(fā)中如何使用定位地圖模塊

這個(gè)key就像我們小程序調(diào)用接口時(shí)的驗(yàn)證碼,有了它我們才能從高德調(diào)取位置的數(shù)據(jù),然后我們點(diǎn)擊key后面的設(shè)置,再點(diǎn)擊微信小程序SDK

小程序開(kāi)發(fā)中如何使用定位地圖模塊

進(jìn)去之后點(diǎn)這兩個(gè),下載amap-wx.js 文件,然后在你的小程序目錄里面創(chuàng)建一個(gè)libs文件,把這個(gè)amap-wx.js扔進(jìn)去

小程序開(kāi)發(fā)中如何使用定位地圖模塊

接下來(lái)我們來(lái)到內(nèi)部定位頁(yè)面的js文件,因?yàn)檫@里要對(duì)全局變量進(jìn)行修改來(lái)達(dá)到修改頁(yè)面數(shù)據(jù)的效果,所以也要引入app.js,并把全局變量初始化到data里面,除此之外我們要引入高德的文件來(lái)實(shí)現(xiàn)高德接口的調(diào)用,在data里面我們這里順便把等會(huì)要用到的熱門(mén)城市等數(shù)據(jù)一并初始化了

const app=getApp()
const appG=app.globalData
//key里面填高德控制臺(tái)里面給你的key
const myAmapFun = new amapFile.AMapWX({key:'xxxxxxxxxx'});
 data: {
city:appG.city,
hotcity:[
 {'cityName':'北京市',longitude:'116.395645038',latitude:'39.9299857781'},
 {'cityName':'上海市',longitude:'121.487899486',latitude:'31.24916171'},
 {'cityName':'廣州市',longitude:'113.307649675',latitude:'23.1200491021'},
 {'cityName':'深圳市',longitude:'114.025973657',latitude:'22.5460535462'},
 {'cityName':'武漢市',longitude:'114.316200103',latitude:'30.5810841269'},
],
tips: {},//搜索自動(dòng)匹配的內(nèi)容
longitude:'116.4',//經(jīng)度(初始值在北京)
latitude:'39.9'//緯度(初始值在北京)
}

然后我們給定位按鈕設(shè)置點(diǎn)擊事件getCity,這里用到高德地圖里面的獲取地址描述數(shù)據(jù)方法,教程可以參考剛剛高德控制臺(tái)微信SDK里面的教程(下面搜索自動(dòng)匹配提示的教程也一樣)

小程序開(kāi)發(fā)中如何使用定位地圖模塊

此外我們我們還要在小程序后臺(tái)給高德的接口添加域名,操作步驟為
登錄微信公眾平臺(tái),“設(shè)置“–>"開(kāi)發(fā)設(shè)置"設(shè)置request合法域名,將https://restapi.amap.com 中添加進(jìn)去,這樣我們才能請(qǐng)求到高德的數(shù)據(jù)

代碼

getCity(){
 myAmapFun.getRegeo({
  success: data=>{
   // that.setData({
   //  city:data[0].desc.slice(0,2)
   // })
   appG.city=data[0].desc
   wx.getLocation({
    success:res=>{
this.setData({
  latitude:res.latitude,
  longitude:res.longitude
})
wx.setStorageSync('city', appG.city)
wx.setStorageSync('latitude', res.latitude)
wx.setStorageSync('longitude', res.longitude)
    }
   })
  },
  fail: function(info){
   //失敗回調(diào)
   console.log(info)
  }
 })
},

getRegeo方法的成功回調(diào)函數(shù)里的參數(shù)包含了定位后的位置信息(可以自己輸出一下),我們把它賦值給全局變量,然后再用setData再次把全局變量appG.city賦值給data里面的city(因?yàn)閍ppG.city已經(jīng)改變了,要重新賦值頁(yè)面才會(huì)更新),除此之外我們還要把獲取到的位置信息同步緩存起來(lái),下次進(jìn)入頁(yè)面的時(shí)候在onLoad里面先判斷有沒(méi)有緩存的數(shù)據(jù),如果有就直接使用緩存的數(shù)據(jù),沒(méi)有就用默認(rèn)值,代碼如下

onLoad: function (options) {
  // 進(jìn)頁(yè)面先看有無(wú)緩存數(shù)據(jù),如果沒(méi)有再讀默認(rèn)值,onLoad里面可以取到this.data
  const latitude=wx.getStorageSync('latitude')
  const longitude=wx.getStorageSync('longitude')
  const city=wx.getStorageSync('city')
  //用了三目運(yùn)算符,不習(xí)慣也可以使用if
  latitude&&longitude&&city&#63;
  this.setData({
   latitude:latitude,
   longitude:longitude
  }):false
 },

6.未定位時(shí)彈出定位框

給當(dāng)前位置標(biāo)簽添加點(diǎn)擊事件,判斷當(dāng)位置信息為初始值暫未定位時(shí),彈出是否定位的選擇框,當(dāng)用戶點(diǎn)擊確定時(shí),執(zhí)行一次getCity函數(shù)即可,效果如下

小程序開(kāi)發(fā)中如何使用定位地圖模塊

代碼

nowCity(){
 if(this.data.city!='暫未定位'){
  wx.switchTab({
   url: '../about/about',
  })
 }else{
  wx.showModal({
   title: '暫未定位',
   content: '現(xiàn)在要進(jìn)行定位嗎',
   success: (res)=>{
    if (res.confirm) {
     this.getCity()
    } else if (res.cancel) {
     return false
    }
   }
  })
 }
},

7.熱門(mén)城市點(diǎn)擊跳轉(zhuǎn),更新數(shù)據(jù)

小程序開(kāi)發(fā)中如何使用定位地圖模塊

當(dāng)我們點(diǎn)擊熱門(mén)城市里面的按鈕時(shí),跳轉(zhuǎn)到外部頁(yè)面,并且把對(duì)應(yīng)熱門(mén)城市名稱更新到全局的city來(lái)傳到外部頁(yè)面顯示,同時(shí)還要更新全局中的經(jīng)緯度數(shù)據(jù),對(duì)于經(jīng)緯度只要更新緩存即可,下一次進(jìn)入內(nèi)部定位頁(yè)面時(shí)再判斷緩存中有無(wú)定位數(shù)據(jù),如果有就直接用,city數(shù)據(jù)是更新+緩存,代碼如下

hotCity(e){
 const index=e.currentTarget.dataset.hotcityindex
 //更新
 appG.city=this.data.hotcity[index].cityName
 //緩存
  wx.setStorageSync('city', appG.city)
 wx.setStorageSync('latitude', this.data.hotcity[index].latitude)
 wx.setStorageSync('longitude', this.data.hotcity[index].longitude)
 //跳轉(zhuǎn)
wx.reLaunch({
 url: '../about/about',
 success:()=>{
  // 不要把數(shù)據(jù)的更新寫(xiě)在這里,要在跳轉(zhuǎn)之前就寫(xiě)好,因?yàn)檫@個(gè)回調(diào)函數(shù)是在跳轉(zhuǎn)的頁(yè)面所有函數(shù)
  // 執(zhí)行完之后才執(zhí)行的,會(huì)導(dǎo)致數(shù)據(jù)兩次跳轉(zhuǎn)次才更新
 }
})
},

上述代碼中注意要在熱門(mén)城市的循環(huán)標(biāo)簽用data-hotcityindex="{{index}}"把下標(biāo)傳到j(luò)s中,再在js中用e.currentTarget.dataset.hotcityindex去取出來(lái)用,這個(gè)下標(biāo)用來(lái)對(duì)應(yīng)熱門(mén)城市數(shù)組的每一個(gè)對(duì)象,這樣我們就可以用this.data.hotcity[index].cityName來(lái)獲取被點(diǎn)擊的城市的名稱,再把它更新到appG.city中,注意跳轉(zhuǎn)的時(shí)候不能用wx.switchTab,因?yàn)閺耐獠宽?yè)面進(jìn)來(lái)的時(shí)候已經(jīng)打開(kāi)了外部頁(yè)面,那么用wx.switchTab的時(shí)候只會(huì)執(zhí)行外部頁(yè)面的onShow函數(shù),而不會(huì)執(zhí)行onLoad,會(huì)導(dǎo)致頁(yè)面數(shù)據(jù)無(wú)法更新

8.搜索跳轉(zhuǎn)和輸入自動(dòng)匹配地名

搜索跳轉(zhuǎn)新頁(yè)面(給內(nèi)部定位頁(yè)面設(shè)置聚焦事件)

bindFocus(e){
 wx.navigateTo({
  url: '../locationSearch/locationSearch',
 })
},

注意內(nèi)部頁(yè)面的搜索框不是自動(dòng)聚焦的,而跳轉(zhuǎn)到新的搜索頁(yè)面的搜索框是會(huì)自動(dòng)聚焦的,這一點(diǎn)我們可以通過(guò)在搜索組件的input標(biāo)簽添加auto-focus="{{autoFocus}}",再控制autoFocus的值來(lái)控制是否自動(dòng)聚焦,代碼如下

<template is="search" data="{{autoFocus}}"></template>

注意data="{{xxx}}"是自定義組件特有的傳參方式,可以把js里面的值傳到組件中使用不過(guò)我們得先在搜索頁(yè)面的js的data中給autoFocus賦值,這里順便把保存自動(dòng)匹配的地名的值tips也初始化了

data: {
autoFocus:true,
tips:{}
 },

接下來(lái)我們寫(xiě)輸入自動(dòng)匹配地名,同樣在搜索頁(yè)面的js引入全局變量和高德js文件

const amapFile = require('../../libs/amap-wx.js');
const app=getApp()
const appG=app.globalData
const myAmapFun = new amapFile.AMapWX({key:'0c2c8f2007702caa7e0498d6ad072f83'});

然后我們來(lái)監(jiān)聽(tīng)用戶的輸入行為,設(shè)置為bindInput函數(shù)

<input type="text" placeholder=" 請(qǐng)輸入你想要的內(nèi)容" placeholder-class="placeholder"
 bindinput="bindInput" bindfocus="bindFocus" auto-focus="{{autoFocus}}"></input>

搜索頁(yè)面的js中定義bindInput

bindInput(e){
 myAmapFun.getInputtips({
  // keywords為必填,不然無(wú)法獲得tips,也就不會(huì)進(jìn)入success函數(shù)
  keywords:e.detail.value,
  success:data=>{
 this.setData({
  tips:data.tips
 })
  }
 })
},

上面的getInputtips就是我們第5點(diǎn)中講到的微信小程序SDK中的獲取提示詞里面的方法,可以自己去看高德的教程,此處不再贅述,上面的keywords的值就是用戶輸入的內(nèi)容,接口會(huì)根據(jù)這個(gè)去尋找對(duì)應(yīng)匹配的地名并返回在success函數(shù)的參數(shù)中,我們只需要在成功回調(diào)函數(shù)中更新tips就可以了,那么此時(shí)假如我們輸入武漢,效果如下

小程序開(kāi)發(fā)中如何使用定位地圖模塊

那么當(dāng)我們點(diǎn)擊自動(dòng)匹配的地名的時(shí)候,需要返回到外部頁(yè)面,并且更新數(shù)據(jù),更新緩存,思路和上面的跳轉(zhuǎn)方法是一樣的,代碼如下

bindSearch(e){
 const location=this.data.tips[e.currentTarget.dataset.searchindex]
 wx.setStorageSync('city', location.name)
 if(location.location.length!=0){
  const longitude=location.location.split(',')[0]
  const latitude=location.location.split(',')[1]
 wx.setStorageSync('latitude', latitude)
 wx.setStorageSync('longitude', longitude)
 wx.reLaunch({
  url: '../about/about',
   success:()=>{
       appG.city=e.currentTarget.dataset.keywords  
  }
 })
 }else{
  wx.reLaunch({
   url: '../about/about',
    success:()=>{
        appG.city=e.currentTarget.dataset.keywords  
        setTimeout(()=>{wx.showToast({
         title: '暫無(wú)經(jīng)緯度數(shù)據(jù)',
        // 提示延遲時(shí)間,不能用字符串
         duration:2000,
         icon:'none'
        })
       },500);
   }
  })
 }

由于不是每一個(gè)自動(dòng)匹配的地點(diǎn)都有經(jīng)緯度,所以我們對(duì)沒(méi)有經(jīng)緯度的地名做業(yè)務(wù)退步處理,僅提醒暫無(wú)經(jīng)緯度的數(shù)據(jù),(有時(shí)候業(yè)務(wù)退一小步,技術(shù)就有一大步的發(fā)揮空間–《大型網(wǎng)站技術(shù)架構(gòu)》——李智慧),細(xì)心的你們肯定注意到上面用了定時(shí)器,因?yàn)槿绻皇褂枚〞r(shí)器,這個(gè)彈框是不會(huì)顯示出來(lái)的,這個(gè)函數(shù)在頁(yè)面加載完成之前就已經(jīng)執(zhí)行了,所以我們給他來(lái)一個(gè)定時(shí)器作為異步函數(shù)延遲執(zhí)行,才能有彈框

9.對(duì)整個(gè)模塊的優(yōu)化和思考

對(duì)上述代碼,筆者開(kāi)發(fā)完之后發(fā)現(xiàn)了如下問(wèn)題:
代碼冗余嚴(yán)重,主要表現(xiàn)在多次使用緩存的api,重復(fù)量的地方很多
整個(gè)模塊內(nèi)部互相調(diào)用復(fù)雜,高耦合,低拓展
某些地方把簡(jiǎn)單的邏輯復(fù)雜化了,代碼不夠整潔
對(duì)于上述問(wèn)題,筆者有如下思考:
通過(guò)封裝緩存api來(lái)減少不必要的代碼量,提高代碼整潔度
對(duì)整個(gè)模塊重新構(gòu)思,提高可拓展性和可復(fù)用性(由于筆者水平有限,暫時(shí)擱置)
模塊從開(kāi)發(fā)開(kāi)始到開(kāi)發(fā)完成需要不斷的演化和改進(jìn),這個(gè)過(guò)程才是讓開(kāi)發(fā)者成長(zhǎng)的關(guān)鍵

關(guān)于小程序開(kāi)發(fā)中如何使用定位地圖模塊問(wèn)題的解答就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,如果你還有很多疑惑沒(méi)有解開(kāi),可以關(guān)注億速云行業(yè)資訊頻道了解更多相關(guān)知識(shí)。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI