0

I've successfully implemented google map direction service api : https://developers.google.com/maps/documentation/javascript/directions with 'draggble' option enabled. Is it possible to show all routes together if multiple routes are available between 2 locations?

The current code is similar to: https://developers.google.com/maps/documentation/javascript/examples/directions-draggable and I do have alternative routes available in response code as I've enabled provideRouteAlternatives: true.

I tried the solution provided in : How to display alternative route using google map api. But when I used that code, I found it draws multiple routes with independent markers. That is, if 4 routes are available, there will be 4 'A' locations and 4 'B' locations and while dragging - only one of them get selected. Please find the below screenshots.

Initial View:

Initial View

After dragging initial locations (issue with duplicate locations)

After dragging initial locations

I need to drag in such a way that, when the location A or B is dragged, there should not be any duplicates and alternate routes should be automatically shown.

My current code is as follows (API key not added here):

<!DOCTYPE html>
<html>
  <head>
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no">
    <meta charset="utf-8">
    <title>Draggable directions</title>
    <style>
      #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: 63%;
        height: 100%;
      }
      #right-panel {
        float: right;
        width: 34%;
        height: 100%;
      }
      .panel {
        height: 100%;
        overflow: auto;
      }
    </style>
  </head>
  <body>
    <div id="map"></div>
    <div id="right-panel">
      <p>Total Distance: <span id="total"></span></p>
    </div>
    <script>
      var map;
      function initMap() {
        map = new google.maps.Map(document.getElementById('map'), {
          zoom: 4,
          center: {lat: -24.345, lng: 134.46}  // Australia.
        });

        var directionsService = new google.maps.DirectionsService;
        var directionsDisplay = new google.maps.DirectionsRenderer({
          draggable: true,
          map: map,
          panel: document.getElementById('right-panel')
        });

        directionsDisplay.addListener('directions_changed', function() {
          computeTotalDistance(directionsDisplay.getDirections());
        });

        displayRoute('Rosedale, MD, USA', 'Savage, MD, USA', directionsService,
            directionsDisplay);
      }

      function displayRoute(origin, destination, service, display) {
        service.route({
          origin: origin,
          destination: destination,
          travelMode: 'DRIVING',
          avoidTolls: true,
          provideRouteAlternatives: true,
        }, function(response, status) {
          if (status === 'OK') {
            for (var i = 0, len = response.routes.length; i < len; i++) {
                new google.maps.DirectionsRenderer({
                    map: map,
                    directions: response,
                    routeIndex: i,
                    draggable : true,
                });
            }
            display.setDirections(response);
          } else {
            alert('Could not display directions due to: ' + status);
          }
        });
      }

      function computeTotalDistance(result) {
        var total = 0;
        var myroute = result.routes[0];
        for (var i = 0; i < myroute.legs.length; i++) {
          total += myroute.legs[i].distance.value;
        }
        total = total / 1000;
        document.getElementById('total').innerHTML = total + ' km';
      }
    </script>
    <script async defer
    src="https://maps.googleapis.com/maps/api/js?key=API-KEY&callback=initMap">
    </script>
  </body>
</html>

Please help me. Thanks in advance!

Community
  • 1
  • 1
Sankar V
  • 4,110
  • 5
  • 28
  • 52
  • @duncan the code is almost same as the code given in https://developers.google.com/maps/documentation/javascript/examples/directions-draggable. The number of locations can be dynamically added by the user. As you can see in that link: `display.setDirections(response);` function creates the path, same as mine. – Sankar V Feb 02 '17 at 13:45
  • 1
    "The number of locations can be dynamically added by the user" - that's not what Google's example code is doing, and they're not getting the same problem with duplicate markers that you are. Just add your code to the question rather than let us try to second guess what you're doing differently. – duncan Feb 02 '17 at 14:34
  • I guess it's because when you drag your directions markers, it doesn't redraw the alternate routes... – MrUpsidown Feb 02 '17 at 18:23
  • @duncan - in the provided Google's example code the intermediate locations are hardcoded. I just said that in my code the user can enter those intermediate locations, if needed. I've updated the question with my code. Also I just found that google will provide only one route if waypoints are added. so we need to consider the case with only 2 locations. Please check and let me know your thoughts. – Sankar V Feb 03 '17 at 04:57
  • 1
    Does this answer your question? [Google Maps JS API v3 - Simple Multiple Marker Example](https://stackoverflow.com/questions/3059044/google-maps-js-api-v3-simple-multiple-marker-example) – Michele La Ferla Dec 18 '20 at 07:41

1 Answers1

2

Each route you draw is editable and has a start and end marker which means that you will always be dragging one of the routes marker and not all at once. You could use the suppressMarkers option to remove markers from the alternate routes but that wouldn't change a lot to the behavior.

The problem is that as each route is separate, if you move the start or end location, you should redraw every route otherwise only one will update.

That said, if you edit a route (other than by changing its start or end location) you should not redraw your routes. If you update the start or end location you will of course then lose any route waypoint you added. Unless you do something about that... which sounds like a pain.

var directionsService = new google.maps.DirectionsService();
var map;

function initialize() {

  var center = new google.maps.LatLng(0, 0);
  var myOptions = {
    zoom: 7,
    mapTypeId: google.maps.MapTypeId.ROADMAP,
    center: center
  }

  map = new google.maps.Map(document.getElementById("map-canvas"), myOptions);

  var start = "Sadulpur, India";
  var end = "New Delhi, India";

  plotDirections(start, end);
}

function plotDirections(start, end) {

  var method = 'DRIVING';

  var request = {
    origin: start,
    destination: end,
    travelMode: google.maps.DirectionsTravelMode[method],
    provideRouteAlternatives: true
  };

  directionsService.route(request, function(response, status) {

    if (status == google.maps.DirectionsStatus.OK) {

      var routes = response.routes;
      var colors = ['red', 'green', 'blue', 'orange', 'yellow', 'black'];
      var directionsDisplays = [];

      // Reset the start and end variables to the actual coordinates
      start = response.routes[0].legs[0].start_location;
      end = response.routes[0].legs[0].end_location;

      // Loop through each route
      for (var i = 0; i < routes.length; i++) {

        var directionsDisplay = new google.maps.DirectionsRenderer({
          map: map,
          directions: response,
          routeIndex: i,
          draggable: true,
          polylineOptions: {

            strokeColor: colors[i],
            strokeWeight: 4,
            strokeOpacity: .3
          }
        });

        // Push the current renderer to an array
        directionsDisplays.push(directionsDisplay);

        // Listen for the directions_changed event for each route
        google.maps.event.addListener(directionsDisplay, 'directions_changed', (function(directionsDisplay, i) {

          return function() {

            var directions = directionsDisplay.getDirections();
            var new_start = directions.routes[0].legs[0].start_location;
            var new_end = directions.routes[0].legs[0].end_location;

            if ((new_start.toString() !== start.toString()) || (new_end.toString() !== end.toString())) {

              // Remove every route from map
              for (var j = 0; j < directionsDisplays.length; j++) {

                directionsDisplays[j].setMap(null);
              }

              // Redraw routes with new start/end coordinates
              plotDirections(new_start, new_end);
            }
          }
        })(directionsDisplay, i)); // End listener
      } // End route loop
    }
  });
}

initialize();
#map-canvas {
  height: 180px;
}
<div id="map-canvas"></div>
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></script>

JSFiddle demo

MrUpsidown
  • 21,592
  • 15
  • 77
  • 131