0

I use the google maps api to draw a route in a embedded google map. I changed the color of the hole route but I also would like to change the color between the waypoints for example:

Start --orange--> firstWP --red-- > secondWP --orange--> firstWP --red--> secondWp --orange--> Destination

The color between firstWP to seceondWP should be changed but secondWP to FirstWP sould be the same color as the other parts of the route.

Furthermore I also need to move the map markers and the route should move/change fitting to the new position of the map marker but keep the different color.

This is a minimal example with draggable map marker and changed color between waypoints but the route does not adapt to the new position of the map markers

var map;
var directionsService;
var directionsDisplay;

function initialize() {
  map = new google.maps.Map(
    document.getElementById("map_canvas"), {
      center: new google.maps.LatLng(37.4419, -122.1419),
      zoom: 13,
      mapTypeId: google.maps.MapTypeId.ROADMAP
    });
  directionsService = new google.maps.DirectionsService();
  directionsDisplay = new google.maps.DirectionsRenderer({
    draggable: true,
    map: map,
    suppressPolylines: true
  });


  calcRoute(39.2903848, -76.6121893, 42.3600825, -71.05888);
}
google.maps.event.addDomListener(window, "load", initialize);

function calcRoute(origin_lat, origin_lng, destination_lat, destination_lng) {
  console.log("Entrée CALC ROUTE");

  var origin = new google.maps.LatLng(origin_lat, origin_lng);
  var destination = new google.maps.LatLng(destination_lat, destination_lng);
  var waypointsArray = document.getElementById('waypoints').value.split("|");

  var waypts = [];

  for (i = 0; i < waypointsArray.length; i++) {
    if (waypointsArray[i] != "") {
      var waypoint = waypointsArray[i];
      var waypointArray = waypoint.split(",");
      var waypointLat = waypointArray[0];
      var waypointLng = waypointArray[1];
      console.log("waypts lat " + waypointLat);
      console.log("waypts lng " + waypointLng);

      waypts.push({
        location: new google.maps.LatLng(waypointLat, waypointLng),
        stopover: true
      })
    }
  }
  console.log("waypts " + waypts.length);

  var request = {
    origin: origin,
    destination: destination,
    travelMode: google.maps.TravelMode.DRIVING,
    waypoints: waypts,
    provideRouteAlternatives: true
  };
  console.log("Calc request " + JSON.stringify(request));

  directionsService.route(request, customDirectionsRenderer);
}

function customDirectionsRenderer(response, status) {
  if (status == google.maps.DirectionsStatus.OK) {
  directionsDisplay.setDirections(response);
    var bounds = new google.maps.LatLngBounds();
    var route = response.routes[0];
    var path = response.routes[0].overview_path;
    var legs = response.routes[0].legs;
    for (i = 0; i < legs.length; i++) {
      var polyline = new google.maps.Polyline({map:map, strokeColor: "blue", path:[]})
      if (i == 1) {
        polyline.setOptions({strokeColor: "red"});
        }
      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);
  }
};
html,
body,
#map_canvas {
  height: 100%;
  width: 100%;
  margin: 0px;
  padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js?libraries=geometry,places&ext=.js"></script>
<input id="waypoints" value="39.9525839,-75.1652215|40.7127837,-74.0059413" />
<div id="map_canvas"></div>

http://jsfiddle.net/westify/vop9o1n5/1/

Is it possible to do that? Or is it only possible if rerender the whole route after moved one waypoint?

geocodezip
  • 158,664
  • 13
  • 220
  • 245
WeSt
  • 889
  • 5
  • 14
  • 32

1 Answers1

2

One option would be to listen for the directions_changed event on the DirectionsRenderer, when that fires, redraw the directions polylines.

var firstTime = true;
google.maps.event.addListener(directionsDisplay, 'directions_changed', function() {
  console.log("directions changed firstTime=" + firstTime);
  // prevent infinite loop
  if (firstTime) {
    google.maps.event.addListenerOnce(directionsDisplay, 'directions_changed', function() {
      console.log("directions changed"); 
      customDirectionsRenderer(directionsDisplay.getDirections(), "OK");
    });
  }
  firstTime = !firstTime;
});

proof of concept fiddle

code snippet:

