當(dāng)前位置:首頁 > IT技術(shù) > 微信平臺 > 正文

基于微信地理位置的附近商家距離坐標(biāo)數(shù)據(jù)查詢方法
2021-08-04 17:44:34

要解決的問題:

1.通過微信公眾平臺獲取用戶地理位置(也就是坐標(biāo)啦,精度和緯度)

2.獲取到地理位置后,記錄用戶的坐標(biāo)

3.計(jì)算出當(dāng)前的用戶坐標(biāo)和數(shù)據(jù)表里商戶的坐標(biāo)的距離

4.距離排序與距離的用戶體驗(yàn)顯示

好吧,現(xiàn)在我們開始具體的細(xì)節(jié)問題解決

?

1.通過微信公眾平臺獲取用戶地理位置

通過微信獲取用戶地理位置有兩種方式

方式a:此方式必須是服務(wù)號,用戶進(jìn)入微信公眾號的時(shí)候,會(huì)向微信服務(wù)端推送關(guān)于用戶的相關(guān)信息,如果你設(shè)置了微信開發(fā)者模式,那么這些信息能接收到用戶的相關(guān)信息

用戶同意上報(bào)地理位置后,每次進(jìn)入公眾號會(huì)話時(shí),都會(huì)在進(jìn)入時(shí)上報(bào)地理位置,上報(bào)地理位置以推送XML數(shù)據(jù)包到開發(fā)者填寫的URL來實(shí)現(xiàn)。

通過這種方式,我們的服務(wù)端接收到的信息格式是這樣的

提示:只有服務(wù)號才能獲取用戶地理位置,并且服務(wù)號經(jīng)過認(rèn)證,并且需要在開發(fā)者的接口權(quán)限中去【開啟】

<xml>
<ToUserName><![CDATA[gh_f6bce85ce621]]></ToUserName> 
<FromUserName><![CDATA[obxLljpChQwixH0mAZYR1ESeWv3Y]]></FromUserName> 
<CreateTime>1460636400</CreateTime> 
<MsgType><![CDATA[event]]></MsgType> 
<Event><![CDATA[LOCATION]]></Event> 
<Latitude>30.660822</Latitude>
<Longitude>104.066566</Longitude> <Precision>65.000000</Precision> </xml>

?

可以看到其中有元素Latitude和Longitude,獲取到了坐標(biāo)就好說啦

?

方式b:用戶訪問我們的微網(wǎng)站的時(shí)候,通過微信的JS-SDK模式獲取用戶的地理位置(服務(wù)號訂閱號都可以)

什么是JS-SDK呢?

微信JS-SDK是微信公眾平臺面向網(wǎng)頁開發(fā)者提供的基于微信內(nèi)的網(wǎng)頁開發(fā)工具包。
微信官方描述:通過使用微信JS-SDK,網(wǎng)頁開發(fā)者可借助微信高效地使用拍照、選圖、語音、位置等手機(jī)系統(tǒng)的能力,同時(shí)可以直接使用微信分享、掃一掃、卡券、支付等微信特有的能力,為微信用戶提供更優(yōu)質(zhì)的網(wǎng)頁體驗(yàn)

這種方式獲取到用戶坐標(biāo)是基于網(wǎng)頁的形式獲得的,所以用戶的地理位置坐標(biāo)需要通過異步的模式存儲(chǔ)到你自己的系統(tǒng)中

這個(gè)是通過JS-SDK的部分代碼

wx.getLocation({ 
  type: "wgs84", // 默認(rèn)為wgs84的gps坐標(biāo),如果要返回直接給openLocation用的火星坐標(biāo),可傳入&#39;gcj02&#39;
  success: function (res) {
    var latitude = res.latitude; // 緯度,浮點(diǎn)數(shù),范圍為90 ~ -90
    var longitude = res.longitude; // 經(jīng)度,浮點(diǎn)數(shù),范圍為180 ~ -180。
    var speed = res.speed; // 速度,以米/每秒計(jì)
    var accuracy = res.accuracy; // 位置精度
   }
})

?

2.獲取到地理位置后,記錄用戶的坐標(biāo)

