As you've learned in previous installments of this ongoing series (tutorial 1, tutorial 2, tutorial 3, tutorial 4), the Google Maps API provides an amazingly capable solution for building compelling spatial applications. Yet one of the glaring omissions from the API has been the ability to map locations without the use of third-party solutions for converting mailing addresses to their corresponding coordinates; just as is the case with the Yahoo! and Microsoft Virtual Earth mapping APIs locations can only be pinpointed using their latitudinal and longitudinal descriptors. Whereas the latter two solutions have offered built-in conversion capabilities for some time, Google Maps API users have had to rely on services such as geocoder.us or the US Census Bureau TIGER/Line data for such tasks.
This longstanding feature request was satisfied on June 11 when Google quietly added geocoding capabilities to the API. What's more, this feature isn't limited to the U.S.; street-level geocoding is also offered for Canada, France, Germany, Italy, Japan, and Spain! While limited to 50,000 daily requests, it's fair to say such constraints won't affect most users, particularly if caching is implemented. This tutorial shows you how to use this new feature, further streamlining your use of this wonderful API.
Before you can use Google's geocoding feature, you'll need to register for an API key. This process was covered in the first installment of this series, therefore please refer to that tutorial for further information. Also, the geocoding class is only available in version 2 of the Google Maps API. Although this new version is intended to be almost completely backwards compatible, you must reference the appropriate version number within the <script> URL. Once done, you can continue referring to the Gmap class while still taking advantage of the geocoding feature. Otherwise, to take care of other features found in version 2, you'll need to change this class name to Gmap2. For more information about upgrading, refer to Google's upgrade guide For the purposes of this exercise, I'll use version 2-specific code as everyone already using the API should consider upgrading soon in order to take advantage of the many new features introduced by the upgrade.
Using the Geocoder
getLocations() returns an object to a callback which looks like this:
<kml> <Response> <name>821 Mohawk St, Columbus, OH</name> <Status> <code>200</code> <request>geocode</request> </Status> <Placemark> <address>821 Mohawk St, Columbus, OH 43206, USA</address> <AddressDetails> <Country> <CountryNameCode>US</CountryNameCode> <AdministrativeArea> <AdministrativeAreaName>OH</AdministrativeAreaName> <SubAdministrativeArea> <SubAdministrativeAreaName>Franklin</SubAdministrativeAreaName> <Locality> <LocalityName>Columbus</LocalityName> <Thoroughfare> <ThoroughfareName>821 Mohawk St</ThoroughfareName> </Thoroughfare> <PostalCode> <PostalCodeNumber>43206</PostalCodeNumber> </PostalCode> </Locality> </SubAdministrativeArea> </AdministrativeArea> </Country> </AddressDetails> <Point> <coordinates>-82.992942,39.945728,0</coordinates> </Point> </Placemark> </Response> </kml>
The following example uses getLocations() to retrieve the coordinates of The Old Mohawk Restaurant, one of my favorite locales here in Columbus, Ohio, and plot it on the map. The end result will look like this:
Here's the script:
Of course, you could have consolidated all of the commands under the load() function; I've broken the code down into two functions for sake of readability.
Retrieving Placemark Details
You'll see from the screenshot that all of the address details appear on the same line, and are perhaps a bit too exhaustive. For instance, it should be fairly apparent this map is positioned somewhere within the U.S.A. if the website was focused on say, favorite restaurants in Columbus, Ohio. To modify this output, you can selectively retrieve data from the Placemark object by calling the appropriate nodes, and then passing the data to the openInfoWindowHtml() method. For example, add the following four lines and modify that method to look like this:
var streetAddress = place.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.Thoroughfare.ThoroughfareName; var city = place.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.SubAdministrativeAreaName; var state = place.AddressDetails.Country.AdministrativeArea.AdministrativeAreaName; var zip = place.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.PostalCode.PostalCodeNumber; // Add address information to marker marker.openInfoWindowHtml(restaurant + '<br />' + streetAddress + '<br />' + city + ', ' + state + ' ' + zip);
Reload the script and you'll see output resembling the following screenshot:
Google's new geocoding feature neatly resolves one of the greatest dilemmas faced by developers interested in using the Maps API. I'd love to check out what you're doing with it! Please contact me at wjATwjgilmore.com.
About the Author
W. Jason Gilmore has developed countless Web applications over the past seven years and has dozens of articles to his credit on Internet application development topics. He is the author of three books, including most recently "Beginning PHP 5 and MySQL 5: From Novice to Professional", (Apress), now in its second edition, and with co-author Robert Treat, "Beginning PHP and PostgreSQL 8: From Novice to Professional" (Apress). Jason is Apress' Open Source Editorial Director, and is the co-founder of IT Enlightenment, a technical training company. Check out his blog at http://www.wjgilmore.com/.