It's the 15th anniversary of Google Maps Platform - Check out the latest news and announcements

Waypoints in Directions

This example demonstrates the use of the DirectionsService object to fetch directions for a route including waypoints.

Read the documentation.

TypeScript

function initMap(): void {
  const directionsService = new google.maps.DirectionsService();
  const directionsRenderer = new google.maps.DirectionsRenderer();
  const map = new google.maps.Map(
    document.getElementById("map") as HTMLElement,
    {
      zoom: 6,
      center: { lat: 41.85, lng: -87.65 }
    }
  );
  directionsRenderer.setMap(map);

  (document.getElementById("submit") as HTMLElement).addEventListener(
    "click",
    () => {
      calculateAndDisplayRoute(directionsService, directionsRenderer);
    }
  );
}

function calculateAndDisplayRoute(
  directionsService: google.maps.DirectionsService,
  directionsRenderer: google.maps.DirectionsRenderer
) {
  const waypts: google.maps.DirectionsWaypoint[] = [];
  const checkboxArray = document.getElementById(
    "waypoints"
  ) as HTMLSelectElement;

  for (let i = 0; i < checkboxArray.length; i++) {
    if (checkboxArray.options[i].selected) {
      waypts.push({
        location: (checkboxArray[i] as HTMLOptionElement).value,
        stopover: true
      });
    }
  }

  directionsService.route(
    {
      origin: (document.getElementById("start") as HTMLInputElement).value,
      destination: (document.getElementById("end") as HTMLInputElement).value,
      waypoints: waypts,
      optimizeWaypoints: true,
      travelMode: google.maps.TravelMode.DRIVING
    },
    (response, status) => {
      if (status === "OK") {
        directionsRenderer.setDirections(response);
        const route = response.routes[0];
        const summaryPanel = document.getElementById(
          "directions-panel"
        ) as HTMLElement;
        summaryPanel.innerHTML = "";

        // For each route, display summary information.
        for (let i = 0; i < route.legs.length; i++) {
          const routeSegment = i + 1;
          summaryPanel.innerHTML +=
            "<b>Route Segment: " + routeSegment + "</b><br>";
          summaryPanel.innerHTML += route.legs[i].start_address + " to ";
          summaryPanel.innerHTML += route.legs[i].end_address + "<br>";
          summaryPanel.innerHTML += route.legs[i].distance.text + "<br><br>";
        }
      } else {
        window.alert("Directions request failed due to " + status);
      }
    }
  );
}

JavaScript

function initMap() {
  const directionsService = new google.maps.DirectionsService();
  const directionsRenderer = new google.maps.DirectionsRenderer();
  const map = new google.maps.Map(document.getElementById("map"), {
    zoom: 6,
    center: { lat: 41.85, lng: -87.65 }
  });
  directionsRenderer.setMap(map);
  document.getElementById("submit").addEventListener("click", () => {
    calculateAndDisplayRoute(directionsService, directionsRenderer);
  });
}

function calculateAndDisplayRoute(directionsService, directionsRenderer) {
  const waypts = [];
  const checkboxArray = document.getElementById("waypoints");

  for (let i = 0; i < checkboxArray.length; i++) {
    if (checkboxArray.options[i].selected) {
      waypts.push({
        location: checkboxArray[i].value,
        stopover: true
      });
    }
  }
  directionsService.route(
    {
      origin: document.getElementById("start").value,
      destination: document.getElementById("end").value,
      waypoints: waypts,
      optimizeWaypoints: true,
      travelMode: google.maps.TravelMode.DRIVING
    },
    (response, status) => {
      if (status === "OK") {
        directionsRenderer.setDirections(response);
        const route = response.routes[0];
        const summaryPanel = document.getElementById("directions-panel");
        summaryPanel.innerHTML = "";

        // For each route, display summary information.
        for (let i = 0; i < route.legs.length; i++) {
          const routeSegment = i + 1;
          summaryPanel.innerHTML +=
            "<b>Route Segment: " + routeSegment + "</b><br>";
          summaryPanel.innerHTML += route.legs[i].start_address + " to ";
          summaryPanel.innerHTML += route.legs[i].end_address + "<br>";
          summaryPanel.innerHTML += route.legs[i].distance.text + "<br><br>";
        }
      } else {
        window.alert("Directions request failed due to " + status);
      }
    }
  );
}

CSS

html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}

#map {
  height: 100%;
  float: left;
  width: 70%;
  height: 100%;
}

#right-panel {
  margin: 20px;
  border-width: 2px;
  width: 20%;
  height: 400px;
  float: left;
  text-align: left;
  padding-top: 0;
}

#directions-panel {
  margin-top: 10px;
  background-color: #ffee77;
  padding: 10px;
  overflow: scroll;
  height: 174px;
}

HTML

