How can I get city name from a latitude and longitude point?
Asked Answered
D

14

119

Is there a way to get a city name from a latitude and longitude point using the google maps api for javascript?

If so could I please see an example?

Dulse answered 1/7, 2011 at 13:21 Comment(1)
you will need to find a web service that offers this.Winkle
F
141

This is called Reverse Geocoding

Feline answered 1/7, 2011 at 13:25 Comment(3)
Per IP address and per single user is the same if you're using the javascript API but if you're using PHP for example and you think you'll reach these limits you'll need to limit the requests to 1 per second or use proxy servers but be careful with proxies, google isn't stupid and you can't hammer them. More info here: developers.google.com/maps/documentation/business/articles/…Talca
Now, you must tu use https instead of httpTownsfolk
is there a way we can pass multiple latlng in a single request?Dorella
N
31

Here is a complete sample:

<!DOCTYPE html>
<html>
  <head>
    <title>Geolocation API with Google Maps API</title>
    <meta charset="UTF-8" />
  </head>
  <body>
    <script>
      function displayLocation(latitude,longitude){
        var request = new XMLHttpRequest();

        var method = 'GET';
        var url = 'http://maps.googleapis.com/maps/api/geocode/json?latlng='+latitude+','+longitude+'&sensor=true';
        var async = true;

        request.open(method, url, async);
        request.onreadystatechange = function(){
          if(request.readyState == 4 && request.status == 200){
            var data = JSON.parse(request.responseText);
            var address = data.results[0];
            document.write(address.formatted_address);
          }
        };
        request.send();
      };

      var successCallback = function(position){
        var x = position.coords.latitude;
        var y = position.coords.longitude;
        displayLocation(x,y);
      };

      var errorCallback = function(error){
        var errorMessage = 'Unknown error';
        switch(error.code) {
          case 1:
            errorMessage = 'Permission denied';
            break;
          case 2:
            errorMessage = 'Position unavailable';
            break;
          case 3:
            errorMessage = 'Timeout';
            break;
        }
        document.write(errorMessage);
      };

      var options = {
        enableHighAccuracy: true,
        timeout: 1000,
        maximumAge: 0
      };

      navigator.geolocation.getCurrentPosition(successCallback,errorCallback,options);
    </script>
  </body>
</html>
Nth answered 6/1, 2013 at 20:21 Comment(5)
There is any way to find out user location from latitude and longitude without user approval ?Platte
@VikasVerma that would be a serious privacy breach if you are allowed to find the user location without their consentVelmaveloce
@Velmaveloce thanks but I made code there I forced user to click allow if he/she want to proceed.Platte
This actually gave me my exact home address. Exactly what I want. How do I extract just like the city and state or zip code?Broaddus
@Benny Code is there a way to pass multiple latlng in a single request?Dorella
G
14

In node.js we can use node-geocoder npm module to get address from lat, lng.,

geo.js

var NodeGeocoder = require('node-geocoder');

var options = {
  provider: 'google',
  httpAdapter: 'https', // Default
  apiKey: ' ', // for Mapquest, OpenCage, Google Premier
  formatter: 'json' // 'gpx', 'string', ...
};

var geocoder = NodeGeocoder(options);

geocoder.reverse({lat:28.5967439, lon:77.3285038}, function(err, res) {
  console.log(res);
});

output:

node geo.js

[ { formattedAddress: 'C-85B, C Block, Sector 8, Noida, Uttar Pradesh 201301, India',
    latitude: 28.5967439,
    longitude: 77.3285038,
    extra: 
     { googlePlaceId: 'ChIJkTdx9vzkDDkRx6LVvtz1Rhk',
       confidence: 1,
       premise: 'C-85B',
       subpremise: null,
       neighborhood: 'C Block',
       establishment: null },
    administrativeLevels: 
     { level2long: 'Gautam Buddh Nagar',
       level2short: 'Gautam Buddh Nagar',
       level1long: 'Uttar Pradesh',
       level1short: 'UP' },
    city: 'Noida',
    country: 'India',
    countryCode: 'IN',
    zipcode: '201301',
    provider: 'google' } ]
Glynn answered 20/2, 2018 at 10:18 Comment(3)
Thanks for the very clear and working feedback, would there be any difference between choice of 'node-geocoder' and '@google/maps' ?, they appear to do the same thing thoughAnopheles
both output are same but node-geocoder is simplified module to get the address and @google/maps is api to get address in that we need to configure.Glynn
node-geocoder would still be limited by the number of free requests you can make to Google Maps, etc.Raffaello
K
7

Here is the latest sample of Google's geocode Web Service

https://maps.googleapis.com/maps/api/geocode/json?latlng=40.714224,-73.961452&key=YOUR_API_KEY

Simply change the YOUR_API_KEY to the API key you get from Google Geocoding API

P/S: Geocoding API is under Places NOT Maps ;)

Knickknack answered 2/11, 2018 at 4:43 Comment(1)
is there a way to pass multiple latlng in a single request?Dorella
F
6

Following Code Works Fine to Get City Name (Using Google Map Geo API) :

HTML

<p><button onclick="getLocation()">Get My Location</button></p>
<p id="demo"></p>
<script src="http://maps.google.com/maps/api/js?key=YOUR_API_KEY"></script>

SCRIPT

var x=document.getElementById("demo");
function getLocation(){
    if (navigator.geolocation){
        navigator.geolocation.getCurrentPosition(showPosition,showError);
    }
    else{
        x.innerHTML="Geolocation is not supported by this browser.";
    }
}

function showPosition(position){
    lat=position.coords.latitude;
    lon=position.coords.longitude;
    displayLocation(lat,lon);
}

function showError(error){
    switch(error.code){
        case error.PERMISSION_DENIED:
            x.innerHTML="User denied the request for Geolocation."
        break;
        case error.POSITION_UNAVAILABLE:
            x.innerHTML="Location information is unavailable."
        break;
        case error.TIMEOUT:
            x.innerHTML="The request to get user location timed out."
        break;
        case error.UNKNOWN_ERROR:
            x.innerHTML="An unknown error occurred."
        break;
    }
}

function displayLocation(latitude,longitude){
    var geocoder;
    geocoder = new google.maps.Geocoder();
    var latlng = new google.maps.LatLng(latitude, longitude);

    geocoder.geocode(
        {'latLng': latlng}, 
        function(results, status) {
            if (status == google.maps.GeocoderStatus.OK) {
                if (results[0]) {
                    var add= results[0].formatted_address ;
                    var  value=add.split(",");

                    count=value.length;
                    country=value[count-1];
                    state=value[count-2];
                    city=value[count-3];
                    x.innerHTML = "city name is: " + city;
                }
                else  {
                    x.innerHTML = "address not found";
                }
            }
            else {
                x.innerHTML = "Geocoder failed due to: " + status;
            }
        }
    );
}
Furfural answered 1/5, 2017 at 7:38 Comment(0)
Y
6

BigDataCloud also has a nice API for this, also for nodejs users.

they have API for client - free. But also for backend, using API_KEY (free according to quota).

Their GitHub page.

the code looks like:

const client = require('@bigdatacloudapi/client')(API_KEY);

async foo() {
    ...
    const location: string = await client.getReverseGeocode({
          latitude:'32.101786566878445', 
          longitude: '34.858965073072056'
    });
}
Yesman answered 10/9, 2020 at 12:2 Comment(0)
P
5

In case if you don't want to use google geocoding API than you can refer to few other Free APIs for the development purpose. for example i used [mapquest] API in order to get the location name.

