Migrate Bing Maps Distance Matrix to Azure Maps Route Matrix

HSB 65 Reputation points
2024-10-22T12:43:25.4366667+00:00

We currently use Bing Maps API to get distances between points using the distance matrix.  We use the following URL:

https://dev.virtualearth.net/REST/v1/Routes/DistanceMatrix?origins={lat0,long0;lat1,lon1;latM,lonM}&destinations={lat0,lon0;lat1,lon1;latN,longN}&travelMode={travelMode}&startTime={startTime}&timeUnit={timeUnit}&key={BingMapsKey}

 

I've reviewed the migration document and it says to use the Route Matrix in Azure Maps, specifically the following URL:

https://atlas.microsoft.com/route/matrix/sync/json?api-version=1.0&subscription-key={subscription-key}

 

When I try to use this URL, I get a 405 error every time.  I'm not sure of the format to add the origins and destinations like the Bing Maps example has. I'd really prefer to use this API over the SDK as I like to be in control of how I retrieve and pull data out of the results.

 

Is there an example of using the Route Matrix API?

Azure Maps
Azure Maps
An Azure service that provides geospatial APIs to add maps, spatial analytics, and mobility solutions to apps.
742 questions
0 comments No comments
{count} votes

Accepted answer
  1. rbrundritt 18,686 Reputation points Microsoft Employee
    2024-10-22T18:38:04.4433333+00:00

    Before diving in, I want to highlight that many of the Bing Maps services are being brought over to Azure Maps. The Bing Distance/Route Matrix API hasn't yet been brought over, however I believe it will be in the not-too-distant future (I'm not on the Azure Maps team, so don't take this as an official statement). That said, the API interface (input and response format) will likely be modernized to align with open data standards (e.g. GeoJSON format is used for most data in Azure Maps). So, there would still be a bit of work to migrate to that new service when it becomes available. I don't have a timeline for when this new service will be made available in Azure Maps, but wanted to make you aware that this is likely to be coming.

    In the meantime, Azure Maps does have an existing route matrix API that works decently well. Looking at your question it appears that you are using a synchronous GET request with Bing Maps with your origin/destination information being in the URL. In Azure Maps you have to use a POST request as GET requests for distance matrix is often too limiting due to URL length constraints. Especially when the Azure Maps version has a ton more options you can specify in the request. There is a GET Azure Maps Route Matrix API documented, but that's actually for getting the status of an asynchronous route matrix job. For your scenario, I suspect a synchronous POST request version of the API would be the easiest option to migrate too and most inline with the Bing Maps example you provided.

    To make a request using the synchronous API you would create a URL request that has all the options you want to apply to the request. If using subscription keys for authentication, you can add that to the URL request, or put it into the request header (Microsoft Entra ID is also available as a more secure authentication method). Here is an example request URL:

    https://atlas.microsoft.com/route/matrix/sync/json?api-version=1.0&routeType=fastest&travelMode=car&subscription-key=<Your_Azure_Maps_Key>

    In the body of the POST request you would then create a JSON object that contains the origins and destination information. I'll use placeholders for lat/lon similar to the Bing Maps example you provided.

    {
      "origins": {
        "type": "MultiPoint",
        "coordinates": [
          [
            lon0,
            lat0
          ],
          [
            lon1,
            lat1
          ]
        ]
      },
      "destinations": {
        "type": "MultiPoint",
        "coordinates": [
          [
            lon0,
            lat0
          ],
          [
            lon1,
            lat1
          ]
        ]
      }
    }
    

    There is an example of this in JavaScript available here: https://samples.azuremaps.com/?sample=calculate-nearest-locations Here is a simply example using the fetch API in JavaScript:

    var routeMatrixUrlRequest = `https://atlas.microsoft.com/route/matrix/sync/json?api-version=1.0&routeType=fastest&travelMode=car&subscription-key=${Azure_Maps_Key}`;
    
    // Create the request body to get a route matrix
    const jsonBody = {
        origins: {
            type: 'MultiPoint',
            coordinates: [
                [-122.338943,47.611483], //Seattle, WA
                [-122.196381, 47.617302]  //Bellevue, WA
            ]
        },
        destinations: {
            type: 'MultiPoint',
            coordinates: [
                [-122.123870, 47.674475], //Redmond, WA
                [-122.441653, 47.253972]  //Tacoma, WA
            ]
        }
    };
    
    fetch(routeMatrixUrlRequest, {
            // Adding method type
            method: "POST",
    
            // Adding body or contents to send
            body: JSON.stringify(jsonBody),
    
            // Adding headers to the request
            headers: {
                "Content-type": "application/json; charset=UTF-8"
            }
        })
        // Converting received data to JSON
        .then(response => response.json())
        .then(json => {
    
            //Do somethign with the results, in this case, creating a table.
            // Create a variable to store HTML
            const html = ['<table><tr><th>Origin</th><th>Destination</th><th>Travel time (sec)</th><th>Travel distance (meters)</th></tr>'];
    
            //Response is a 2D array, where row index is the origin and column index is the destination.
            const originNames = ['Seattle', 'Bellevue'];
            const destinationNames = ['Redmond', 'Tacoma'];
    
            // Loop through the results
            for (let r = 0; r < originNames.length; r++) {
                for (let c = 0; c < destinationNames.length; c++) {
    
                    html.push(`<tr>
                        <td>${originNames[r]}</td>
                        <td>${destinationNames[c]}</td>`);                       
    
                    if (json.matrix[r][c].statusCode === 200) {
                        let summary = json.matrix[r][c].response.routeSummary;
    
                        html.push(`<td>${summary.travelTimeInSeconds}</td>
                                <td>${summary.lengthInMeters}</td>         
                            </tr>`);
                    } else {
                        html.push(`<td colspan="2">Error: ${json.matrix[r][c].statusCode}</td></tr>`);
                    }
                }
            }
    
            // Display result
            document.body.innerHTML = html.join('');
        });
    

    Here is what the above code generates:

    enter image description here


0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.