In this tutorial, we will go through the process of creating a small widget that allows users to retrieve turn-by-turn directions to a specified location. We'll be using the Google Maps API, via JavaScript, to provide this rather advanced functionality.
Getting An API Key
The only caveat with using Google Maps is we must apply for an API key, but this is a fairly trivial process if you already have a Google/GMail account. Unfortunately due to the requirements of Google we must develop on the domain that we provide Google, i.e. we can not develop on a local server. Fortunately for us the process will be quick and we won't spend a lot of time on the live server. Also, be sure to store you API key in a safe place because I could not find a way to retrieve them once generated, though I guess you could just recreate one.

The State of Affairs
Before we dive into code let me discuss the reason behind this idea. As most developers I spend a lot of time on the web. One particular subset of websites I visit are local businesses who certainly don't have great resources to devote to web design, but hopefully the people that are developing those sites will see articles like this and realize how easy it is to include a full-featured map into any webpage. Almost any website representing a small business has a page dedicated to telling users how to locate their physical location. Often times you get a map with their location pinned on it, which doesn't help users who don't know the area. In this tutorial we are going to change that and let users enter their address and get turn-by-turn directions to any address we want.
Including the Google Maps Javascript Library
Now that the soapbox is out of way lets look into code. The first thing we need to do is include the Javascript library that contains all the Google Maps methods. Google probably generated this code when you created your API key, but that might have pointed to the version 3 API which is still in beta testing. Here is the link to the API version 2 be sure to insert your API key. We are also going to include a file, application.js that will hold our custom functions, I stored mine in a directory at the root level called js. The following code goes within the head section of your page.
<script src="http://maps.google.com/?file=api&v=2&key=INSERT_API_KEY_HERE" type="text/javascript"></script> <script src="./js/application.js" type="text/javascript"></script>
The HTML Code
In the body section of our page we need some limited markup. I will briefly go over the required bits, and you can look at the source code to see the fluff I included in my demo. The first element is an empty div with an ID of map_canvas, this is the placeholder that we point the Google Maps calls to and it will generate all the map markup within that element.
<div id="map_canvas"></div>
Next I created a div to hold the organization address and the form for the user to enter their address. You can look over this code but it is pretty simple and not very hard to discern it's meeting. Be sure to look at my CSS to see how it is styled in my demo.
<div id="addresses">
<div class="address-panel">
<h2>Our Address</h2>
<address>
1450 Jayhawk Blvd #223<br />
Lawrence, KS<br />
66045
</address>
</div>
<div class="address-panel">
<h2>Your Address</h2>
<form action="./index.php" onsubmit="overlayDirections();return false;" method="post">
<div>
<label for="street">Street Address</label>
<input id="street" name="street_address" type="text" />
</div>
<div>
<div class="address-form-column">
<label for="city">City</label>
<input id="city" name="city" type="text" />
</div>
<div class="address-form-column">
<label for="state">State</label>
<select id="state" name="state">
<option value="AL">Alabama</option>
<option value="AK">Alaska</option>
<option value="AZ">Arizona</option>
<option value="AR">Arkansas</option>
<option value="CA">California</option>
<option value="CO">Colorado</option>
...
</select>
</div>
<div class="address-form-column">
<label for="zip">Zip Code</label>
<input id="zip" name="zip_code" type="text" maxlength="5" size="5" />
</div>
</div>
<div class="button">
<input name="submit" type="submit" value="Get Directions" />
</div>
</form>
</div>
</div>
Notice that we are submitting this page to itself this is so we can process the page using PHP if the user has JS disabled. If they have JS enabled we want to execute a function, overlayDirections() which we will take a look at a little later. The bulk of this code goes to the select box that lets the user pick their state, I've condensed it for the sake of those printing this article, but you can grab the full code from the download. Other interesting notes is we set the size and maxlength of the zip code text field to 5. The final thing to take note is that we have assigned ids and names to all of the form elements.
Bootstrapping and Declaring Variables
Alright now we can move into the meat of this tutorial, the JavaScript code. Nearly all the calls we are going to make come from the Google Maps API that we referenced earlier. Google provides excellent documentation and example code on their website so be sure to check it out. I'll try to link to relevant pages as I use them.

