Soru Belirli bir koordinatın yalnızca PHP kullanılarak başka bir koordinat yarıçapına düşüp düşmediğini kontrol etme


Çok fazla fonksiyon gördüm ama sadece MySQL veya Postgresql için çalışıyor. PHP için eşdeğer mantığı istiyorum. Bazı karşılaştırmalar yapıyorum oluşturulduğunda üretilen bu verilere sahip olduğum gibi.

Lat: 56.130366
Long: -106.34677099999

Daha sonra, bu koordinatların başka bir koordinatın yarıçapı içinde olup olmayacağını kontrol etmek istiyorum.

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

Şimdiden teşekkürler!


16
2017-09-15 18:03


Menşei


Google "Haversine formülü" veya "Vincenty formülü" iki lat / long pozisyonu arasındaki mesafeyi hesaplamak için - Mark Baker


Cevaplar:


Yardım için teşekkürler. Aşağıda, iki boylam ve enlem koordinatlarını koordine eden ve ikisi arasındaki mesafeyi veren bir örnek fonksiyon bulunmaktadır.

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";
}

35
2017-09-15 18:35



Eşdeğer, ama Javascript çünkü bunu aramak için çok uzun zaman harcadım. - MoshMage
@AamirR bu doğru ama tamamen farklıydı. Onu değiştirdim ve bir cevap olarak yayınladım. Neden şimdi? Zaten 5 yıl geçti dostum lol - Kenneth Palaganas


Kullanmalısın Haversine formülü İki nokta arasındaki mesafeyi hesaplamak için. Senin bir Burada PHP versiyonu.

O zaman sadece kontrol edin distance < 100000.


7
2017-09-15 18:10



İyi kodlar var. Ama mesafe gerçekten mi, yoksa metre mi? - Kenneth Palaganas
Toprak yarıçapına bağlıdır. Eğer bağlandığım kodda 6371 kullanırsanız, bu kilometredir :) - Guillaume Poussel
6367'yi toprak yarıçapı olarak kullanan bazı algoritmalar gördüm, ancak bunların çoğu 6371 mi gerçekten önemli değil mi? neyse teşekkürler :) - Kenneth Palaganas


Bu yardımcı olmalı

$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
2017-09-15 18:11





//  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); 

1
2017-09-15 18:11