2016-12-28 24 views
2

我正在爲我的「候選人」雄辯模型添加地理位置屬性。我想根據他們的位置找到候選人。例如,找到舊金山20英里範圍內的所有候選人。我的Eloquent模型應該如何在數據庫中存儲候選人的位置?如何通過Laravel 5中的地理位置查詢?

如何根據他們的位置查詢候選人?我正在使用Laravel 5.3。

回答

4

就我個人而言,我之前通過存儲一組經緯度座標來實現此目的。

你可以使用一種叫做Haversine formula的東西來計算一組指定座標之間的「作爲烏鴉」距離,在你的情況下是一組候選。

下面是這樣一個查詢的例子。例如,這個計算「距離37,-122座標25英里半徑內最近的20個位置」。

SELECT id, (3959 * acos(cos(radians(37)) * cos(radians(lat)) 
* cos(radians(lng) - radians(-122)) + sin(radians(37)) * sin(radians(lat)))) AS distance 
FROM markers 
HAVING distance < 25 
ORDER BY distance 
LIMIT 0 , 20; 

最初發現here

如果您要將lat/lng添加到Candidate模型中,可以很容易地根據您的需要對其進行調整。

SELECT *, (3959 * acos(cos(radians(37)) * cos(radians(lat)) 
* cos(radians(lng) - radians(-122)) + sin(radians(37)) * sin(radians(lat)))) AS distance 
FROM candidates 
ORDER BY distance 
LIMIT 0, 20; 

你或許可以實現這個作爲某種查詢範圍,例如, (未測試和具有最小的輸入清理)

public function scopeClosestTo($query, $lat, $lng) 
{ 
    return $query->orderByRaw(
     '(3959 * acos(cos(radians(' . floatval($lat) . ')) * cos(radians(lat)) * cos(radians(lng) - radians(' . floatval($lng) . ')) + sin(radians(' . intval($lat) . ')) * sin(radians(lat)))) ASC' 
    ); 
} 

注: 3959在這種情況下是地球的以英里半徑和式將計算以英里的距離。如果您需要距離爲公里,請將3959更改爲6371.感謝@Lionel在評論中指出了這一點。

+2

請注意,3959是以英里爲單位的地球半徑。如果您在KM中需要它,只需將其更改爲6371(KM)。 –

+0

好有意思。這似乎很深奧,但看起來這是做到這一點的最佳方式!必須製作一些SQL語句。谷歌地圖有一個教程,他們也寫了一個類似的SQL查詢:https://developers.google.com/maps/articles/phpsqlsearch_v3謝謝 –

+0

是的,谷歌地圖教程是我最初發現的Haversine的SQL版本公式:)沒問題。 – Jonathon