Laravel 如何获得附近的用户和距离?

Laravel 如何获得附近的用户和距离?,laravel,geolocation,Laravel,Geolocation,首先,我想向您展示当前的数据库结构。有两个表格: 用户 身份证 名字 位置标识 地点 身份证 城市 拉特 液化天然气 现在我想实现一个API,它可以获取附近的用户及其距离。与附近的用户一样: {{name:user1,distance:5km},(name:user2,distance:7 km)} 你可以这样试试 用户模型 public function location(){ return $this->belongsTo('App\Location'); } /*

首先,我想向您展示当前的数据库结构。有两个表格:

用户

  • 身份证
  • 名字
  • 位置标识
地点

  • 身份证
  • 城市
  • 拉特
  • 液化天然气
现在我想实现一个API,它可以获取附近的用户及其距离。与附近的用户一样:

{{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
),然后重试。这是一个工作代码,我在项目中使用过它