/**
  * Calculate the spherical distance from current coordinate to a other one.
  *
  * @param \Beluga\GIS\Coordinate $otherPoint
  * @return integer
  */
 public function calcSphericalDistanceTo(Coordinate $otherPoint)
 {
     if (!$this->isValid()) {
         return 0;
     }
     $b1 = $this->Latitude->getDecimalValue();
     $l1 = $this->Longitude->getDecimalValue();
     $b2 = $otherPoint->Latitude->getDecimalValue();
     $l2 = $otherPoint->Longitude->getDecimalValue();
     $rbreite1 = $b1 * self::DEG2RAD;
     $rlaenge1 = $l1 * self::DEG2RAD;
     $rbreite2 = $b2 * self::DEG2RAD;
     $rlaenge2 = $l2 * self::DEG2RAD;
     $rwinkel = \acos(\sin($rbreite1) * \sin($rbreite2) + \cos($rbreite1) * \cos($rbreite2) * \cos(\abs($rlaenge2 - $rlaenge1)));
     $entfernung = $rwinkel * 6370;
     return \round($entfernung, 3);
 }
 /**
  * Converts a UTM formatted GPS coordinate (e.g.: 10T E 549142 N 5280803) to a latitude and longitude and
  * returns as {@see \Beluga\GIS\Latitude} and {@see \Beluga\GIS\Longitude} instances inside a array with the keys
  * 'Longitude' and 'Latitude'.
  *
  * Attention! If you want to determine the parameters of this method not only manually from a string, so
  * you can also use the {@see \Beluga\GIS\Converter::ParseUtm2LL()} method.
  *
  * @param  string  $ellipsoid   See the \Beluga\GIS\Ext\Ellipsoid::TYPE_* constants.
  * @param  integer $UTMNorthing The northing UTM definition
  * @param  integer $UTMEasting  The easting UTM definition
  * @param  string  $UTMZone     The UTM zone. (e.g.: 10T)
  * @return array|FALSE
  */
 public static function Utm2LL(string $ellipsoid, int $UTMNorthing, int $UTMEasting, string $UTMZone)
 {
     $k0 = 0.9996;
     if (!isset(Ellipsoid::$Ellipsoid[$ellipsoid])) {
         return false;
     }
     $a = Ellipsoid::$Ellipsoid[$ellipsoid][0];
     $eccSquared = Ellipsoid::$Ellipsoid[$ellipsoid][1];
     $e1 = (1 - \sqrt(1 - $eccSquared)) / (1 + \sqrt(1 - $eccSquared));
     $x = $UTMEasting - 500000.0;
     $y = $UTMNorthing;
     #$NorthernHemisphere = 0;
     $zoneNumber = \intval(\substr($UTMZone, 0, -1));
     $ZoneLetter = \strtoupper($UTMZone[\strlen($UTMZone) - 1]);
     $NorthernHemisphere = $ZoneLetter == 'N';
     if ($NorthernHemisphere) {
         $y -= 10000000.0;
     }
     $longOrigin = ($zoneNumber - 1) * 6 - 180 + 3;
     $eccPrimeSquared = $eccSquared / (1 - $eccSquared);
     $M = $y / $k0;
     $mu = $M / ($a * (1 - $eccSquared / 4 - 3 * $eccSquared * $eccSquared / 64 - 5 * $eccSquared * $eccSquared * $eccSquared / 256));
     $phi1Rad = $mu + (3 * $e1 / 2 - 27 * $e1 * $e1 * $e1 / 32) * \sin(2 * $mu) + (21 * $e1 * $e1 / 16 - 55 * $e1 * $e1 * $e1 * $e1 / 32) * \sin(4 * $mu) + 151 * $e1 * $e1 * $e1 / 96 * \sin(6 * $mu);
     #$phi1 = $phi1Rad * self::RAD2DEG;
     $N1 = $a / \sqrt(1 - $eccSquared * \sin($phi1Rad) * \sin($phi1Rad));
     $T1 = \tan($phi1Rad) * \tan($phi1Rad);
     $C1 = $eccPrimeSquared * \cos($phi1Rad) * \cos($phi1Rad);
     $R1 = $a * (1 - $eccSquared) / \pow(1 - $eccSquared * \sin($phi1Rad) * \sin($phi1Rad), 1.5);
     $D = $x / ($N1 * $k0);
     $Lat = $phi1Rad - $N1 * \tan($phi1Rad) / $R1 * ($D * $D / 2 - (5 + 3 * $T1 + 10 * $C1 - 4 * $C1 * $C1 - 9 * $eccPrimeSquared) * $D * $D * $D * $D / 24 + (61 + 90 * $T1 + 298 * $C1 + 45 * $T1 * $T1 - 252 * $eccPrimeSquared - 3 * $C1 * $C1) * $D * $D * $D * $D * $D * $D / 720);
     $Lat = $Lat * static::RAD2DEG;
     $Long = ($D - (1 + 2 * $T1 + $C1) * $D * $D * $D / 6 + (5 - 2 * $C1 + 28 * $T1 - 3 * $C1 * $C1 + 8 * $eccPrimeSquared + 24 * $T1 * $T1) * $D * $D * $D * $D * $D / 120) / \cos($phi1Rad);
     $Long = $longOrigin + $Long * static::RAD2DEG;
     if (!Longitude::TryParse($Long, $_lo) || !Latitude::TryParse($Lat, $_la)) {
         return false;
     }
     $res = ['Longitude' => $_lo, 'Latitude' => $_la];
     return $res;
 }
 /**
  * Init a new instance.
  *
  * @param  \Beluga\GIS\Latitude|string|double $latitude
  * @param  \Beluga\GIS\Longitude|string|double $longitude
  * @throws \Beluga\ArgumentError
  */
 public function __construct($latitude, $longitude)
 {
     if (!\is_null($latitude) && $latitude instanceof Longitude) {
         throw new ArgumentError('latitude', $latitude, 'GIS', 'Can not use a longitude as latitude!');
     }
     if (!\is_null($longitude) && $longitude instanceof Latitude) {
         throw new ArgumentError('longitude', $longitude, 'GIS', 'Can not use a latitude as longitude!');
     }
     $lat = null;
     if (\is_null($latitude)) {
         $this->Latitude = $latitude;
     } else {
         if ($latitude instanceof Latitude) {
             $this->Latitude = $latitude;
         } else {
             if (Latitude::TryParse($latitude, $lat)) {
                 $this->Latitude = $lat;
             } else {
                 $this->Latitude = null;
             }
         }
     }
     $lon = null;
     if (\is_null($longitude)) {
         $this->Longitude = $longitude;
     } else {
         if ($longitude instanceof Longitude) {
             $this->Longitude = $longitude;
         } else {
             if (Longitude::TryParse($longitude, $lon)) {
                 $this->Longitude = $lon;
             } else {
                 $this->Longitude = null;
             }
         }
     }
 }