Pastebin launched a little side project called VERYVIRAL.com, check it out ;-) Want more features on Pastebin? Sign Up, it's FREE!
Guest

Untitled

By: a guest on Mar 27th, 2012  |  syntax: PHP  |  size: 4.18 KB  |  views: 29  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. class Location
  2. {
  3.         protected $longitude;
  4.         protected $latitude;
  5.        
  6.         /**
  7.          * Constructs a new location.
  8.          *
  9.          * @param float $lat
  10.          * @param float $lon
  11.          * @throws InvalidArgumentException
  12.          */
  13.         public function __construct($lat, $lon)
  14.         {
  15.                 $this->setLatitude($lat);
  16.                 $this->setLongitude($lon);
  17.         }
  18.        
  19.         public function bearingTo(Location $location)
  20.         {
  21.                 $result = $this->distanceAndBearing($location);
  22.                 return $result['bearing'];
  23.         }
  24.        
  25.         /**
  26.          * Returns the approximate distance in meters between this location and the given location.
  27.          *
  28.          * @returns float
  29.          */
  30.         public function distanceTo(Location $location)
  31.         {
  32.                 $result = $this->distanceAndBearing($location);
  33.                 return $result['distance'];
  34.         }
  35.        
  36.         /**
  37.          * Returns the latitude for this location.
  38.          *
  39.          * @return float
  40.          */
  41.         public function getLatitude()
  42.         {
  43.                 return $this->latitude;
  44.         }
  45.  
  46.         /**
  47.          * Returns the longitude for this location.
  48.          *
  49.          * @return float
  50.          */    
  51.         public function getLongitude()
  52.         {
  53.                 return $this->longitude;
  54.         }
  55.        
  56.         /**
  57.          * Sets the latitude for this location.
  58.          *
  59.          * @param float $latitude
  60.          * @throws InvalidArgumentException
  61.          */
  62.         public function setLatitude($latitude)
  63.         {
  64.                 if (!is_numeric($latitude))
  65.                 {
  66.                         throw new InvalidArgumentException("Argument must be numeric.");
  67.                 }
  68.                 $this->latitude = (float) $latitude;
  69.         }
  70.        
  71.         /**
  72.          * Sets the longitude for this location.
  73.          *
  74.          * @param float $longitude
  75.          * @throws InvalidArgumentException
  76.          */
  77.         public function setLongitude($longitude)
  78.         {
  79.                 if (!is_numeric($longitude))
  80.                 {
  81.                         throw new InvalidArgumentException("Argument must be numeric.");
  82.                 }
  83.                 $this->longitude = (float) $longitude;
  84.         }
  85.        
  86.         private function distanceAndBearing(Location $location)
  87.         {
  88.         // Based on http://www.ngs.noaa.gov/PUBS_LIB/inverse.pdf
  89.         // using the "Inverse Formula" (section 4)
  90.                 $lat1 = deg2rad($this->getLatitude());
  91.                 $lat2 = deg2rad($location->getLatitude());
  92.                 $lon1 = deg2rad($this->getLongitude());
  93.                 $lon2 = deg2rad($location->getLongitude());
  94.                
  95.                 $major = 6378137.0;
  96.                 $minor = 6356752.3142;
  97.                 $f = ($major-$minor)/$major;
  98.                
  99.                 $aSqMinusBSqOverBSq = (pow($major, 2) - pow($minor, 2))/($minor*$minor);
  100.                 $L = $lon2 - $lon1;
  101.                 $U1 = atan((1.0 - $f) * tan($lat1));
  102.                 $U2 = atan((1.0 - $f) * tan($lat2));
  103.                
  104.                 $cosU1 = cos($U1);
  105.                 $cosU2 = cos($U2);
  106.                 $sinU1 = sin($U1);
  107.                 $sinU2 = sin($U2);
  108.                 $sinU1sinU2 = $sinU1 * $sinU2;
  109.                 $cosU1cosU2 = $cosU1 * $cosU2;
  110.                
  111.                 $A = 0.0;
  112.                 $cos2SM = 0.0;
  113.                 $sinSigma = 0.0;
  114.                 $cosSigma = 0.0;
  115.                 $deltaSigma = 0.0;
  116.                 $sinLambda = 0.0;
  117.                 $cosLambda = 0.0;
  118.                 $sigma = 0.0;
  119.                 $lambda = $L;
  120.                
  121.                 for ($i = 0; $i < 20; $i++)
  122.                 {
  123.                         $lambdaOrig = $lambda;
  124.                         $cosLambda = cos($lambda);
  125.                         $sinLambda = sin($lambda);
  126.                         $t1 = $cosU1 * $sinLambda;
  127.                         $t2 = $cosU1 * $sinU2 - $sinU1 * $cosU2 * $cosLambda;
  128.                         $sinSqSigma = pow($t1, 2) + pow($t2, 2);
  129.                         $sinSigma = sqrt($sinSqSigma);
  130.                         $sinAlpha = ($sinSigma == 0) ? 0.0 : $cosU1cosU2 * $sinLambda / $sinSigma;
  131.                         $cosSqAlpha = 1.0 - pow($sinAlpha, 2);
  132.                         $uSq = $cosSqAlpha * $aSqMinusBSqOverBSq;
  133.  
  134.                         $A = 1 + ($uSq / 16384.0) *     (4096.0 + $uSq * (-768 + $uSq * (320.0 - 175.0 * $uSq)));
  135.                         $B = ($uSq / 1024.0) * (256.0 + $uSq * (-128.0 + $uSq * (74.0 - 47.0 * $uSq)));
  136.                         $C = ($f / 16.0) * $cosSqAlpha * (4.0 + $f * (4.0 - 3.0 * $cosSqAlpha));
  137.  
  138.                         $cosSigma = $sinU1sinU2 + $cosU1cosU2 * $cosLambda;
  139.                         $cos2SM = ($cosSqAlpha == 0) ? 0.0 : $cosSigma - 2.0 * $sinU1sinU2 / $cosSqAlpha;
  140.                        
  141.                         $sigma = atan2($sinSigma, $cosSigma);
  142.                         $cos2SMSq = pow($cos2SM, 2);
  143.                         $deltaSigma = $B * $sinSigma * ($cos2SM + ($B / 4.0) * ($cosSigma * (-1.0 + 2.0 * $cos2SMSq) - ($B / 6.0) * $cos2SM * (-3.0 + 4.0 * pow($sinSigma, 2)) * (-3.0 + 4.0 * $cos2SMSq)));
  144.                        
  145.                         $lambda = $L + (1.0 - $C) * $f * $sinAlpha * ($sigma + $C * $sinSigma * ($cos2SM + $C * $cosSigma * (-1.0 + 2.0 * $cos2SM * $cos2SM)));
  146.                         $delta = ($lambda - $lambdaOrig) / $lambda;
  147.                         if (abs($delta) < 1.0e-12) break;
  148.                 }
  149.                 $distance = (float) ($minor * $A * ($sigma - $deltaSigma));
  150.                 $bearing = (float) rad2deg(atan2($cosU2 * $sinLambda, $cosU1 * $sinU2 - $sinU1 * $cosU2 * $cosLambda));
  151.                
  152.                 return array(
  153.                         'distance' => $distance,
  154.                         'bearing' => $bearing
  155.                 );
  156.         }
  157. }
clone this paste RAW Paste Data