LBS地理位置距離計算方法之geohash算法


隨着移動終端的普及,很多應用都基於LBS功能,附近的某某(餐館、銀行、妹紙等等)。
基礎數據中,一般保存了目標位置的經緯度;利用用戶提供的經緯度,進行對比,從而獲得是否在附近。這里需要在設置出一個字段,是關於編碼的字段,一會看下文哈……


地理位置距離實現目標:
查找附近多少公里內的人或者商家

比如:微信、陌陌、美團、基於O2O的一些APP這些應用或者移動網頁都需要用到地理位置計算

目前來說:移動地理位置距離計算比較好的算法是geohash,特此整理分享。

 

geohash有以下幾個特點:

第一:geohash用一個字符串表示經度和緯度兩個坐標。

某些情況下無法在兩列上同時應用索引 (例如MySQL 4之前的版本,Google App Engine的數據層等),利用geohash,只需在一列上應用索引即可。

(這里插一句:我們的mysql為字段創建的索引,其實原理就是利用二分法算法來做路徑查詢簡化,快速查找出想要的字段位置)

第二:geohash表示的並不是一個點,而是一個矩形區域。比如編碼wx4g0ec19,它表示的是一個矩形區域。

使用者可以發布地址編碼,既能表明自己位於北海公園附近,又不至於暴露自己的精確坐標,有助於隱私保護。

第三:編碼的前綴可以表示更大的區域。


例如wx4g0ec1,它的前綴wx4g0e表示包含編碼wx4g0ec1在內的更大范圍。 這個特性可以用於附近地點搜索。首先根據用戶當前坐標計算geohash(例如wx4g0ec1)然后取其前綴進行查詢 (SELECT * FROM place WHERE geohash LIKE 'wx4g0e%'),即可查詢附近的所有地點。

Geohash比直接用經緯度的高效很多。

 

Geohash的原理

Geohash的最簡單的解釋就是:將一個經緯度信息,轉換成一個可以排序,可以比較的字符串編碼

 

geohash能做到:

require_once('geohash.class.php');
$geohash = new Geohash;
//得到這點的hash值
$hash = $geohash->encode(39.98123848, 116.30683690);
//取前綴,前綴約長范圍越小
$prefix = substr($hash, 0, 6);
//取出相鄰八個區域
$neighbors = $geohash->neighbors($prefix);
array_push($neighbors, $prefix);

print_r($neighbors);
  • 得到9個geohash值
//得到9個geohash值

Array
(
  [top] => wx4eqx
  [bottom] => wx4eqt
  [right] => wx4eqy
  [left] => wx4eqq
  [topleft] => wx4eqr
  [topright] => wx4eqz
  [bottomright] => wx4eqv
  [bottomleft] => wx4eqm
  [0] => wx4eqw
)

  

  • 范圍如圖:
  • 用sql語句查詢
  • SELECT * FROM xy WHERE geohash LIKE 'wx4eqw%';
    SELECT * FROM xy WHERE geohash LIKE 'wx4eqx%';
    SELECT * FROM xy WHERE geohash LIKE 'wx4eqt%';
    SELECT * FROM xy WHERE geohash LIKE 'wx4eqy%';
    SELECT * FROM xy WHERE geohash LIKE 'wx4eqq%';
    SELECT * FROM xy WHERE geohash LIKE 'wx4eqr%';
    SELECT * FROM xy WHERE geohash LIKE 'wx4eqz%';
    SELECT * FROM xy WHERE geohash LIKE 'wx4eqv%';
    SELECT * FROM xy WHERE geohash LIKE 'wx4eqm%';
    
  • 看一下是否用上索引 (一共有50多萬行測試數據):
  • 索引:




其他資料:

- geohash演示: http://openlocation.org/geohash/geohash-js/

- wiki: http://en.wikipedia.org/wiki/Geohash

- 原理: https://github.com/CloudSide/geohash/wiki

 

 

移動端地理算法探討 交流QQ: 187395037 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM