34

I'm familiar with HTML5 geolocation for returning rough coordinates of the user’s location.

However, how can I return the name of the country that their coordinates are in?

Paul D. Waite
  • 96,640
  • 56
  • 199
  • 270
Curtis
  • 101,612
  • 66
  • 270
  • 352

7 Answers7

38

If you just want the country, here's a much simpler approach using ws.geonames.org rather than Google:

if (navigator.geolocation) {
    navigator.geolocation.getCurrentPosition(function(position) {
        $.getJSON('http://ws.geonames.org/countryCode', {
            lat: position.coords.latitude,
            lng: position.coords.longitude,
            type: 'JSON'
        }, function(result) {
            alert(result.countryName);
        });
    });
}​

Normally I would say that using a Google service would mean greater reliability, but with so many Google services being retired lately it's probably a good idea to look at some other solutions.


By the way, I did some experiments using all the free geocoding services I could find. It returns the country and the name of the service responsible as soon as one of them finds an acceptable result.

Feel free to play with it via JSFiddle: Deferred look up country code via multiple geolocation webapis

hippietrail
  • 15,848
  • 18
  • 99
  • 158
  • 1
    I really like the simplicity of this answer ... and its the more open answer ;) – Pykler Apr 10 '13 at 18:23
  • 1
    The best answer for countries that block Google :) – Armfoot Sep 11 '13 at 10:59
  • Error : lease add a username to each call in order for geonames to be able to identify the calling application and count the credits – zloctb Jun 18 '14 at 13:48
  • 1
    @zloctb: Yes it seems geonames has changed its webservice to now require a registered username: "The parameter 'username' needs to be passed with each request. The username for your application can be registered [here](http://www.geonames.org/login). You will then receive an email with a confirmation link and after you have confirmed the email you can enable your account for the webservice on [your account page](http://www.geonames.org/manageaccount)" – hippietrail Jun 19 '14 at 01:53
  • Great solution. Just need to change http:// to https:// in each URL. ;) – GlennFriesen Apr 26 '18 at 17:46
  • 8
    ws.geonames.org now appears to be dead – Andy Oct 11 '19 at 11:34
31
    var geocoder = new google.maps.Geocoder();
    geocoder.geocode({'latLng': <YOURLATLNGRESPONSEFROMGEO>}, function(results, status) {
            if (status == google.maps.GeocoderStatus.OK) {
                if (results[0]) {
                    var loc = getCountry(results);
                }
            }
        });

    function getCountry(results)
    {
        for (var i = 0; i < results[0].address_components.length; i++)
        {
        var shortname = results[0].address_components[i].short_name;
        var longname = results[0].address_components[i].long_name;
        var type = results[0].address_components[i].types;
        if (type.indexOf("country") != -1)
        {
            if (!isNullOrWhitespace(shortname))
            {
                return shortname;
            }
            else
            {
                return longname;
            }
        }
    }

}

function isNullOrWhitespace(text) {
    if (text == null) {
        return true;
    }
    return text.replace(/\s/gi, '').length < 1;
}

This is what I use :)

slandau
  • 23,528
  • 42
  • 122
  • 184
  • 1
    This is almostt perfect, but google returns 'United Kingdom' rather than 'England' or 'Scotland' etc.. Ideally it needs to return 'England' etc as the purpose of the app I'm building is to identify between them two! :/ – Curtis Jul 19 '11 at 14:30
  • Look through the different types and see if you can grab what you want. http://code.google.com/apis/maps/documentation/geocoding/#Types – slandau Jul 19 '11 at 14:44
  • Just to be super picky here but it is safer to use '===' instead of '==' for comparing null values. – Victor Ramos Jul 15 '15 at 01:33
  • Just a heads up: "Geocoding Service: You must use an API key to authenticate each request to Google Maps Platform APIs. For additional information, please refer to http://g.co/dev/maps-no-account" – Benjamin Castor Jun 10 '20 at 20:00
2

If you have problem getting geolocation to work like I had in Chrome, then I can recommend this alternative way (example with jQuery):

$.getJSON("https://freegeoip.net/json/", function(data) {
    const countryCode = data.country_code;
    const countryName = data.country_name;
    const ip = data.ip;
    const timezone = data.time_zone;
    const latitude = data.latitude;
    const longitude = data.longitude;

    alert("Country Code: " + countryCode);
    alert("Country Name: " + countryName);
    alert("IP: " + ip); 
    alert("Time Zone: " + timezone);
    alert("Latitude: " + latitude);
    alert("Longitude: " + longitude);   
});
nilsi
  • 10,351
  • 10
  • 67
  • 79
1

pay attention you need set 'username' property for using this api,otherwise you'll get error.

setTimeout(function() {
                if (navigator.geolocation) {
                    navigator.geolocation.getCurrentPosition(function(position) {
                        $.getJSON('http://api.geonames.org/countryCode', {
                            lat : position.coords.latitude,
                            lng : position.coords.longitude,
                            type : 'JSON',
                            username : 'demo'
                        }, function(result) {
                            alert(result.countryName);
                        });
                    });
                }

            }, 1000);
Kirill Shur
  • 280
  • 2
  • 4
0

Similar answer as from @hippietrail but with another service without registration.

if ( navigator.geolocation ) {
  navigator.geolocation.getCurrentPosition(function(position) {

  $.ajax('http://www.datasciencetoolkit.org/coordinates2politics/'
    + position.coords.latitude + ','
    + position.coords.longitude, {dataType: 'jsonp'})
  .done(function(data, textStatus, jqXHR) {
    if ( textStatus === 'success' ) {
      var country = data[0].politics[0].name
      alert(country)
    }
  })
}
fentas
  • 1,011
  • 12
  • 14
0

Without using geoloc or IP lookup APIs (are free for dev use only)

Using Intl.DateTimeFormat().resolvedOptions().timeZone and file extracted from moment-timezone

Link to demo (user region code), you can download a file.

abdelgrib
  • 843
  • 7
  • 11
-1

You will need a Reverse Geocoder service.

Gabi Purcaru
  • 30,940
  • 9
  • 79
  • 95