2012-03-06 43 views
8

Tôi có một kinh độ và vĩ độ như là một chuỗi trong PHP như dưới đâyTìm kinh độ và vĩ độ gần nhất trong mảng?

49.648881 
-103.575312 

Và tôi muốn đi đó và nhìn vào một mảng các giá trị để tìm ra gần nhất. Mảng trông giống như

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

Tôi muốn trả về mảng có thân dài và chàng trai gần nhất. Trong trường hợp này, nó sẽ là cái đầu tiên (và có tôi biết -400 không phải là một giá trị có thể).

Có cách nào nhanh chóng và dễ dàng để thực hiện việc này không? Tôi đã thử tìm kiếm mảng nhưng điều đó không hiệu quả.

đang Difference

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

bạn có thể vui lòng cung cấp mã của bạn, nơi bạn sẽ có được khoảng cách giữa hai cặp lat/dài như 'chức năng khoảng cách ($ lat1, $ long1, $ lat2, $ long2) {... '? – hakre

+0

Điều đó không có ý nghĩa, đó là toán học đơn giản? 55 - 49 = 6, 55-100 = 45 6 nhỏ hơn 45. – Steven

+0

Bạn có thực sự biết cách tính khoảng cách giữa hai điểm trên quả địa cầu? – hakre

Trả lời

20

Bạn cần để lập bản đồ khoảng cách của mỗi mục đến điểm tham chiếu đầu tiên.

Sau đó, bạn sắp xếp bản đồ và sau đó bạn có thể biết được có mức thấp nhất (hoặc cao nhất nếu bạn đảo ngược tìm kiếm) khoảng cách:

$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)]); 

Output:

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

Chăm sóc bạn có đúng thứ tự của lat và dài.

Chức năng khoảng cách (chỉ tiêu đề hơi thay đổi và các đơn vị đã được giảm):

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

Rực rỡ! Câu trả lời chính xác! – nickspiel

1

Không có cách nào nhanh chóng và dễ dàng để làm điều đó. Bạn phải lặp qua tất cả các phần tử và tính toán khoảng cách giữa chúng và điểm bắt đầu, lưu kết quả và lặp lại, chỉ lưu kết quả nếu nó thấp hơn trước đó.

0

Lặp lại qua mảng, so sánh các giá trị với những gì bạn có. Nếu giá trị nhỏ hơn giá trị hiện đang được lưu trữ của bạn (hoặc nếu bạn không có giá trị hiện đang được lưu trữ), hãy lưu trữ giá trị đó thay vào đó, nếu không thì hãy bỏ đi.

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

Tất nhiên, điều này sẽ được thực hiện khó khăn hơn bởi thực tế là vĩ độ và kinh độ đang ở trên một hình cầu, và kinh độ 179 và -179 là gần hơn 90 và 179.

+0

Tôi đã cập nhật câu trả lời của bạn một cách đáng kể, thêm 'null' làm giá trị mặc định thay vì chuỗi trống, kiểm tra nghiêm ngặt là' null', đã nêu rõ rằng '179' và' -179' là về kinh độ. – Tadeck

+0

Và đó là lý do tại sao tôi là nhà phát triển giao diện người dùng chứ không phải là một chuyên gia về PHP. Cảm ơn bạn. :) –

4

Thay bằng cách sử dụng định lý cos cho khoảng cách, bạn có thể sử dụng xấp xỉ trái đất phẳng. Phương trình trái đất bằng phẳng làm giảm số lượng các hàm trig trong phép tính. Δlat, Δlon là sự khác biệt giữa điểm tham chiếu và điểm kiểm tra.

công thức này sẽ không được chính xác để điều hướng đường dài (hàng ngàn dặm) nhưng đối với vấn đề cụ thể này, bạn không phải thực sự quan tâm đến khoảng cách chính xác, nhưng ai là điểm gần nhất với tôi. Đây là một công thức đơn giản mà sẽ cung cấp cho bạn điều đó.

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 

tham khảo:http://www.movable-type.co.uk/scripts/latlong.html

đang Khỏang cách

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, tôi chỉ cần đọc tên hàm của bạn là distanceMeters ... Bỏ qua tôi. – Steven

+0

Nếu bạn không quan tâm đến khoảng cách thực tế (tức là chỉ phân loại), bạn cũng có thể thả 'R *' từ bước cuối cùng vì nó là phép nhân liên tục cho tất cả các mục nhập – MatsLindh

Các vấn đề liên quan