46

I am looking for a way to get the user's current location (city) based on is IP address using the Google Maps APIs.

Something similar to http://freegeoip.net/json but only using the Google Maps APIs. Is this possible?

Nicolas Garnier
  • 12,134
  • 2
  • 42
  • 39
Ankit
  • 481
  • 1
  • 4
  • 5
  • afaik, google doesn't have an api for ip based locating – keune Jul 01 '13 at 10:35
  • 7
    you can try https://geoipify.whoisxmlapi.com/ –  Dec 16 '17 at 04:03
  • You can do that, you need to use the Google Maps Geolocation API to get the Lat Lon (based on API) and then reverse-geocode it. Here is some code: https://github.com/firebase/friendlypix-web/blob/master/public/scripts/ipfilter.js#L55-L101 – Nicolas Garnier May 28 '18 at 13:26

3 Answers3

24

Google already appends location data to all requests coming into GAE (see Request Header documentation for go, java, php and python). You should be interested X-AppEngine-Country, X-AppEngine-Region, X-AppEngine-City and X-AppEngine-CityLatLong headers.

An example looks like this:

X-AppEngine-Country:US
X-AppEngine-Region:ca
X-AppEngine-City:norwalk
X-AppEngine-CityLatLong:33.902237,-118.081733
matt burns
  • 24,742
  • 13
  • 105
  • 107
Peter Knego
  • 79,991
  • 11
  • 123
  • 154
  • I went through your link and found the PHP version for it (https://developers.google.com/appengine/docs/php/#PHP_Request_headers) but I'm not sure how to use this service. I'm basically making a website that would need to figure out the user's country code and that comes along the `X-AppEngine-Country` header you mentioned. What is the AppEngine or what is it's purpose? I'm just trying to know if it's something I should implement just to get a country code. Thanks in advance – Fernando Silva Jun 21 '14 at 16:58
  • 2
    That is only for apps, and covers server-side processing of app-provided data. Thus it is not applicable to web pages. – Patanjali Sep 11 '16 at 01:09
  • 1
    I agree with @Patanjali To this date Google API does not accept 'Ip Address' as part of its parameters. It will give you the caller's geolocation. If you place this api call in your server code, it gives you the geolocation of your server. Unless this is a client side code, which could give you geo locaion of the user. (I would test it for different browsers anyways) – Mahshid Zeinaly Feb 09 '17 at 18:56
  • https://stackoverflow.com/a/40049684/2557517 also works. It works on the client side – Kira Oct 06 '19 at 04:23
10

It looks like Google actively frowns on using IP-to-location mapping:

https://developers.google.com/maps/articles/geolocation?hl=en

That article encourages using the W3C geolocation API. I was a little skeptical, but it looks like almost every major browser already supports the geolocation API:

http://caniuse.com/geolocation

Jeremy Wadhams
  • 1,744
  • 18
  • 26
  • 1
    Sadly having support won't mean the user has the feature enabled, many of the browser versions listed as supported by caniuse.com have support, but it is disabled by default. – Dan Jun 20 '14 at 19:08
  • 1
    @Jeremy Wadhams The precision is quite good with this API, but I'm looking for a way to enable certain discounts based on the user's country and making the user have to allow it will simply break the whole idea. Do you have any tips as to how to get a hang of the user's country in a simple way that wouldn't depend on 3rd party services or maybe only google, as it's the only service my employer trusts. – Fernando Silva Jun 21 '14 at 16:51
  • 1
    Two years later, but still relevant. The context of the OP appears to be server-side, but the Google stuff is client-side (uses the *navigator.geolocation* property as per W3C, requiring javascript, which means that you cannot serve a page based upon the location. The freegeoip.net et al solutions can be totally server-side, though they rely upon the IP address being correct (that is, no VPN). – Patanjali Sep 11 '16 at 01:03
  • Won't work in most parts of Africa, as Opera still doesn't support it (in 2016). – Patanjali Sep 11 '16 at 01:04
  • https://stackoverflow.com/a/40049684/2557517 is a better answer. It works on the client side – Kira Oct 06 '19 at 04:24
4

Here's a script that will use the Google API to acquire the users postal code and populate an input field.

function postalCodeLookup(input) {
    var head= document.getElementsByTagName('head')[0],
        script= document.createElement('script');
    script.src= '//maps.googleapis.com/maps/api/js?sensor=false';
    head.appendChild(script);
    script.onload = function() {
        if (navigator.geolocation) {
            var a = input,
                fallback = setTimeout(function () {
                    fail('10 seconds expired');
                }, 10000);

            navigator.geolocation.getCurrentPosition(function (pos) {
                clearTimeout(fallback);
                var point = new google.maps.LatLng(pos.coords.latitude, pos.coords.longitude);
                new google.maps.Geocoder().geocode({'latLng': point}, function (res, status) {
                    if (status == google.maps.GeocoderStatus.OK && typeof res[0] !== 'undefined') {
                        var zip = res[0].formatted_address.match(/,\s\w{2}\s(\d{5})/);
                        if (zip) {
                            a.value = zip[1];
                        } else fail('Unable to look-up postal code');
                    } else {
                        fail('Unable to look-up geolocation');
                    }
                });
            }, function (err) {
                fail(err.message);
            });
        } else {
            alert('Unable to find your location.');
        }
        function fail(err) {
            console.log('err', err);
            a.value('Try Again.');
        }
    };
}

You can adjust accordingly to acquire different information. For more info, check out the Google Maps API documentation.

davidcondrey
  • 34,416
  • 17
  • 114
  • 136
  • Hey thanks for sharing this! I'm trying to call your function like this `(function () { var showPostCode = document.getElementById("showPS"); var ps = postalCodeLookup(showPostCode); showPostCode.value() = ps; });` but no joy. What am I doing wrong? – U r s u s Mar 14 '15 at 15:33
  • https://stackoverflow.com/a/40049684/2557517 is a better answer. It works on the client side – Kira Oct 06 '19 at 04:23