如何获取附近的用户和距离?
Posted
技术标签:
【中文标题】如何获取附近的用户和距离?【英文标题】:How to get nearby users and distances? 【发布时间】:2018-09-05 12:17:47 【问题描述】:首先我想向您展示当前的数据库结构。有两个表:
用户
身份证 姓名 location_id位置
身份证 城市 纬度 lng现在我想实现一个获取附近用户及其距离的 API。喜欢附近的用户:
name:user1,distance:5km,(name:user2,distance:7 km)
【问题讨论】:
您可以在数据库中实现存储过程来计算距离,然后选择有条件和排序的记录,比如最近的不超过5km。如果你使用 PostgreSQL - 看这个postgis.net 同意@ineersa,你当然可以在 Transact SQL 中做到这一点。现在真正的问题是您拥有的用户数量和频率,因为这可能需要一些时间来计算。根据具体情况,您可能希望实现一个表来存储此信息。 【参考方案1】:你可以这样试试
用户模型
public function location()
return $this->belongsTo('App\Location');
在 Location 模型中创建一个函数名称rsine
,然后创建一个以scopeIsWithinMaxDistance
命名的本地作用域,如下所示
位置模型
/**
* Scope for adding distance filter
*/
public function scopeIsWithinMaxDistance($query, $rsine, $radius = 5)
return $query->selectRaw("*, $rsine AS distance")
->whereRaw("$rsine < ?", [$radius])
->orderBy('distance');
/**
* Sql command for finding distance between 2 coordinates
*/
public static function rsine($coordinates)
return '(6371 * acos(cos(radians(' . $coordinates['latitude'] . '))
* cos(radians(`lat`))
* cos(radians(`lng`)
- radians(' . $coordinates['longitude'] . '))
+ sin(radians(' . $coordinates['latitude'] . '))
* sin(radians(`lat`))))';
public static function convertKMToMiles($dist)
return $dist * 1.609344;
现在在控制器中调用它
$coordinates = ['latitude' => '28.392200', 'longitude' => '77.320801'];
$rsine = Location::rsine($coordinates);
$radius = Location::convertKMToMiles(5); //convert KM to miles
$users = User::with(['location' => function ($query) use ($rsine)
$query->selectRaw("*, $rsine AS distance");
])->whereHas('location', function ($query) use ($radius, $rsine)
$query->isWithinMaxDistance($rsine, $radius);
)->get();
现在你可以这样打印了
foreach($users as $user)
$user->name;
$user->location->city;
$user->location->distance;
【讨论】:
SQLSTATE[42000]:语法错误或访问冲突:1064 您的 SQL 语法有错误;检查与您的 mysql 服务器版本相对应的手册以获取正确的语法以使用.......... 您需要将radians(
latitude)
更改为radians(
lat)
和radians(
longitude)
更改为radians(
lng)
@987654 方法中的@9876543在您的位置表中有lat
和lng
字段。更新答案检查一下
我也试过下面的代码: public static function rsine($coordinates) return Location::select('id', DB::raw(' 6371 * acos( cos( radians(' . $坐标['纬度'] . ') ) * cos( 弧度( lat ) ) * cos( 弧度( lng ) - 弧度(' . $coordinates['longitude'] . ') ) + sin( 弧度(' . $coordinates ['纬度'] . ') ) * sin( 弧度( lat ) ) ) 作为距离'))->get();
SQLSTATE[HY093]:无效参数号:混合命名和位置参数(SQL:选择*,*,[\“距离\”:10723.218919804329,\“距离\”:1285.513973341391 ,\"distance\":1284.2498526350137] AS 距离locations
其中users
.location_id
= locations
.id
和 [\"distance\":10723.218919804329,\"distance\ ":1285.513973341391,\"distance\":1284.2498526350137] > 8.04672 order by distance
asc)",
使用与我的答案相同的方法不要尝试将return Location::select
放入rsine
方法中,并将` 放入弧度(lat
)然后尝试。这是一个工作代码,我在项目中使用过它以上是关于如何获取附近的用户和距离?的主要内容,如果未能解决你的问题,请参考以下文章