var map;
var directionsService;
var directionsDisplay;
var firstTime = true;

function initialize() {
  map = new google.maps.Map(
    document.getElementById("map_canvas"), {
      center: new google.maps.LatLng(37.4419, -122.1419),
      zoom: 13,
      mapTypeId: google.maps.MapTypeId.ROADMAP
    });
  directionsService = new google.maps.DirectionsService();
  directionsDisplay = new google.maps.DirectionsRenderer({
    draggable: true,
    map: map,
    suppressPolylines: true
  });
  google.maps.event.addListener(directionsDisplay, 'directions_changed', function() {
    console.log("directions changed firstTime=" + firstTime);
    if (firstTime) {
      google.maps.event.addListenerOnce(directionsDisplay, 'directions_changed', function() {
        console.log("directions changed"); //+JSON.stringify(directionsDisplay.getDirections()));
        customDirectionsRenderer(directionsDisplay.getDirections(), "OK");
      });
    }
    firstTime = !firstTime;
  });


  calcRoute(39.2903848, -76.6121893, 42.3600825, -71.05888);
}
google.maps.event.addDomListener(window, "load", initialize);

function calcRoute(origin_lat, origin_lng, destination_lat, destination_lng) {
  console.log("Entrée CALC ROUTE");

  var origin = new google.maps.LatLng(origin_lat, origin_lng);
  var destination = new google.maps.LatLng(destination_lat, destination_lng);
  var waypointsArray = document.getElementById('waypoints').value.split("|");

  var waypts = [];

  for (i = 0; i < waypointsArray.length; i++) {
    if (waypointsArray[i] != "") {
      var waypoint = waypointsArray[i];
      var waypointArray = waypoint.split(",");
      var waypointLat = waypointArray[0];
      var waypointLng = waypointArray[1];
      console.log("waypts lat " + waypointLat);
      console.log("waypts lng " + waypointLng);

      waypts.push({
        location: new google.maps.LatLng(waypointLat, waypointLng),
        stopover: true
      })
    }
  }
  console.log("waypts " + waypts.length);

  var request = {
    origin: origin,
    destination: destination,
    travelMode: google.maps.TravelMode.DRIVING,
    waypoints: waypts,
    provideRouteAlternatives: true
  };
  console.log("Calc request " + JSON.stringify(request));

  directionsService.route(request, customDirectionsRenderer);
}
var polylines = [];

function customDirectionsRenderer(response, status) {
  for (var i = 0; i < polylines.length; i++) {
    polylines[i].setMap(null);
  }
  polylines = [];
  if (status == google.maps.DirectionsStatus.OK) {
    directionsDisplay.setDirections(response);
    var bounds = new google.maps.LatLngBounds();
    var route = response.routes[0];
    var path = response.routes[0].overview_path;
    var legs = response.routes[0].legs;
    for (i = 0; i < legs.length; i++) {
      var polyline = new google.maps.Polyline({
        map: map,
        strokeColor: "blue",
        path: []
      });
      polylines.push(polyline);
      if (i == 1) {
        polyline.setOptions({
          strokeColor: "red"
        });
      }
      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);
  }
};
html,
body,
#map_canvas {
  height: 100%;
  width: 100%;
  margin: 0px;
  padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js"></script>
<input id="waypoints" value="39.9525839,-75.1652215|40.7127837,-74.0059413" />
<div id="map_canvas"></div>
geocodezip
  • 158,664
  • 13
  • 220
  • 245
  • Thats works nice. But what will be annoying in my application is that everytime the map will be rerendered, the maps zooms complete out. What I wanted was to zoom in to a waypoint and stay at that zoom position so I can see if the waypoint snaped to the correct position. In this example I have to zoom in, move and zoom in again to check the position – WeSt Jan 11 '18 at 10:47
  • There is an option: preserveViewport. Then it doesn't change the boundaries. https://stackoverflow.com/questions/18085305/do-not-change-map-center-or-zoom-level-when-rendering-directions – Emmanuel Delay Jan 11 '18 at 10:55
  • 1
    This code is using a `customDirectionsRenderer`, which zooms to fit it's bounds. In this case remove the `map.fitBounds(bounds);` in that function (or call it conditionally) – geocodezip Jan 11 '18 at 11:08