2017-08-07 176 views
-1

我有一系列的功能,用来计算从目标地址到我的几个地点之一的最近驾驶距离,并且大部分地方它运作良好。它首先得到我最近的位置,然后用这个地址计算到目标地址的实际驾驶距离,这就是问题所在。有时候,乌鸦的飞行距离离一个地方更近,但距离另一个地方更近一些,所以我如何计算从一开始的驾驶距离,然后像乌鸦苍蝇计算一样跳过?寻找最近的驾车距离

// Provides "as the crow flies" distance from my closest location to target address 
function closestLocation($Address) { 
    $values = locationFromAddress($Address); 
    $center_lat = $values[0]; 
    $center_lng = $values[1]; 
    // My locations 
    $query = sprintf("SELECT ID, Address, (3959 * acos(cos(radians('%s')) * cos(radians(lat)) * cos(radians(lng) - radians('%s')) + sin(radians('%s')) * sin(radians(lat)))) AS Distance 
    FROM locations 
    WHERE Address > 0 AND lat <> 0 AND lng <> 0 
    ORDER BY Distance ASC 
    LIMIT 1", 
     $center_lat, 
     $center_lng, 
     $center_lat); 
    $rowCat = DBConnect($query, "Select", "pchome_geoip"); 

    // Returns array of the location 
    return $rowCat; 
} 

你可以看到,查询简单地使用存储在数据库中的纬度和经度使用locationFromAddress提供的目标地址的纬度和经度()来计算它的功能:

function locationFromAddress($Address) { 
    $Address = urlencode($Address); 
    if ($Address) : 
     $geocode = file_get_contents("http://maps.google.com/maps/api/geocode/json?address=$Address&sensor=false"); 
     $output = json_decode($geocode); 
     $lat = $output->results[0]->geometry->location->lat; 
     $long = $output->results[0]->geometry->location->lng; 
     return array($lat,$long); 
    else: 
     return ""; 
    endif; 
} 

而且那么细节用于计算使用谷歌API的驾驶距离:

function compareDistance($unit,$inLatitude,$inLongitude,$outLatitude,$outLongitude) { 
    $url = "http://maps.googleapis.com/maps/api/directions/json?origin=$inLatitude,$inLongitude&destination=$outLatitude,$outLongitude&sensor=false"; 

    // Retrieve the URL contents 
    $c = curl_init(); 
    curl_setopt($c, CURLOPT_RETURNTRANSFER, 1); 
    curl_setopt($c, CURLOPT_URL, $url); 
    $jsonResponse = curl_exec($c); 
    curl_close($c); 

    $dataset = json_decode($jsonResponse); 
    if(!$dataset) 
     return 0; 
    if(!isset($dataset->routes[0]->legs[0]->distance->value)) 
     return 0; 
    $miles = ($dataset->routes[0]->legs[0]->distance->value * .00062); 
    // Google API returns meters, multiplied by .00062 to get miles 

    // Round up to nearest unit 
    if ($unit == "K") : 
     return ceil($miles * 1.609344); 
    elseif ($unit == "N") : 
     return ceil($miles * 0.8684); 
    else : 
     return ceil($miles); 
    endif; 
} 

function getDrivingDistance($myAddress, $custAddress, $unit) { 
    // 'M' is statute miles 
    // 'K' is kilometers 
    // 'N' is nautical miles 
    // Get accurate latitude and longitude based on actual location 
    $myValues = locationFromAddress($myAddress); 
    $myLat = $myValues[0]; 
    $myLng = $myValues[1]; 

    $custValues = locationFromAddress($custAddress); 
    $custLat = $custValues[0]; 
    $custLng = $custValues[1]; 

    // Returns actual driving distance 
    return compareDistance($unit,$myLat,$myLng,$custLat,$custLng); 
} 

此外,是否有API参数为最接近而非最快路线?

+0

相关的问题:?如何找到最佳路线众多指标之一(https://stackoverflow.com/questions/11345165/how-to-find-optimal-route-to-one-of -many-markers) – geocodezip

+0

[Google Maps API - 取得最接近邮政编码的点]的可能副本(https://stackoverflow.com/questions/17280787/google-maps-api-getting-closest-points-to-zipcode) – geocodezip

+0

在相关的问题上,答案之一正是我想要避免的:直线就是乌鸦的计算。另一种是通过邮编,这不足以满足我的需求。 – DonP

回答

0

我重写了这个函数,完全消除了closestLocation()和另一个函数,所以它简化了一些东西。我需要重新安排被调用的其他几个区域,但它确实似乎拉出了有效的驾驶距离,尽管有时它是最快的,而不是最接近的。 Google API是否有最接近的开关?

function getDrivingDistance($Address,$unit="M") { 
    if ($Address) : 
     $values = locationFromAddress($Address); 
     $inLatitude = $values[0]; 
     $inLongitude = $values[1]; 

     // Fetch all of my locations 
     $sqlLocation = "SELECT ID, Address, lat, lng 
         FROM locations"; 
     $rowLocation = DBConnect($sqlLocation, "Multiple", "pchome_geoip"); 

     // Create array of driving distances based on latidude and longitude 
     foreach ($rowLocation as $key) : 
      $outLatitude = $key['lat']; 
      $outLongitude = $key['lng']; 
      $output[] = compareDistance($inLatitude,$inLongitude,$outLatitude,$outLongitude,$unit); 
     endforeach; 

     //sort($output, SORT_NUMERIC); 
     if (array_sum($output) > 0) : 
      return min(array_diff($output,array(0))); 
     else : 
      return 0; 
     endif; 
    endif; 
} 
+0

我用条件更新了一下,以防止在没有提供地址的情况下崩溃。也意识到,如果使用min(),则不需要对数组元素进行排序,而是添加代码来只取出最小的非0结果。所有0值的数组都会导致崩溃,因此重新检测数组是否全为0。在这种情况下,没有负数,所以array_sum()做到了这一点。 – DonP