Вы можете попробовать это так
Модель пользователя
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;
}