Twitter: raymondcamden

Address: Lafayette, LA, USA

Simple Reverse Geocoding Example

03-05-2013 26,956 views jQuery, JavaScript, HTML5 53 Comments

Have you ever seen a web site that seemed to know where you were located? I'm not talking about a map, but the actual name of the location? This is done with a process called "Reverse Geocoding." Whereas geocoding refers to translating a human-readable address into a longitude/latitude pair, reverse geocoding is, well, the opposite of that. Given a longitude/latitude pair, what would be the description of that location. In this blog post I'll show a simple example of this process. My example application will attempt to report the city and state you live in.

Once again I'll be making use of Google for my example. One of the services of the Google Maps API is geocoding as well as reverse geocoding. Their reverse geocode API needs a longitude and latitude, we can get that easily enough using Geolocation. Here is a snippet of code that begins the process:

Please note that in this demo, if the user doesn't support geolocation I'm not going to do anything else. They won't get an error though and won't know what they are missing.

Once we have the longitude and latitude, we then fire off a request to the geocode service.

As with our initial geolocation support, all I care about here is a success. If anything goes wrong, I don't care and I just ignore it.

So, here comes the difficult part. The result was from the geocode call is fairly complex. You get an array of results ordered by the quality of the match. If you check the docs, you can see an example of this. Each individual result is also fairly complex. You get an array of address parts that represent, obviously, parts of an address. If you read the "Address Component Types" section of the docs, you can see an explanation of the types of address parts. Each part has one or more of these types applied as a tag.

Based on my reading of the spec, I determined I could get the city when the tag was "locality" and the state when the tag was "administrative_area_level_1." This is US-centric and I've not done any testing yet with other countries.

Given that I knew which tags to look for, I decided to work with the first result and see if I could match those tags:

Again, if there isn't a match I don't throw an error. Since this is simply window dressing for the site it doesn't really matter if we don't get a match. Want to see this in action? Check out the demo below.


