Laravel 如何获得附近的用户和距离?
首先,我想向您展示当前的数据库结构。有两个表格: 用户Laravel 如何获得附近的用户和距离?,laravel,geolocation,Laravel,Geolocation,首先,我想向您展示当前的数据库结构。有两个表格: 用户 身份证 名字 位置标识 地点 身份证 城市 拉特 液化天然气 现在我想实现一个API,它可以获取附近的用户及其距离。与附近的用户一样: {{name:user1,distance:5km},(name:user2,distance:7 km)} 你可以这样试试 用户模型 public function location(){ return $this->belongsTo('App\Location'); } /*
- 身份证
- 名字
- 位置标识
- 身份证
- 城市
- 拉特
- 液化天然气
{{name:user1,distance:5km},(name:user2,distance:7 km)}
你可以这样试试 用户模型
public function location(){
return $this->belongsTo('App\Location');
}
/**
* 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;
}
在位置模型中,创建一个函数名rsine
,然后创建一个名为scopeIsWithinMaxDistance
的本地作用域,如下所示
位置模型
public function location(){
return $this->belongsTo('App\Location');
}
/**
* 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;
}
现在你可以这样打印了
foreach($users as $user){
$user->name;
$user->location->city;
$user->location->distance;
}
您可以在数据库中实现存储过程来计算距离,然后选择具有条件和顺序的记录,例如最近距离不超过5km。如果您使用PostgreSQL-请注意,这与@ineersa一致,您当然也可以在Transact-SQL中这样做。现在真正的问题是,由于计算可能需要一些时间,您的用户数量和频率是多少。根据具体情况,您可能希望实现一个表来存储此信息。SQLSTATE[42000]:语法错误或访问冲突:1064您的SQL语法中有一个错误;查看与MySQL服务器版本对应的手册,以了解正确的语法使用…………您需要将
弧度(
纬度)
更改为弧度(
lat)
和弧度(
经度)
更改为弧度(
lng)
在rsine
方法中,因为在位置表中有lat
和lng
字段。更新的答案检查itI也尝试了以下代码:公共静态函数rsine($coordinates){return Location::select('id',DB::raw('6371*acos(弧度('.$coordinates['latitude']))*cos(弧度(lat))*cos(弧度(lng)-弧度('.$coordinates['longitude']))+sin(弧度('.$coordinates['latitudit']))*sin(弧度(lat)))作为距离“)->get();}SQLSTATE[HY093]:无效参数编号:混合命名参数和位置参数(SQL:select*,*,[{“distance\”:10723.218919804329},{“distance\”:1285.51397341391},{“distance\”:1284.2498526350137}]作为与位置的距离,其中用户位置id
=位置id
和[{“距离”:10723.218919804329},{“距离”:1285.51397341391},{“距离”:1284.2498526350137}]>8.04672按距离排序“,使用与我的答案相同的方法。不要尝试在rsine
方法中输入返回位置::选择,并输入`弧度(lat
),然后重试。这是一个工作代码,我在项目中使用过它