The first thing is while we have our HTML page open lets bootstrap the initialize function by setting onload attribute. Note: this could be done in jQuery using the $(document).ready() function.
<body onload="initialize()">
Now we are going to move in to the js/appication.js file. The very first thing we need to do is set some variables. Some code evangelist will probably hunt me down for declaring global variables, but I believe in this case we should be okay. I'll give you the code and then explain how we will use each one.
var gdir, fromAddress, toAddress;
- gdir: holds the GDirections object used to obtain driving directions results and display them on a map and/or a text panel.
- fromAddress: a string that holds the full address of the user.
- toAddress: a string that holds the business/organization address
The initialize() Function
The initialize() function we called earlier will be used to create the Map on the page and place a custom marker of our location.
/*
**
* Bootstrap function to setup map and apply
* custom company marker
*/
function initialize() {
if (GBrowserIsCompatible()) {
//settings
var companyMarkerImage= "./images/jayhawk.gif";
var companyLatLng = new GLatLng(38.957101, -95.251469);
var companyMarkerSize = new GSize(55, 52); //width, height
toAddress = "1450 Jayhawk Blvd #223 Lawrence, KS 66045";
var defaultZoomLevel = 13;
//end settings
//setup elements
map = new GMap2(document.getElementById("map_canvas"));
gdir = new GDirections(map, document.getElementById("directions"));
//error handler
GEvent.addListener(gdir, "error", handleErrors);
//set company marker
var companyMarker = createMarker(companyLatLng, companyMarkerImage, companyMarkerSize);
//set map center
map.setCenter(companyLatLng, defaultZoomLevel);
map.addOverlay(companyMarker);
}
}
The first thing we need to do is check if the browser is compatible with Google Maps, and for this Google provides the GBrowserIsCompatible() in their API. In essence it returns true if the browser is compatible and allows us to move into the rest of our function. I decided to abstract some of the values to variables at the top of the function so that this could easily be ported to many applications.
//settings var companyMarkerImage= "./images/jayhawk.gif"; var companyLatLng = new GLatLng(38.957101, -95.251469); var companyMarkerSize = new GSize(55, 52); //width, height toAddress = "1450 Jayhawk Blvd #223 Lawrence, KS 66045"; var defaultZoomLevel = 13; //end settings
The companyMarkerImage is a string of the location of a small image we will place at our location on the map. This is something I think is a nice touch to have a custom icon to represent your business which will personalize the generic Google Map view. Next, companyLatLng holds a GLatLng object corresponding to a latitude, longitude point in the world. Don't run out and buy a GPS device to get these numbers we can use maps.google.com . In the search box type your address and when it finds the location click the Link button on the top right of the map. Scroll through the first text box in the modal window and find &sll=....

