1

i am using directions api with some waypoints. the thing is that its not optimized, it goes with the order of my array and not with the most efficient order. i dont want the order of my array to take part of how the path will be. for example always the api will direct me to the first object on the array, thats not right, it should direct me to, the most efficient.

const destinations = [
        { latitude: 40.962259, longitude: 24.506937,stopover: true }, 
        { latitude: 37.993381, longitude: 23.713517,stopover: true }, 
        { latitude: 40.936184, longitude: 24.401282,stopover: true }, 
        // Add more destinations
      ];
      
      const startingPoint = { latitude: 40.400304, longitude: 23.876982 };
    async function planRoute() {
        
      
        try {
          const response = await client.directions({
            params: {
              origin: `${startingPoint.latitude},${startingPoint.longitude}`,
              destination: `${40.397665},${23.884578}`,
              waypoints: destinations,
              optimizeWaypoints: true,
              key: apikey
            },
          });
      
          if (response) {
            // The optimized route is in response.data.routes[0]
            const route = response.data.routes[0];
            console.log('Optimized route:', route);
          }

i tried to change order of the objects on the array and it changed the path of my directions, thats not right.

2
  • 1
    according to the documentation I found, it looks like the parameter should be optimizeWaypointOrder, not optimizeWaypoints Commented Oct 11, 2023 at 13:56
  • 1
    Please clarify: are you really using the Directions API, or the new Routes API? Your code looks like the latter but doesn't really work with either, what is that client.directions() you are using?
    – miguev
    Commented Oct 19, 2023 at 15:11

1 Answer 1

0

There are multiple issues with your code

I'm not sure how you even made it work, but first of all, your waypoints array is not how it should be formatted in relation to the documentation.

A waypoint is specified as an object literal with fields shown below:

location specifies the location of the waypoint, as a LatLng, as a Place object or as a String which will be geocoded. stopover is a boolean which indicates that the waypoint is a stop on the route, which has the effect of splitting the route into two routes.

Using your format gives me an error:

[
  { latitude: 40.962259, longitude: 24.506937,stopover: true }, 
  { latitude: 37.993381, longitude: 23.713517,stopover: true }, 
  { latitude: 40.936184, longitude: 24.401282,stopover: true }, 
]

So I fixed it following the documentation:

[
  { location: {lat: 40.962259, lng: 24.506937},stopover: true }, 
  { location: {lat: 37.993381, lng: 23.713517},stopover: true }, 
  { location: {lat: 40.936184, lng: 24.401282},stopover: true }, 
]

Then with this, the code works.

Then passing in the optimizeWaypoints seems to work fine and is working as intended.

Here's a sample snippet for you to verify it yourself using some of your given locations as an example:

/**
 * @license
 * Copyright 2019 Google LLC. All Rights Reserved.
 * SPDX-License-Identifier: Apache-2.0
 */
function initMap() {
  const map = new google.maps.Map(document.getElementById("map"), {
    zoom: 4,
    center: { lat: -24.345, lng: 134.46 }, // Australia.
  });
  const directionsService = new google.maps.DirectionsService();
  const directionsRenderer = new google.maps.DirectionsRenderer({
    draggable: true,
    map,
    panel: document.getElementById("panel"),
  });

  directionsRenderer.addListener("directions_changed", () => {
    const directions = directionsRenderer.getDirections();

    if (directions) {
      computeTotalDistance(directions);
    }
  });
  displayRoute(
        {lat:40.973614, lng: 24.593084},
    {lat: 40.397665, lng: 23.884578},
    directionsService,
    directionsRenderer,
  );
}

function displayRoute(origin, destination, service, display) {
  service
    .route({
      origin: origin,
      destination: destination,
      // Change this to true and the Total Distance 
      // becomes shorter
      optimizeWaypoints: false,
      waypoints:  [
        { location: {lat: 40.962259, lng: 24.506937},stopover: true }, 
        { location:{lat: 37.993381, lng: 23.713517},stopover: true }, 
        { location:{lat: 40.936184, lng: 24.401282},stopover: true }, 
      ],
      travelMode: google.maps.TravelMode.DRIVING,
      avoidTolls: true,
    })
    .then((result) => {
      display.setDirections(result);
    })
    .catch((e) => {
      alert("Could not display directions due to: " + e);
    });
}

function computeTotalDistance(result) {
  let total = 0;
  const myroute = result.routes[0];

  if (!myroute) {
    return;
  }

  for (let i = 0; i < myroute.legs.length; i++) {
    total += myroute.legs[i].distance.value;
  }

  total = total / 1000;
  document.getElementById("total").innerHTML = total + " km";
}

window.initMap = initMap;
/**
 * @license
 * Copyright 2019 Google LLC. All Rights Reserved.
 * SPDX-License-Identifier: Apache-2.0
 */
/* Optional: Makes the sample page fill the window. */
html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}

#container {
  height: 100%;
  display: flex;
}

#sidebar {
  flex-basis: 15rem;
  flex-grow: 1;
  padding: 1rem;
  max-width: 30rem;
  height: 100%;
  box-sizing: border-box;
  overflow: auto;
}

#map {
  flex-basis: 0;
  flex-grow: 4;
  height: 100%;
}
<!doctype html>
<!--
 @license
 Copyright 2019 Google LLC. All Rights Reserved.
 SPDX-License-Identifier: Apache-2.0
-->
<html>
  <head>
    <title>Draggable Directions</title>
    <script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>
    <!-- jsFiddle will insert css and js -->
  </head>
  <body>
    <div id="container">
      <div id="map"></div>
      <div id="sidebar">
        <p>Total Distance: <span id="total"></span></p>
        <div id="panel"></div>
      </div>
    </div>

    <!-- 
      The `defer` attribute causes the callback to execute after the full HTML
      document has been parsed. For non-blocking uses, avoiding race conditions,
      and consistent behavior across browsers, consider loading using Promises.
      See https://developers.google.com/maps/documentation/javascript/load-maps-js-api
      for more information.
      -->
    <script
      src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initMap&v=weekly"
      defer
    ></script>
  </body>
</html>

If you try changing the optimizeWaypoints to true you will notice that the total distance of the path is significantly reduced. This shows that the optimizeWaypoints is working as intended. Switching around the waypoint order does not seem to affect it.

I hope this helps!

Not the answer you're looking for? Browse other questions tagged or ask your own question.