Geocoding Tool for Virtual Earth & Google Maps

Would you like to be able to geocode Virtual Earth and/or Google Maps without the hassle? Or how about any application requiring the use of javascript?

Well, you can use this API for it:

It is a javascript API and you can call it like so:

The base url is:

To enter a freeform location (you have one entry box that accepts any address format such as street address, zipcode, city/state, etc):,+Mountain+View+CA++94043
In other words, just use the “loc” parameter. Currently, only the US is supported for freeforms….I have to decode all potential formats for non-US addresses.

If you would like more accuracy (or international support), break the text entry fields up into multiple fields. Mix and match and use whichever you’d like from the following parameters:
address (street address)
some examples:

The default URLs above are for the Google Maps API. To use the Virtual Earth API, construct the url the same as you would above and add the following parameter “&ve=1” … for example,,+Mountain+View+CA++94043&ve=1

Alternatively, if you choose to use neither Google Maps nor Virtual Earth (or to have better control to do what you want), you can set a callback parameter with ‘cb=<MethodName>’ like so:

Some intillegence is there to try to guess the appropriate one…however, if you prefer to override it with your own, you can add the parameter “level=
For example: yields Google Maps zoom level 4
but you can force it to zoom level 1 by using this url:

Default behavior is for an alert to happen onerror (currently there are only 2 errors: ‘location not found’ and ‘Please provide a location’). To override this behavior, you can specify a callback for errors by adding a parameter ‘cbe=<function_name>’
For example, the first link below will provide an alert error but the second one will use the specified callback:

If you are not very familiar with javascript and how to leverage this, you can take a look at some of the source of some of the sites using them:
Virtual Earth example
Google Maps Example

Basically, you’ll either use a “script src=<url>” or

var s = document.createElement( “script” );
s.type = “text/javascript”;
document.getElementsByTagName( “head” )[0].appendChild(s);

Recommendations? Errors? Feature requests? Post them here and I’ll try and fix/add.

UPDATE: You can now lookup information and geocode by IP Address.
To lookup by the requesting ip address, just add “by_ip=1” like so:

To get city/state info, use a callback:

To lookup an ip address by passing it in, rather than using the requestor’s ip:

Keep in mind, when using ip addresses, that this info isn’t always very good and, in fact, many ip addresses will not have any data. I have built it in to try looking up by ip address when the by_ip=1 parameter is used but to fall back on the other lookup info (i.e. loc or city infor passed in) if the ip address lookup fails.

To try it out, check out the virtual earth or google earth geourl sites and click on the “Guess by my IP Address” link.

UPDATE: API now supports &phone= as well as &format=.
The phone parameter tries doing a reverse lookup to find an address then geocodes that address for you.
The format parameter accepts “xml” or “json” to output in those corresponding formats. Here is an example utilizing both of these features:
The above is a lookup of the Burbank Chamber of Commerce phone number.

So what am I asking in return for use of this tool?
Well, I’m asking (but not requiring) a reciprocal link to either the homepage or to this blog’s homepage.

Any usage limitations?
Well, if you overburden this server, I might throttle you or even shut you down if you abuse it (never happened yet!). If you think you are blocked, feel free to email me and I will unblock you as long as we clear up any issues.

UPDATE: I have added a new feature as of 2004/02/24. You can now do a reverse lookup of lat/long to address. It currently is much more limited in area and in accuracy than other components of this framework and its performance/response time is not that great yet so use with caution and I will improve over time (feedback always welcome).
To use it, just specify a latitude and longitude in your request like so:

Like this service? Help make sure it keeps a good level of service (or even improves it) by donating:

… or how about just a link back to me or

Author: emad

Cofounder of Connectivity / YellowBot; Former IAC Exec / CTO Citysearch and Local Search speaker; Husband & Father; BasketBall & Lakers fan

