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.
Archived Comments
Blank screen on Safari.
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. :)
Very interesting!
i tried the demo getting i'm near catanzaro - calabria, why not country (ITALY) too?
Salvatore, I didn't do any testing outside of America. As you know, America is the only important country in the world.
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.
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?
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.
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 :)
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.
;)
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 :)
You sure about that longitude? Btw, where are you? (Ie, what value would you expect to see for city/state)
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.
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?
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.
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?
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.
Works like a charm here in Mexico ... Hello to you out there in Monterrey, Nuevo Leon!
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)
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....
Thanks for sharing.
Working fine here in India with chrome browser.
Carlos, in the future, please use Pastebin or a Gist. (My previous site had a warning about that - I need to add it back. :)
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 ...
ok sorry :p
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.
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 !!!
I did a script for european cities, states/regions/countys and countries 3 years ago, maybe I can find it and share.
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.
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.
in order to force the GPS usage you can use "enableHighAccuracy" in the getCurrentPosition function, something like navigator.geolocation.getCurrentPosition(onSuccess, onError, { enableHighAccuracy: true });
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...
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 ;)
@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.)
@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 ;)
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
@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.
@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. :)
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!
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.
Blank screen with Chrome 25 and Firefox 19 on Win 7 box.
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.)
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...
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.
thanks man, you save my life!!!
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...
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.
Thanks, worked like a charm !
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
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.
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?
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.
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?
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.
*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.
works like a charm
Thanks for the demo. Pretty useful
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?
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.