2012-03-06 9 views
8

は、私は以下の配列の中で最も近い経度と緯度を見つけますか?

49.648881 
-103.575312 

のようなPHPの文字列として経度と緯度を持っていると私はそれを取ると、最も近いものを見つけるために値の配列で見てみたいです。配列は次のようになります

array(
'0'=>array('item1','otheritem1details....','55.645645','-42.5323'), 
'1'=>array('item1','otheritem1details....','100.645645','-402.5323') 
); 

最も近いlongとladを持つ配列を返したいと思います。この場合、それは最初のものになります(そして、私は-400が可能な値ではないことを知っています)。

これを行う簡単な方法はありますか?私は配列の検索を試みたが、それは動作しませんでした。

違いコード

function distance($lat1, $lon1, $lat2, $lon2, $unit) { 

    $theta = $lon1 - $lon2; 
    $dist = sin(deg2rad($lat1)) * sin(deg2rad($lat2)) + cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * cos(deg2rad($theta)); 
    $dist = acos($dist); 
    $dist = rad2deg($dist); 
    $miles = $dist * 60 * 1.1515; 
    $unit = strtoupper($unit); 

    if ($unit == "K") { 
    return ($miles * 1.609344); 
    } else if ($unit == "N") { 
     return ($miles * 0.8684); 
    } else { 
     return $miles; 
     } 
} 
+0

あなたは '関数の距離($ LAT1、$のような2緯度/長いペア間の距離を取得する場所、あなたのコードを提供していただけますlong1、$ lat2、$ long2){... '? – hakre

+0

それは意味がありません、それは簡単な数学ですか? 55 - 49 = 6、55-100 = 45 6は45より小さい。 – Steven

+0

地球上の2点間の距離を計算する方法は実際に分かっていますか? – hakre

答えて

20

より近い経度します最初に各項目の基準点までの距離。

その後、マップを並べ替えた後、あなたは距離(あなたが検索逆場合または最高)最低持っている伝えることができます:

$ref = array(49.648881, -103.575312); 

$items = array(
    '0' => array('item1','otheritem1details....','55.645645','-42.5323'), 
    '1' => array('item1','otheritem1details....','100.645645','-402.5323') 
); 

$distances = array_map(function($item) use($ref) { 
    $a = array_slice($item, -2); 
    return distance($a, $ref); 
}, $items); 

asort($distances); 

echo 'Closest item is: ', var_dump($items[key($distances)]); 

出力:

Closest item is: array(4) { 
    [0]=> 
    string(5) "item1" 
    [1]=> 
    string(21) "otheritem1details...." 
    [2]=> 
    string(9) "55.645645" 
    [3]=> 
    string(8) "-42.5323" 
} 

世話をあなたは持っています緯度と経度の正しい順序。

距離関数(ヘッダのみわずかに変化し、ユニットが削除された):距離のために余弦の法則を用いて

function distance($a, $b) 
{ 
    list($lat1, $lon1) = $a; 
    list($lat2, $lon2) = $b; 

    $theta = $lon1 - $lon2; 
    $dist = sin(deg2rad($lat1)) * sin(deg2rad($lat2)) + cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * cos(deg2rad($theta)); 
    $dist = acos($dist); 
    $dist = rad2deg($dist); 
    $miles = $dist * 60 * 1.1515; 
    return $miles; 
} 
+0

ブリリアント!素晴らしい答え! – nickspiel

1

それを行うには迅速かつ簡単な方法はありません。すべての要素を反復処理し、開始点との距離を計算し、結果を保存して繰り返し、前回よりも小さい場合にのみ結果を保存する必要があります。

0

値をあなたが持っているものと比較しながら配列を繰り返します。値が現在格納されている値よりも小さい場合(または現在格納されている値がない場合)は、その値を格納します。

$closest = null; 
foreach($array as $key => $value){ 
    $distance = //compare distance here; 
    if ($closest === null || $closest > $distance) { 
     $closest = $distance; 
    }; 
}; 

はもちろん、これは、緯度と経度が球体上にあるという事実によってより困難になる、と、マップする必要179及び-179 90および179

+0

空文字列の代わりにデフォルト値として 'null'を追加し、' null'を明示的に厳密にチェックし、 '179'と' -179'は経度に近いことを明確に述べて答えを大幅に更新しました。 – Tadeck

+0

それで私はPHPの教祖ではなく、フロントエンドの開発者です。ありがとうございました。 :) –

4

むしろ、あなたは平型アース近似を使用することができます。平らな地球方程式は計算における三角関数の数を減らす。 Δlat、Δlonは、基準点とテスト点の差です。

この式は、長距離のナビゲーション(数千マイル)では正確ではありませんが、この特定の問題については、正確な距離には本当に関心がありませんが、私に最も近いポイントです。これはあなたにそれを与えるべきであるより簡単な定式化です。

x = Δlon * cos(lat) // lat/lon are in radians! 
y = Δlat 
distance = R * sqrt(x² + y²) // R is radius of the earth; 
           // typical value is 6371 km 

参考:http://www.movable-type.co.uk/scripts/latlong.html

距離コード

function distanceMeters($lat1, $lon1, $lat2, $lon2) { 
    $x = deg2rad($lon1 - $lon2) * cos(deg2rad($lat1)); 
    $y = deg2rad($lat1 - $lat2); 
    $dist = 6371000.0 * sqrt($x*$x + $y*$y); 

    return $dist; 
} 
+0

LOL nvm、私はちょうどあなたの関数名を読んでいますdistanceMeters ...私を無視してください。 – Steven

+0

実際の距離(ソート)に関心がない場合は、最後のステップから 'R *'を削除することもできます。これは、すべてのエントリに対して定数を乗算することです – MatsLindh

関連する問題