2

I am not experienced in javascript, therefore I do not know much about it!

I make multiple calls to the google API service google.maps.DistanceMatrixService.getDistanceMatrix() as follows:

for (i=0;i<n;i++) {
    var service = new google.maps.DistanceMatrixService();
    service.getDistanceMatrix(
    {
        origins: [origin],
        destinations: destinations[i],
        travelMode: google.maps.TravelMode.DRIVING,
        unitSystem: google.maps.UnitSystem.METRIC,
        avoidHighways: false,
        avoidTolls: false
    }, callback);   
}

So I create several service requests. When those requests are done, the callback function is called. I assume, this can happen in a different order.

So when the callback function is called with distance informations, how do I know if the results correspond to destionations[0]? Or destinations[1]...? Unfortunately, the location data given in the responses is a string denoting the destination place, like 'Bonigerweg, 4852 Rothrist, Schweiz' instead of a google.maps.LatLng-object. And here I do not want to call the geocoder service to back-transform the address to a google.maps.LatLng-object.

Is there some sane way to solve my problem? Or should I use timing? Make the next call to google.maps.DistanceMatrixService.getDistanceMatrix() only if the response to the first call has been received?

1 Answer 1

2

If you have 25 or fewer destinations, you can just pass them all in with one call:

var service = new google.maps.DistanceMatrixService();
service.getDistanceMatrix({
    origins: [ origin ],
    destinations: destinations,
    travelMode: google.maps.TravelMode.DRIVING,
    unitSystem: google.maps.UnitSystem.METRIC,
    avoidHighways: false,
    avoidTolls: false
}, callback );

The response passed to the callback will contain the distances in the same order as the destinations array.

Or you could use a closure to let JavaScript keep track of the individual destination values. Just call a function each time through the loop and pass destinations[i] as a parameter, like this:

for( i = 0;  i < n;  i++ ) {
    getDistance( destinations[i] );
}

function getDistance( destination ) {
    // Inside this function, destination is the destinations[i]
    // value it was called with, even when the getDistanceMatrix
    // callback is called asynchronously when the request finishes.
    var service = new google.maps.DistanceMatrixService();
    service.getDistanceMatrix({
        origins: [ origin ],
        destinations: destination,
        travelMode: google.maps.TravelMode.DRIVING,
        unitSystem: google.maps.UnitSystem.METRIC,
        avoidHighways: false,
        avoidTolls: false
    }, function( response, status ) {
        // Here we have the response and status for the
        // getDistanceMatrix callback, *and* we have
        // destination which is the destination for this call.
        // If you don't want the callback code inline here, you
        // can call it from this function:
        callback( response, status, destination );
    });
}

You should be aware of the usage limits for the distance matrix service. If you are only making a few calls you should be OK, but for a larger number of calls you would want to delay between the requests.

2
  • Yes of course! The only downside is to have the callback function defined inside the getDistance function, which makes the whole script a but cluttered...
    – Alex
    Commented Jun 26, 2015 at 7:06
  • You can certainly put your callback somewhere else in the code if you like, just use a one-line callback here and call your real callback passing it the destination value. I added this to the example. Also see the option of passing all the destinations at once if there are 25 or fewer. Commented Jun 26, 2015 at 7:15

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