google-mapsmatrixgoogle-api

Route between multiple markers


Is it possible to plot multiple markers as well show routes between these and origin? For example: I have one origin and four different destinations. I want the routes to be shown between the origin and the destinations, so that it is A to B, A to C, A to D, A to E. Can this be done? I have only seen the option to display the route between two points or to calculate distance between multiple. I want to be able to calculate the distance as well as showing the route on the map.

So far this is what my code looks like:

$("#submit").click(function() {

  var values = $("#street").val();

  var geocoder = new google.maps.Geocoder();
  var address = values;

  geocoder.geocode( { 'address': address}, function(results, status) {

    if (status == google.maps.GeocoderStatus.OK) {
      var latitude = results[0].geometry.location.lat();
      var longitude = results[0].geometry.location.lng();
    } 

    service = new google.maps.DistanceMatrixService();

    var origin = new google.maps.LatLng(latitude, longitude);
    var destination = new google.maps.LatLng(48.856614, 2.352222);
    var destinationb = new google.maps.LatLng(41.385064, 2.173403);
    var destinationc = new google.maps.LatLng(44.584910, 5.133122);
    var destinationd = new google.maps.LatLng(45.365187, 0.647394);
    var destinationIcon = 'data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2278%22%20height%3D%2238%22%20viewBox%3D%220%200%2038%2038%22%3E%3Cpath%20fill%3D%22%23333333%22%20stroke%3D%22%23ccc%22%20stroke-width%3D%22.5%22%20d%3D%22M34.305%2016.234c0%208.83-15.148%2019.158-15.148%2019.158S3.507%2025.065%203.507%2016.1c0-8.505%206.894-14.304%2015.4-14.304%208.504%200%2015.398%205.933%2015.398%2014.438z%22%2F%3E%3Ctext%20transform%3D%22translate(19%2018.5)%22%20fill%3D%22%23fff%22%20style%3D%22font-family%3A%20Arial%2C%20sans-serif%3Bfont-weight%3Abold%3Btext-align%3Acenter%3B%22%20font-size%3D%2212%22%20text-anchor%3D%22middle%22%3E' + "" + '%3C%2Ftext%3E%3C%2Fsvg%3E';
    var originIcon = 'data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2238%22%20height%3D%2238%22%20viewBox%3D%220%200%2038%2038%22%3E%3Cpath%20fill%3D%22%23808880%22%20stroke%3D%22%23ccc%22%20stroke-width%3D%22.5%22%20d%3D%22M34.305%2016.234c0%208.83-15.148%2019.158-15.148%2019.158S3.507%2025.065%203.507%2016.1c0-8.505%206.894-14.304%2015.4-14.304%208.504%200%2015.398%205.933%2015.398%2014.438z%22%2F%3E%3Ctext%20transform%3D%22translate%2819%2018.5%29%22%20fill%3D%22%23fff%22%20style%3D%22font-family%3A%20Arial%2C%20sans-serif%3Bfont-weight%3Abold%3Btext-align%3Acenter%3B%22%20font-size%3D%2212%22%20text-anchor%3D%22middle%22%3E' + "" + '%3C%2Ftext%3E%3C%2Fsvg%3E';
    var infowindow = new google.maps.InfoWindow();


    service.getDistanceMatrix(
        {
            origins: [origin],
            destinations: [destination, destinationb, destinationc, destinationd],
            travelMode: google.maps.TravelMode.DRIVING,
            avoidHighways: false,
            avoidTolls: false
        }, 
        callback
    );   

    function callback(response, status) {

        if(status=="OK") {
            var originList = response.originAddresses;
            var destinationList = response.destinationAddresses;
            var bounds = new google.maps.LatLngBounds;
            var outputDiv = document.getElementById('output');

           var showGeocodedAddressOnMap = function(distance, asDestination) {
              var icon = asDestination ? destinationIcon : originIcon;
              return function(results, status) {
                if (status === 'OK') {
                  map.fitBounds(bounds.extend(results[0].geometry.location));
                  var markersArray = new google.maps.Marker({
                    map: map,
                    position: results[0].geometry.location,
                    icon: icon
                  });

                  google.maps.event.addListener(markersArray, 'click', function (evt) {
                    infowindow.setContent('<strong>Avstånd:</strong> ' + distance);
                    infowindow.open(map, this);
                  });



                } else {
                  alert('Geocode was not successful due to: ' + status);
                }
              };
            };            

        for (var i = 0; i < originList.length; i++) {
              var results = response.rows[i].elements;
              geocoder.geocode({'address': originList[i]},
                  showGeocodedAddressOnMap(results[i].distance.text, false));
              for (var j = 0; j < results.length; j++) {
                geocoder.geocode({'address': destinationList[j]}, showGeocodedAddressOnMap(results[j].distance.text, true));

                outputDiv.innerHTML += originList[i] + ' to ' + destinationList[j] +
                    ': ' + results[j].distance.text + '<br>';



              }
            }

        } else {
            alert("Error: " + status);
        }
    }

        var map = new google.maps.Map(document.getElementById('map'), {
          showTooltip: true,
          showInfoWindow: true
        });



  }); 

});