you can fetch location name easily by implementing this following function

 const fetchLocationName = async (lat,lng) => {
    await fetch(
      'https://www.mapquestapi.com/geocoding/v1/reverse?key=API-Key&location='+lat+'%2C'+lng+'&outFormat=json&thumbMaps=false',
    )
      .then((response) => response.json())
      .then((responseJson) => {
        console.log(
          'ADDRESS GEOCODE is BACK!! => ' + JSON.stringify(responseJson),
        );
      });
  };
Privacy answered 30/10, 2020 at 8:37 Comment(2)
OP was asking for solution with Google Maps API, I think you're not answering the question.Scorpion
Sorry but i just suggested an alternative way to do so. and it does work fine if he have google geo coding api key.Privacy
B
4

Here's a modern solution using a promise:

function getAddress (latitude, longitude) {
    return new Promise(function (resolve, reject) {
        var request = new XMLHttpRequest();

        var method = 'GET';
        var url = 'http://maps.googleapis.com/maps/api/geocode/json?latlng=' + latitude + ',' + longitude + '&sensor=true';
        var async = true;

        request.open(method, url, async);
        request.onreadystatechange = function () {
            if (request.readyState == 4) {
                if (request.status == 200) {
                    var data = JSON.parse(request.responseText);
                    var address = data.results[0];
                    resolve(address);
                }
                else {
                    reject(request.status);
                }
            }
        };
        request.send();
    });
};

And call it like this:

getAddress(lat, lon).then(console.log).catch(console.error);

The promise returns the address object in 'then' or the error status code in 'catch'

Buffoon answered 22/12, 2016 at 4:57 Comment(1)
This wouldn't work without an access key. The sensor parameter is obsolete tooRevolver
M
2

Same as @Sanchit Gupta.

in this part

if (results[0]) {
 var add= results[0].formatted_address ;
 var  value=add.split(",");
 count=value.length;
 country=value[count-1];
 state=value[count-2];
 city=value[count-3];
 x.innerHTML = "city name is: " + city;
}

just console the results array

if (results[0]) {
 console.log(results[0]);
 // choose from console whatever you need.
 var city = results[0].address_components[3].short_name;
 x.innerHTML = "city name is: " + city;
}
Mercurial answered 3/1, 2018 at 8:54 Comment(0)
R
2

Following Code Works Fine For Me to Get City, state, country, zipcode (Using Google Map Geo API) :

 var url = "https://maps.googleapis.com/maps/api/geocode/json?latlng="+lat+","+long+"&key=KEY_HERE&sensor=false";
        $.get(url, function(data) {
        var results = data.results;
            if (data.status === 'OK') 
            {
                //console.log(JSON.stringify(results));
                if (results[0]) 
                {
                    var city = "";
                    var state = "";
                    var country = "";
                    var zipcode = "";
                    
                   var address_components = results[0].address_components;
                    
                    for (var i = 0; i < address_components.length; i++) 
                    {
                       if (address_components[i].types[0] === "administrative_area_level_1" && address_components[i].types[1] === "political") {
                            state = address_components[i].long_name;    
                        }
                        if (address_components[i].types[0] === "locality" && address_components[i].types[1] === "political" ) {                                
                            city = address_components[i].long_name;   
                        }
                        
                        if (address_components[i].types[0] === "postal_code" && zipcode == "") {
                            zipcode = address_components[i].long_name;

                        }
                        
                        if (address_components[i].types[0] === "country") {
                            country = address_components[i].long_name;

                        }
                    }
                  var address = {
                        "city": city,
                        "state": state,
                        "country": country,
                        "zipcode": zipcode,
                  };
                  console.log(address);
               } 
               else 
               {
                   window.alert('No results found');
               }
            } 
            else 
            {
                window.alert('Geocoder failed due to: ' + status);
            
            }
        });
Responsible answered 6/3, 2022 at 19:55 Comment(0)
E
1

There are many tools available

  1. google maps API as like all had written
  2. use this data "https://simplemaps.com/data/world-cities" download free version and convert excel to JSON with some online converter like "http://beautifytools.com/excel-to-json-converter.php"
  3. use IP address which is not good because using IP address of someone may not good users think that you can hack them.