57 thoughts on “Geocoding Tool for Virtual Earth & Google Maps”

  1. I would like to be able to just point a browser to, without having a web site of my own. Is there a way to do this?


  2. Is this getting a query string? I don’t understand how this works:

    document.getElementsByTagName( “head� )[0].appendChild(s);

    I’m trying to use the query string to append to the localsearchmaps url as you’ve done above, but this doesn’t work (I’v already set up a web page with a google maps ID, that part is working), and QueryString is parsed elsewhere

    function go_to_url() {

    var queries = QueryString(‘loc’);
    var url1 = “”+queries
    var temp1 = “”
    var temp3 = temp1 + url1 + temp2


  3. this: document.getElementsByTagName( “head� )[0].appendChild(s);
    is appending the javascript to you created in the object named “s” at the end of the “” tags…just remember to use the entire snippet provided above to create that object.

    This api is meant to be called as an external javascript file.

    Once you’ve created the url:
    var url1 = “�+queries

    You can either use the document.getElementsByTagName( “head� )[0].appendChild(s) method or you can do a:

    If you want more help, and are willing to provide your url, email it to me or post it here and I’ll be glad to help.

    Good luck!

  4. I was asked by Arsen Vladimirskiy who asked what the source of the geocoding was.

    My geocoding leverages multiple freely available sources that any of you could build. This API was made for those who don’t want to go through the hassle of 1, let alone all of them.

    The sources include many I’ve mentioned here but am too lazy to write and put links for (so go to that entry to get them). 🙂

    I then weight the different sources based on their reliability/accuracy based on experience and algorithmically to get the best results (i.e. many of those sources are national US only, etc). I then fall back to the next most reliable if the geocoded info isn’t available.

  5. Thanks for building this!

    I’m having a hard time figuring out how this should work wil the whole



    How do I get the correct “….” in there?


  6. hmmm…the comments didn’t like my copy paste…here goes again:

    function createMap(){ var map = new GMap(document.getElementById(“map”));
    map.addControl(new GSmallMapControl());
    map.centerAndZoom(new GPoint(-74.005565,40.739101), 2);
    var point = new GPoint(-74.005565,40.739101);
    var marker = new GMarker(point);

  7. actually, no.

    i’m trying to get the results from to appear within in js that draws the gmap…


    function createMap(){ var map = new GMap(document.getElementById(“map”));
    map.addControl(new GSmallMapControl());

    var s = document.createElement( “script” );
    s.type = “text/javascript”;
    document.getElementsByTagName( “head” )[0].appendChild(s);

    var marker = new GMarker(point);

    does nothing for me…
    the s.rc shows the correct address to query, but how do i get back that essential line, “map.centerAndZoom(new GPoint(-83.7458, 42.2833), 4);”

    is that more clear?

  8. this still returns a big grey map:
    (sorry! and thanks sooo much!)

    function createMap(){
    var map = new GMap(document.getElementById(“map”));
    map.addControl(new GSmallMapControl());

    var s = document.createElement( “script” );
    s.type = “text/javascript”;
    document.getElementsByTagName( “head” )[0].appendChild(s);

    var marker = new GMarker(point);

  9. np!

    check out the source to this page (don’t forget to replace the google api key with yours when you download it).

    A few things:
    1. when adding a marker, you have not defined the variable called “point.” To add one, use “var point = new GPoint(xcoord,ycoord);”
    2. You needed to properly scope the “map” variable. So I scoped it outside of the createMap function so other things outside of that method can access/use it

  10. This feature would help because of the long time for responding. When the page make the call, can showup a ‘LOADING’ message, and after loding to hide it.

    For now, the user click it and wait.. and wait… without knowing what’s happening.

  11. My map displays correctly using the appendChild method you demonstrate. My question is, how do I get the x and y coordinates from that to use in creating my marker?

  12. Thanks for the service Emad, it works like a charm (although the data for my country is pretty inaccurate, but I believe that’s my ISP’s fault).

    Mike, you could try using some PHP, like this:

    $query = “zip=12345”;
    $info = file_get_contents(“$query”);

    and then parsing $info to get the coords, and use them elsewhere on your page.

  13. Hi Humberto.

    Thanks! This tool uses ISO country codes but I try to transalte country names as well.

    Please let me know if there are countries that aren’t getting translated.

    TODO: handle FIPS country codes as well. 🙂 (assuming no collision between ISO and FIPS mapping the same 2 characters to different countries).

  14. Thanks for your reply.
    There are collision bettween ISO and FIPS codes – e.g. AS is American Samoa in ISO and Australia in FIPS. So better keep only one standar.
    About country names. I have try some names and for some it works even if I try the names in my native language (portuguese) others doesn’t work neither with native names and english names.
    So my opinion is: use only one country codes standar and let your users use the country names in what language they want and passe the code to your tool.
    Best regards

  15. Hi, again.
    After some research it seems you are using ISO 3166-1 alpha-2 wher thw code for East Timor transitional reservation TP ( the code your recognize), but now the code is TL.
    Making a search for Dili (East Timor capital) with country code TP the results are correct, using TL gives a place somwhere in New Mexico USA.
    Thanks and keep going

  16. Hi,

    We at were trying to use your service for geocoding, however your web app was down for some time on the 11th of April. Does your app go down a lot? Thanks for providing this service.

  17. Hi David,

    The service wasn’t actually down…the problem was with an upstream network provider. Depending on where you were located, you might have experienced network slowness trying to communicate with my servers.

    Site availability has always been good (even when the problem is out of my hands due to upstream providers). I’ve always monitored my site (even before this service was launched) to create the best possible availability…but understand this is a free service.

    I have and will continue to improve availability…All my sites and services will be expanding to a load-balanced environment across 2 completely different network environments. This will hopefully eliminate all availability issues since I will have a fully redundant copy of all my applications and data in 2 completely different locations. My timeline for this is within 3-4 months. In the meantime, like I said, the availability of the site is pretty good.

  18. Hi Emad,

    Thanks for the tool – it is very useful, but since I upgraded my Google Map API from version 1 to version 2, I think the Longitude and Latitude are appearing in the wrong order (ie. they appear currently as latitude-longitude, when it should now be longitude-latitude). Any ideas on how I can switch this around?

    Thanks, Alan

  19. In fact, looking into it further, Google have changed alot of the functions. And so, if you are using the new Google Map version 2 output should look something like this:

    map.setCenter(new GLatLng(51.5063, -0.1271), 1);

  20. Good point, Alan!

    I have now created another type “google2”

    so, you can append the parameter “&use=google2” to the url (or “google” or “ve”) or you can specify it the same way you do above “&google2=1

    your choice on which to use.

  21. Just to let you know…your output is:

    map.setCenter(new GLatLng(“34.1003, -118.3271”), 4);

    It should have no perentecies

    thanks 🙂

  22. Exactly what I was looking for! Thanks, Emad!

    One issue I came across: Safari has problems with “long” when using dot notation with the returned json data.

    For example, if I assign the json result to the variable “jsonResult”, referring to “jsonResult.long” causes Safari to generate a “SyntaxError – Parse error” and aborts the whole page. On the other hand, using jsonResult[“long”] works fine.

  23. Rob,

    You are getting the “best possible” match for your entry.

    In your first example, you are supplying a valid zipcode of 83714 so you are getting a zipcode-level match against that zipcode.

    This type of behavior allows for the best possible experience for you user.

    You can, however, get more access to information about the geocoding. If you use the json or xml output, you get a level or matchlevel parameter, respectively (and other extended data). These tell you how good the match was.

  24. Is there a way to just get back the x and y coordinates for the latitude an longitude? I assume I need those for the var point = new GPoint(xcoord,ycoord); line so I can get the marker to appear on the page. I figure I could parse those coordinates out of what you return in but I thought there might be an easier way.

    Love your tools!

  25. Hi Jochen,

    While I wasn’t originally sure if I wanted to support it because it was originally running off of my dsl line and could easily chew up my bandwidth, I let people go ahead and do it as long as they paced out their requests a bit.

    However, I have now moved my application to a dedicated host and will “officially” support it. 🙂

    In other words, go ahead!

    If the data you want batch-geocoded is large, feel free to contact me about sending me a file and having the geocoding done locally on the machine, then have the results returned to you. This can be faster for large data sets since you avoid the network overhead on each request.

  26. Great service, just what I was looking for! Reall pleased you can do UK postcode lookups as well as US zips.

    Rather than using the include file suggested above, I plan to make HTTP calls via AJAX. If I use a custom callback method name, all I need to do is evaluate the response text.


  27. Glad you like it Stu. Just as an FYI, I like using the JSON calls with AJAX. The output can be eval’ed or parsed within javascript.

  28. Hi, I am the author of phpGoogleStoreLocator, an open source project that utilizes the googlemaps api as well as yahoo and for geocoding addresses in the US/Canada. I’ve been searching for a UK geocoder (as well as Australia) for about 8 months now and had absolutely no success what so ever at finding a free one until now. I wanted to know if you would have any objections to me adding your geocoder to my application for my user base to use. I noticed it does more than just the UK and would be interested to know if there are any hit per day limitations I need to let them know about and what other countries it is capable of geocoding. I wish I could have found your site sooner, but I just stumbled upon it today.

  29. I was wondering why my unit tests suddenly start failing for the locating! I think it’s a good idea that you changed the uri to stop people from scraping the site. Just so you know i’m using it for my site and have so far probably only requested about 10 sets of coords =)

    I’m going to be giving you a plug in my about page.

    Have you considered maybe implementing some kind of api-key system to make sure people register in order to use the service? Might stop people leaching…

  30. mathieu Gosselin is using this service with his yahoo maps application in flash. He emailed to tell me that it wasn’t working and asked if I had blocked his IP Address since he could reach it in his browser but not within the application.

    I did a bit of research and found that flash applications make requests to crossdomain.xml from the intended target uri of a domain to make sure that applications that exist outside of a domain can access services from that domain.

    Since, I didn’t have one, the flash application would not make the request to the geocoding url. I have gone ahead and created this file and made it universally accessible by all domains. Feel free to utilize your flash applications with this tool.

    Thanks, Mathieu!

  31. Hi there – superb piece of coding! Been looking for a postcode to lat long geocoder that a. doesn’t cost a fortune and b. is a piece if cake to use.

    Looking at using this API in a new community GPS sit i’m building. Will happily credit you if ican use this api – i’ve read the notes about throttling piss-takers!

    Drop me a line if you can with any info you think a should know / a graphic or logo if you’d like me to use one on the site and anything else you think may be relevant.

    Many thanks


  32. This might not be the right place but it looks like someone might know an answer.

    I have a co-ordinate, 51°32.350711N, 003°08.165039W – anyone know how I can geocode that so that i can use it in Google Maps?


  33. I’d just like to say that Emad’s Geocoder service is fantastic and he is prompt and generous with any help he can give. The world would be a nicer place with more guys like him. Thanks again for the help you gave me Emad!

  34. Anyone know of a utility similar to this(or this one) that we can use without having to pay Google $10,000 a year? and not break their T&C’s


  35. Looking for the code to this so that I can use it on my server. Tried to run from the links on the pages and nothing spits back. It’s the solution to my page generation problem. I was surprised that there was an actual example of what I was looking for.

Leave a Reply

Your email address will not be published. Required fields are marked *