Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

murilo's avatar
Level 10

How to find nearest cities from Latitude and Longitude

Hello GUYS , I am working in a project that I want make a search with latitude and Logitude , like this -

latitude -21.1774558
longitude -47.8063571

and return all cities with RADIUS of 30 km around this coordinate.

I have all the cities with the Longitude and Latitude in My DB. like this -

name_city  | latitude  | longitude 


Can I calculate those values and get all the cities around or do I have to use some IPI from Google ?

0 likes
18 replies
sutherland's avatar
Level 28

If you already have the latitude and longitudes in your database you might as well query them yourself. This is from an older project (so may not work or be the best method) where I'm doing something similar:

$cities = City::select(DB::raw('*, ( 6367 * acos( cos( radians('.$latitude.') ) * cos( radians( latitude ) ) * cos( radians( longitude ) - radians('.$longitude.') ) + sin( radians('.$latitude.') ) * sin( radians( latitude ) ) ) ) AS distance'))
    ->having('distance', '<', 25)
    ->orderBy('distance')
    ->get();
5 likes
mdeorue's avatar

If you use google maps api?

https://maps.googleapis.com/maps/api/geocode/json?latlng=lat,long

Reponse:

json
{
   "results" : [
      {
         "address_components" : [
            {
               "long_name" : "277",
               "short_name" : "277",
               "types" : [ "street_number" ]
            },
            {
               "long_name" : "Bedford Avenue",
               "short_name" : "Bedford Ave",
               "types" : [ "route" ]
            },
            {
               "long_name" : "Williamsburg",
               "short_name" : "Williamsburg",
               "types" : [ "neighborhood", "political" ]
            },
            {
               "long_name" : "Brooklyn",
               "short_name" : "Brooklyn",
               "types" : [ "sublocality", "political" ]
            },
            {
               "long_name" : "Kings",
               "short_name" : "Kings",
               "types" : [ "administrative_area_level_2", "political" ]
            },
            {
               "long_name" : "New York",
               "short_name" : "NY",
               "types" : [ "administrative_area_level_1", "political" ]
            },
            {
               "long_name" : "United States",
               "short_name" : "US",
               "types" : [ "country", "political" ]
            },
            {
               "long_name" : "11211",
               "short_name" : "11211",
               "types" : [ "postal_code" ]
            }
         ],
         "formatted_address" : "277 Bedford Avenue, Brooklyn, NY 11211, USA",
         "geometry" : {
            "location" : {
               "lat" : 40.714232,
               "lng" : -73.9612889
            },
            "location_type" : "ROOFTOP",
            "viewport" : {
               "northeast" : {
                  "lat" : 40.7155809802915,
                  "lng" : -73.9599399197085
               },
               "southwest" : {
                  "lat" : 40.7128830197085,
                  "lng" : -73.96263788029151
               }
            }
         },
         "place_id" : "ChIJd8BlQ2BZwokRAFUEcm_qrcA",
         "types" : [ "street_address" ]
      },
murilo's avatar
Level 10

very nice @sutherland , but what is 'distance' ? It gave me this error -

 Syntax error or access violation: 1463 Non-grouping field 'distance' is used in HAVING clause

Do I have to have in my table , a field called distance ?

sutherland's avatar

The raw query in the select is using AS to calculate the distance. I just copied it from an old Laravel 4 project so I'm not sure what's changed.

Maybe try changing ->having('distance', '<', 30) to ->where('distance', '<', 30)?

murilo's avatar
Level 10

@sutherland , does have any Column called 'distance' ? what value do I have to insert in this column ? It is giving this error -

Column not found: 1054 Unknown column 'distance' in 'where clause' 
Column not found: 1054 Unknown column 'distance' in 'where clause' (SQL: select *, ( 6367 * acos( cos( radians(-21.1774558) ) * cos( radians( latitude ) ) * cos( radians( longitude ) - radians(-47.8063571) ) + sin( radians(-21.1774558) ) * sin( radians( latitude ) ) ) ) AS distance from `loc_neighborhoods` where `distance` < 30 order by `distance` asc)

sutherland's avatar

You don't need a distance column, the raw select statement is calculating it for you.

I just tested this on Laravel 5.6 with no issues:

$latitude = 25.000;
$longitude = 25.000;

$cities = City::selectRaw('*, ( 6367 * acos( cos( radians( ? ) ) * cos( radians( latitude ) ) * cos( radians( longitude ) - radians( ? ) ) + sin( radians( ? ) ) * sin( radians( latitude ) ) ) ) AS distance', [$latitude, $longitude, $latitude])
    ->having('distance', '<', 30)
    ->orderBy('distance')
    ->get();

What database driver are you using?

2 likes
murilo's avatar
Level 10

Hello sutherland , thanks for the help , But still giving errors -

SQLSTATE[42000]: Syntax error or access violation: 1463 Non-grouping field 'distance' is used in HAVING clause (SQL: select *, ( 6367 * acos( cos( radians( 25 ) ) * cos( radians( latitude ) ) * cos( radians( longitude ) - radians( 25 ) ) + sin( radians( 25 ) ) * sin( radians( latitude ) ) ) ) AS distance from `cities` having `distance` < 30 order by `distance` asc)

Are you using Mysql ?

murilo's avatar
Level 10

@sutherland , now it is working , In my config , database . I changed to -

'strict' => false

It is working now .

sutherland's avatar

@murilo strange, I almost suggested that but in my config I had it set to true so I thought it wouldn't matter. I guess maybe I have that configured somewhere else...

murilo's avatar
Level 10

@sutherland , in this code - City::selectRaw('*, ()) you are getting all columns in the table, do you know how cold I get just those columns -

id , latitude , longitude

in this table ? Thanks

sutherland's avatar

Change it to City::selectRaw('id, latitude, longitude, (...))

2 likes
syedsaadahmed's avatar

@sutherland can you tell me what's 30 in this? ->having('distance', '<', 30) I want to get nearest locations within 5 kms to the chosen longitude and latitude.

GandalfTheDark's avatar

->having('distance', '<', 30) does not work when you use sqlsrv. It gives me column not found error. Would you have a work around it?

Please or to participate in this conversation.