private static Coordinate MGRS_Polar_ToLatLong(MilitaryGridReferenceSystem mgrs, EagerLoad el) { //WORKING bool isNorth = true; if (mgrs.latZone.ToUpper() == "A" || mgrs.latZone.ToUpper() == "B") { isNorth = false; } string latz = mgrs.LatZone; string digraph = mgrs.Digraph; char eltr = digraph[0]; char nltr = digraph[1]; string digraphLettersE; if (!isNorth) { digraphLettersE = "KLPQRSTUXYZABCFGH"; } else { digraphLettersE = "RSTUXYZABCFGHJ"; } string digraphLettersN; if (!isNorth) { digraphLettersN = "VWXYBCDEFGHJKLMNPQRSTUVWXYZ"; } else { digraphLettersN = "ABCDEFGHJKLMNP"; } string digraphLettersAll = ""; for (int lt = 1; lt < 31; lt++) { digraphLettersAll += digraphLettersN; } var eidx = digraphLettersE.IndexOf(eltr); //Offsets are set due to less Easting Identifiers. //North has 4 less than S double offset = 9; if (isNorth) { offset = 13; } if (mgrs.latZone == "B" && eidx < offset && mgrs.easting != 0) { eidx += 18; } double subbase = eidx + offset; var ebase = 100000 * subbase; var latBand = digraphLettersE.IndexOf(latz); var latBandLow = 8 * latBand - 96; var latBandHigh = 8 * latBand - 88; if (!isNorth) { latBandLow = -90; latBandHigh = -80; } else { latBandLow = 84; latBandHigh = 90; } var lowLetter = Math.Floor(100 + 1.11 * latBandLow); var highLetter = Math.Round(100 + 1.11 * latBandHigh); string latBandLetters = null; int l = Convert.ToInt32(lowLetter); int h = Convert.ToInt32(highLetter + 7); if (mgrs.LongZone / 2.0 == Math.Floor(mgrs.LongZone / 2.0)) { latBandLetters = digraphLettersAll.Substring(l + 5, h + 5).ToString(); } else { latBandLetters = digraphLettersAll.Substring(l, h).ToString(); } //North offset + 4 due to lower band count. double nOffset = 13; if (!isNorth) { nOffset = 10; } else { latBandLetters = digraphLettersN; } int index = latBandLetters.IndexOf(nltr); if (index == -1 && nltr == 'A') { index -= 1; } //ALPHA PATCH //int subset = 0; //if ((latz == "Y" || latz == "Z") && (nOffset+index)>25 && (ebase> 2100000 || ebase<2000000) && ebase!= 2000000) { subset = -14; } var nbase = 100000 * (index + nOffset); var x = ebase + mgrs.Easting; var y = nbase + mgrs.Northing; if (mgrs.systemType != MGRS_Type.MGRS_Polar) { if (y > 10000000) { y = y - 10000000; } if (nbase >= 10000000) { y = nbase + mgrs.northing - 10000000; } } // Debug.WriteLine("MGRS {0} {1}", x, y); UniversalTransverseMercator utm = new UniversalTransverseMercator(mgrs.LatZone, mgrs.LongZone, x, y, true); utm.equatorial_radius = mgrs.equatorialRadius; utm.inverse_flattening = mgrs.inverseFlattening; Coordinate c = UniversalTransverseMercator.ConvertUTMtoLatLong(utm, el); c.Set_Datum(mgrs.equatorialRadius, mgrs.inverseFlattening); return(c); }
private static Coordinate UTMtoLatLong(double x, double y, double zone, double equatorialRadius, double flattening, EagerLoad el) { //x easting //y northing //http://home.hiwaay.net/~taylorc/toolbox/geography/geoutm.html double phif, Nf, Nfpow, nuf2, ep2, tf, tf2, tf4, cf; double x1frac, x2frac, x3frac, x4frac, x5frac, x6frac, x7frac, x8frac; double x2poly, x3poly, x4poly, x5poly, x6poly, x7poly, x8poly; double sm_a = equatorialRadius; double sm_b = equatorialRadius * (1 - (1.0 / flattening)); //Polar Radius /* Get the value of phif, the footpoint latitude. */ phif = FootpointLatitude(y, equatorialRadius, flattening); /* Precalculate ep2 */ ep2 = (Math.Pow(sm_a, 2.0) - Math.Pow(sm_b, 2.0)) / Math.Pow(sm_b, 2.0); /* Precalculate cos (phif) */ cf = Math.Cos(phif); /* Precalculate nuf2 */ nuf2 = ep2 * Math.Pow(cf, 2.0); /* Precalculate Nf and initialize Nfpow */ Nf = Math.Pow(sm_a, 2.0) / (sm_b * Math.Sqrt(1 + nuf2)); Nfpow = Nf; /* Precalculate tf */ tf = Math.Tan(phif); tf2 = tf * tf; tf4 = tf2 * tf2; /* Precalculate fractional coefficients for x**n in the equations * below to simplify the expressions for latitude and longitude. */ x1frac = 1.0 / (Nfpow * cf); Nfpow *= Nf; /* now equals Nf**2) */ x2frac = tf / (2.0 * Nfpow); Nfpow *= Nf; /* now equals Nf**3) */ x3frac = 1.0 / (6.0 * Nfpow * cf); Nfpow *= Nf; /* now equals Nf**4) */ x4frac = tf / (24.0 * Nfpow); Nfpow *= Nf; /* now equals Nf**5) */ x5frac = 1.0 / (120.0 * Nfpow * cf); Nfpow *= Nf; /* now equals Nf**6) */ x6frac = tf / (720.0 * Nfpow); Nfpow *= Nf; /* now equals Nf**7) */ x7frac = 1.0 / (5040.0 * Nfpow * cf); Nfpow *= Nf; /* now equals Nf**8) */ x8frac = tf / (40320.0 * Nfpow); /* Precalculate polynomial coefficients for x**n. * -- x**1 does not have a polynomial coefficient. */ x2poly = -1.0 - nuf2; x3poly = -1.0 - 2 * tf2 - nuf2; x4poly = 5.0 + 3.0 * tf2 + 6.0 * nuf2 - 6.0 * tf2 * nuf2 - 3.0 * (nuf2 * nuf2) - 9.0 * tf2 * (nuf2 * nuf2); x5poly = 5.0 + 28.0 * tf2 + 24.0 * tf4 + 6.0 * nuf2 + 8.0 * tf2 * nuf2; x6poly = -61.0 - 90.0 * tf2 - 45.0 * tf4 - 107.0 * nuf2 + 162.0 * tf2 * nuf2; x7poly = -61.0 - 662.0 * tf2 - 1320.0 * tf4 - 720.0 * (tf4 * tf2); x8poly = 1385.0 + 3633.0 * tf2 + 4095.0 * tf4 + 1575 * (tf4 * tf2); /* Calculate latitude */ double nLat = phif + x2frac * x2poly * (x * x) + x4frac * x4poly * Math.Pow(x, 4.0) + x6frac * x6poly * Math.Pow(x, 6.0) + x8frac * x8poly * Math.Pow(x, 8.0); /* Calculate longitude */ double nLong = zone + x1frac * x + x3frac * x3poly * Math.Pow(x, 3.0) + x5frac * x5poly * Math.Pow(x, 5.0) + x7frac * x7poly * Math.Pow(x, 7.0); double dLat = RadToDeg(nLat); double dLong = RadToDeg(nLong); if (dLat > 90) { dLat = 90; } if (dLat < -90) { dLat = -90; } if (dLong > 180) { dLong = 180; } if (dLong < -180) { dLong = -180; } Coordinate c = new Coordinate(dLat, dLong, el, equatorialRadius, flattening); c.Set_Datum(equatorialRadius, flattening); return(c); }
/// <summary> /// Creates a Coordinate object from an MGRS/NATO UTM Coordinate /// </summary> /// <param name="mgrs">MilitaryGridReferenceSystem</param> /// <param name="eagerLoad">EagerLoad</param> /// <returns>Coordinate object</returns> /// <example> /// The following example creates (converts to) a geodetic Coordinate object based on a MGRS object. /// <code> /// MilitaryGridReferenceSystem mgrs = new MilitaryGridReferenceSystem("N", 21, "SA", 66037, 61982); /// Coordinate c = MilitaryGridReferenceSystem.MGRStoLatLong(mgrs, new EagerLoad(false)); /// Console.WriteLine(c); //N 0º 33' 35.988" W 60º 0' 0.01" /// </code> /// </example> public static Coordinate MGRStoLatLong(MilitaryGridReferenceSystem mgrs, EagerLoad eagerLoad) { if (mgrs.systemType == MGRS_Type.MGRS_Polar) { return(MGRS_Polar_ToLatLong(mgrs, eagerLoad)); } string latz = mgrs.LatZone; string digraph = mgrs.Digraph; char eltr = digraph[0]; char nltr = digraph[1]; string digraphLettersE = "ABCDEFGHJKLMNPQRSTUVWXYZ"; string digraphLettersN = "ABCDEFGHJKLMNPQRSTUV"; string digraphLettersAll = ""; for (int lt = 1; lt < 25; lt++) { digraphLettersAll += digraphLettersN; } var eidx = digraphLettersE.IndexOf(eltr); var pbase = 100000; double fl = Math.Floor(Convert.ToDouble(eidx) / 8); double subbase = 1 + eidx - 8 * fl; var ebase = pbase * subbase; var latBand = digraphLettersE.IndexOf(latz); var latBandLow = 8 * latBand - 96; var latBandHigh = 8 * latBand - 88; if (latBand < 2) { latBandLow = -90; latBandHigh = -80; } else if (latBand == 21) { latBandLow = 72; latBandHigh = 84; } else if (latBand > 21) { latBandLow = 84; latBandHigh = 90; } var lowLetter = Math.Floor(100 + 1.11 * latBandLow); var highLetter = Math.Round(100 + 1.11 * latBandHigh); string latBandLetters = null; int l = Convert.ToInt32(lowLetter); int h = Convert.ToInt32(highLetter); if (mgrs.LongZone / 2.0 == Math.Floor(mgrs.LongZone / 2.0)) { latBandLetters = digraphLettersAll.Substring(l + 5, h + 5).ToString(); } else { latBandLetters = digraphLettersAll.Substring(l, h).ToString(); } var nbase = 100000 * (lowLetter + latBandLetters.IndexOf(nltr)); //latBandLetters.IndexOf(nltr) value causing incorrect Northing below -80 var x = ebase + mgrs.Easting; var y = nbase + mgrs.Northing; if (mgrs.systemType != MGRS_Type.MGRS_Polar) { if (y > 10000000) { y = y - 10000000; } if (nbase >= 10000000) { y = nbase + mgrs.northing - 10000000; } } UniversalTransverseMercator utm = new UniversalTransverseMercator(mgrs.LatZone, mgrs.LongZone, x, y, true); utm.equatorial_radius = mgrs.equatorialRadius; utm.inverse_flattening = mgrs.inverseFlattening; Coordinate c = UniversalTransverseMercator.ConvertUTMtoLatLong(utm, eagerLoad); c.Set_Datum(mgrs.equatorialRadius, mgrs.inverseFlattening); return(c); }
/// <summary> /// Creates a Coordinate object from an MGRS/NATO UTM Coordinate /// </summary> /// <param name="mgrs">MilitaryGridReferenceSystem</param> /// <returns>Coordinate object</returns> public static Coordinate MGRStoLatLong(MilitaryGridReferenceSystem mgrs) { string latz = mgrs.LatZone; string digraph = mgrs.Digraph; char eltr = digraph[0]; char nltr = digraph[1]; string digraphLettersE = "ABCDEFGHJKLMNPQRSTUVWXYZ"; string digraphLettersN = "ABCDEFGHJKLMNPQRSTUV"; string digraphLettersAll = ""; for (int lt = 1; lt < 25; lt++) { digraphLettersAll += "ABCDEFGHJKLMNPQRSTUV"; } var eidx = digraphLettersE.IndexOf(eltr); var nidx = digraphLettersN.IndexOf(nltr); if (mgrs.LongZone / 2.0 == Math.Floor(mgrs.LongZone / 2.0)) { nidx -= 5; // correction for even numbered zones } var ebase = 100000 * (1 + eidx - 8 * Math.Floor(Convert.ToDouble(eidx) / 8)); var latBand = digraphLettersE.IndexOf(latz); var latBandLow = 8 * latBand - 96; var latBandHigh = 8 * latBand - 88; if (latBand < 2) { latBandLow = -90; latBandHigh = -80; } else if (latBand == 21) { latBandLow = 72; latBandHigh = 84; } else if (latBand > 21) { latBandLow = 84; latBandHigh = 90; } var lowLetter = Math.Floor(100 + 1.11 * latBandLow); var highLetter = Math.Round(100 + 1.11 * latBandHigh); string latBandLetters = null; int l = Convert.ToInt32(lowLetter); int h = Convert.ToInt32(highLetter); if (mgrs.LongZone / 2.0 == Math.Floor(mgrs.LongZone / 2.0)) { latBandLetters = digraphLettersAll.Substring(l + 5, h + 5).ToString(); } else { latBandLetters = digraphLettersAll.Substring(l, h).ToString(); } var nbase = 100000 * (lowLetter + latBandLetters.IndexOf(nltr)); var x = ebase + mgrs.Easting; var y = nbase + mgrs.Northing; if (y > 10000000) { y = y - 10000000; } if (nbase >= 10000000) { y = nbase + mgrs.northing - 10000000; } var southern = nbase < 10000000; UniversalTransverseMercator utm = new UniversalTransverseMercator(mgrs.LatZone, mgrs.LongZone, x, y); utm.equatorial_radius = mgrs.equatorialRadius; utm.inverse_flattening = mgrs.inverseFlattening; Coordinate c = UniversalTransverseMercator.ConvertUTMtoLatLong(utm); c.Set_Datum(mgrs.equatorialRadius, mgrs.inverseFlattening); // Coordinate nc = new Coordinate(c.Latitude.ToDouble(), c.Longitude.ToDouble()); return(c); }