By lisovaccaro


2011-07-23 01:00:58 8 Comments

I managed to get the user's latitude and longitude using html5 geolocation.

//Check if browser supports W3C Geolocation API
if (navigator.geolocation) {
    navigator.geolocation.getCurrentPosition(successFunction, errorFunction);
} 
//Get latitude and longitude;
function successFunction(position) {
    var lat = position.coords.latitude;
    var long = position.coords.longitude;
}

I want to display the city name, it seems the only way to get it is to use a reverse geolocation api. I read google's documentation for reverse geolocation but I don't know how to get the output on my site.

I don't know how to go use this: "//maps.googleapis.com/maps/api/geocode/json?latlng='+lat+','+long+'&sensor=true" to display the city name on the page.

What is standard way to do it?

10 comments

@Jonathan 2017-09-05 20:05:22

As @PirateApp mentioned in his comment, it's explicitly against Google's Maps API Licensing to use the Maps API as you intend.

You have a number of alternatives, including downloading a Geoip database and querying it locally or using a third party API service, such as ipdata.co.

ipdata gives you the geolocation, organisation, currency, timezone, calling code, flag and Tor Exit Node status data from any IPv4 or IPv6 address.

And is scalable with 10 global endpoints each able to handle >10,000 requests per second!

This answer uses a 'test' API Key that is very limited and only meant for testing a few calls. Signup for your own Free API Key and get up to 1500 requests daily for development.

$.get("https://api.ipdata.co?api-key=test", function(response) {
  $("#ip").html("IP: " + response.ip);
  $("#city").html(response.city + ", " + response.region);
  $("#response").html(JSON.stringify(response, null, 4));
}, "jsonp");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1><a href="https://ipdata.co">ipdata.co</a> - IP geolocation API</h1>

<div id="ip"></div>
<div id="city"></div>
<pre id="response"></pre>

The fiddle; https://jsfiddle.net/ipdata/6wtf0q4g/922/

@Jonathan 2018-05-18 10:50:47

Why the downvote?

@Kurt Van den Branden 2015-12-18 15:07:28

Using html5 geolocation requires user permission. In case you don't want this, go for an external locator like https://geoip-db.com IPv6 is supported.

Example:

<!DOCTYPE html>
<html>
<head>
    <title>GEOIP DB - jQuery example</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
</head>
<body>
    <div>Country: <span id="country"></span>
    <div>State: <span id="state"></span>
    <div>City: <span id="city"></span>
    <div>Latitude: <span id="latitude"></span>
    <div>Longitude: <span id="longitude"></span>
    <div>IP: <span id="ip"></span>
    <script>
        $.ajax({
            url: "https://geoip-db.com/jsonp",
            jsonpCallback: "callback",
            dataType: "jsonp",
            success: function( location ) {
                $('#country').html(location.country_name);
                $('#state').html(location.state);
                $('#city').html(location.city);
                $('#latitude').html(location.latitude);
                $('#longitude').html(location.longitude);
                $('#ip').html(location.IPv4);  
            }
        });     
    </script>
</body>
</html>

For a pure javascript example, without using jQuery, check out this answer.

@Vindhyachal Kumar 2017-07-29 13:58:50

You can use https://ip-api.io/ to get city Name. It supports IPv6.

As a bonus it allows to check whether ip address is a tor node, public proxy or spammer.

Javascript Code:

$(document).ready(function () {
        $('#btnGetIpDetail').click(function () {
            if ($('#txtIP').val() == '') {
                alert('IP address is reqired');
                return false;
            }
            $.getJSON("http://ip-api.io/json/" + $('#txtIP').val(),
                 function (result) {
                     alert('City Name: ' + result.city)
                     console.log(result);
                 });
        });
    });

HTML Code

<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<div>
    <input type="text" id="txtIP" />
    <button id="btnGetIpDetail">Get Location of IP</button>
</div>

JSON Output

{
    "ip": "64.30.228.118",
    "country_code": "US",
    "country_name": "United States",
    "region_code": "FL",
    "region_name": "Florida",
    "city": "Fort Lauderdale",
    "zip_code": "33309",
    "time_zone": "America/New_York",
    "latitude": 26.1882,
    "longitude": -80.1711,
    "metro_code": 528,
    "suspicious_factors": {
        "is_proxy": false,
        "is_tor_node": false,
        "is_spam": false,
        "is_suspicious": false
    }
}