</script>
<div id="output"></div>
<p></p>
<div id="map"></div>

Solution

  • To display the routes, call the directions service. Modified function from the example in the documentation:

    function calculateAndDisplayRoute(start, end, map) {
      var directionsService = new google.maps.DirectionsService();
      var directionsDisplay = new google.maps.DirectionsRenderer({
        map: map,
        suppressMarkers: true,
        preserveViewport: true
      });
      directionsService.route({
        origin: start,
        destination: end,
        travelMode: 'DRIVING'
      }, function(response, status) {
        if (status === 'OK') {
          directionsDisplay.setDirections(response);
        } else {
          window.alert('Directions request failed due to ' + status);
        }
      });
    }
    
    calculateAndDisplayRoute(origin, destination, map);
    calculateAndDisplayRoute(origin, destinationb, map);
    calculateAndDisplayRoute(origin, destinationc, map);
    calculateAndDisplayRoute(origin, destinationd, map);
    

    proof of concept fiddle

    code snippet:

    function calculateAndDisplayRoute(start, end, map) {
      var directionsService = new google.maps.DirectionsService();
      var directionsDisplay = new google.maps.DirectionsRenderer({
        map: map,
        suppressMarkers: true,
        preserveViewport: true
      });
      directionsService.route({
        origin: start,
        destination: end,
        travelMode: 'DRIVING'
      }, function(response, status) {
        if (status === 'OK') {
          directionsDisplay.setDirections(response);
        } else {
          window.alert('Directions request failed due to ' + status);
        }
      });
    }
    
    var map = new google.maps.Map(document.getElementById('map'), {
      showTooltip: true,
      showInfoWindow: true
    });
    var values = $("#street").val();
    var geocoder = new google.maps.Geocoder();
    var address = values;
    geocoder.geocode({
      'address': address
    }, function(results, status) {
      if (status == google.maps.GeocoderStatus.OK) {
        var latitude = results[0].geometry.location.lat();
        var longitude = results[0].geometry.location.lng();
      }
      service = new google.maps.DistanceMatrixService();
      var origin = new google.maps.LatLng(latitude, longitude);
      var destination = new google.maps.LatLng(48.856614, 2.352222);
      var destinationb = new google.maps.LatLng(41.385064, 2.173403);
      var destinationc = new google.maps.LatLng(44.584910, 5.133122);
      var destinationd = new google.maps.LatLng(45.365187, 0.647394);
      var destinationIcon = 'data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2278%22%20height%3D%2238%22%20viewBox%3D%220%200%2038%2038%22%3E%3Cpath%20fill%3D%22%23333333%22%20stroke%3D%22%23ccc%22%20stroke-width%3D%22.5%22%20d%3D%22M34.305%2016.234c0%208.83-15.148%2019.158-15.148%2019.158S3.507%2025.065%203.507%2016.1c0-8.505%206.894-14.304%2015.4-14.304%208.504%200%2015.398%205.933%2015.398%2014.438z%22%2F%3E%3Ctext%20transform%3D%22translate(19%2018.5)%22%20fill%3D%22%23fff%22%20style%3D%22font-family%3A%20Arial%2C%20sans-serif%3Bfont-weight%3Abold%3Btext-align%3Acenter%3B%22%20font-size%3D%2212%22%20text-anchor%3D%22middle%22%3E' + "" + '%3C%2Ftext%3E%3C%2Fsvg%3E';
      var originIcon = 'data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2238%22%20height%3D%2238%22%20viewBox%3D%220%200%2038%2038%22%3E%3Cpath%20fill%3D%22%23808880%22%20stroke%3D%22%23ccc%22%20stroke-width%3D%22.5%22%20d%3D%22M34.305%2016.234c0%208.83-15.148%2019.158-15.148%2019.158S3.507%2025.065%203.507%2016.1c0-8.505%206.894-14.304%2015.4-14.304%208.504%200%2015.398%205.933%2015.398%2014.438z%22%2F%3E%3Ctext%20transform%3D%22translate%2819%2018.5%29%22%20fill%3D%22%23fff%22%20style%3D%22font-family%3A%20Arial%2C%20sans-serif%3Bfont-weight%3Abold%3Btext-align%3Acenter%3B%22%20font-size%3D%2212%22%20text-anchor%3D%22middle%22%3E' + "" + '%3C%2Ftext%3E%3C%2Fsvg%3E';
      var infowindow = new google.maps.InfoWindow();
    
      calculateAndDisplayRoute(origin, destination, map);
      calculateAndDisplayRoute(origin, destinationb, map);
      calculateAndDisplayRoute(origin, destinationc, map);
      calculateAndDisplayRoute(origin, destinationd, map);
    
      service.getDistanceMatrix({
          origins: [origin],
          destinations: [destination, destinationb, destinationc, destinationd],
          travelMode: google.maps.TravelMode.DRIVING,
          avoidHighways: false,
          avoidTolls: false
        },
        callback
      );
    
      function callback(response, status) {
        if (status == "OK") {
          var originList = response.originAddresses;
          var destinationList = response.destinationAddresses;
          var bounds = new google.maps.LatLngBounds;
          var outputDiv = document.getElementById('output');
    
          var showGeocodedAddressOnMap = function(distance, asDestination) {
            var icon = asDestination ? destinationIcon : originIcon;
            return function(results, status) {
              if (status === 'OK') {
                map.fitBounds(bounds.extend(results[0].geometry.location));
                var markersArray = new google.maps.Marker({
                  map: map,
                  position: results[0].geometry.location,
                  icon: icon
                });
                google.maps.event.addListener(markersArray, 'click', function(evt) {
                  if (asDestination) {
                    infowindow.setContent('<strong>Avstånd:</strong> ' + distance);
                  } else {
                    infowindow.setContent('<strong>Origin</strong> ');
                  }
                  infowindow.open(map, this);
                });
              } else {
                alert('Geocode was not successful due to: ' + status);
              }
            };
          };
    
          for (var i = 0; i < originList.length; i++) {
            var results = response.rows[i].elements;
            var text;
            if (results[i].status != "OK") {
              text = results[i].status;
            } else {
              results[i].distance.text;
            }
            geocoder.geocode({
                'address': originList[i]
              },
              showGeocodedAddressOnMap(text, false));
            for (var j = 0; j < results.length; j++) {
              console.log("j=" + j + " destinationList[" + j + "]=" + destinationList[j] + " results[" + j + "]=" + results[j]);
              geocoder.geocode({
                'address': destinationList[j]
              }, showGeocodedAddressOnMap(results[j].distance.text, true));
              outputDiv.innerHTML += originList[i] + ' to ' + destinationList[j] +
                ': ' + results[j].distance.text + '<br>';
            }
          }
        } else {
          alert("Error: " + status);
        }
      }
    });
    html,
    body,
    #map {
      height: 90%;
      width: 100%;
      margin: 0px;
      padding: 0px
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></script>
    <div id="output"></div>
    <input id="street" value="Orléans, France" />
    <input id="submit" type="button" value="click" />
    <p></p>
    <div id="map"></div>