other free and paid tools are available also

Erikerika answered 19/6, 2020 at 5:33 Comment(0)
J
1

You can use this library in your API based on Node to do reverse geocoding:

https://github.com/rapomon/geojson-places

Jeweljeweler answered 3/12, 2022 at 0:5 Comment(1)
This is a good library, and free! tyvmCanara
D
0

public function retornaCidade ( $lat, $lng )

  {
      $key      = "SUA CHAVE";
      $url      = 'https://maps.googleapis.com/maps/api/geocode/json?latlng=' . $lat . ',' . $lng . '&key=' . $key;
      $geoFull = json_decode ( file_get_contents ( $url ), true );

      if ( $geoFull[ 'results' ] )
      {
          //console.log(JSON.stringify(results));
          if ( $geoFull[ 'results' ][ 0 ] )
          {
              $cidade = "";
              $estado = "";
              $pais   = "";
              $cep    = "";

              $address_components = $geoFull[ 'results' ][ 0 ][ 'address_components' ];

              for ( $i = 0; $i < count ( $address_components ); $i++ )
              {
                  if ( ($address_components[ $i ][ 'types' ][ 0 ] == "administrative_area_level_1") && ($address_components[ $i ][ 'types' ][ 1 ] == "political" ))
                  {
                      $estado = str_replace('State of ', '',$address_components[ $i ][ 'long_name' ]);];
                  }
                  if ( ($address_components[ $i ][ 'types' ][ 0 ] == "administrative_area_level_2") && ($address_components[ $i ][ 'types' ][ 1 ] == "political" ))
                  {
                      $cidade = $address_components[ $i ][ 'long_name' ];
                  }

                  if ( $address_components[ $i ][ 'types' ][ 0 ] == "postal_code" && $cep == "" )
                  {
                      $cep = $address_components[ $i ][ 'long_name' ];
                  }

                  if ($address_components[ $i ][ 'types' ][ 0 ] == "country" )
                  {
                      $pais = $address_components[ $i ][ 'long_name' ];
                  }
              }
              $endereco = [
                  "cidade" => $cidade,
                  "estado" => $estado,
                  "pais"   => $pais,
                  "cep"    => $cep,
              ];
            
              return $endereco;
          }
          else
          {
              return false;
          }
      }
      else
      {
          return false;
      }
  }
Donielle answered 30/11, 2022 at 12:59 Comment(1)
While this code may answer the question, providing additional context regarding why and/or how this code answers the question improves its long-term value.Contumacy
D
-3

you can do it with pure php and google geocode api

/*
 *
 * @param latlong (String) is Latitude and Longitude with , as separator for example "21.3724002,39.8016229"
 **/
function getCityNameByLatitudeLongitude($latlong)
{
    $APIKEY = "AIzaXXXXXXXXXXXXXXXXXXXXXXXXXXX"; // Replace this with your google maps api key 
    $googleMapsUrl = "https://maps.googleapis.com/maps/api/geocode/json?latlng=" . $latlong . "&language=ar&key=" . $APIKEY;
    $response = file_get_contents($googleMapsUrl);
    $response = json_decode($response, true);
    $results = $response["results"];
    $addressComponents = $results[0]["address_components"];
    $cityName = "";
    foreach ($addressComponents as $component) {
        // echo $component;
        $types = $component["types"];
        if (in_array("locality", $types) && in_array("political", $types)) {
            $cityName = $component["long_name"];
        }
    }
    if ($cityName == "") {
        echo "Failed to get CityName";
    } else {
        echo $cityName;
    }
}
Dobsonfly answered 30/4, 2019 at 7:34 Comment(2)
Not a javascript solutionRancho
@Hemdi is there a way to pass multiple latlng in a single request?Dorella

© 2022 - 2024 — McMap. All rights reserved.