如何通过Laravel 5中的地理位置查询?

Con*_*ech 4 php geolocation laravel eloquent laravel-5

我希望为我的"Candidate"Eloquent模型添加一个geolocation属性.我想根据他们的位置找到候选人.例如,找到距离旧金山20英里范围内的所有候选人.我的Eloquent模型应该如何将候选人的位置存储在数据库中?

如何根据候选人的位置查询候选人?我正在使用Laravel 5.3.

Jon*_*hon 5

就个人而言,我之前通过存储一组纬度和经度坐标实现了这一目标.

你可以使用一个叫做Haversine公式的东西来计算一组指定坐标和你的情况下候选集之间的"乌鸦飞行"距离.

这是一个这样的查询的例子.例如,这个计算"距离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;
Run Code Online (Sandbox Code Playgroud)

最初在这里找到.

如果您要为您的候选模型添加lat/lng,可以很容易地调整以满足您的需求.

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;
Run Code Online (Sandbox Code Playgroud)

您可以将其实现为某种查询范围,例如(未经过测试且具有最小的输入清理)

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'
    );
}
Run Code Online (Sandbox Code Playgroud)

注意:在这种情况下,3959是地球的半径(英里),公式将计算以英里为单位的距离.如果您需要距离为公里,请将3959更改为6371.感谢@Lionel在评论中指出这一点.

  • 请注意,3959是以英里为单位的地球半径.如果您需要在KM中,只需将其更改为6371(KM). (2认同)