Search code examples
google-maps-api-3google-apigoogle-polyline

How to draw different coloured polylines with direction service with snap to road feature


I am trying to render bus routes of bangalore city with snap to road feature provided by google api. If I just render single route, it is visible with the colour I mention for stroke color property of polyline.If the route is pretty long, then I am splitting the route into multiple paths for that route. But, when I add the second route, a polyline from the end of first route to the start of second route is drawn. I am not able to figure out, where I am going wrong. Any help is deeply appreciated. Please find the javascript code of the same.

<script type="text/javascript">
var infoWindow = new google.maps.InfoWindow();  
var routePath;
var OrgDest;
var OrgDestpoints;
var wp;
var waypts;
var traceroutePath;
var service;
var map;
var marker, markloc;
var markers = [];
var orgdest = {"1": [[12.9197565816171, 77.5923588994416,12.95719452, 77.56829549],[12.95719452, 77.56829549,12.98997477, 77.57209867],[12.98997477, 77.57209867,13.02311, 77.55029]],"KHC": [[12.97466107, 77.58199613,12.97466107, 77.58199613]]};
var waypoints = {"1":[[12.92268932, 77.59338455,12.92318598, 77.58877168,12.9279596, 77.58760419,12.93610683, 77.58392363,12.93672057, 77.57217014,12.93956243, 77.57215225,12.94189, 77.57358,12.94574241, 77.57070059],[12.95850855, 77.57402561,12.96161187, 77.57527904,12.96366, 77.56843,12.96811874, 77.56800682,12.97736, 77.57074,12.98997477, 77.57209867],[12.98997477, 77.57209867,12.99789013, 77.57130999,13.00908169, 77.5710476,13.01742075, 77.55707759]],"KHC": [[12.98420536, 77.59761828,12.98368012, 77.6035693]]};
var routeColors = {"1": "#FF00FF","KHC": "#800000"};
var routeNames = ["1","KHC"];

 function initialize() {
 var mapOptions = {
      center: new google.maps.LatLng(12.9536775, 77.5883784),
      zoom: 12
    };
 map = new google.maps.Map(document.getElementById("map-canvas"),mapOptions);
    //directionsDisplay.setMap(map);

    var routeInfoWindow = new google.maps.InfoWindow({ // this info window shows the route name when the mouse hovers over a route line
    disableAutoPan: true
    });

    for (var i = 0; i < routeNames.length; i++) { // loop over each route
        var routeName = routeNames[i];  
        for (var j = 0; j < orgdest[routeName].length; j++) { // loop over each path on the route               
            OrgDest = orgdest[routeName][j];
            OrgDestpoints = []              
            for (var k = 0; k < OrgDest.length; k += 2) { // loop over each point in the path
                OrgDestpoints.push(new google.maps.LatLng(OrgDest[k], OrgDest[k+1]));
            }
            waypts = [];
            if(waypoints[routeName].length > 0)
            {
                wp = waypoints[routeName][j];
                for (var k = 0; k < wp.length; k += 2) { // loop over each waypoints in the path
                    waypts.push(
                    {location:new google.maps.LatLng(wp[k], wp[k+1]),
                    stopover:true
                    });
                }
            }

            if(j>0)// & (j!=(orgdest[routeName].length)))
                traceroutePath.setMap(null); //clearing previously rendered map
            if(i>0 & j==0)
            {
                traceroutePath.setMap(null); //clearing previously rendered map
            }

            routePath = OrgDestpoints;              
            traceroutePath = new google.maps.Polyline({
                path: routePath,
                strokeColor: routeColors[routeName],
                strokeOpacity: 1.0,
                strokeWeight: 2
                });
            service = new google.maps.DirectionsService(),traceroutePath,snap_path=[];  
            traceroutePath.setMap(map);             
            for(z=0;z<routePath.length-1;z++){
            service.route({origin: routePath[z],destination: routePath[z+1],
            travelMode: google.maps.DirectionsTravelMode.DRIVING,
            waypoints: waypts},
            function(result, status) {
                if(status == google.maps.DirectionsStatus.OK) {
                    snap_path = snap_path.concat(result.routes[0].overview_path);
                    alert(result.routes[0].legs[0].start_location)
                    traceroutePath.setPath(snap_path);
                } else alert("Directions request failed: "+status);        
            });
            }                                       
        } //end of j for loop; paths to form a route

    }//end of i for loop; all routes        
  }
  google.maps.event.addDomListener(window, 'load', initialize);
</script>