<!DOCTYPE html>
<html>
  <head>
    <title>Waypoints in Directions</title>
    <script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>
    <script
      src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap&libraries=&v=weekly"
      defer
    ></script>
    <link rel="stylesheet" type="text/css" href="./style.css" />
    <script src="./app.js"></script>
  </head>
  <body>
    <div id="map"></div>
    <div id="right-panel">
      <div>
        <b>Start:</b>
        <select id="start">
          <option value="Halifax, NS">Halifax, NS</option>
          <option value="Boston, MA">Boston, MA</option>
          <option value="New York, NY">New York, NY</option>
          <option value="Miami, FL">Miami, FL</option>
        </select>
        <br />
        <b>Waypoints:</b> <br />
        <i>(Ctrl+Click or Cmd+Click for multiple selection)</i> <br />
        <select multiple id="waypoints">
          <option value="montreal, quebec">Montreal, QBC</option>
          <option value="toronto, ont">Toronto, ONT</option>
          <option value="chicago, il">Chicago</option>
          <option value="winnipeg, mb">Winnipeg</option>
          <option value="fargo, nd">Fargo</option>
          <option value="calgary, ab">Calgary</option>
          <option value="spokane, wa">Spokane</option>
        </select>
        <br />
        <b>End:</b>
        <select id="end">
          <option value="Vancouver, BC">Vancouver, BC</option>
          <option value="Seattle, WA">Seattle, WA</option>
          <option value="San Francisco, CA">San Francisco, CA</option>
          <option value="Los Angeles, CA">Los Angeles, CA</option>
        </select>
        <br />
        <input type="submit" id="submit" />
      </div>
      <div id="directions-panel"></div>
    </div>
  </body>
</html>

All

<!DOCTYPE html>
<html>
  <head>
    <title>Waypoints in Directions</title>
    <script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>
    <script
      src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap&libraries=&v=weekly"
      defer
    ></script>
    <style type="text/css">
      #right-panel {
        font-family: "Roboto", "sans-serif";
        line-height: 30px;
        padding-left: 10px;
      }

      #right-panel select,
      #right-panel input {
        font-size: 15px;
      }

      #right-panel select {
        width: 100%;
      }

      #right-panel i {
        font-size: 12px;
      }

      html,
      body {
        height: 100%;
        margin: 0;
        padding: 0;
      }

      #map {
        height: 100%;
        float: left;
        width: 70%;
        height: 100%;
      }

      #right-panel {
        margin: 20px;
        border-width: 2px;
        width: 20%;
        height: 400px;
        float: left;
        text-align: left;
        padding-top: 0;
      }

      #directions-panel {
        margin-top: 10px;
        background-color: #ffee77;
        padding: 10px;
        overflow: scroll;
        height: 174px;
      }
    </style>
    <script>
      "use strict";

      function initMap() {
        const directionsService = new google.maps.DirectionsService();
        const directionsRenderer = new google.maps.DirectionsRenderer();
        const map = new google.maps.Map(document.getElementById("map"), {
          zoom: 6,
          center: {
            lat: 41.85,
            lng: -87.65
          }
        });
        directionsRenderer.setMap(map);
        document.getElementById("submit").addEventListener("click", () => {
          calculateAndDisplayRoute(directionsService, directionsRenderer);
        });
      }

      function calculateAndDisplayRoute(directionsService, directionsRenderer) {
        const waypts = [];
        const checkboxArray = document.getElementById("waypoints");

        for (let i = 0; i < checkboxArray.length; i++) {
          if (checkboxArray.options[i].selected) {
            waypts.push({
              location: checkboxArray[i].value,
              stopover: true
            });
          }
        }

        directionsService.route(
          {
            origin: document.getElementById("start").value,
            destination: document.getElementById("end").value,
            waypoints: waypts,
            optimizeWaypoints: true,
            travelMode: google.maps.TravelMode.DRIVING
          },
          (response, status) => {
            if (status === "OK") {
              directionsRenderer.setDirections(response);
              const route = response.routes[0];
              const summaryPanel = document.getElementById("directions-panel");
              summaryPanel.innerHTML = ""; // For each route, display summary information.

              for (let i = 0; i < route.legs.length; i++) {
                const routeSegment = i + 1;
                summaryPanel.innerHTML +=
                  "<b>Route Segment: " + routeSegment + "</b><br>";
                summaryPanel.innerHTML += route.legs[i].start_address + " to ";
                summaryPanel.innerHTML += route.legs[i].end_address + "<br>";
                summaryPanel.innerHTML +=
                  route.legs[i].distance.text + "<br><br>";
              }
            } else {
              window.alert("Directions request failed due to " + status);
            }
          }
        );
      }
    </script>
  </head>
  <body>
    <div id="map"></div>
    <div id="right-panel">
      <div>
        <b>Start:</b>
        <select id="start">
          <option value="Halifax, NS">Halifax, NS</option>
          <option value="Boston, MA">Boston, MA</option>
          <option value="New York, NY">New York, NY</option>
          <option value="Miami, FL">Miami, FL</option>
        </select>
        <br />
        <b>Waypoints:</b> <br />
        <i>(Ctrl+Click or Cmd+Click for multiple selection)</i> <br />
        <select multiple id="waypoints">
          <option value="montreal, quebec">Montreal, QBC</option>
          <option value="toronto, ont">Toronto, ONT</option>
          <option value="chicago, il">Chicago</option>
          <option value="winnipeg, mb">Winnipeg</option>
          <option value="fargo, nd">Fargo</option>
          <option value="calgary, ab">Calgary</option>
          <option value="spokane, wa">Spokane</option>
        </select>
        <br />
        <b>End:</b>
        <select id="end">
          <option value="Vancouver, BC">Vancouver, BC</option>
          <option value="Seattle, WA">Seattle, WA</option>
          <option value="San Francisco, CA">San Francisco, CA</option>
          <option value="Los Angeles, CA">Los Angeles, CA</option>
        </select>
        <br />
        <input type="submit" id="submit" />
      </div>
      <div id="directions-panel"></div>
    </div>
  </body>