These comments will soon be imported into Disqus. To add a comment, use Disqus above.
  • Commented on 03-05-2013 at 9:28 AM
    Blank screen on Safari.
  • Commented on 03-05-2013 at 9:30 AM
    Right. Read the source code. Since nothing else is done on the page, if your browser doesn't support geolocation or if the geocode fails, you would see a white page. In a typical page, there would be more content there. This demo just adds 'flair' to the page. Since the page is empty (again, it is a demo), it fails gracefully but leaves nothing else behind. So this is expected. :)
  • Salvatore fusto #
    Commented on 03-05-2013 at 9:51 AM
    Very interesting!
    i tried the demo getting i'm near catanzaro - calabria, why not country (ITALY) too?
  • Commented on 03-05-2013 at 9:52 AM
    Salvatore, I didn't do any testing outside of America. As you know, America is the only important country in the world.
  • Commented on 03-05-2013 at 9:53 AM
    Ok, sorry - I had to say that. ;) So my demo does NOT do country. Note where I talk about the address types. I specifically said I was looking at city/state only, not country. The code could be modified for that of course.
  • Commented on 03-05-2013 at 10:43 AM
    Weird that Chrome doesn't support it. Asked me if I wanted to allow the page to track my location, hit allow, white screen.

    Or am I missing something?
  • Commented on 03-05-2013 at 10:45 AM
    Chrome absolutely does allow it. This is what I recommend. VIew source, save. Now, add some simply console.log messages and see where it fails. It must be failing someplace.
  • Commented on 03-05-2013 at 10:45 AM
    Nothing in FireFox either, so I'm guessing that my city == '' and my state == '' !

    I think you should make a little modification so we can see a bit of location info in foreignland, Ray :)
  • Commented on 03-05-2013 at 10:48 AM
    Louis, share your long/lat with me. I'll hack it to use that and look at the results.

    Or move to America. We rule.

  • Commented on 03-05-2013 at 10:51 AM
    52.629312, 1.296816

    Thanks for the offer but I'm gonna stay in the UK. Less guns here. We use good old fashioned <a href="; to protect ourselves :)
  • Commented on 03-05-2013 at 11:00 AM
    You sure about that longitude? Btw, where are you? (Ie, what value would you expect to see for city/state)
  • Commented on 03-05-2013 at 11:04 AM
    Am I sure, no! That's the value I got from Google Maps. Stick that into Google Maps search and you should see Norwich, UK.
  • Commented on 03-05-2013 at 11:06 AM
    Ok, I did some testing. First off, thank you Europeans. You're making me expand this a bit. ;)

    For Louis, he had a locality. He did not have a administrative_area_level_1.

    How to handle that is a bit up in the air I suppose. His address came out as:

    27 Castle Meadow, Norwich, Norfolk NR1 3DS, UK

    In a conversation, how would you use that Louis?

    Would you say Norwich, Norfolk?

    Or Norwhich, UK?
  • Commented on 03-05-2013 at 11:10 AM
    I didn't use my exact address but that's the correct location.

    In a conversation to someone in the UK I would say Norwich, Norfolk. Norwich = City, Norfolk = County. If I was talking to someone outside the UK I would say Norwich, UK, or Norwich, England.
  • Commented on 03-05-2013 at 11:24 AM
    Norfolk comes up as administrative_area_level_2. Now you may think, ok, that makes it easy. Look for locality and admin_area_2. But for MY address, and American ones in general (I believe), admin_area_2 would be the same as my locality.

    Perhaps the logic could be:

    1) FIrst try the American way (won't repeat that flow)
    2) Then see if locality != admin_area_2 (assuming we have values for both), and if so, render that instead.

  • Commented on 03-05-2013 at 11:28 AM
    Sounds about right. I guess you'd need a couple of addresses from a decent selection of countries to get an idea of how it relates globally. Plus a little bit of local knowledge to see how addresses read in those countries.

    We had a similar thing at work where an address app of electoral information returned things like Building Number, Building Name, Sub-Building Number, Sub-Building Name, Throughfare, Sub-Throughfare and on and on! Bit of a nightmare but once I'd looked at a decent number of addresses I was able to make some rules that got the address right 99% of the time.
  • Carlos Arizpe (Fenhir) #
    Commented on 03-05-2013 at 11:30 AM
    Works like a charm here in Mexico ... Hello to you out there in Monterrey, Nuevo Leon!
  • Commented on 03-05-2013 at 11:31 AM
    Woot! Which reminds me - I need to get a trip down there. Haven't been to Mexico since my honeymoon. (Maztelan - probably spelling that wrong)
  • Carlos Lopez #
    Commented on 03-05-2013 at 11:35 AM
    i do something like this...

    var onSuccess = function(position) {
          s('lat', position.coords.latitude);
          s('long', position.coords.longitude);

    var geocoder = new google.maps.Geocoder();
    geocoder.geocode( {'location': new google.maps.LatLng(g('lat'),g('long')) },
    function(place, status) {
       fields = 'name,city,state,country,address,street,route,zip,countie'.split(',');
       for( x in fields )
          eval( 'var ' + fields[x] + ' = \'\';' );

       place = place[0];
       name =
                for( x=0;x<place.address_components.length;x++ )
                   types = place.address_components[x].types;
                   sn = place.address_components[x].short_name;
                   for( y=0;y<types.length;y++ )
                      currentType = types[y];
                      if( currentType == 'country' )            
                         country = sn;
                      else if( currentType == 'administrative_area_level_1' )
                         state = sn;
                      else if( currentType == 'administrative_area_level_2' )
                         countie = sn;
                      else if( currentType == 'locality' )
                         city = sn;
                      else if( currentType == 'postal_code' )
                         zip = sn;
                      else if( currentType == 'street_number' )
                         street = sn;
                      else if( currentType == 'route' )
                         route = sn;

                for( x in fields )
          eval( 's(\'' + fields[x] + '\' = ' + fields[x] + ');' );

    // s and g are just localstorage setitem and getitem alias....
  • Upendra Roul #
    Commented on 03-05-2013 at 11:36 AM
    Thanks for sharing.
    Working fine here in India with chrome browser.
  • Commented on 03-05-2013 at 11:41 AM
    Carlos, in the future, please use Pastebin or a Gist. (My previous site had a warning about that - I need to add it back. :)
  • Carlos Arizpe (Fenhir) #
    Commented on 03-05-2013 at 11:44 AM
    Hehe almost had it "Mazatlan", and indeed some heavy CF evangelization needs to be done down here... I'm being interview to migrate some code from CF to .Net , trying my very best to convince them not to. getting the "CF is dying" thing that truly gets to my nerves ...
  • Carlos Lopez #
    Commented on 03-05-2013 at 11:47 AM
    ok sorry :p
  • Commented on 03-05-2013 at 11:48 AM
    No problem. I just fixed that. Also, I forgot to disable the Submit button on click, which means you could accidentally submit twice (which I did). Fixed that too.
  • Anastassios XCrystallis #
    Commented on 03-05-2013 at 11:56 AM
    Hi Ray,

    Thank you for sharing your code with us.
    I tested your demo from Volos city,
    Thessalia- Sterea Ellada region, in Greece
    and here are the results:

    In Firefox 19.0 it works just fine. The response was
    "Hello to you out there in Volos, Thessalia Sterea Ellada!"

    In Chrome v. 25 it was also fine, exactly the same response with Firefox.

    In Internet Explorer 9, the phrase
    "Hello to you out there in" was written in English as in FF and Chrome, but the city and region was written in Greek, but they were also correct !!!
  • Commented on 03-05-2013 at 12:10 PM
    I did a script for european cities, states/regions/countys and countries 3 years ago, maybe I can find it and share.
  • papichulo #
    Commented on 03-05-2013 at 12:25 PM
    I'm running as fast as I can from any website that publicly tells me they know where I am located. I can't imagine anything that would scare visitors away faster.
  • Commented on 03-05-2013 at 12:33 PM
    papichulo: Geolocation requires the user to approve it, so is it really that scary? Also, geolocation can be incredibly useful. For a retail site, it could tell you the closest location.
  • Carlos Lopez #
    Commented on 03-05-2013 at 1:14 PM
    in order to force the GPS usage you can use "enableHighAccuracy" in the getCurrentPosition function, something like navigator.geolocation.getCurrentPosition(onSuccess, onError, { enableHighAccuracy: true });
  • Carlos Lopez #
    Commented on 03-05-2013 at 1:20 PM
    papichulo: i think this is very important, for example if you have a pizza ordering website and the business have many branches you can get the user current location and show him the route from the user current location to the nearest pizza branch... i'm sure you and your clients will like this feature...
  • Commented on 03-05-2013 at 1:23 PM
    Good point there. I wonder if that would be considered necessary for something like this - something specifically looking to get your 'region' and not your precise location. (ie, we aren't firing a cruise missile at you ;)
  • Commented on 03-05-2013 at 1:24 PM
    @Carlos: And you can use another Google service for that - the Directions API. (For folks new to my blog, I've done many entries on that as well.)
  • Commented on 03-05-2013 at 2:30 PM
    @papichulo - As Ray says, you're asked permission in any reputable browser.

    There is no doubt in my mind that maintaining the right to privacy will be one of the biggest issues we face in the 21st century but ultimately location web services are only making it quicker to supply the information we were going to type in anyway ;)
  • Chris Bowyer #
    Commented on 03-05-2013 at 3:04 PM
    Just FYI. I got Sydney, New South Wales, but I am located 100 kilometres miles north, between the City of Gosford and the City of Newcastle. Sydney is just the state capital
  • papichulo #
    Commented on 03-05-2013 at 3:21 PM
    @Ray - It's not that scary, but imagine if everyone starts doing this, I will have to be bothered to "disapprove" 100 times a day while surfing the web.

    @Carlos - I never said it wasn't good technology. BTW, if I search in Google right now for my favorite pizzeria, it already shows me the closest location in my city. If I click on the map of it in the sidebar you can get the driving directions with one click. So in this case all it will add is the annoying "xxxxx wants to know your location."

    My concern is if everybody starts doing this. Do I really need a popup asking me to approve "grandmasjelly in Maine wants to know your location?" No, she doesn't.
  • Commented on 03-05-2013 at 3:25 PM
    @papichulo: How do you think Google knows your location? It is either making guesses based on your IP, or you told it your location in the past (like when signing up for GMail, etc). I do get your drift here - that sites asking for permission could get annoying. At least the browsers use a 'top bar' UX metaphor that you can chose to completely ignore if you want.

    Actually I just checked, and Chrome has a setting where you can turn it off completely. There ya go - problem solved. :)
  • papichulo #
    Commented on 03-05-2013 at 4:03 PM
    What about my grandma? She doesn't use chrome. Will she know how to turn it off? She surfs like 200 sites a day:)
    It doesn't matter since I'm probably the only one left on the planet that doesn't like being tracked. I guess I can turn on "Start private browsing" in Chrome which routes all data through Google's servers. Now that's what I call privacy!
  • Commented on 03-05-2013 at 4:08 PM
    I think, in general, the whole "Permissions UX" thing is definitely a work in progress. As an example, File System storage (a Chrome only feature), has very minimal support in terms of user-side configuration. It can definitely improve.
  • Patrick Heppler #
    Commented on 03-06-2013 at 9:20 AM
    Blank screen with Chrome 25 and Firefox 19 on Win 7 box.
  • Commented on 03-06-2013 at 10:07 AM
    Patrick, you may have not read the earlier comments. I didn't include any additional UI. So if the reverse geocode fails, then you won't see anything at all. If you do not live in America, then it won't match correctly. (Again, see the earlier comments about Euro vs American locales.)
  • Frank #
    Commented on 03-25-2013 at 1:35 PM
    Ray, have you used this API in the context of a PhoneGap app? I am wondering how the usage limit would apply in a case like that...
  • Commented on 03-25-2013 at 1:47 PM
    It is based on your API key, so the same limits would apply. If your app isn't terribly popular, then it won't be a problem. If it is - then you will have to cough up some money.
  • Commented on 04-26-2013 at 10:19 AM
    thanks man, you save my life!!!
  • Jaffer Sulaiman #
    Commented on 09-16-2013 at 12:16 AM
    Hi buddies,

    I want to get the details of nearby places as a category for my geo coordinates using HTML5..Could you please help to find? One thing , i want to develop this Location finder APP for can u suggest any of the best tool ??

  • Commented on 09-16-2013 at 9:54 AM
    Google has a "Places" API that does that. You give it a location, a type, and it will find nearby businesses. I built an app that did that.
  • Gagan #
    Commented on 03-20-2014 at 9:57 PM
    Thanks, worked like a charm !
  • Oscar #
    Commented on 04-05-2014 at 2:09 AM
    Hi there, very interesting the post, some advice to do the next:

    When visits come from 3 states of Mexico, they cannot see the banners ads.

    After doing the reverse geo, how can i collate if the place (city, town, etc) belongs of any of those 3 states and blocking the banners?

    Im stuck
  • Commented on 04-05-2014 at 7:01 AM
    Not quite sure I understand what you are asking. If you want to not do something if a person is from certain cities, or regions, just check the result against a list.
  • Oscar #
    Commented on 04-05-2014 at 11:07 AM
    Thanx Raymond for you super fast answer.

    Yes, not do something if for example the person is from Acapulco.

    And ..... that list will be a records on a database? or a xml?
  • Commented on 04-06-2014 at 9:20 AM
    Well, if the list was in a db, you would need an application server on your server (like ColdFusion, PHP, etc). You would do an XHR to server to get the list of OK states. Then when reverse geolocation is back, just compare.
  • Cjones #
    Commented on 08-08-2014 at 7:32 AM
    As others have stated "Nice post". I am wondering if there is a way to determine it the long/lat is within the city limits? If you visually look on Google Maps you can see that it is, but the resulting XML does not seem to indicate this. This would be a US only application. Any thoughts?
  • Commented on 08-08-2014 at 8:35 AM
    All I can suggest is to check the Google Maps API. It is pretty thorough so it may indeed have something like this. Check the docs and let us know.
  • Commented on 10-07-2014 at 5:11 AM

    @Sylvia, please do not post large code blocks as comments. Use a Gist, Pastebin, or another service to do so. I'm deleting your comment. You are welcome to post it again if you do what I asked.