$salons = Salon::select(\'salons.*\')
->selectRaw(\'( 6371* acos( cos( radians(?) ) *
cos( radians( lat ) )
* cos( radians(
Better way will be to use PHP. SQL calculations are expensive. In certain raw counts difference can be 30sec vs 0.04 sec ;)
public function scopeDistance($query, $from_latitude, $from_longitude, $distance)
{
$between_coords = \App\Services\PlaceServices::calcCoordinates($from_longitude, $from_latitude, $distance);
return $query
->where(function ($q) use ($between_coords) {
$q->whereBetween('places.longitude', [$between_coords['min']['lng'], $between_coords['max']['lng']]);
})
->where(function ($q) use ($between_coords) {
$q->whereBetween('places.latitude', [$between_coords['min']['lat'], $between_coords['max']['lat']]);
});
}
and calcCoodinates()
public static function calcCoordinates($longitude, $latitude, $radius = 20)
{
$lng_min = $longitude - $radius / abs(cos(deg2rad($latitude)) * 69);
$lng_max = $longitude + $radius / abs(cos(deg2rad($latitude)) * 69);
$lat_min = $latitude - ($radius / 69);
$lat_max = $latitude + ($radius / 69);
return [
'min' => [
'lat' => $lat_min,
'lng' => $lng_min,
],
'max' => [
'lat' => $lat_max,
'lng' => $lng_max,
],
];
}
Then just use YourModel::distance($lat, $lon, $km)->get()
for obtaining the km
you should use 111.045 km
per degree (as an approximation)
( 111.045 * acos( cos( radians(?) ) *
cos( radians( lat ) )
* cos( radians( lng ) - radians(?)
) + sin( radians(?) ) *
sin( radians( lat ) ) )
)
Try below query
$data = DB::table('salons AS S')
->selectRaw("
( FLOOR(6371 * ACOS( COS( RADIANS( '$lat' ) ) * COS( RADIANS( S.lat ) ) * COS( RADIANS( S.lng ) - RADIANS( '$lng' ) ) + SIN( RADIANS( '$lat' ) ) * SIN( RADIANS( S.lat ) ) )) ) distance")
->havingRaw("distance < 25")
->where("category_Id" , "=" , $id)
->get();
$lat, $lng are variables.