Getting Directions Using the Google Maps API

Share this article

In Working with Geolocation and the Google Maps API you learned how to determine a user’s physical location and display it on a map. In this followup article, you’ll create a service that lets a user get directions from one address to another. To enhance the user experience, the service will also allow the user to automatically use their current position as the starting point. This article assumes that the reader is familiar with the content from the previous post. With that said – let’s get started.

Exploring the Google Maps API Further

In the demo you’ll become reacquainted with your old friends Map, LatLng and Geocoder. You’ll also make some new friends. The first one is google.maps.DirectionsService, which calculates directions (or routes) between two or more locations. This class is very simple. Its constructor takes no parameters, and it has just one method, route(), which calculates directions. This method accepts two parameters, a google.maps.DirectionsRequest object and a callback function. The google.maps.DirectionsRequest object is used to set options that the route request must satisfy. The only required properties of this object are origin, destination, and travelMode. The first two properties define the start and the end of the path, while travelMode defines your mode of transportation. The possible values are bicycling, driving, walking, and transit (using the public transportation). One important thing to note is that origin
and destination can use either a LatLng instance or a string containing the address. As I said, the request can also include several options like unitSystem that ask to return the distances using a specific unit system. The possible values are metric (google.maps.UnitSystem.METRIC) and imperial (google.maps.UnitSystem.IMPERIAL). The default is chosen based on the country of origin. You can also specify a set of intermediate points to pass through using the waypoints property. Additionally, you can constrain the directions. For example, you can ask for a route that doesn’t use highways, if possible, by setting the property avoidHighways to true. You can also try to avoid toll roads by setting the avoidTolls property to true. The callback function of DirectionsService returns two values, a google.maps.DirectionsResult object and one of the possible values (actually properties) of the google.maps.DirectionsStatus
class. The former has just one property, routes, that is an array of DirectionsRoute and contains the information for every path calculated. The DirectionsStatus represents the final state of the request, and can indicate success (DirectionsStatus.OK), no results (DirectionsStatus.ZERO_RESULTS), or an error (like DirectionsStatus.INVALID_REQUEST or DirectionsStatus.REQUEST_DENIED). Another of our new friends is the google.maps.DirectionsRenderer class. It renders directions retrieved in the form of a DirectionsResult object retrieved from the DirectionsService. This class only contains getters and setters, so we won’t explore it further. The only remarkable thing is its constructor, which accepts a google.maps.DirectionsRendererOptions object that allows you to set several options. The key properties of the latter are directions and map, that set the routes to display (retrieved using DirectionsService) and the map object used to show the routes.

Let’s Start Coding

Now that you’ve seen all of the new classes used in this article, it’s time to dive into the code. To enable the user to ask for a path from an origin to a destination, the first thing you need is a form. It’ll be very simple because it needs just two <input> elements and a submit button. However, to enhance the user experience, the page will also offer the chance to automatically fill an <input> with the user’s current position. To achieve this goal, I’ll put a link below each <input> that once clicked, will retrieve the user’s address using Geolocation and the Google Maps API. The form to implement this feature is shown below.
<form id="calculate-route" name="calculate-route" action="#" method="get">
  <label for="from">From:</label>
  <input type="text" id="from" name="from" required="required" placeholder="An address" size="30" />
  <a id="from-link" href="#">Get my position</a>
  <br />

  <label for="to">To:</label>
  <input type="text" id="to" name="to" required="required" placeholder="Another address" size="30" />
  <a id="to-link" href="#">Get my position</a>
  <br />

  <input type="submit" />
  <input type="reset" />
