/** * 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; } } } }
/** * 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; }