You can copy and paste those coordinates into the parameters of our GLatLng constructor. This is the point on the map where we will place our custom image. The next variable, companyMarkerSize, holds a GSize object which represents the width and height of your custom marker image. Next we set toAddress which is the address of the business. The final variable, defaultZoomLevel, just tells the map what you want the default zoom level to be ranging from 1 to 18.
//setup elements
map = new GMap2(document.getElementById("map_canvas"));
gdir = new GDirections(map, document.getElementById("directions"));
The next line of code creates a GMap2 object. Google describes this as "the central class in the API." This loads the map data and allows us to manipulate what is shown in the map area. It takes one argument a DOM object pointing to the element containing the map, #map_canvas. Next we set gdir to hold the GDirections object. This is the interface we use to query Google Maps for directions. The constructor takes two arguments a map object and a DOM object where we want to put the turn-by-turn directions. I choose to create an empty div below #addresses called #directions.
//error handler GEvent.addListener(gdir, "error", handleErrors);
When using web services we always run the risk of getting an error returned. We can make this as pain free as possible using the GEvent class. In this bit of code we are saying that if we have an error getting the directions to execute a custom callback function, handleErrors in our case. We directly call the addListener() function which registers a callback. It takes 3 arguments a source object, a string referring to the type of event we want to execute the callback on, and a handler which points to a function we want executed. The function, handleErrors, is something we will look at later.
//set company marker var companyMarker = createMarker(companyLatLng, companyMarkerImage, companyMarkerSize); //set map center map.setCenter(companyLatLng, defaultZoomLevel); map.addOverlay(companyMarker);
The last few lines in initialize() are used to create our custom marker, I chose a Jayhawk found on KU's homepage. createMarker is a wrapper function I wrote to abstract the code required to create a custom marker. It takes three arguments: a reference to a GLatLng object where we want to place the image on the, a string respresenting the path to an image, and a reference to a GSize object that represents the size of the image. Next we use the setCenter() method of the GMap2 class which takes two arguments a GLatLng object of the coordinates to center on, and an integer for the zoom level. Notice we are passing in the variables we set in the settings block at the top of the initialize() function. The final line of code uses the addOverlay() method. This is what actually adds the custom image to the map.
The initialize() function does a lot of heavy lifting, but it certainly can show for it. After we write the createMarker() function next you will be able to load up the application and see some progress. But first lets recap the initialize() function.
The createMarker() Function
Next we will create a wrapper function that takes all the pain out of creating a marker with a custom image. The reason I choose to abstract this is because it is an involved process and would clutter up our initialize() function even more. Another added benefit is that we can add multiple markers very quickly without repeating a lot of code.
/*
**
* Wrapper function to create/return a marker object
* with custom image
*/
function createMarker(latlng, imageURL, imageSize)
{
var marker = new GIcon(G_DEFAULT_ICON, imageURL);
marker.iconSize = imageSize;
return new GMarker(latlng, { icon: marker });
}
Considerably smaller than our first function, but just as important. First we declare a new variable, marker, and store a GIcon object. It can take two arguments copy which is a GIcon object that it will copy properties from, and image which is a string representing a path to a custom image. G_DEFAULT_ICON is a constant that represents a default marker, and the imageURL comes from the settings block in initialize(). We only have to set one more property, iconSize which is of type GSize, this represents the size of our custom image and also comes from the settings block. The final line of code returns a GMarker object which takes two arguments latlng, and icon. The first, latlng is a reference to the GLatLng object we declared in the settings block. The next argument is for the GIcon object we just created. That is all we need to do for the map portion of our application to work. You can now load up the page and see how easy it is to get a nice map on our website.

Adding Directions
This is by far my favorite part about this tutorial, allowing users to enter an address and receive back a map with the route highlighted and turn-by-turn directions. Through the use of this API we can condense something that would require thousands of lines of code and an incredible amount of processing resources to just a handful of code.
/*
**
* Looks up the directions, overlays route on map,
* and prints turn-by-turn to #directions.
*/
function overlayDirections()
{
fromAddress =
document.getElementById("street").value
+ " " + document.getElementById("city").value
+ " " + document.getElementById("state").options[document.getElementById("state").selectedIndex].value
+ " " + document.getElementById("zip").value;
gdir.load("from: " + fromAddress + " to: " + toAddress);
}
The first line I have actually extended into five lines for clarity. In essence this grabs all the values from the form and puts a space between each part. I thought this was better than asking the user to enter the whole address into a single text box because that can become confusing.
The second line makes use of the gdir we set in initialize(). We call the load() method and pass a single string argument, which is essentially what we would pass maps.google.com via the search box. The from: and to: keywords help tell Google which address needs to be the starting point and which needs to be the ending point. That is all we need to do for directions, yeah I was shocked too! If you visit your page again you can see this in action.

