Advertisement
Guest User

Untitled

a guest
Feb 20th, 2018
233
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 8.13 KB | None | 0 0
  1. <?php
  2. namespace App\Classes;
  3.  
  4. /**
  5.  * <p>Represents a point on the surface of a sphere. (The Earth is almost
  6.  * spherical.)</p>
  7.  *
  8.  * <p>To create an instance, call one of the static methods fromDegrees() or
  9.  * fromRadians().</p>
  10.  *
  11.  * <p>This is a PHP port of Java code that was originally published at
  12.  * <a href="http://JanMatuschek.de/LatitudeLongitudeBoundingCoordinates#Java">
  13.  * http://JanMatuschek.de/LatitudeLongitudeBoundingCoordinates#Java</a>.</p>
  14.  *
  15.  * Many thanks to the original author: Jan Philip Matuschek
  16.  *
  17.  * @author Anthony Martin
  18.  * @version November 21 2012
  19.  */
  20. class GeoLocation {
  21.  
  22.     private $radLat;  // latitude in radians
  23.     private $radLon;  // longitude in radians
  24.  
  25.     private $degLat;     // latitude in degrees
  26.     private $degLon;  // longitude in degrees
  27.  
  28.     private $angular; // angular radius
  29.  
  30.     const EARTHS_RADIUS_KM = 6371.01;
  31.     const EARTHS_RADIUS_MI = 3958.762079;
  32.  
  33.     protected static $MIN_LAT;  // -PI/2
  34.     protected static $MAX_LAT;  //  PI/2
  35.     protected static $MIN_LON;  // -PI
  36.     protected static $MAX_LON;  //  PI
  37.  
  38.     public function __construct() {
  39.         self::$MIN_LAT = deg2rad(-90);   // -PI/2
  40.         self::$MAX_LAT = deg2rad(90);    //  PI/2
  41.         self::$MIN_LON = deg2rad(-180);  // -PI
  42.         self::$MAX_LON = deg2rad(180);   //  PI
  43.     }
  44.  
  45.     /**
  46.      * @param double $latitude the latitude, in degrees.
  47.      * @param double $longitude the longitude, in degrees.
  48.      * @return GeoLocation
  49.      */
  50.     public static function fromDegrees($latitude, $longitude) {
  51.         $location = new GeoLocation();
  52.         $location->radLat = deg2rad($latitude);
  53.         $location->radLon = deg2rad($longitude);
  54.         $location->degLat = $latitude;
  55.         $location->degLon = $longitude;
  56.         $location->checkBounds();
  57.         return $location;
  58.     }
  59.  
  60.     /**
  61.      * @param double $latitude the latitude, in radians.
  62.      * @param double $longitude the longitude, in radians.
  63.      * @return GeoLocation
  64.      */
  65.     public static function fromRadians($latitude, $longitude) {
  66.         $location = new GeoLocation();
  67.         $location->radLat = $latitude;
  68.         $location->radLon = $longitude;
  69.         $location->degLat = rad2deg($latitude);
  70.         $location->degLon = rad2deg($longitude);
  71.         $location->checkBounds();
  72.         return $location;
  73.     }
  74.  
  75.     protected function checkBounds() {
  76.         if ($this->radLat < self::$MIN_LAT || $this->radLat > self::$MAX_LAT ||
  77.                 $this->radLon < self::$MIN_LON || $this->radLon > self::$MAX_LON)
  78.             throw new \Exception("Invalid Argument");
  79.     }
  80.  
  81.   /**
  82.    * Computes the great circle distance between this GeoLocation instance
  83.    * and the location argument.
  84.    * @param GeoLocation $location
  85.    * @param string $unit_of_measurement
  86.    * @internal param float $radius the radius of the sphere, e.g. the average radius for a
  87.    * spherical approximation of the figure of the Earth is approximately
  88.    * 6371.01 kilometers.
  89.    * @return double the distance, measured in the same unit as the radius
  90.    * argument.
  91.    */
  92.     public function distanceTo(GeoLocation $location, $unit_of_measurement) {
  93.         $radius = $this->getEarthsRadius($unit_of_measurement);
  94.  
  95.         return acos(sin($this->radLat) * sin($location->radLat) +
  96.                     cos($this->radLat) * cos($location->radLat) *
  97.                     cos($this->radLon - $location->radLon)) * $radius;
  98.     }
  99.  
  100.     /**
  101.      * @return double the latitude, in degrees.
  102.      */
  103.     public function getLatitudeInDegrees() {
  104.         return $this->degLat;
  105.     }
  106.  
  107.     /**
  108.      * @return double the longitude, in degrees.
  109.      */
  110.     public function getLongitudeInDegrees() {
  111.         return $this->degLon;
  112.     }
  113.  
  114.     /**
  115.      * @return double the latitude, in radians.
  116.      */
  117.     public function getLatitudeInRadians() {
  118.         return $this->radLat;
  119.     }
  120.  
  121.     /**
  122.      * @return double the longitude, in radians.
  123.      */
  124.     public function getLongitudeInRadians() {
  125.         return $this->radLon;
  126.     }
  127.  
  128.     /**
  129.      * @return double angular radius.
  130.      */
  131.     public function getAngular() {
  132.         return $this->angular;
  133.     }
  134.  
  135.     public function __toString() {
  136.         return "(" . $this->degLat . ", " . $this->degLon . ") = (" .
  137.                 $this->radLat . " rad, " . $this->radLon . " rad";
  138.     }
  139.  
  140.  
  141.   /**
  142.    * <p>Computes the bounding coordinates of all points on the surface
  143.    * of a sphere that have a great circle distance to the point represented
  144.    * by this GeoLocation instance that is less or equal to the distance
  145.    * argument.</p>
  146.    * <p>For more information about the formulae used in this method visit
  147.    * <a href="http://JanMatuschek.de/LatitudeLongitudeBoundingCoordinates">
  148.    * http://JanMatuschek.de/LatitudeLongitudeBoundingCoordinates</a>.</p>
  149.    *
  150.    * @param double $distance the distance from the point represented by this
  151.    * GeoLocation instance. Must me measured in the same unit as the radius
  152.    * argument.
  153.    * @param string $unit_of_measurement
  154.    * @throws \Exception
  155.    * @internal param radius the radius of the sphere, e.g. the average radius for a
  156.    * spherical approximation of the figure of the Earth is approximately
  157.    * 6371.01 kilometers.
  158.    * @return GeoLocation[] an array of two GeoLocation objects such that:<ul>
  159.    * <li>The latitude of any point within the specified distance is greater
  160.    * or equal to the latitude of the first array element and smaller or
  161.    * equal to the latitude of the second array element.</li>
  162.    * <li>If the longitude of the first array element is smaller or equal to
  163.    * the longitude of the second element, then
  164.    * the longitude of any point within the specified distance is greater
  165.    * or equal to the longitude of the first array element and smaller or
  166.    * equal to the longitude of the second array element.</li>
  167.    * <li>If the longitude of the first array element is greater than the
  168.    * longitude of the second element (this is the case if the 180th
  169.    * meridian is within the distance), then
  170.    * the longitude of any point within the specified distance is greater
  171.    * or equal to the longitude of the first array element
  172.    * <strong>or</strong> smaller or equal to the longitude of the second
  173.    * array element.</li>
  174.    * </ul>
  175.    */
  176.     public function boundingCoordinates($distance, $unit_of_measurement) {
  177.         $radius = $this->getEarthsRadius($unit_of_measurement);
  178.         if ($radius < 0 || $distance < 0) throw new \Exception('Arguments must be greater than 0.');
  179.  
  180.         // angular distance in radians on a great circle
  181.         $this->angular = $distance / $radius;
  182.  
  183.         $minLat = $this->radLat - $this->angular;
  184.         $maxLat = $this->radLat + $this->angular;
  185.  
  186.         $minLon = 0;
  187.         $maxLon = 0;
  188.         if ($minLat > self::$MIN_LAT && $maxLat < self::$MAX_LAT) {
  189.             $deltaLon = asin(sin($this->angular) /
  190.                 cos($this->radLat));
  191.             $minLon = $this->radLon - $deltaLon;
  192.             if ($minLon < self::$MIN_LON) $minLon += 2 * pi();
  193.             $maxLon = $this->radLon + $deltaLon;
  194.             if ($maxLon > self::$MAX_LON) $maxLon -= 2 * pi();
  195.         } else {
  196.             // a pole is within the distance
  197.             $minLat = max($minLat, self::$MIN_LAT);
  198.             $maxLat = min($maxLat, self::$MAX_LAT);
  199.             $minLon = self::$MIN_LON;
  200.             $maxLon = self::$MAX_LON;
  201.         }
  202.  
  203.         return array(
  204.             GeoLocation::fromRadians($minLat, $minLon),
  205.             GeoLocation::fromRadians($maxLat, $maxLon)
  206.         );
  207.     }
  208.  
  209.     protected function getEarthsRadius($unit_of_measurement) {
  210.         $u = $unit_of_measurement;
  211.         if($u == 'miles' || $u == 'mi')
  212.             return $radius = self::EARTHS_RADIUS_MI;
  213.         elseif($u == 'kilometers' || $u == 'km')
  214.             return $radius = self::EARTHS_RADIUS_KM;
  215.  
  216.         else throw new \Exception('You must supply a valid unit of measurement');
  217.     }
  218.    
  219.     /**
  220.      *  Retrieves Geocoding information from Google
  221.      *  eg. $response = GeoLocation::getGeocodeFromGoogle($location);
  222.      *      $latitude = $response->results[0]->geometry->location->lng;
  223.      *      $longitude = $response->results[0]->geometry->location->lng;
  224.      *  @param string $location address, city, state, etc.
  225.      *  @return \stdClass
  226.      */
  227.     public static function getGeocodeFromGoogle($location) {
  228.         $url = 'http://maps.googleapis.com/maps/api/geocode/json?address='.urlencode($location).'&sensor=false';
  229.         $ch = curl_init();
  230.         curl_setopt($ch, CURLOPT_URL,$url);
  231.         curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  232.         return json_decode(curl_exec($ch));
  233.     }
  234.     public static function MilesToKilometers($miles) {
  235.         return $miles * 1.6093439999999999;
  236.     }
  237.     public static function KilometersToMiles($km) {
  238.         return $km * 0.621371192237334;
  239.     }
  240. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement