2012-09-15 27 views
12

Tôi đã thấy rất nhiều chức năng nhưng nó chỉ hoạt động đối với MySQL hoặc Postgresql. Tôi muốn có logic tương đương cho PHP. Tôi đang thực hiện một số so sánh, như tôi có dữ liệu này đã được tạo khi tạo.Cách kiểm tra xem một tọa độ nhất định có nằm trong bán kính tọa độ khác bằng cách sử dụng PHP chỉ

Lat: 56.130366 
Long: -106.34677099999 

Sau đó, tôi muốn kiểm tra xem tọa độ này có nằm trong bán kính của tọa độ khác sau đó trả về true hay không.

Lat: 57.223366 
Long: -106.34675644699 
radius: 100000 (meters) 

Cảm ơn bạn trước!

+1

Google "Haversine formula" hoặc "Vincenty formula" để tính khoảng cách giữa hai vị trí vĩ độ/dài –

Trả lời

28

Thanks for the help. Dưới đây là một ví dụ chức năng mà có hai bộ kinh độ và vĩ độ phối hợp và trả về khoảng cách giữa hai.

function getDistance($latitude1, $longitude1, $latitude2, $longitude2) { 
    $earth_radius = 6371; 

    $dLat = deg2rad($latitude2 - $latitude1); 
    $dLon = deg2rad($longitude2 - $longitude1); 

    $a = sin($dLat/2) * sin($dLat/2) + cos(deg2rad($latitude1)) * cos(deg2rad($latitude2)) * sin($dLon/2) * sin($dLon/2); 
    $c = 2 * asin(sqrt($a)); 
    $d = $earth_radius * $c; 

    return $d; 
} 

$distance = getDistance(56.130366, -106.34677099999, 57.223366, -106.34675644699); 
if($distance < 100) { 
    echo "Within 100 kilometer radius"; 
} else { 
    echo "Outside 100 kilometer radius"; 
} 
+2

[Tương đương, nhưng trong Javascript] (https://gist.github.com/moshmage/2ae02baa14d10bd6092424dcef5a1186) vì tôi đã dành quá nhiều thời gian để tìm kiếm điều này. – MoshMage

6

Bạn nên sử dụng Haversine formula để tính khoảng cách giữa hai điểm. Bạn có một số PHP version here.

Sau đó, chỉ cần kiểm tra xem distance < 100000.

+0

Các mã tốt bạn có. Nhưng khoảng cách thực sự bằng mét hay ki lô mét? –

+0

Nó phụ thuộc vào bán kính trái đất. Nếu bạn sử dụng 6371 như trong mã tôi đã liên kết, nó là kilômét :) –

+0

Tôi thấy một số thuật toán sử dụng 6367 như bán kính trái đất nhưng hầu hết trong số chúng là 6371 nó có thực sự quan trọng hay không? anyway thanks :) –

1

Điều này sẽ giúp,

$lat_origin = 56.130366; 
$long_origin = -106.34677099999; 

$lat_dest = 57.223366; 
$long_dest = -106.34675644699; 

$radius  = 3958;  # Earth's radius (miles, convert to meters) 
$deg_per_rad = 57.29578; # Number of degrees/radian (for conversion) 

$distance = ($radius * pi() * sqrt(
      ($lat_origin - $lat_dest) 
      * ($lat_origin - $lat_dest) 
      + cos($lat_origin/$deg_per_rad) # Convert these to 
      * cos($lat_dest/$deg_per_rad) # radians for cos() 
      * ($long_origin - $long_dest) 
      * ($long_origin - $long_dest) 
    )/180); 
1
// Vincenty formula to calculate great circle distance between 2 locations 
//  expressed as Lat/Long in KM 

function VincentyDistance($lat1,$lat2,$lon1,$lon2){ 
    $a = 6378137 - 21 * sin(lat); 
    $b = 6356752.3142; 
    $f = 1/298.257223563; 

    $p1_lat = $lat1/57.29577951; 
    $p2_lat = $lat2/57.29577951; 
    $p1_lon = $lon1/57.29577951; 
    $p2_lon = $lon2/57.29577951; 

    $L = $p2_lon - $p1_lon; 

    $U1 = atan((1-$f) * tan($p1_lat)); 
    $U2 = atan((1-$f) * tan($p2_lat)); 

    $sinU1 = sin($U1); 
    $cosU1 = cos($U1); 
    $sinU2 = sin($U2); 
    $cosU2 = cos($U2); 

    $lambda = $L; 
    $lambdaP = 2*PI; 
    $iterLimit = 20; 

    while(abs($lambda-$lambdaP) > 1e-12 && $iterLimit>0) { 
     $sinLambda = sin($lambda); 
     $cosLambda = cos($lambda); 
     $sinSigma = sqrt(($cosU2*$sinLambda) * ($cosU2*$sinLambda) + ($cosU1*$sinU2-$sinU1*$cosU2*$cosLambda) * ($cosU1*$sinU2-$sinU1*$cosU2*$cosLambda)); 

     //if ($sinSigma==0){return 0;} // co-incident points 
     $cosSigma = $sinU1*$sinU2 + $cosU1*$cosU2*$cosLambda; 
     $sigma = atan2($sinSigma, $cosSigma); 
     $alpha = asin($cosU1 * $cosU2 * $sinLambda/$sinSigma); 
     $cosSqAlpha = cos($alpha) * cos($alpha); 
     $cos2SigmaM = $cosSigma - 2*$sinU1*$sinU2/$cosSqAlpha; 
     $C = $f/16*$cosSqAlpha*(4+$f*(4-3*$cosSqAlpha)); 
     $lambdaP = $lambda; 
     $lambda = $L + (1-$C) * $f * sin($alpha) * ($sigma + $C*$sinSigma*($cos2SigmaM+$C*$cosSigma*(-1+2*$cos2SigmaM*$cos2SigmaM))); 
    } 

    $uSq = $cosSqAlpha*($a*$a-$b*$b)/($b*$b); 
    $A = 1 + $uSq/16384*(4096+$uSq*(-768+$uSq*(320-175*$uSq))); 
    $B = $uSq/1024 * (256+$uSq*(-128+$uSq*(74-47*$uSq))); 

    $deltaSigma = $B*$sinSigma*($cos2SigmaM+$B/4*($cosSigma*(-1+2*$cos2SigmaM*$cos2SigmaM)- $B/6*$cos2SigmaM*(-3+4*$sinSigma*$sinSigma)*(-3+4*$cos2SigmaM*$cos2SigmaM))); 

    $s = $b*$A*($sigma-$deltaSigma); 
    return $s/1000; 
} 


echo VincentyDistance($lat1,$lat2,$lon1,$lon2); 
Các vấn đề liên quan