/* * UTMXYToLatLon * * Converts x and y coordinates in the Universal Transverse Mercator * projection to a latitude/longitude pair. * * Inputs: * x - The easting of the point, in meters. * y - The northing of the point, in meters. * zone - The UTM zone in which the point lies. * southhemi - True if the point is in the southern hemisphere; * false otherwise. * * Outputs: * latlon - A 2-element array containing the latitude and * longitude of the point, in radians. * * Returns: * The public double does not return a value. * */ public GeographicCoordinate UtmXyToLatLon(CartecianCoordinate utm, int zone, bool southhemi) { var x = utm.X - 500000.0; x = x / UTMScaleFactor; /* If in southern hemisphere, adjust y accordingly. */ var y = utm.Y; if (southhemi) { y -= 10000000.0; } y = y/ UTMScaleFactor; var cmeridian = UtmCentralMeridian(zone); return MapXyToLatLon(new CartecianCoordinate(x,y), cmeridian); }
/* * MapXYToLatLon * * Converts x and y coordinates in the Transverse Mercator projection to * a latitude/longitude pair. Note that Transverse Mercator is not * the same as UTM; a scale factor is required to convert between them. * * Reference: Hoffmann-Wellenhof, B., Lichtenegger, H., and Collins, J., * GPS: Theory and Practice, 3rd ed. New York: Springer-Verlag Wien, 1994. * * Inputs: * x - The easting of the point, in meters. * y - The northing of the point, in meters. * lambda0 - Longitude of the central meridian to be used, in radians. * * Outputs: * philambda - A 2-element containing the latitude and longitude * in radians. * * Returns: * The public double does not return a value. * * Remarks: * The local variables Nf, nuf2, tf, and tf2 serve the same purpose as * N, nu2, t, and t2 in MapLatLonToXY, but they are computed with respect * to the footpoint latitude phif. * * x1frac, x2frac, x2poly, x3poly, etc. are to enhance readability and * to optimize computations. * */ public GeographicCoordinate MapXyToLatLon(CartecianCoordinate xy, double lambda0) { /* Get the value of phif, the footpoint latitude. */ var phif = FootpointLatitude(xy.Y); /* Precalculate ep2 */ var ep2 = (Math.Pow(sm_a, 2.0) - Math.Pow(sm_b, 2.0)) / Math.Pow(sm_b, 2.0); /* Precalculate cos (phif) */ var cf = Math.Cos(phif); /* Precalculate nuf2 */ var nuf2 = ep2 * Math.Pow(cf, 2.0); /* Precalculate Nf and initialize Nfpow */ var Nf = Math.Pow(sm_a, 2.0) / (sm_b * Math.Sqrt(1 + nuf2)); var Nfpow = Nf; /* Precalculate tf */ var tf = Math.Tan(phif); var tf2 = tf * tf; var tf4 = tf2 * tf2; /* Precalculate fractional coefficients for x**n in the equations below to simplify the expressions for latitude and longitude. */ var x1frac = 1.0 / (Nfpow * cf); Nfpow *= Nf; /* now equals Nf**2) */ var x2frac = tf / (2.0 * Nfpow); Nfpow *= Nf; /* now equals Nf**3) */ var x3frac = 1.0 / (6.0 * Nfpow * cf); Nfpow *= Nf; /* now equals Nf**4) */ var x4frac = tf / (24.0 * Nfpow); Nfpow *= Nf; /* now equals Nf**5) */ var x5frac = 1.0 / (120.0 * Nfpow * cf); Nfpow *= Nf; /* now equals Nf**6) */ var x6frac = tf / (720.0 * Nfpow); Nfpow *= Nf; /* now equals Nf**7) */ var x7frac = 1.0 / (5040.0 * Nfpow * cf); Nfpow *= Nf; /* now equals Nf**8) */ var x8frac = tf / (40320.0 * Nfpow); /* Precalculate polynomial coefficients for x**n. -- x**1 does not have a polynomial coefficient. */ var x2poly = -1.0 - nuf2; var x3poly = -1.0 - 2 * tf2 - nuf2; var x4poly = 5.0 + 3.0 * tf2 + 6.0 * nuf2 - 6.0 * tf2 * nuf2 - 3.0 * (nuf2 * nuf2) - 9.0 * tf2 * (nuf2 * nuf2); var x5poly = 5.0 + 28.0 * tf2 + 24.0 * tf4 + 6.0 * nuf2 + 8.0 * tf2 * nuf2; var x6poly = -61.0 - 90.0 * tf2 - 45.0 * tf4 - 107.0 * nuf2 + 162.0 * tf2 * nuf2; var x7poly = -61.0 - 662.0 * tf2 - 1320.0 * tf4 - 720.0 * (tf4 * tf2); var x8poly = 1385.0 + 3633.0 * tf2 + 4095.0 * tf4 + 1575 * (tf4 * tf2); /* Calculate latitude */ var lat = phif + x2frac * x2poly * (xy.X * xy.X) + x4frac * x4poly * Math.Pow(xy.X, 4.0) + x6frac * x6poly * Math.Pow(xy.X, 6.0) + x8frac * x8poly * Math.Pow(xy.X, 8.0); /* Calculate longitude */ var lon = lambda0 + x1frac * xy.X + x3frac * x3poly * Math.Pow(xy.X, 3.0) + x5frac * x5poly * Math.Pow(xy.X, 5.0) + x7frac * x7poly * Math.Pow(xy.X, 7.0); return new GeographicCoordinate(RadToDeg(lon), RadToDeg(lat)); }