</form>
Now we’ll move on to the business logic behind the demo. Unlike the first article, we’ll take advantage of jQuery to quickly select elements in the DOM and to attach handlers in a cross-browser manner. Since all of the work is done on the client-side, the first thing we need is to block the default behavior of the form, and run some additional JavaScript that we’ll cover later. To achieve this goal, we’ll attach a handler to the form’s submit event. The handler uses the jQuery preventDefault() method and then calls the calculateRoute() function. The code that implements this is shown below.
$("#calculate-route").submit(function(event) {
  event.preventDefault();
  calculateRoute($("#from").val(), $("#to").val());
});
The most important code is contained in the calculateRoute() function. The function will accept two parameters, from and to, that represent the origin and the destination address, respectively. The first step is to create the map instance, as shown in the following code.
// Center initialized to Naples, Italy
var myOptions = {
  zoom: 10,
  center: new google.maps.LatLng(40.84, 14.25),
  mapTypeId: google.maps.MapTypeId.ROADMAP
};
// Draw the map
var mapObject = new google.maps.Map(document.getElementById("map"), myOptions);
Before we go any further, there are some considerations I’d like to discuss. As you have seen, I used a static position to initially center the map. As you learned in the previous article, the center property is required. In this demo, you might be tempted to omit it because if the route request succeeds, the map is redrawn and centered accordingly. You shouldn’t do this, because if the request fails, you’ll see a gray-filled area. An alternative could be to initially center the map based on the user’s current position. This requires an additional geolocation lookup, so you might consider it a waste of resources. Next, you need to create the DirectionsService instance and the directionsRequest object, as shown below. This demo only uses the unitSystem option, but you can expand further.
var directionsService = new google.maps.DirectionsService();
var directionsRequest = {
  origin: from,
  destination: to,
  travelMode: google.maps.DirectionsTravelMode.DRIVING,
  unitSystem: google.maps.UnitSystem.METRIC
};
The last step, is to use the route() method to run the request. We must also write the callback function which uses the response to set and show the calculated path. In the callback function we’ll check if the request has been successful, in which case we’ll display the route, or not, in which case we’ll display an error. This is implemented by the code below.
directionsService.route(
  directionsRequest,
  function(response, status)
  {
    if (status == google.maps.DirectionsStatus.OK)
    {
      new google.maps.DirectionsRenderer({
        map: mapObject,
        directions: response
      });
    }
    else
      $("#error").append("Unable to retrieve your route<br />");
  }
);

Putting it all Together

The previous section explained the key components of the demo. Now, it’s time to put those pieces together into the final result, which is shown below.
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>Find a route using Geolocation and Google Maps API</title>
    <script src="http://maps.google.com/maps/api/js?sensor=true"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
    <script>
      function calculateRoute(from, to) {
        // Center initialized to Naples, Italy
        var myOptions = {
          zoom: 10,
          center: new google.maps.LatLng(40.84, 14.25),
          mapTypeId: google.maps.MapTypeId.ROADMAP
        };
        // Draw the map
        var mapObject = new google.maps.Map(document.getElementById("map"), myOptions);

        var directionsService = new google.maps.DirectionsService();
        var directionsRequest = {
          origin: from,
          destination: to,
          travelMode: google.maps.DirectionsTravelMode.DRIVING,
          unitSystem: google.maps.UnitSystem.METRIC
        };
        directionsService.route(
          directionsRequest,
          function(response, status)
          {
            if (status == google.maps.DirectionsStatus.OK)
            {
              new google.maps.DirectionsRenderer({
                map: mapObject,
                directions: response
              });
            }
            else
              $("#error").append("Unable to retrieve your route<br />");
          }
        );
      }

      $(document).ready(function() {
        // If the browser supports the Geolocation API
        if (typeof navigator.geolocation == "undefined") {
          $("#error").text("Your browser doesn't support the Geolocation API");
          return;
        }

        $("#from-link, #to-link").click(function(event) {
          event.preventDefault();
          var addressId = this.id.substring(0, this.id.indexOf("-"));

          navigator.geolocation.getCurrentPosition(function(position) {
            var geocoder = new google.maps.Geocoder();
            geocoder.geocode({
              "location": new google.maps.LatLng(position.coords.latitude, position.coords.longitude)
            },
            function(results, status) {
              if (status == google.maps.GeocoderStatus.OK)
                $("#" + addressId).val(results[0].formatted_address);
              else
                $("#error").append("Unable to retrieve your address<br />");
            });
          },
          function(positionError){
            $("#error").append("Error: " + positionError.message + "<br />");
          },
          {
            enableHighAccuracy: true,
            timeout: 10 * 1000 // 10 seconds
          });
        });

        $("#calculate-route").submit(function(event) {
          event.preventDefault();
          calculateRoute($("#from").val(), $("#to").val());
        });
      });
    </script>
    <style type="text/css">
      #map {
        width: 500px;
        height: 400px;
        margin-top: 10px;
      }
    </style>
  </head>
  <body>
    <h1>Calculate your route</h1>
    <form id="calculate-route" name="calculate-route" action="#" method="get">
      <label for="from">From:</label>
      <input type="text" id="from" name="from" required="required" placeholder="An address" size="30" />
      <a id="from-link" href="#">Get my position</a>
      <br />

      <label for="to">To:</label>
      <input type="text" id="to" name="to" required="required" placeholder="Another address" size="30" />
      <a id="to-link" href="#">Get my position</a>
      <br />

      <input type="submit" />
      <input type="reset" />
    </form>
    <div id="map"></div>
    <p id="error"></p>
  </body>
