基於LBS的地理位置附近的搜索以及由近及遠的排序


Nosql學習之Redis資料(一)php

http://redis.io/downloadhtml

 

目前基於LBS地理位置的搜索已經應用很是廣了,的確是個很方便的東西。html5

咱們作程序的就是要考慮如何經過這些功能,來作出更符合用戶的內容來。git

1,如何獲取位置

例如微信,能夠經過發送地理位置來獲取到當前用戶的經緯度。查看redis

在網頁端,可使用html5獲取地理定位。查看sql

2,數據表設計

數據庫中要預存本身的位置數據,如何獲取數據請查看相關地圖api。數據庫

字段:十進制數的緯度 latitude FLOAT(10,6) 十進制數的經度 longitude FLOAT(10,6)api

假設咱們數據庫中已經存儲大量酒店的位置信息緩存

3,根據用戶位置查詢附近

如上圖,假設當前用戶所在的位置爲座標O,那麼咱們要查詢附近的酒店,理想的範圍應該是以O爲原點的圓內,可是咱們先不這樣作,後面會講到。微信

咱們先以O爲原點,在座標上以0.3的差值標識了4個位置,其實這樣就是一個正方形範圍,大體應該符合咱們的要求。

那麼咱們就要從數據庫中查詢範圍在這個正方形以內的全部酒店了。

一,獲取到用戶的經緯度座標:

$latitude;$longitude

  

二,定義一個差值,設置經度和緯度的範圍:

$i = 0.3; //差值可自定義,值越大,範圍就越大
$min_latitude = $latitude - $i; //緯度最小值
$max_latitude = $latitude + $i; //緯度最大值
$min_longitude = $longitude - $i; //經度最小值
$max_longitude = $longitude + $i; //經度最大值

  

三,數據庫中查詢在這個範圍以內的酒店:

SELECT * FROM table WHERE (latitude BETWEEN $min_latitude AND $max_latitude) AND (longitude BETWEEN $min_longitude AND $max_longitude);

  

這樣咱們的附近搜索基本完成了

四,以地理位置由遠及近的排序:

若是咱們要篩選出最近的10個的話,用上面的語句來查詢,可能會把稍遠的先查出來,後面的就沒有機會了,那麼咱們得作個排序了。

如上圖,若是咱們要獲取E位置和F位置分別距離O點的長度,那麼咱們就須要計算OE和OF的長度分別爲多少,這裏咱們要用到直角三角形的數學公式:C^2 = A^2 + B^2,知道A和B,那麼C的值也就獲得了。

注意:請首先在表中創建一個字段d,以做後面緩存距離使用,不然會報錯

咱們能夠根據經緯度的差分別來獲取到A和B的值,SQL語句是這樣的:

SELECT *,SQRT(POWER($latitude - latitude, 2) + POWER($longitude  - longitude, 2)) AS d FROM table WHERE (latitude BETWEEN $min_latitude AND $max_latitude) AND (longitude BETWEEN $min_longitude AND $max_longitude) AND d < $i ORDER BY d ASC LIMIT 10;

  

SQRT(X):求X的平方根,POWER(X, Y):求X的Y次方

經過這樣一步,咱們的範圍已經鎖定在圓形以內了,而且按照由近及遠的方式進行排序(在不考慮效率的狀況下)。

相關文章
相關標籤/搜索