用戶的坐標(biāo)獲取到后,自行記錄到你的系統(tǒng)里,通過緩存也好,session也好,cookie也好,還是數(shù)據(jù)表也好隨便你

?

3.計(jì)算出當(dāng)前的用戶坐標(biāo)和數(shù)據(jù)表里商戶的坐標(biāo)的距離

我們目前來個(gè)假設(shè)一個(gè)獲取到坐標(biāo)

例如我的坐標(biāo)是:30.664385188806,104.07559730274

表名:merchants

表字段:itemid,title,hits,lat,lng lat是經(jīng)度 lat是緯度

基于微信地理位置的附近商家距離坐標(biāo)數(shù)據(jù)查詢方法_基于LBS定位

?

?

通過SQL語句的運(yùn)算把距離和排序一次性解決。

mysql函數(shù)計(jì)算坐標(biāo)距離

其中30.664385188806是你的經(jīng)度,104.07559730274是你的緯度

以下SQL語句是全部查詢并運(yùn)算出坐標(biāo)的的語句

select itemid,title,hits,telephone,ROUND(6378.138*2*ASIN(SQRT(POW(SIN((30.664385188806*PI()/180-lat*PI()/180)/2),2)+COS(30.664385188806*PI()/180)*COS(lat*PI()/180)*POW(SIN((104.07559730274*PI()/180-lng*PI()/180)/2),2)))*1000) AS distance from merchants order by distance

通過如下方式的SQL運(yùn)行就可查詢出相應(yīng)的距離+排序+多少公里范圍的條件檢索

下面的檢索出5公里范圍的語句

select * from (select itemid,title,hits,telephone, ROUND(6378.138*2*ASIN(SQRT(POW(SIN((30.664385188806*PI()/180-lat*PI()/180)/2),2)+COS(30.664385188806*PI()/180)*COS(lat*PI()/180)*POW(SIN((104.07559730274*PI()/180-lng*PI()/180)/2),2)))*1000) AS distance from merchants order by distance ) as a where a.distance<=5000

查詢結(jié)果見下圖

?基于微信地理位置的附近商家距離坐標(biāo)數(shù)據(jù)查詢方法_基于LBS定位_02

?

4.距離排序與距離的用戶體驗(yàn)顯示

查詢計(jì)算出的distance是數(shù)字,需要顯示的用戶體驗(yàn)更好一點(diǎn)

例如:我和這個(gè)商家的精確距離是1290米,因?yàn)榫鹊脑?,其?shí)精確距離其實(shí)偏差非常大,不能顯示一個(gè)具體的數(shù)字 ,所以要優(yōu)化顯示為1.3公里或者1.5公里內(nèi)的模式更好

我自用的方法是這樣的

A方式

//輸入distance,然后對數(shù)字做優(yōu)化顯示 
?
function mToKm($number){
 if(!is_numeric($number)) 
    return ""; 
    switch ($number){ 
case $number>1800&&$number<=2000: 
$v="2"; break; 
case $number>1500&&$number<=1800: 
$v="1.8"; break; 
case $number>1200&&$number<=1500: 
$v="1.5"; break; 
case $number>1000&&$number<=1200: 
$v="1.2"; break; 
case $number>900&&$number<=1000: 
$v="1"; break; 
default: $v=ceil($number/100)*100; break;  
}  
 if($v<100){ 
$v= "距離我【".$v."】千米內(nèi)。";
} else{ 
$v= "距離我【".$v."】米內(nèi)。"; 
}
 return $v;  
}
?

?

?

?



B方式

function distanceDesc($number){
 if(!is_numeric($number))
 return "";
 switch ($number){
 case $number>3000&&$number<=5000: $v="5"; break; 
case $number>2000&&$number<=3000: $v="3"; break;
 case $number>1000&&$number<=2000: $v="2"; break;
 case $number>500&&$number<=1000: $v="1"; break;
 case $number<=500: $v="0.5"; break; default: $v=ceil($number/1000); break; } 
if($number<=300) {
 $distance = "【500米內(nèi)】";
 }else{ 
$distance = "【".$v."千米內(nèi)】"; 
}
 return $distance; 
 }

?













?
?
?
?

本文摘自 :https://blog.51cto.com/u

開通會(huì)員,享受整站包年服務(wù)立即開通 >