</html>

Conclusion

This article introduced you to several new classes and properties from the Google Maps API. You used these classes to develop a basic service that allows a user to get directions from one address to another. In the next article, you’ll learn how to create a polyline to join several points on a map.

Frequently Asked Questions (FAQs) about Using Geolocation and Google Maps API

How can I troubleshoot when the Google Maps API returns no results?

If the Google Maps API returns no results, it could be due to several reasons. The most common reason is that the API key is not correctly set up. Make sure you have correctly generated and implemented the API key. Another reason could be that the locations you are trying to find a route between are not accessible by the mode of transport you have selected. For example, some locations may not be accessible by car but may be accessible by foot or bicycle. Lastly, ensure that the coordinates you are using are correct and in the right format.

How can I use the Google Maps API to find a route between two locations?

To find a route between two locations using the Google Maps API, you need to use the DirectionsService object. This object communicates with the Google Maps API Directions Service which receives direction requests and returns computed results. You can specify the origin and destination as either a string (e.g., “Chicago, IL”) or as a LatLng object.

What is Geolocation and how does it work with Google Maps API?

Geolocation is a service that allows you to get the geographical location of a device. When used with the Google Maps API, it can provide real-time location-based data. This can be particularly useful for applications that require location-based services such as navigation apps.

How can I use the Google Maps API to display the route on a map?

To display the route on a map, you need to use the DirectionsRenderer object. This object renders directions obtained from the DirectionsService. You can customize the appearance of the directions by changing the properties of the DirectionsRendererOptions object.

How can I customize the appearance of the map and the route?

The Google Maps API provides several options to customize the appearance of the map and the route. You can change the map type (e.g., roadmap, satellite, hybrid, terrain), zoom level, and center of the map. You can also change the appearance of the route by changing the color, opacity, and weight of the polyline.

How can I handle errors when using the Google Maps API?

The Google Maps API provides several ways to handle errors. The most common way is to use the status field in the DirectionsResult object. This field contains the status of the request, and can be used to determine whether the request was successful or not.

How can I use the Google Maps API to calculate the distance and duration of the route?

The Google Maps API provides the distance and duration of the route in the legs field of the DirectionsResult object. The distance is provided in meters and the duration is provided in seconds.

How can I use the Google Maps API to get directions in different languages?

The Google Maps API supports many different languages. You can specify the language in the request by setting the language parameter to the appropriate language code.

How can I use the Google Maps API to get directions for different modes of transport?

The Google Maps API supports several modes of transport including driving, walking, bicycling, and transit. You can specify the mode in the request by setting the mode parameter to the appropriate value.

How can I use the Google Maps API to avoid certain types of roads or routes?

The Google Maps API provides several options to avoid certain types of roads or routes. You can specify these options in the request by setting the avoid parameter to the appropriate value.

Aurelio De RosaAurelio De Rosa
View Author

I'm a (full-stack) web and app developer with more than 5 years' experience programming for the web using HTML, CSS, Sass, JavaScript, and PHP. I'm an expert of JavaScript and HTML5 APIs but my interests include web security, accessibility, performance, and SEO. I'm also a regular writer for several networks, speaker, and author of the books jQuery in Action, third edition and Instant jQuery Selectors.

functionsgeolocationIntermediate
Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week