Solution

  • You have two issues that are causing the issue.

    1. the code is concatenating the paths from the directions requests together, that is an issue because:

      a. the directions service is asynchronous, the routes may come back in a different order than you send them (unless you send them one by one).

      b. the routes requested are not continuous.

    for (z = 0; z < routePath.length - 1; z++) {
      service.route({
          origin: routePath[z],
          destination: routePath[z + 1],
          travelMode: google.maps.DirectionsTravelMode.DRIVING,
          waypoints: waypts
        },
        function(result, status) {
          if (status == google.maps.DirectionsStatus.OK) {
            var snap_path = result.routes[0].overview_path;
            var traceroutePath = new google.maps.Polyline({
              strokeColor: routeColors[routeName],
              strokeOpacity: 1.0,
              strokeWeight: 2,
              map: map
            });
            traceroutePath.setPath(snap_path);
          } else alert("Directions request failed: " + status);
        });
    

    proof of concept fiddle

    code snippet:

    var infoWindow = new google.maps.InfoWindow();
    var routePath;
    var OrgDest;
    var OrgDestpoints;
    var wp;
    var waypts;
    var traceroutePath;
    var service;
    var map;
    var marker, markloc;
    var markers = [];
    var orgdest = {
      "1": [
        [12.9197565816171, 77.5923588994416, 12.95719452, 77.56829549],
        [12.95719452, 77.56829549, 12.98997477, 77.57209867],
        [12.98997477, 77.57209867, 13.02311, 77.55029]
      ],
      "KHC": [
        [12.97466107, 77.58199613, 12.97466107, 77.58199613]
      ]
    };
    var waypoints = {
      "1": [
        [12.92268932, 77.59338455, 12.92318598, 77.58877168, 12.9279596, 77.58760419, 12.93610683, 77.58392363, 12.93672057, 77.57217014, 12.93956243, 77.57215225, 12.94189, 77.57358, 12.94574241, 77.57070059],
        [12.95850855, 77.57402561, 12.96161187, 77.57527904, 12.96366, 77.56843, 12.96811874, 77.56800682, 12.97736, 77.57074, 12.98997477, 77.57209867],
        [12.98997477, 77.57209867, 12.99789013, 77.57130999, 13.00908169, 77.5710476, 13.01742075, 77.55707759]
      ],
      "KHC": [
        [12.98420536, 77.59761828, 12.98368012, 77.6035693]
      ]
    };
    var routeColors = {
      "1": "#FF00FF",
      "KHC": "#800000"
    };
    var routeNames = ["1", "KHC"];
    
    function initialize() {
      var mapOptions = {
        center: new google.maps.LatLng(12.9536775, 77.5883784),
        zoom: 12
      };
      map = new google.maps.Map(document.getElementById("map-canvas"), mapOptions);
    
      var routeInfoWindow = new google.maps.InfoWindow({ // this info window shows the route name when the mouse hovers over a route line
        disableAutoPan: true
      });
    
      for (var i = 0; i < routeNames.length; i++) { // loop over each route
        var routeName = routeNames[i];
        for (var j = 0; j < orgdest[routeName].length; j++) { // loop over each path on the route               
          OrgDest = orgdest[routeName][j];
          OrgDestpoints = []
          for (var k = 0; k < OrgDest.length; k += 2) { // loop over each point in the path
            OrgDestpoints.push(new google.maps.LatLng(OrgDest[k], OrgDest[k + 1]));
          }
          waypts = [];
          if (waypoints[routeName].length > 0) {
            wp = waypoints[routeName][j];
            for (var k = 0; k < wp.length; k += 2) { // loop over each waypoints in the path
              waypts.push({
                location: new google.maps.LatLng(wp[k], wp[k + 1]),
                stopover: true
              });
            }
          }
    
          if (j > 0) // & (j!=(orgdest[routeName].length)))
            traceroutePath.setMap(null); //clearing previously rendered map
          if (i > 0 & j == 0) {
            traceroutePath.setMap(null); //clearing previously rendered map
          }
    
          routePath = OrgDestpoints;
          traceroutePath = new google.maps.Polyline({
            path: routePath,
            strokeColor: routeColors[routeName],
            strokeOpacity: 1.0,
            strokeWeight: 2
          });
          service = new google.maps.DirectionsService(), traceroutePath, snap_path = [];
          traceroutePath.setMap(map);
          for (z = 0; z < routePath.length - 1; z++) {
            service.route({
                origin: routePath[z],
                destination: routePath[z + 1],
                travelMode: google.maps.DirectionsTravelMode.DRIVING,
                waypoints: waypts
              },
              function(result, status) {
                if (status == google.maps.DirectionsStatus.OK) {
                  var snap_path = result.routes[0].overview_path;
                  var traceroutePath = new google.maps.Polyline({
                    strokeColor: routeColors[routeName],
                    strokeOpacity: 1.0,
                    strokeWeight: 2,
                    map: map
                  });
                  traceroutePath.setPath(snap_path);
                } else alert("Directions request failed: " + status);
              });
          }
        } //end of j for loop; paths to form a route
    
      } //end of i for loop; all routes        
    }
    google.maps.event.addDomListener(window, 'load', initialize);
    html,
    body,
    #map-canvas {
      height: 100%;
      width: 100%;
      margin: 0px;
      padding: 0px
    }
    <script src="https://maps.googleapis.com/maps/api/js"></script>
    <div id="map-canvas"></div>