</html>
"use strict"; function initMap() { const directionsService = new google.maps.DirectionsService(); const directionsRenderer = new google.maps.DirectionsRenderer(); const map = new google.maps.Map(document.getElementById("map"), { zoom: 6, center: { lat: 41.85, lng: -87.65 } }); directionsRenderer.setMap(map); document.getElementById("submit").addEventListener("click", () => { calculateAndDisplayRoute(directionsService, directionsRenderer); }); } function calculateAndDisplayRoute(directionsService, directionsRenderer) { const waypts = []; const checkboxArray = document.getElementById("waypoints"); for (let i = 0; i < checkboxArray.length; i++) { if (checkboxArray.options[i].selected) { waypts.push({ location: checkboxArray[i].value, stopover: true }); } } directionsService.route( { origin: document.getElementById("start").value, destination: document.getElementById("end").value, waypoints: waypts, optimizeWaypoints: true, travelMode: google.maps.TravelMode.DRIVING }, (response, status) => { if (status === "OK") { directionsRenderer.setDirections(response); const route = response.routes[0]; const summaryPanel = document.getElementById("directions-panel"); summaryPanel.innerHTML = ""; // For each route, display summary information. for (let i = 0; i < route.legs.length; i++) { const routeSegment = i + 1; summaryPanel.innerHTML += "<b>Route Segment: " + routeSegment + "</b><br>"; summaryPanel.innerHTML += route.legs[i].start_address + " to "; summaryPanel.innerHTML += route.legs[i].end_address + "<br>"; summaryPanel.innerHTML += route.legs[i].distance.text + "<br><br>"; } } else { window.alert("Directions request failed due to " + status); } } ); }
#right-panel { font-family: "Roboto", "sans-serif"; line-height: 30px; padding-left: 10px; } #right-panel select, #right-panel input { font-size: 15px; } #right-panel select { width: 100%; } #right-panel i { font-size: 12px; } html, body { height: 100%; margin: 0; padding: 0; } #map { height: 100%; float: left; width: 70%; height: 100%; } #right-panel { margin: 20px; border-width: 2px; width: 20%; height: 400px; float: left; text-align: left; padding-top: 0; } #directions-panel { margin-top: 10px; background-color: #ffee77; padding: 10px; overflow: scroll; height: 174px; }
<!DOCTYPE html> <html> <head> <title>Waypoints in Directions</title> <script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script> <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCb1xprYSpXd0q_yDsJ1W2UGhfl9_YGKU0&callback=initMap&libraries=&v=weekly" defer ></script> <!-- jsFiddle will insert css and js --> </head> <body> <div id="map"></div> <div id="right-panel"> <div> <b>Start:</b> <select id="start"> <option value="Halifax, NS">Halifax, NS</option> <option value="Boston, MA">Boston, MA</option> <option value="New York, NY">New York, NY</option> <option value="Miami, FL">Miami, FL</option> </select> <br /> <b>Waypoints:</b> <br /> <i>(Ctrl+Click or Cmd+Click for multiple selection)</i> <br /> <select multiple id="waypoints"> <option value="montreal, quebec">Montreal, QBC</option> <option value="toronto, ont">Toronto, ONT</option> <option value="chicago, il">Chicago</option> <option value="winnipeg, mb">Winnipeg</option> <option value="fargo, nd">Fargo</option> <option value="calgary, ab">Calgary</option> <option value="spokane, wa">Spokane</option> </select> <br /> <b>End:</b> <select id="end"> <option value="Vancouver, BC">Vancouver, BC</option> <option value="Seattle, WA">Seattle, WA</option> <option value="San Francisco, CA">San Francisco, CA</option> <option value="Los Angeles, CA">Los Angeles, CA</option> </select> <br /> <input type="submit" id="submit" /> </div> <div id="directions-panel"></div> </div> </body> </html>