Created
July 18, 2013 20:12
-
-
Save thomasorten/6032641 to your computer and use it in GitHub Desktop.
Convert UTM northing/easting to latitude and longitude.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// Original source from Steven Dutch, https://www.uwgb.edu/dutchs/UsefulData/ConvertUTMNoOZ.HTM | |
// Rewritten by Thomas Orten | |
function UTMtoLatLon ($input_lat, $input_long, $utm_zone, $south_of_equator = false) { | |
$DatumEqRad = array(6378137.0, 6378137.0, 6378137.0, 6378135.0, 6378160.0, 6378245.0, 6378206.4, 6378388.0, 6378388.0, 6378249.1, 6378206.4, 6377563.4, 6377397.2, 6377276.3); | |
$DatumFlat = array(298.2572236, 298.2572236, 298.2572215, 298.2597208, 298.2497323, 298.2997381, 294.9786982, 296.9993621, 296.9993621, 293.4660167, 294.9786982, 299.3247788, 299.1527052, 300.8021499); | |
$Item = 0; // Default | |
$k0 = 0.9996; // scale on central meridian | |
$a = $DatumEqRad[$Item]; // equatorial radius, meters. | |
$f = 1/$DatumFlat[$Item]; // polar flattening. | |
$b = $a*(1-$f); // polar axis. | |
$e = sqrt(1 - $b*$b/$a*$a); // eccentricity | |
$drad = pi()/180; // Convert degrees to radians) | |
$phi = 0; // latitude (north +, south -), but uses phi in reference | |
$lng = 0; // Longitude (e = +, w = -) - can't use long - reserved word | |
$lng0 = 0; // longitude of central meridian | |
$lngd = 0; // longitude in degrees | |
$M = 0; // M requires calculation | |
$x = 0; // x coordinate | |
$y = 0; // y coordinate | |
$k = 1; // local scale | |
// Convert UTM Coordinates to Geographic | |
$k0 = 0.9996; // scale on central meridian | |
$b = $a*(1-$f); // polar axis. | |
$e = sqrt(1 - ($b/$a)*($b/$a)); // eccentricity | |
$e0 = $e/sqrt(1 - $e*$e); // Called e prime in reference | |
$esq = (1 - ($b/$a)*($b/$a)); // e squared for use in expansions | |
$e0sq = $e*$e/(1-$e*$e); // e0 squared - always even powers | |
// Easting | |
$x = floatval($input_long); | |
if ($x<160000 || $x>840000){ echo("Outside permissible range of easting values. Results may be unreliable. Use with caution \n"); } | |
// Northing | |
$y = floatval($input_lat); | |
if ($y<0){ echo("Negative values not allowed. Results may be unreliable. Use with caution \n"); } | |
if ($y>10000000){ echo("Northing may not exceed 10,000,000. Results may be unreliable. Use with caution \n"); } | |
// Zone. Just number! | |
$utmz = floatval($utm_zone); | |
$zcm = 3 + 6*($utmz-1) - 180; // Central meridian of zone | |
$e1 = (1 - sqrt(1 - $e*$e))/(1 + sqrt(1 - $e*$e)); // Called e1 in USGS PP 1395 also | |
$M0 = 0; // In case origin other than zero lat - not needed for standard UTM | |
$M = $M0 + $y/$k0; // Arc length along standard meridian. | |
// IF not south of qeuator, set to true | |
if ($south_of_equator){ | |
$M=$M0+($y-10000000)/$k; | |
} | |
$mu = $M/($a*(1 - $esq*(1/4 + $esq*(3/64 + 5*$esq/256)))); | |
$phi1 = $mu + $e1*(3/2 - 27*$e1*1/32)*sin(2*$mu) + $e1*$e1*(21/16 -55*$e1*$e1/32)*sin(4*$mu); //Footprint Latitude | |
$phi1 = $phi1 + $e1*$e1*$e1*(sin(6*$mu)*151/96 + $e1*sin(8*$mu)*1097/512); | |
$C1 = $e0sq*pow(cos($phi1),2); | |
$T1 = pow(tan($phi1),2); | |
$N1 = $a/sqrt(1-pow($e*sin($phi1),2)); | |
$R1 = $N1*(1-$e*$e)/(1-pow($e*sin($phi1),2)); | |
$D = ($x-500000)/($N1*$k0); | |
$phi = ($D*$D)*(1/2 - $D*$D*(5 + 3*$T1 + 10*$C1 - 4*$C1*$C1 - 9*$e0sq)/24); | |
$phi = $phi + pow($D,6)*(61 + 90*$T1 + 298*$C1 + 45*$T1*$T1 -252*$e0sq - 3*$C1*$C1)/720; | |
$phi = $phi1 - ($N1*tan($phi1)/$R1)*$phi; | |
//Output Latitude | |
$lat = floor(1000000*$phi/$drad)/1000000; | |
//Longitude | |
$lng = $D*(1 + $D*$D*((-1 -2*$T1 -$C1)/6 + $D*$D*(5 - 2*$C1 + 28*$T1 - 3*$C1*$C1 +8*$e0sq + 24*$T1*$T1)/120))/cos($phi1); | |
$lngd = $zcm+$lng/$drad; | |
//Output Longitude | |
$long = floor(1000000*$lngd)/1000000; | |
if ($lat == 0 || $lat == 0) { | |
echo "Could not convert $input_lat, $input_long. \n"; | |
} else { | |
echo "Latitude: $lat , Longitude: $long \n"; | |
return array ( | |
'lat' => $lat, | |
'lng' => $long | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment