客户要求我计算从某个地址到固定地址的距离。我使用Google Distance Matrix API制作了一个PHP脚本来计算距离。但是,这并没有给我最短的距离。它似乎只是给了谷歌认为最好的东西。例如,我的脚本在2个地址之间返回11.7公里,而Google地图则提供以下结果:
如你所见,8.7km与11.7km相比差别很大。
我会考虑除Google Distance Matrix API之外的其他选项。
我的剧本:(简而言之)
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));
}
我尝试添加&alternatives=true
,但没有成功。
答案 0 :(得分:15)
DistanceMatrixService(以及DirectionsService)通常不会返回最短路线,它们将返回最快路线。
使用DirectionsService,而将其他参数alternatives
设置为true:
当您添加alternatives
- 参数时,您还会获得备用路由,当您检查返回的结果时,您将看到它还包含9km路径。但是这条路线的持续时间为17分钟,而建议的(较长的)路线的持续时间为16分钟,这就是为什么较长的路线是建议的路线。
因此,从返回的路线中取出最短的路线。
示例:
<?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
?>
注意:您可能会在google-maps和服务上获得不同的结果,因为google-maps会考虑当前的流量情况,但服务不会(除非您有营业执照)
答案 1 :(得分:2)
我有类似的问题。
我的客户想要两个数据点。最短的路线,最短的距离'如乌鸦苍蝇'。
我仍然将距离矩阵用于“最快”路线,因为我发现这非常准确,可以考虑本地数据甚至流量。
我在两个地址的lat长度上使用数学计算了直接点对点距离 - http://www.movable-type.co.uk/scripts/latlong.html
但这里也可能存在问题。在我的一个案例中,距离矩阵在一个海港大桥上开辟了一条路线,显示的距离远远超过了长距离计算的距离,这当然是直接在水上。
另一个小警告:任何IP可以对Google Maps API进行的呼叫数量都有限制。我使用最终客户端配额而不是服务器配额将大部分匹配移动到JavaScript中的API - https://developers.google.com/maps/documentation/geocoding/#Limits
答案 2 :(得分:0)
如果有多条腿,则上述解决方案将无效。所以,这是我的替代版本。
public function get_shortest_route($routes)
{
if(!$routes){
return null;
}
$shortest_route = $routes[0];
foreach($routes as $index => $route){
if(!isset($routes[$index+1])){
break;
}
$totalDistance1 = 0;
foreach($route->legs as $leg){
$totalDistance1 += $leg->distance->value;
}
$totalDistance2 = 0;
foreach($route[$index+1]->legs as $leg){
$totalDistance2 += $leg->distance->value;
}
$shortest_route = $totalDistance1 < $totalDistance2 ? $route : $routes[$index+1];
}
return $shortest_route;
}