@Onur Yıldırım 2016-07-01 23:32:01

geolocator.js can do that. (I'm the author).

Getting City Name (Limited Address)

geolocator.locateByIP(options, function (err, location) {
    console.log(location.address.city);
});

Getting Full Address Information

Example below will first try HTML5 Geolocation API to obtain the exact coordinates. If fails or rejected, it will fallback to Geo-IP look-up. Once it gets the coordinates, it will reverse-geocode the coordinates into an address.

var options = {
    enableHighAccuracy: true,
    fallbackToIP: true, // fallback to IP if Geolocation fails or rejected
    addressLookup: true
};
geolocator.locate(options, function (err, location) {
    console.log(location.address.city);
});

This uses Google APIs internally (for address lookup). So before this call, you should configure geolocator with your Google API key.

geolocator.config({
    language: "en",
    google: {
        version: "3",
        key: "YOUR-GOOGLE-API-KEY"
    }
});

Geolocator supports geo-location (via HTML5 or IP lookups), geocoding, address look-ups (reverse geocoding), distance & durations, timezone information and a lot more features...

@Shiva 2017-07-29 03:43:48

This library works like a charm!

@user3124360 2017-05-24 18:13:30

Here is another go at it .. Adding more to the accepted answer possibly more comprehensive .. of course switch -case will make it look for elegant.

function parseGeoLocationResults(result) {
    const parsedResult = {}
    const {address_components} = result;

    for (var i = 0; i < address_components.length; i++) {
        for (var b = 0; b < address_components[i].types.length; b++) {
            if (address_components[i].types[b] == "street_number") {
                //this is the object you are looking for
                parsedResult.street_number = address_components[i].long_name;
                break;
            }
            else if (address_components[i].types[b] == "route") {
                //this is the object you are looking for
                parsedResult.street_name = address_components[i].long_name;
                break;
            }
            else if (address_components[i].types[b] == "sublocality_level_1") {
                //this is the object you are looking for
                parsedResult.sublocality_level_1 = address_components[i].long_name;
                break;
            }
            else if (address_components[i].types[b] == "sublocality_level_2") {
                //this is the object you are looking for
                parsedResult.sublocality_level_2 = address_components[i].long_name;
                break;
            }
            else if (address_components[i].types[b] == "sublocality_level_3") {
                //this is the object you are looking for
                parsedResult.sublocality_level_3 = address_components[i].long_name;
                break;
            }
            else if (address_components[i].types[b] == "neighborhood") {
                //this is the object you are looking for
                parsedResult.neighborhood = address_components[i].long_name;
                break;
            }
            else if (address_components[i].types[b] == "locality") {
                //this is the object you are looking for
                parsedResult.city = address_components[i].long_name;
                break;
            }
            else if (address_components[i].types[b] == "administrative_area_level_1") {
                //this is the object you are looking for
                parsedResult.state = address_components[i].long_name;
                break;
            }

            else if (address_components[i].types[b] == "postal_code") {
                //this is the object you are looking for
                parsedResult.zip = address_components[i].long_name;
                break;
            }
            else if (address_components[i].types[b] == "country") {
                //this is the object you are looking for
                parsedResult.country = address_components[i].long_name;
                break;
            }
        }
    }
    return parsedResult;
}

@SKYnine 2017-06-16 18:46:19

best answer I found so far, great snippet thanks!

@Jafo 2016-05-25 14:30:50

After some searching and piecing together a couple of different solutions along with my own stuff, I came up with this function:

function parse_place(place)
{
    var location = [];

    for (var ac = 0; ac < place.address_components.length; ac++)
    {
        var component = place.address_components[ac];

        switch(component.types[0])
        {
            case 'locality':
                location['city'] = component.long_name;
                break;
            case 'administrative_area_level_1':
                location['state'] = component.long_name;
                break;
            case 'country':
                location['country'] = component.long_name;
                break;
        }
    };

    return location;
}

@Mikhail 2016-04-29 04:12:07

You can get the name of the city, country, street name and other geodata using the Google Maps Geocoding API

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
    <script type="text/javascript" src="https://code.jquery.com/jquery-2.2.3.js"></script>
</head>
<body>
    <script type="text/javascript">
        navigator.geolocation.getCurrentPosition(success, error);

        function success(position) {
            console.log(position.coords.latitude)
            console.log(position.coords.longitude)

            var GEOCODING = 'https://maps.googleapis.com/maps/api/geocode/json?latlng=' + position.coords.latitude + '%2C' + position.coords.longitude + '&language=en';

            $.getJSON(GEOCODING).done(function(location) {
                console.log(location)
            })

        }

        function error(err) {
            console.log(err)
        }
    </script>
</body>
</html>

and to display this data on the page using jQuery

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
    <script type="text/javascript" src="https://code.jquery.com/jquery-2.2.3.js"></script>
</head>
<body>

    <p>Country: <span id="country"></span></p>
    <p>State: <span id="state"></span></p>
    <p>City: <span id="city"></span></p>
    <p>Address: <span id="address"></span></p>

    <p>Latitude: <span id="latitude"></span></p>
    <p>Longitude: <span id="longitude"></span></p>

    <script type="text/javascript">
        navigator.geolocation.getCurrentPosition(success, error);

        function success(position) {

            var GEOCODING = 'https://maps.googleapis.com/maps/api/geocode/json?latlng=' + position.coords.latitude + '%2C' + position.coords.longitude + '&language=en';

            $.getJSON(GEOCODING).done(function(location) {
                $('#country').html(location.results[0].address_components[5].long_name);
                $('#state').html(location.results[0].address_components[4].long_name);
                $('#city').html(location.results[0].address_components[2].long_name);
                $('#address').html(location.results[0].formatted_address);
                $('#latitude').html(position.coords.latitude);
                $('#longitude').html(position.coords.longitude);
            })

        }

        function error(err) {
            console.log(err)
        }
    </script>
</body>
</html>

@Ben Dowling 2013-07-30 12:43:52

Another approach to this is to use my service, http://ipinfo.io, which returns the city, region and country name based on the user's current IP address. Here's a simple example:

$.get("http://ipinfo.io", function(response) {
    console.log(response.city, response.country);
}, "jsonp");

Here's a more detailed JSFiddle example that also prints out the full response information, so you can see all of the available details: http://jsfiddle.net/zK5FN/2/

@Salman Abbas 2014-01-20 20:30:49

Not as accurate though.

@Jehy 2014-04-07 08:22:02

Could not detect city and even trgion from IP of a big Russian provider : (

@major-mann 2014-07-11 06:06:31

Lol... this gives my internal network ip (192.168...)

@Arti 2015-01-21 05:59:44

Can I do it from a device(handheld) browser?

@SearchForKnowledge 2015-05-13 13:33:25

Doesn't seem to work anymore for me.

@user786033 2017-06-16 12:25:25

You're awesome!

@Ashish Goyal 2018-05-04 05:20:27

Doesnt seem reliable. I am using a laptop and a mobile phone right now. The cities shown in both the devices through ipinfo.io are 530 kilometers apart!

@Pradeep 2015-03-01 09:59:46

Here is updated working version for me which will get City/Town, It looks like some fields are modified in the json response. Referring previous answers for this questions. ( Thanks to Michal & one more reference : Link

var geocoder;

if (navigator.geolocation) {
  navigator.geolocation.getCurrentPosition(successFunction, errorFunction);
}
// Get the latitude and the longitude;
function successFunction(position) {
  var lat = position.coords.latitude;
  var lng = position.coords.longitude;
  codeLatLng(lat, lng);
}

function errorFunction() {
  alert("Geocoder failed");
}

function initialize() {
  geocoder = new google.maps.Geocoder();

}

function codeLatLng(lat, lng) {
  var latlng = new google.maps.LatLng(lat, lng);
  geocoder.geocode({latLng: latlng}, function(results, status) {
    if (status == google.maps.GeocoderStatus.OK) {
      if (results[1]) {
        var arrAddress = results;
        console.log(results);
        $.each(arrAddress, function(i, address_component) {
          if (address_component.types[0] == "locality") {
            console.log("City: " + address_component.address_components[0].long_name);
            itemLocality = address_component.address_components[0].long_name;
          }
        });
      } else {
        alert("No results found");
      }
    } else {
      alert("Geocoder failed due to: " + status);
    }
  });
}

@Michal 2011-07-23 03:15:09

You would do something like that using Google API.

Please note you must include the google maps library for this to work. Google geocoder returns a lot of address components so you must make an educated guess as to which one will have the city.

"administrative_area_level_1" is usually what you are looking for but sometimes locality is the city you are after.

Anyhow - more details on google response types can be found here and here.

Below is the code that should do the trick:

<!DOCTYPE html> 
<html> 
<head> 
<meta name="viewport" content="initial-scale=1.0, user-scalable=no"/> 
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/> 
<title>Reverse Geocoding</title> 

<script type="text/javascript" src="//maps.googleapis.com/maps/api/js?sensor=false"></script> 
<script type="text/javascript"> 
  var geocoder;

  if (navigator.geolocation) {
    navigator.geolocation.getCurrentPosition(successFunction, errorFunction);
} 
//Get the latitude and the longitude;
function successFunction(position) {
    var lat = position.coords.latitude;
    var lng = position.coords.longitude;
    codeLatLng(lat, lng)
}

function errorFunction(){
    alert("Geocoder failed");
}

  function initialize() {
    geocoder = new google.maps.Geocoder();



  }

  function codeLatLng(lat, lng) {

    var latlng = new google.maps.LatLng(lat, lng);
    geocoder.geocode({'latLng': latlng}, function(results, status) {
      if (status == google.maps.GeocoderStatus.OK) {
      console.log(results)
        if (results[1]) {
         //formatted address
         alert(results[0].formatted_address)
        //find country name
             for (var i=0; i<results[0].address_components.length; i++) {
            for (var b=0;b<results[0].address_components[i].types.length;b++) {

            //there are different types that might hold a city admin_area_lvl_1 usually does in come cases looking for sublocality type will be more appropriate
                if (results[0].address_components[i].types[b] == "administrative_area_level_1") {
                    //this is the object you are looking for
                    city= results[0].address_components[i];
                    break;
                }
            }
        }
        //city data
        alert(city.short_name + " " + city.long_name)


        } else {
          alert("No results found");
        }
      } else {
        alert("Geocoder failed due to: " + status);
      }
    });
  }
</script> 
</head> 
<body onload="initialize()"> 

</body> 
</html> 

@Ming Tsai 2012-06-03 16:38:57

Not true for admin area level 1, sometimes the city name is not there. - {"long_name"=>"San Francisco", "types"=>["administrative_area_level_2", "political"] , "short_name"=>"San Francisco"}, {"long_name"=>"California", "types"=>["administrative_area_level_1", "political"], "short_name"=>"CA" }, {"long_name"=>"United States", "types"=>["country", "political"], "short_name"=>"US"}

@Michal 2012-06-04 07:55:29

That is why I said it is an educated guess..

@binarygiant 2013-03-04 00:20:49

For V3, the {'latlng':latlng} string should be changed to 'location', as in ...geocode({'location':latlng}). This example got me almost there, but the 'latlng' string no longer seems to be valid in newer apis. See: developers.google.com/maps/documentation/javascript/… for specifics.

@ajay 2013-03-30 07:00:47

@Michal how can we find only country name or country code instead of full address?

@Michal 2013-03-31 00:51:33

@ajay in the if statement test for "country" and the city variable will now return country data. If re-name it country = results[0].address_components[i] you can access the data by country.long_name and country.short_name

@durbnpoisn 2014-06-26 17:18:57

Holy friggin crap! This is EXACTLY what I was looking for. You never know what you'll find in a quick search!

@Umeed 2016-07-06 14:11:41

Is there a way to narrow this down to cities within a province or just to check if location is from specific province, and if it is user gets redirected to a specific webpage?

Related Questions

Sponsored Content

73 Answered Questions

[SOLVED] How can I get query string values in JavaScript?

19 Answered Questions

[SOLVED] Get the current URL with JavaScript?

  • 2009-06-23 19:26:45
  • dougoftheabaci
  • 2386810 View
  • 2548 Score
  • 19 Answer
  • Tags:   javascript url

36 Answered Questions

[SOLVED] How do you get a timestamp in JavaScript?

2 Answered Questions

[SOLVED] GeoLocation Google Maps not working

16 Answered Questions

[SOLVED] How to get the children of the $(this) selector?

1 Answered Questions

[SOLVED] How do I get geolocation in openweather API

0 Answered Questions

Metoer geolocation get city state and country name name

1 Answered Questions

[SOLVED] What is the best way to get a user's city?

Sponsored Content