Handling Errors
Next we are going to declare the handleErrors() function. I grabbed this from Google Sample code on their API website. I won't go into any detail because it fairly straightforward.
function handleErrors(){
if (gdir.getStatus().code == G_GEO_UNKNOWN_ADDRESS)
alert("No corresponding geographic location could be found for one of the specified addresses. This may be due to the fact that the address is relatively new, or it may be incorrect.\nError code: " + gdir.getStatus().code);
else if (gdir.getStatus().code == G_GEO_SERVER_ERROR)
alert("A geocoding or directions request could not be successfully processed, yet the exact reason for the failure is not known.\n Error code: " + gdir.getStatus().code);
else if (gdir.getStatus().code == G_GEO_MISSING_QUERY)
alert("The HTTP q parameter was either missing or had no value. For geocoder requests, this means that an empty address was specified as input. For directions requests, this means that no query was specified in the input.\n Error code: " + gdir.getStatus().code);
else if (gdir.getStatus().code == G_GEO_BAD_KEY)
alert("The given key is either invalid or does not match the domain for which it was given. \n Error code: " + gdir.getStatus().code);
else if (gdir.getStatus().code == G_GEO_BAD_REQUEST)
alert("A directions request could not be successfully parsed.\n Error code: " + gdir.getStatus().code);
else alert("An unknown error occurred.");
}
It has a long if...elseif...else statement that checks for many error types and alerts the user if any occur. You can modify this if you wish to make the alert less technical.
Degradable
As good web developers we should make sure our website works for as many users as possible, including those with JavaScript disabled. In this situation I chose to redirect those with JS disabled to Google Maps with the search performed so they still get directions. This is done using PHP to evaluate the form and redirect to Google Maps. At the top of your HTML page insert this code:
<?php
//settings
$TO = "1450 Jayhawk Blvd #223 Lawrence, KS 66045"; //company address
//end settings
//they seem to have JS disabled, let's redirect them to
//Google Maps and prefill the query
if($_POST['submit']) {
$FROM = $_POST['street'] . " " . $_POST['city'] . ", " . $_POST['state'] . " " . $_POST['zip'];
$LOC = $_POST['language'];
$url = "http://maps.google.com/maps?hl=".urlencode($LOC)."&q=from:".urlencode($FROM)."+to:".urlencode($TO)."&ie=UTF8";
header("Location: " . $url);
}
?>
...
First we have a settings block again which only has one variable to set, $TO. This is similar to what we did in JavaScript for toAddress, but we need the same string in PHP too. Next we have an if statement to check for POSTed data which means our form was submitted. Now we grab the form values and place them in a string with spaces and store that in a variable, $FROM. Then we store the language value to $LOC, more on this later. The $url variable will hold the string representing the query URL to Google. Notice that we url-encode our values so they safely travel on the redirect. The final line of code uses PHP headers to redirect the user to Google.
Optional: Add Multi-Language Support
As a business you want to reach out to as many people as possible and part of that process is supporting multiple languages. In Google Maps supporting other languages comes at no extra cost to us.
First open up your HTML page and insert the following code between your form tags.
... <select id="language" name="language"> <option value="en" selected>English</option> <option value="fr">French</option> <option value="de">German</option> <option value="ja">Japanese</option> <option value="es">Spanish</option> </select> ...
Of course if you want to remove any languages just delete the option tag for it, you can also change the default by moving the selected attribute.
Moving to js/application.js, we need to make just two changes. Starting in the overlayDirections() function after we create the string fromAddress add this to grab the selected value from the language select box and save it to our language variable.
...
var language = document.getElementById("language").options[document.getElementById("language").selectedIndex].value;
...
Next, add an argument to the gdir.load() function, this takes an options set. In our case we only need to declare locale so it knows the proper language and units for the turn-by-turn directions.
...
gdir.load("from: " + fromAddress + " to: " + toAddress, { "locale": language });
...
Note: We already included this in the PHP redirect and if you want to disable this just statically set $LOC.
... $LOC = 'en' ...

Conclusion
That is all we need for this amazing feature, and I hope you learned a bit about Google Maps along the way. I challenge you as developers to continue to find interesting ways to integrate maps in to your applications. Anytime a model is location aware, you should question if your project has a use for visual representation on a map. Thanks for reading; as always, I am here to help in the comments or on Twitter (@noahhendrix).
- Follow us on Twitter, or subscribe to the NETTUTS RSS Feed for more daily web development tuts and articles.
Related Posts
Check out some more great tutorials and articles that you might like
Plus Members
Source Files, Bonus Tutorials and
More for $9 a month for all TUTS+
sites in one subscription.











