/***************************************************************************/ /* */ /* geodtm */ /* */ /* Routine to convert from latitude and longitude to Transverse Mercator.*/ /* Method based on Redfearn's formulation as expressed in GDA technical */ /* manual at http://www.anzlic.org.au/icsm/gdatm/index.html */ /* Loosely based on FORTRAN source code by J.Hannah and A.Broadhurst. */ /* */ /* Takes parameters */ /* input latitude (radians) */ /* input longitude (radians) */ /* output easting (metres) */ /* output northing (metres) */ /* */ /***************************************************************************/ private static void geod_tm(tmprojection *tm, double ln, double lt, double *ce, double *cn) { double fn = tm->falsen; double fe = tm->falsee; double sf = tm->scalef; double e2 = tm->e2; double a = tm->a; double cm = tm->meridian; double om = tm->om; double utom = tm->utom; double dlon; double m; double slt; double eslt; double eta; double rho; double psi; double clt; double w; double wc; double wc2; double t; double t2; double t4; double t6; double trm1; double trm2; double trm3; double gce; double trm4; double gcn; dlon = ln - cm; while (dlon > PI) { dlon -= TWOPI; } while (dlon < -PI) { dlon += TWOPI; } m = meridian_arc(tm, lt); slt = Math.Sin(lt); eslt = (1.0 - e2 * slt * slt); eta = a / Math.Sqrt(eslt); rho = eta * (1.0 - e2) / eslt; psi = eta / rho; clt = Math.Cos(lt); w = dlon; wc = clt * w; wc2 = wc * wc; t = slt / clt; t2 = t * t; t4 = t2 * t2; t6 = t2 * t4; trm1 = (psi - t2) / 6.0; trm2 = (((4.0 * (1.0 - 6.0 * t2) * psi + (1.0 + 8.0 * t2)) * psi - 2.0 * t2) * psi + t4) / 120.0; trm3 = (61 - 479.0 * t2 + 179.0 * t4 - t6) / 5040.0; gce = (sf * eta * dlon * clt) * (((trm3 * wc2 + trm2) * wc2 + trm1) * wc2 + 1.0); *ce = gce / utom + fe; trm1 = 1.0 / 2.0; trm2 = ((4.0 * psi + 1) * psi - t2) / 24.0; trm3 = ((((8.0 * (11.0 - 24.0 * t2) * psi - 28.0 * (1.0 - 6.0 * t2)) * psi + (1.0 - 32.0 * t2)) * psi - 2.0 * t2) * psi + t4) / 720.0; trm4 = (1385.0 - 3111.0 * t2 + 543.0 * t4 - t6) / 40320.0; gcn = (eta * t) * ((((trm4 * wc2 + trm3) * wc2 + trm2) * wc2 + trm1) * wc2); *cn = (gcn + m - om) * sf / utom + fn; return; }
/* Functions implementation the TM projection specifically for the * NZTM coordinate system */ public static void nztm_geod(double n, double e, double *lt, double *ln) { tmprojection *nztm = get_nztm_projection(); tm_geod(nztm, e, n, ln, lt); }
/***************************************************************************/ /* */ /* tmgeod */ /* */ /* Routine to convert from Tranverse Mercator to latitude and longitude. */ /* Method based on Redfearn's formulation as expressed in GDA technical */ /* manual at http://www.anzlic.org.au/icsm/gdatm/index.html */ /* */ /* Takes parameters */ /* input easting (metres) */ /* input northing (metres) */ /* output latitude (radians) */ /* output longitude (radians) */ /* */ /***************************************************************************/ private static void tm_geod(tmprojection *tm, double ce, double cn, double *ln, double *lt) { double fn = tm->falsen; double fe = tm->falsee; double sf = tm->scalef; double e2 = tm->e2; double a = tm->a; double cm = tm->meridian; double om = tm->om; double utom = tm->utom; double cn1; double fphi; double slt; double clt; double eslt; double eta; double rho; double psi; double E; double x; double x2; double t; double t2; double t4; double trm1; double trm2; double trm3; double trm4; cn1 = (cn - fn) * utom / sf + om; fphi = foot_point_lat(tm, cn1); slt = Math.Sin(fphi); clt = Math.Cos(fphi); eslt = (1.0 - e2 * slt * slt); eta = a / Math.Sqrt(eslt); rho = eta * (1.0 - e2) / eslt; psi = eta / rho; E = (ce - fe) * utom; x = E / (eta * sf); x2 = x * x; t = slt / clt; t2 = t * t; t4 = t2 * t2; trm1 = 1.0 / 2.0; trm2 = ((-4.0 * psi + 9.0 * (1 - t2)) * psi + 12.0 * t2) / 24.0; trm3 = ((((8.0 * (11.0 - 24.0 * t2) * psi - 12.0 * (21.0 - 71.0 * t2)) * psi + 15.0 * ((15.0 * t2 - 98.0) * t2 + 15)) * psi + 180.0 * ((-3.0 * t2 + 5.0) * t2)) * psi + 360.0 * t4) / 720.0; trm4 = (((1575.0 * t2 + 4095.0) * t2 + 3633.0) * t2 + 1385.0) / 40320.0; *lt = fphi + (t * x * E / (sf * rho)) * (((trm4 * x2 - trm3) * x2 + trm2) * x2 - trm1); trm1 = 1.0; trm2 = (psi + 2.0 * t2) / 6.0; trm3 = (((-4.0 * (1.0 - 6.0 * t2) * psi + (9.0 - 68.0 * t2)) * psi + 72.0 * t2) * psi + 24.0 * t4) / 120.0; trm4 = (((720.0 * t2 + 1320.0) * t2 + 662.0) * t2 + 61.0) / 5040.0; *ln = cm - (x / clt) * (((trm4 * x2 - trm3) * x2 + trm2) * x2 - trm1); }