Click Below to subscribe

How to Find Nearest Location Using Latitude and Longitude In Laravel 2022

Sometimes you need to find the nearest location using latitude and longitude within a radius.

In this article, we gonna learn how to use laravel eloquent for finding nearby locations.

DB Structure - users table

Here is an example for finding nearby 5 users within 1 km.

$latitude = 28.626137;
$longitude = 79.821602;
$distance = 1;

$haversine = "(
    6371 * acos(
        cos(radians(" .$latitude. "))
        * cos(radians(`latitude`))
        * cos(radians(`longitude`) - radians(" .$longitude. "))
        + sin(radians(" .$latitude. ")) * sin(radians(`latitude`))
    )
)";

$users = User::select("id")
    ->selectRaw("$haversine AS distance")
    ->having("distance", "<=", $distance)
    ->orderby("distance", "desc")
    ->limit(5)
    ->get();

Note:- In case of miles just replace the 6371 with 3959 in the haversine formula.

Miles - 3959 

Kilometer6371

you can also round the distance in query. 

$users = User::select("id")
    ->selectRaw("round($haversine, 2) AS distance")
    ->having("distance", "<=", $distance)
    ->orderby("distance", "desc")
    ->limit(5)
    ->get();

We can also make it reusable by defining this as a scope inside the model.

app/Models/User.php

public function scopeDistance($query, $latitude, $longitude, $distance, $unit = "km")
{
    $constant = $unit == "km" ? 6371 : 3959;
    $haversine = "(
        $constant * acos(
            cos(radians(" .$latitude. "))
            * cos(radians(`latitude`))
            * cos(radians(`longitude`) - radians(" .$longitude. "))
            + sin(radians(" .$latitude. ")) * sin(radians(`latitude`))
        )
    )";

    return $query->selectRaw("$haversine AS distance")
        ->having("distance", "<=", $distance);
}

Note:- I have passed km as the default unit. so you don't need to pass in case of kilometer calculation.

Now in the controller, you can call this scope.

$users = User::select("id")
    ->distance($latitude, $longitude, $distance)
    ->orderby("distance", "desc")
    ->limit(5)
    ->get();

In the case of miles.

$users = User::select("id")
    ->distance($latitude, $longitude, $distance, "m")
    ->orderby("distance", "desc")
    ->limit(5)
    ->get();

Leave Your Comment