'Bing Maps Route Optimization

I am attempting to generate an optimized route using Bing Maps re this article, https://docs.microsoft.com/en-us/bingmaps/rest-services/examples/optimized-waypoints-example#example, but am struggling to know how to render the resultant route on screen. For normal routes I am using this routine which seems to work well enough...

function traceRoute(){
   infobox.setOptions({visible:false});
    
   if(Object.entries(fromCoords).length !== 0 && Object.entries(toCoords).length !== 0){
     Microsoft.Maps.loadModule('Microsoft.Maps.Directions', function () {
       var directionsManager = new Microsoft.Maps.Directions.DirectionsManager(map);

       directionsManager.setRequestOptions({ routeMode: Microsoft.Maps.Directions.RouteMode.driving });

       var waypoint1 = new Microsoft.Maps.Directions.Waypoint({ address: fromCoords.title, location: new Microsoft.Maps.Location(fromCoords.lat,fromCoords.long) });
       var waypoint2 = new Microsoft.Maps.Directions.Waypoint({ address: toCoords.title, location: new Microsoft.Maps.Location(toCoords.lat,toCoords.long) });

       directionsManager.addWaypoint(waypoint1);
       directionsManager.addWaypoint(waypoint2);
            
       // Set the element in which the itinerary will be rendered
       directionsManager.setRenderOptions({ itineraryContainer: document.getElementById('printoutPanel') });
       directionsManager.calculateDirections();          
     });
   }
 }

However, I cannot figure out how to do they same with an optimised API call. Is it possible to add a list of way points to the directionsManager and set an Optimised flag?



Solution 1:[1]

Digging through the documentation and trying to reverse engineer the directions module/manager, there doesn't appear to be any support for this option in the module.

One solution would be to call the REST service directly to get the optimized ordering of the waypoints, then pass those ordered waypoints into the directions manager. This will allow you to leverage the rendering capabilities of the directions module which will make development a lot easier.

Here is a code sample:

<!DOCTYPE html>
<html lang="en">
<head>
    <title></title>

    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
    
    <script type='text/javascript' src='https://www.bing.com/api/maps/mapcontrol?callback=GetMap&key=<Your Bing Maps Key>'></script>
        
    <script>
    var map, directionsManager;
    
    //Get optimized waypoint orders based on time with traffic, and only get minimial information back.
    var directionsUrl = 'http://dev.virtualearth.net/REST/V1/Routes/Driving?&optimizeWaypoints=true&optimize=timeWithTraffic&routeAttributes=excludeItinerary&key={key}';

    function GetMap()
    {
        map = new Microsoft.Maps.Map('#myMap', {});

        //Load the directions module.
        Microsoft.Maps.loadModule('Microsoft.Maps.Directions', function () {
            //Create an instance of the directions manager.
            directionsManager = new Microsoft.Maps.Directions.DirectionsManager(map);
            directionsManager.setRequestOptions({ routeOptimization: 'timeWithTraffic' });

            //Pass in waypoints to calculate optimized order.
            calculateOptimizedOrder([
                
                new Microsoft.Maps.Directions.Waypoint({ address: '86 Pike Pl, Seattle, WA 98101' }),
                new Microsoft.Maps.Directions.Waypoint({ address: 'Troll Ave N, Seattle, WA 98103' }),
                new Microsoft.Maps.Directions.Waypoint({ address: '3800 Montlake Blvd NE, Seattle, WA 98195' }),
                new Microsoft.Maps.Directions.Waypoint({ address: '1000 4th Ave, Seattle, WA 98104' }),
                new Microsoft.Maps.Directions.Waypoint({ address: '5400 Ballard Ave NW, Seattle, WA 98107' })
            ]);
        });
    }
    
    function calculateOptimizedOrder(waypoints) {
        map.getCredentials((sessionId) => {
            //Add the key to the REST request.
            var request = [directionsUrl.replace('{key}', sessionId)];
            
            //Add the waypoints to the REST request.
            for(var i=0;i<waypoints.length;i++){
                var wp = waypoints[i];
                
                request.push('&wp.', i, '=');
                
                var loc = wp.getLocation();
                var add = wp.getAddress();
                
                if(loc) {
                    request.push(loc.toString());
                } else if(add){
                    request.push(encodeURIComponent(add));
                } else {
                    throw 'No waypoint info provided';
                }
            }   
            
            //Combine the request parts to create the URL.
            var url = request.join('');
            
            //Process the request.
            fetch(url).then(r => r.json()).then(r => {
            
                var orderedWaypoints = [];
                
                var waypointsOrder = r.resourceSets[0].resources[0].waypointsOrder;
                
                for(var i=0;i<waypointsOrder.length;i++){
                    //Extract the number from the waypoint order text.
                    var idx = parseInt(waypointsOrder[i].replace('wp.',''));
                    
                    //Cross reference the original waypoints.
                    orderedWaypoints.push(waypoints[idx]);
                }
                
                //Calculate and render directions using the optimized order.
                calculateDirections(orderedWaypoints);

                alert('Optimized order: ' + waypointsOrder.join(','));          
            });
        });     
    }
    
    
    function calculateDirections(orderedWaypoints) {
    
        for(var i=0;i< orderedWaypoints.length;i++){
            directionsManager.addWaypoint(orderedWaypoints[i]);
        }
        
        //Calculate directions.
        directionsManager.calculateDirections();
    }
    </script>
    
</head>
<body>
    <div id="myMap" style="position:relative;width:100%;min-width:290px;height:600px;"></div>
</body>
</html>

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 rbrundritt