Simple Reverse Geocoding Example

This post is more than 2 years old.

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.

Raymond Camden's Picture

About Raymond Camden

Raymond is a senior developer evangelist for Adobe. He focuses on document services, JavaScript, and enterprise cat demos. If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support. You can even buy me a coffee!

Lafayette, LA https://www.raymondcamden.com

Archived Comments

Comment 1 by Jakob Ward posted on 3/5/2013 at 8:28 PM

Blank screen on Safari.

Comment 2 by Raymond Camden posted on 3/5/2013 at 8:30 PM

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. :)

Comment 3 by Salvatore fusto posted on 3/5/2013 at 8:51 PM

Very interesting!
i tried the demo getting i'm near catanzaro - calabria, why not country (ITALY) too?

Comment 4 by Raymond Camden posted on 3/5/2013 at 8:52 PM

Salvatore, I didn't do any testing outside of America. As you know, America is the only important country in the world.

Comment 5 by Raymond Camden posted on 3/5/2013 at 8:53 PM

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.

Comment 6 by Louis posted on 3/5/2013 at 9:43 PM

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?

Comment 7 by Raymond Camden posted on 3/5/2013 at 9:45 PM

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.

Comment 8 by Louis posted on 3/5/2013 at 9:45 PM

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 :)

Comment 9 by Raymond Camden posted on 3/5/2013 at 9:48 PM

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.

;)

Comment 10 by Louis posted on 3/5/2013 at 9:51 PM

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="http://en.wikipedia.org/wik...">Marquess_of_Queensberry_Rules</a> to protect ourselves :)

Comment 11 by Raymond Camden posted on 3/5/2013 at 10:00 PM

You sure about that longitude? Btw, where are you? (Ie, what value would you expect to see for city/state)

Comment 12 by Louis posted on 3/5/2013 at 10:04 PM

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.

Comment 13 by Raymond Camden posted on 3/5/2013 at 10:06 PM

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?

Comment 14 by Louis posted on 3/5/2013 at 10:10 PM

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.

Comment 15 by Raymond Camden posted on 3/5/2013 at 10:24 PM

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.

Thoughts?

Comment 16 by Louis posted on 3/5/2013 at 10:28 PM

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.

Comment 17 by Carlos Arizpe (Fenhir) posted on 3/5/2013 at 10:30 PM

Works like a charm here in Mexico ... Hello to you out there in Monterrey, Nuevo Leon!

Comment 18 by Raymond Camden posted on 3/5/2013 at 10:31 PM

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)

Comment 19 by Carlos Lopez posted on 3/5/2013 at 10:35 PM

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 = place.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....

Comment 20 by Upendra Roul posted on 3/5/2013 at 10:36 PM

Thanks for sharing.
Working fine here in India with chrome browser.

Comment 21 by Raymond Camden posted on 3/5/2013 at 10:41 PM

Carlos, in the future, please use Pastebin or a Gist. (My previous site had a warning about that - I need to add it back. :)

Comment 22 by Carlos Arizpe (Fenhir) posted on 3/5/2013 at 10:44 PM

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 ...

Comment 23 by Carlos Lopez posted on 3/5/2013 at 10:47 PM

ok sorry :p

Comment 24 by Raymond Camden posted on 3/5/2013 at 10:48 PM

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.

Comment 25 by Anastassios XCrystallis posted on 3/5/2013 at 10:56 PM

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 !!!

Comment 26 by jcesar posted on 3/5/2013 at 11:10 PM

I did a script for european cities, states/regions/countys and countries 3 years ago, maybe I can find it and share.

Comment 27 by papichulo posted on 3/5/2013 at 11: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.

Comment 28 by Raymond Camden posted on 3/5/2013 at 11: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.

Comment 29 by Carlos Lopez posted on 3/6/2013 at 12:14 AM

in order to force the GPS usage you can use "enableHighAccuracy" in the getCurrentPosition function, something like navigator.geolocation.getCurrentPosition(onSuccess, onError, { enableHighAccuracy: true });

Comment 30 by Carlos Lopez posted on 3/6/2013 at 12:20 AM

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...

Comment 31 by Raymond Camden posted on 3/6/2013 at 12:23 AM

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 ;)

Comment 32 by Raymond Camden posted on 3/6/2013 at 12:24 AM

@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.)

Comment 33 by Louis posted on 3/6/2013 at 1:30 AM

@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 ;)

Comment 34 by Chris Bowyer posted on 3/6/2013 at 2:04 AM

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

Comment 35 by papichulo posted on 3/6/2013 at 2:21 AM

@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.

Comment 36 by Raymond Camden posted on 3/6/2013 at 2:25 AM

@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. :)

Comment 37 by papichulo posted on 3/6/2013 at 3:03 AM

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!

Comment 38 by Raymond Camden posted on 3/6/2013 at 3:08 AM

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.

Comment 39 by Patrick Heppler posted on 3/6/2013 at 8:20 PM

Blank screen with Chrome 25 and Firefox 19 on Win 7 box.

Comment 40 by Raymond Camden posted on 3/6/2013 at 9:07 PM

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.)

Comment 41 by Frank posted on 3/25/2013 at 10: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...

Comment 42 by Raymond Camden posted on 3/25/2013 at 10: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.

Comment 43 by Bruno Bincoletto posted on 4/26/2013 at 7:19 PM

thanks man, you save my life!!!

Comment 44 by Jaffer Sulaiman posted on 9/16/2013 at 9: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 mobile...so can u suggest any of the best tool ??

Thanks...

Comment 45 by Raymond Camden posted on 9/16/2013 at 6:54 PM

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.

Comment 46 by Gagan posted on 3/21/2014 at 6:57 AM

Thanks, worked like a charm !

Comment 47 by Oscar posted on 4/5/2014 at 11: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

Comment 48 by Raymond Camden posted on 4/5/2014 at 4:01 PM

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.

Comment 49 by Oscar posted on 4/5/2014 at 8:07 PM

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?

Comment 50 by Raymond Camden posted on 4/6/2014 at 6:20 PM

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.

Comment 51 by Cjones posted on 8/8/2014 at 4:32 PM

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?

Comment 52 by Raymond Camden posted on 8/8/2014 at 5:35 PM

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.

Comment 53 by Raymond Camden posted on 10/7/2014 at 2:11 PM

*sigh*

@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.

Comment 54 by null posted on 1/21/2015 at 2:27 PM

works like a charm

Comment 55 by Ajay Kelkar posted on 1/30/2015 at 12:02 PM

Thanks for the demo. Pretty useful

Comment 56 by Amit Schandillia posted on 5/9/2015 at 6:11 AM

Can one do something like this in a commercial app? I mean say the app reads the coordinates off the phone and spits out the address returned by the reverse lookup. I was reading Google's Maps API ToS and it says one must show the address on Google Maps! What if I just want to show the text of the address? Is it really against their ToS or am I misinterpreting it?

Comment 57 (In reply to #56) by Raymond Camden posted on 5/9/2015 at 1:00 PM

I honestly don't know. I'd suggest asking Google directly. If you don't feel comfortable with it, there's other reverse lookup services.