2
我正在爲我的「候選人」雄辯模型添加地理位置屬性。我想根據他們的位置找到候選人。例如,找到舊金山20英里範圍內的所有候選人。我的Eloquent模型應該如何在數據庫中存儲候選人的位置?如何通過Laravel 5中的地理位置查詢?
如何根據他們的位置查詢候選人?我正在使用Laravel 5.3。
我正在爲我的「候選人」雄辯模型添加地理位置屬性。我想根據他們的位置找到候選人。例如,找到舊金山20英里範圍內的所有候選人。我的Eloquent模型應該如何在數據庫中存儲候選人的位置?如何通過Laravel 5中的地理位置查詢?
如何根據他們的位置查詢候選人?我正在使用Laravel 5.3。
就我個人而言,我之前通過存儲一組經緯度座標來實現此目的。
你可以使用一種叫做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在評論中指出了這一點。
請注意,3959是以英里爲單位的地球半徑。如果您在KM中需要它,只需將其更改爲6371(KM)。 –
好有意思。這似乎很深奧,但看起來這是做到這一點的最佳方式!必須製作一些SQL語句。谷歌地圖有一個教程,他們也寫了一個類似的SQL查詢:https://developers.google.com/maps/articles/phpsqlsearch_v3謝謝 –
是的,谷歌地圖教程是我最初發現的Haversine的SQL版本公式:)沒問題。 – Jonathon