User Comments
( ADD YOURS )Meshach June 30th
Very nice!!
( )Brian Cray June 30th
Great!
If you ONLY want the driving distance between to locations, visit my tutorial “How to calculate driving distance with Google Maps API”: http://briancray.com/2009/06/23/calculate-driving-distance-google-maps-api/
If you want to find the visitor’s location, visit my tutorial “Find web visitor’s location automatically with javascript and Google APIs” http://briancray.com/2009/05/29/find-web-visitors-location-javascript-google-api/
( )Noah Hendrix June 30th
Wow very impressive I am glad to see other developers agree that Google Maps has incredible potential on company/personal websites.
( )Ian July 1st
Just so you know your driving distance between to locations tutorial violates the Google Maps API. You’re pretty much not allowed to use the API unless you also display a map on the page.
( )Myfacefriends June 30th
another great tuts! thanks
( )netoxico June 30th
very useful!!! thanks man!!!
( )Johnathan June 30th
I wanna give this a go but I wanna see a demo of what it actually does before I put the time in. Anyone done it and got it online?
( )Noah Hendrix June 30th
Here is the demo I created while writing this tutorial, http://su.pr/2oM1FD
( )Johnathan June 30th
Thanks, any chance you could give me a local address? My UK one wont work with it
Noah Hendrix June 30th
Haha yeah you can use
1800 Engel Rd
Lawrence, KS
66045
My old dorm address.
Neil June 30th
interesting… handleErrors is not defined
[Break on this error] GEvent.addListener(gdir, “error”, handleErrors);
Noah Hendrix June 30th
Neil, you might need to read further down and put the handleErrors code into the application.js file as well. Let me know if that still breaks it and we can take a closer look.
crysfel June 30th
thanks for the tut, i really like the google maps api
( )Paul June 30th
Cool tutorial. (Too bad you had to put that ugly mythical bird on there.)
( )saurabh shah June 30th
wow ! nice tutorial … will try it out soon …
( )Christoph June 30th
greate tutorial, but the api version 2.x is old
( )google have published the new api 3.0 at 27 may 2009
there is fast, supported mobile devices, no api key and match more…
looked at http://googlegeodevelopers.blogspot.com/2009/05/announcing-google-maps-api-v3.html
Steve August 29th
api 3.0 isn’t finished yet, for example it doesn’t currently support directions.
( )david June 30th
Rather than pass a street address would it not be better to pass lat and lng? That way the Google servers do not have to geocode (a very expensive task) your address each time. Furthermore if you pass a street address there is no guarantee that it will point to the correct building. Google updates its geocoding algorithm all the time. If you pass lat and lng then you know for sure its the correct building.
( )Chris June 30th
Exactly. And all users know their longitude and latitude, so it’d be easy!
( )Kevin Urrutia June 30th
nice trying it soon
( )Andi June 30th
Google offers some good APIs, very well documented. Thanks for this tutorial.
( )Dario Gutierrez June 30th
Google Maps API is incredible!! Very detailed tut, thanks.
( )Martin June 30th
For those who want to try this out on their local development server here is a API key for ‘localhost’:
ABQIAAAAnfs7bKE82qgb3Zc2YyS-oBT2yXp_ZAY8_ufC3CFXhHIE1NvwkxSySz_REpPq-4WZA27OwgbtyR3VcA
( )Sam June 30th
Brilliant… just what I have been looking for… thanks mate
( )dave June 30th
sure looks a lot like
http://www.easykiss123.com/add-google-maps-to-your-website/#more-8
If that’s where you got it from you need to credit the original author..
Also using the body tag to load it is anything but ideal.
( )Noah Hendrix June 30th
While I agree that they are solving the same problem that I am, I do not see why you claim I used that resource without crediting when there are many websites that have similar tutorials elsewhere.
http://briancray.com/2009/06/23/calculate-driving-distance-google-maps-api/
http://econym.org.uk/gmap/directions.htm
I did not use these websites including the one you reference, but they are an example of how similar tutorials have been written and each are well written.
The only resource I used was Google Maps API website and the examples provided on it, which I do link to many times in my tutorial.
——
I agree that the body tag is not the ideal place to load javascript, I would much rather use the JQuery onready() function (as I mention in the tutorial), but it felt dirty to drag in JQuery for that small reason.
( )dave June 30th
ok.. well I just thought it was pretty close to that other one and just making sure….
Bringing jquery in wouldn’t be a “small” thing it would be much more useful. If your site uses a header file and you only need the body onload function once then it is not real good practice to always have it there. With the way I used it before from other article I just switched out the body tag if it was on maps page but that isn’t ideal either. I guess you “could” just have jquery replace the body tag on that page.
Aayush June 30th
great tutorial….it’ll be really helpful in my next client project….
( )Md. Shoriful Islam Ronju July 1st
Great job buddy. I think this will help me a lot.
( )ryr July 1st
mmmmmmmmmmmmmmmmm
The FLASH implementation in FlashTUTs was a lot better
( )GP July 1st
Hello,
Can someone say how much a total site will cost if you want 1?
Something like: http://www.abduzeedo.com
If i want something like this, total made and coded, how much will that cost me?
GP
( )diddy July 1st
does the image marker work for anyone?
( )Mark July 1st
Rock Chalk!!! Now I can find my way from west Lawrence to campus. But serious, thanks for the tutorial.
( )webangel78 July 2nd
It looks easy to do. I was looking for tutorial like this. Thanks.
( )Tony Smith July 3rd
An impressive article… I often use a private search engine called aafter.com to find the direction of a place. All I need to do is write the address in the search box and the search engine returns the map and direction of the address.
( )hcabbos July 4th
Hmm. Can’t get the demo at http://demo.collegeaintcheap.com/envato/GMaps/ to work on Firefox or Safari on Mac. Anyone else finding this to be the case?
( )colt July 4th
Its not working on mac either….
( )Noah Hendrix July 7th
I had removed my API to create the zip download, it should be all fixed now.
( )webmasterdubai July 5th
hi im getting this error sendToGoogle is not defined. helpe me.
( )Noah Hendrix July 7th
For people having this problem update line 23 of application.js to this
GEvent.addListener(gdir, “error”, handleErrors);
Sorry for the mis-type in the demo
( )Alex July 6th
Right now there is only a blank map at page load. I have to input address info before I see the map. Is there a way to have the map show up without adding any info into the form fields?
Thanks
( )Noah Hendrix July 7th
Make sure you update the onload function in the body tag.
( )Chris July 8th
I’m having the same problem. I’m unclear on what you mean by that. Is there a correction that I’ve missed?
Also whenever I click “get directions” it hops to the google maps page and says this “Your search – from: El Dorado, KS to: – did not match any locations.” I’ve followed your instructions step-by-step. What did I miss?
Cool idea and thanks for sharing! Rock Chalk
Brandon Davis September 8th
@Noah what do you by ” Make sure you update the onload function in the body tag.” ?
And if there is no way to get the map to show before the user adds an address. Is there a way to change the color of the off white square that is displayed…?
Marty September 16th
I’m in the same boat here. Anyone found a solution?
Thanks.
michael July 13th
Nice job.how can i search for a location and save it on a database
( )Terry July 13th
I spent ages trying to figure out why every address I put in returned a 602 error..
You have not defined the toAddress anywhere.
It needs to be either hard coded into the application.js or maybe as a hidden field in the original form, then read as toAddress = document.getElementById(”to_address”).value;
( )Visitor July 14th
Is it possible to change the styles of the turn-by-turn directions ?
I can’t find any reference to that anywhere, and my directions are in a huge font on screen.
( )James July 21st
Use Firebug to define the style that is being applied to the text and then overwrite the style in your own css stylesheet.
Worked for me
( )Ken July 26th
I unzipped the zip into my web folder and replaced INSERT_API_KEY_HERE with the api key I got from google, but I couldn’t get it to work. Do I need to wait 24 hour or something?
( )Ricardo August 8th
Awesome!!! Thanks!!!
( )Adnan August 18th
Hi
How can I make this tutorial workable for places where Direction feature is not supported? I am from Pakistan and want to make route app for my city
Thanks
( )Siddique Daur November 2nd
Crystal Clear…
Thumbs Up
( )Siddique Daur November 2nd
Adnan.
U can get the direction through any gps device.
go 2 maps.google and give directions and copy the link
from there..
im Peshawar here
( )YhwhDesign November 6th
This might be a dumb question, but is there not any way to do this exact thing but by using flash? for the google map, the text fields, the whole shabang…
Any ideas? thanks
( )nimmy November 20th
hi,, i want to calaculate the shortest distance to my destination in london…it is not working with this code. can u tel how can i get it?
( )