Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Google Distance Matrix JSON shortest path (PHP)

A client requested me to calculate the distance from a certain address to a fixed address. I made a PHP script utilizing the Google Distance Matrix API to calculate the distance. However, this does not give me the shortest distance. It seems to just give whatever Google thinks is best. For example, my script returns 11.7 kilometers between 2 addresses while Google Maps gives these results:

  • 8.7km
  • 14km
  • 13.8km

As you can see, 8.7km is a pretty significant difference from 11.7km.

I would consider other options than the Google Distance Matrix API.

My script: (in a nutshell)

if ($this->getVar('to', false) && $this->getVar('to', false) != '') {
    $to = urlencode(urldecode($this->getVar('to', false)));
    $url = 'http://maps.googleapis.com/maps/api/distancematrix/json?origins=Etterbeeksesteenweg+180+Brussel&destinations='.$to.'&mode=driving&language=nl-BE&sensor=false';
    $this->view->response = json_decode(file_get_contents($url));
}

I tried to add &alternatives=true, but with no success.

like image 407
Ruben Coolen Avatar asked Sep 02 '13 13:09

Ruben Coolen


Video Answer


2 Answers

The DistanceMatrixService(and the DirectionsService too) usually will not return the shortest route, they will return the fastest route.

Use the DirectionsService instead with an additional parameter alternatives set to true:

http://maps.googleapis.com/maps/api/directions/json?origin=bomerstraat%2018,%20peer&destination=kievitwijk%2028,%20helchteren&alternatives=true&sensor=false

When you add the alternatives-parameter you also get alternative routes, when you inspect the returned result you will see that it also contains the 9km-route. But this route has a duration of 17 minutes, while the suggested (longer) route has a duration of 16 minutes, that's why the longer route is the suggested route.

So fetch the shortest route out of the returned routes.

Example:

<?php
  //request the directions
$routes=json_decode(file_get_contents('http://maps.googleapis.com/maps/api/directions/json?origin=bomerstraat%2018,%20peer&destination=kievitwijk%2028,%20helchteren&alternatives=true&sensor=false'))->routes;

  //sort the routes based on the distance
usort($routes,create_function('$a,$b','return intval($a->legs[0]->distance->value) - intval($b->legs[0]->distance->value);'));

 //print the shortest distance
echo $routes[0]->legs[0]->distance->text;//returns 9.0 km
?>

Note: you may get different results on google-maps and from the service, because google-maps will take into account the current traffic-situation, but the service will not (except when you have a business-license)

like image 72
Dr.Molle Avatar answered Sep 23 '22 13:09

Dr.Molle


I had a similar issue.

My client wanted two data points. Shortest route, and shortest distance 'as the crow flies'.

I still use the distancematrix for 'quickest' route as I have found this to be very accurate taking local data and even traffic into account.

I calculated the direct point to point distance using math on the lat long of the two addresses - http://www.movable-type.co.uk/scripts/latlong.html

There can be issues here too though. In one of my cases the distancematrix took a route over a harbour bridge showing a much greater distance than the lat long calc did, which of course was direct over water.

One other little warning: There is a limit to the number of calls any IP can make to the Google Maps API. I moved a large portion of the hits to the API in JavaScript, using the end clients quota rather than that of the server - https://developers.google.com/maps/documentation/geocoding/#Limits

like image 27
Eclectic Avatar answered Sep 25 '22 13:09

Eclectic