Search code examples
javascriptgoogle-maps-api-3

Get a polyline from Google maps directions V3


I am trying to get a polyline on a Google map after getting directions. I want to use the v3_epoly to place markers along a polyline.

I found this post, which worked, but I found it wasn't completely accurate. In the image, the Google directions is the light blue and the polyline is the darker blue:

enter image description here

You can see it's quite inaccurate.

This is the code:

directions_service.route(req, function(response, status) {
  if (status == google.maps.DirectionsStatus.OK) {
    path = response.routes[0].overview_path;
    $(path).each(function(index, item) {
      route.getPath().push(item);
      bounds.extend(item);
    });
    route.setMap(map);
    map.fitBounds(bounds);
    directions_display.setDirections(response);
  }
});

Anyone know either how to improve this accuracy or to get the polyline another way?

EDIT:

I wanted to add the code that got it working:

legs = response.routes[0].legs;
$(legs).each(function(index, item) {
  steps = item.steps;
  $(steps).each(function(index, item) {
    path = item.path;
    $(path).each(function(index, item) {
      route.getPath().push(item);
      counter++;
      bounds.extend(item);
    });
  });
});

Solution

  • Don't use overview_path for the polyline, it doesn't include all the points, grab the points out of all the legs and use them to create the polyline.

    var polyline = new google.maps.Polyline({
      path: [],
      strokeColor: '#FF0000',
      strokeWeight: 3
    });
    var bounds = new google.maps.LatLngBounds();
    
    
    var legs = response.routes[0].legs;
    for (i=0;i<legs.length;i++) {
      var steps = legs[i].steps;
      for (j=0;j<steps.length;j++) {
        var nextSegment = steps[j].path;
        for (k=0;k<nextSegment.length;k++) {
          polyline.getPath().push(nextSegment[k]);
          bounds.extend(nextSegment[k]);
        }
      }
    }
    
    polyline.setMap(map);
    map.fitBounds(bounds);
    

    example

    code snippet:

    function initialize() {
      var map = new google.maps.Map(
        document.getElementById("map_canvas"), {
          center: new google.maps.LatLng(51.276092, 1.028938),
          zoom: 13,
          mapTypeId: google.maps.MapTypeId.ROADMAP
        });
      var directionsService = new google.maps.DirectionsService();
      var directionsDisplay = new google.maps.DirectionsRenderer({
        map: map,
        preserveViewport: true
      });
      directionsService.route({
        origin: new google.maps.LatLng(51.269776, 1.061326),
        destination: new google.maps.LatLng(51.30118, 0.926486),
        waypoints: [{
          stopover: false,
          location: new google.maps.LatLng(51.263439, 1.03489)
        }],
        travelMode: google.maps.TravelMode.DRIVING
      }, function(response, status) {
        if (status === google.maps.DirectionsStatus.OK) {
          // directionsDisplay.setDirections(response);
          var polyline = new google.maps.Polyline({
            path: [],
            strokeColor: '#0000FF',
            strokeWeight: 3
          });
          var bounds = new google.maps.LatLngBounds();
    
    
          var legs = response.routes[0].legs;
          for (i = 0; i < legs.length; i++) {
            var steps = legs[i].steps;
            for (j = 0; j < steps.length; j++) {
              var nextSegment = steps[j].path;
              for (k = 0; k < nextSegment.length; k++) {
                polyline.getPath().push(nextSegment[k]);
                bounds.extend(nextSegment[k]);
              }
            }
          }
    
          polyline.setMap(map);
        } else {
          window.alert('Directions request failed due to ' + status);
        }
      });
    }
    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?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></script>
    <div id="map_canvas"></div>