Haversine distance calculation between two points in Laravel Haversine distance calculation between two points in Laravel sql sql

Haversine distance calculation between two points in Laravel


This was my implementation of it. I've chosen to alias my query out ahead of time, this way I can take advantage of Pagination. Furthermore, you need to explicitly select the columns that you wish to retrieve from the query. add them at the ->select(). Such as users.latitude, users.longitude, products.name, or whatever they may be.

I have created a scope which looks something like this:

public function scopeIsWithinMaxDistance($query, $location, $radius = 25) {     $haversine = "(6371 * acos(cos(radians($location->latitude))                      * cos(radians(model.latitude))                      * cos(radians(model.longitude)                      - radians($location->longitude))                      + sin(radians($location->latitude))                      * sin(radians(model.latitude))))";     return $query        ->select() //pick the columns you want here.        ->selectRaw("{$haversine} AS distance")        ->whereRaw("{$haversine} < ?", [$radius]);}

You can apply this scope to any model with a latitude andlongitude.

Replace the $location->latitude with your latitude that you wish to search against, and replace the $location->longitude with the longitude that you wish to search against.

Replace the model.latitude and model.longitude with the Models you wish to find around the $location based on the distance defined in the $radius.

I know you have a functioning Haversine formula, but if you need to Paginate you can't use the code you've supplied.

Hopefully this helps.


Create this function in your Model

 public static function getNearBy($lat, $lng, $distance,                                             $distanceIn = 'miles')        {            if ($distanceIn == 'km') {                $results = self::select(['*', DB::raw('( 0.621371 * 3959 * acos( cos( radians('.$lat.') ) * cos( radians( lat ) ) * cos( radians( lng ) - radians('.$lng.') ) + sin( radians('.$lat.') ) * sin( radians(lat) ) ) ) AS distance')])->havingRaw('distance < '.$distance)->get();            } else {                $results = self::select(['*', DB::raw('( 3959 * acos( cos( radians('.$lat.') ) * cos( radians( lat ) ) * cos( radians( lng ) - radians('.$lng.') ) + sin( radians('.$lat.') ) * sin( radians(lat) ) ) ) AS distance')])->havingRaw('distance < '.$distance)->get();            }            return $results;        }

And you can use orderby, groupBy as per your requirement.


Using Haversine method, you can calculate distance between two points using this function. It works but I don't know how to implement this in Laravel. Thought of sharing this anyway.

$lat1 //latitude of first point$lon1 //longitude of first point $lat2 //latitude of second point$lon2 //longitude of second point $unit- unit- km or milefunction point2point_distance($lat1, $lon1, $lat2, $lon2, $unit='K')     {         $theta = $lon1 - $lon2;         $dist = sin(deg2rad($lat1)) * sin(deg2rad($lat2)) +  cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * cos(deg2rad($theta));         $dist = acos($dist);         $dist = rad2deg($dist);         $miles = $dist * 60 * 1.1515;        $unit = strtoupper($unit);        if ($unit == "K")         {            return ($miles * 1.609344);         }         else if ($unit == "N")         {        return ($miles * 0.8684);        }         else         {        return $miles;      }    }