如何用口才来查询两个坐标之间的距离 [英] How to query distances between two coordinates with Eloquent
问题描述
我知道这个问题已经问了很多遍了.但是我没有想到要根据自己的需要来做.
I know this has been ask many times. But I didn't figure out to make it according to my needs.
我需要从另一个用户那里查询最近的用户.基本上,我有一个 users
表,该表与 users_locations
表具有一对一
关系,该表具有纬度和经度字段.
I need to query the nearest users from another user.
Basically, I have a users
table this table has a one to one
relation with the users_locations
table which has a latitude and a longitude field.
所以我看过了 https://laravel.io/forum/04-23-2014-convert-this-geolocation-query-to-query-builder-for?page=1 这可能是最好的解决方案.
So I've seen this https://laravel.io/forum/04-23-2014-convert-this-geolocation-query-to-query-builder-for?page=1 and this may be the best solution.
但是我的基本查询是:
\App\Model\User::whereNotIn('id', $ids)
->where('status', 1)
->whereHas('user_location', function($q) use ($lat, $lng, $radius) {
/** This is where I'm stuck to write the query **/
})->select('id', 'firstname')
->get();
在这种情况下,我不知道如何实施该解决方案.
I don't figure out how to implement the solution in this case.
预先感谢您的帮助
编辑更清楚地说:我需要获得半径为5公里的用户.
EDIT To be more clear: I need to get the users that are in a 5 kilometers radius.
推荐答案
感谢EddyTheDove和Ohgodwhy,我找到了解决方案.
I found the solution, thanks to EddyTheDove and Ohgodwhy.
就这样:
\App\Model\User::whereNotIn('id', $ids)
->where('status', 1)
->whereHas('user_location', function($q) use ($radius, $coordinates) {
$q->isWithinMaxDistance($coordinates, $radius);
})->select('id', 'firstname')
->get();
在我的 UserLocation
模型中,我具有此本地范围
And in my UserLocation
Model I have this local scope
public function scopeIsWithinMaxDistance($query, $coordinates, $radius = 5) {
$haversine = "(6371 * acos(cos(radians(" . $coordinates['latitude'] . "))
* cos(radians(`latitude`))
* cos(radians(`longitude`)
- radians(" . $coordinates['longitude'] . "))
+ sin(radians(" . $coordinates['latitude'] . "))
* sin(radians(`latitude`))))";
return $query->select('id', 'users_id', 'cities_id')
->selectRaw("{$haversine} AS distance")
->whereRaw("{$haversine} < ?", [$radius]);
}
Ohgodwhy的原始答案在这里:在Laravel中两点之间的Haversine距离计算
The original answer by Ohgodwhy is here: Haversine distance calculation between two points in Laravel
编辑
使用MySQL中存储的函数执行此操作的另一种方法:
Another way to perform it with stored functions in MySQL:
DELIMITER $$
DROP FUNCTION IF EXISTS haversine$$
CREATE FUNCTION haversine(
lat1 FLOAT, lon1 FLOAT,
lat2 FLOAT, lon2 FLOAT
) RETURNS FLOAT
NO SQL DETERMINISTIC
COMMENT 'Returns the distance in degrees on the Earth
between two known points of latitude and longitude'
BEGIN
RETURN DEGREES(ACOS(
COS(RADIANS(lat1)) *
COS(RADIANS(lat2)) *
COS(RADIANS(lon2) - RADIANS(lon1)) +
SIN(RADIANS(lat1)) * SIN(RADIANS(lat2))
));
END$$
DELIMITER ;
我乘以111.045,将结果转换为km.(我不确定该值是否正确,我发现许多其他值与该值相距不远,因此,如果有人对此有精确度,可能会很好)
I multiply by 111.045 to convert the result in km. (I'm not sure that this value is right, I found many others values not far from this one so if someone have precision about it, it could be nice)
原始文章: https://www.plumislandmedia.net/mysql/stored-function-haversine-distance-computation/
然后用雄辩的话:
\App\Model\User::whereNotIn('id', $ids)
->where('status', 1)
->whereHas('user_location', function($q) use ($radius, $coordinates) {
$q->whereRaw("111.045*haversine(latitude, longitude, '{$coordinates['latitude']}', '{$coordinates['longitude']}') <= " . $radius]);
})->select('id', 'firstname')
->get();
这篇关于如何用口才来查询两个坐标之间的距离的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!