2017-08-07 201 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