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