/// <summary> /// Set a custom datum for coordinate conversions and distance calculation for specified coordinate formats only. /// Objects must be loaded prior to setting if EagerLoading is turned off. /// </summary> /// <param name="radius">Equatorial Radius</param> /// <param name="flattening">Inverse Flattening</param> /// <param name="datum">Coordinate_Datum</param> /// <example> /// The following example demonstrates how to set the earths ellipsoid values for UTM/MGRS conversions only. /// <code> /// //Initialize a coordinate with the default WGS84 Ellipsoid that eagerloads UTM/MGRS only. /// EagerLoadType et = EagerLoadType.UTM_MGRS; /// EagerLoad eagerLoad = new EagerLoad(et); /// Coordinate c = new Coordinate(25, 25, et); /// /// //Change Ellipsoid to GRS80 Datum for UTM_MGRS calculations only. /// c.Set_Datum(6378160.000, 298.25, Coordinate_Datum.UTM_MGRS); /// </code> /// </example> public void Set_Datum(double radius, double flattening, Coordinate_Datum datum) { //WGS84 //RADIUS 6378137.0; //FLATTENING 298.257223563; if (datum.HasFlag(Coordinate_Datum.UTM_MGRS)) { if (utm == null || mgrs == null) { throw new NullReferenceException("UTM/MGRS objects must be loaded prior to changing the datum."); } utm.inverse_flattening = flattening; utm.ToUTM(Latitude.ToDouble(), Longitude.ToDouble(), utm); mgrs = new MilitaryGridReferenceSystem(utm); NotifyPropertyChanged("UTM"); NotifyPropertyChanged("MGRS"); } if (datum.HasFlag(Coordinate_Datum.ECEF)) { if (ECEF == null) { throw new NullReferenceException("ECEF objects must be loaded prior to changing the datum."); } ecef.equatorial_radius = radius; ecef.inverse_flattening = flattening; ecef.ToECEF(this); NotifyPropertyChanged("ECEF"); } if (datum.HasFlag(Coordinate_Datum.LAT_LONG)) { equatorial_radius = radius; inverse_flattening = flattening; } }
/*DATUM-ELLIPSOID METHODS*/ /// <summary> /// Set a custom datum for coordinate conversions and distance calculation. /// Objects must be loaded prior to setting if EagerLoading is turned off or else the items Datum won't be set. /// Use overload if EagerLoading options are used. /// </summary> /// <param name="radius">Equatorial Radius</param> /// <param name="flattening">Inverse Flattening</param> /// <example> /// The following example demonstrates how to set the earths ellipsoid values for UTM/MGRS and ECEF conversion as well as Distance calculations /// that use ellipsoidal earth values. /// <code> /// //Initialize a coordinate with the default WGS84 Ellipsoid. /// Coordinate c = new Coordinate(25,25); /// /// //Change Ellipsoid to GRS80 Datum /// c.Set_Datum(6378160.000, 298.25); /// </code> /// </example> public void Set_Datum(double radius, double flattening) { //WGS84 //RADIUS 6378137.0; //FLATTENING 298.257223563; if (utm != null) { utm.inverse_flattening = flattening; utm.ToUTM(Latitude.ToDouble(), Longitude.ToDouble(), utm); mgrs = new MilitaryGridReferenceSystem(utm); NotifyPropertyChanged("UTM"); NotifyPropertyChanged("MGRS"); } if (ecef != null) { ecef.equatorial_radius = radius; ecef.inverse_flattening = flattening; ecef.ToECEF(this); NotifyPropertyChanged("ECEF"); } equatorial_radius = radius; inverse_flattening = flattening; NotifyPropertyChanged("Equatorial_Radius"); NotifyPropertyChanged("Inverse_Flattening"); CoordinateChanged?.Invoke(this, new EventArgs()); }
/// <summary> /// Creates a Coordinate object with default values and a custom datum. /// </summary> /// <remarks> /// Default Coordinate objects will initialize with a latitude and longitude of 0 degrees, /// a GeoDate of 1900-1-1 00:00:00. All properties will be set to EagerLoaded. /// </remarks> internal Coordinate(double equatorialRadius, double inverseFlattening, bool t) { FormatOptions = new CoordinateFormatOptions(); geoDate = new DateTime(1900, 1, 1, 0, 0, 0, DateTimeKind.Utc); latitude = new CoordinatePart(CoordinateType.Lat); longitude = new CoordinatePart(CoordinateType.Long); latitude.parent = this; longitude.parent = this; celestialInfo = new Celestial(); utm = new UniversalTransverseMercator(latitude.ToDouble(), longitude.ToDouble(), this, equatorialRadius, inverseFlattening); mgrs = new MilitaryGridReferenceSystem(utm); cartesian = new Cartesian(this); ecef = new ECEF(this); EagerLoadSettings = new EagerLoad(); Set_Datum(equatorialRadius, inverseFlattening); }
/// <summary> /// Attempts to parse a string into an MGRS coordinate. /// </summary> /// <param name="value">string</param> /// <param name="radius">Equatorial Radius (Semi-Major Axis)</param> /// <param name="flattening">Inverse Flattening</param> /// <param name="mgrs">MilitaryGridReferenceSystem</param> /// <returns>MilitaryGridReferenceSystem</returns> /// <example> /// The following example attempts to parse an MGRS coordinate set with GRS80 system ellipsoid values. /// <code> /// MilitaryGridReferenceSystem mgrs; /// if(!MilitaryGridReferenceSystem.TryParse("16U EA 00872 05009", 6378137.0, 298.257222101, out mgrs)) /// { /// Console.WriteLine(mgrs);//16U EA 00872 05009 /// } /// </code> /// </example> public static bool TryParse(string value, double radius, double flattening, out MilitaryGridReferenceSystem mgrs) { string[] vals = null; if (FormatFinder.TryMGRS(value, out vals) || FormatFinder.TryMGRS_Polar(value, out vals)) { try { double zone = Convert.ToDouble(vals[0], CultureInfo.InvariantCulture); double easting = Convert.ToDouble(vals[3], CultureInfo.InvariantCulture); double northing = Convert.ToDouble(vals[4], CultureInfo.InvariantCulture); mgrs = new MilitaryGridReferenceSystem(vals[1], (int)zone, vals[2], easting, northing, radius, flattening); return(true); } catch {//Parser failed try next method } } mgrs = null; return(false); }
/// <summary> /// Creates a Signed Degree double[] object from an MGRS/NATO UTM Coordinate /// </summary> /// <param name="mgrs">MilitaryGridReferenceSystem</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); /// double[] sd = MilitaryGridReferenceSystem.MGRStoSignedDegree(mgrs); /// Coordinate c = new Coordinate(sd[0],sd[1], new EagerLoad(false)); /// Console.WriteLine(c); //N 0º 33' 35.988" W 60º 0' 0.01" /// </code> /// </example> public static double[] MGRStoSignedDegree(MilitaryGridReferenceSystem mgrs) { Regex upsCheck = new Regex("[AaBbYyZz]"); if (upsCheck.IsMatch(mgrs.latZone)) { Coordinate c = MGRStoLatLong(mgrs); return(new double[] { c.Latitude.ToDouble(), c.Longitude.ToDouble() }); } 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)); //latBandLetters.IndexOf(nltr) value causing incorrect Northing below -80 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; double[] sd = UniversalTransverseMercator.ConvertUTMtoSignedDegree(utm); return(sd); }
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); }
/// <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> /// <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); /// Console.WriteLine(c); //N 0º 33' 35.988" W 60º 0' 0.01" /// </code> /// </example> public static Coordinate MGRStoLatLong(MilitaryGridReferenceSystem mgrs) { return(MGRStoLatLong(mgrs, GlobalSettings.Default_EagerLoad)); }
//Add main to Coordinate and tunnel to Format class. Add private methods to format. //WHEN PARSING NO EXCPETIONS FOR OUT OF RANGE ARGS WILL BE THROWN public static bool TryParse(string coordString, CartesianType ct, out Coordinate c) { try { //Turn of eagerload for efficiency EagerLoad eg = new EagerLoad(); eg.Cartesian = false; eg.Celestial = false; eg.UTM_MGRS = false; c = new Coordinate(eg); if (string.IsNullOrEmpty(coordString)) { return(false); } string s = coordString; s = s.Trim(); //Trim all spaces before and after string double[] d; //Try Signed Degree if (TrySignedDegree(s, out d)) { try { c = new Coordinate(d[0], d[1], eg); c.Parse_Format = Parse_Format_Type.Signed_Degree; return(true); } catch {//Parser failed try next method } } //Try Decimal Degree if (TryDecimalDegree(s, out d)) { try { c = new Coordinate(d[0], d[1], eg); c.Parse_Format = Parse_Format_Type.Decimal_Degree; return(true); } catch {//Parser failed try next method } } //Try DDM if (TryDegreeDecimalMinute(s, out d)) { try { //0 Lat Degree //1 Lat Minute //2 Lat Direction (0 = N, 1 = S) //3 Long Degree //4 Long Minute //5 Long Direction (0 = E, 1 = W) CoordinatesPosition latP = CoordinatesPosition.N; CoordinatesPosition lngP = CoordinatesPosition.E; if (d[2] != 0) { latP = CoordinatesPosition.S; } if (d[5] != 0) { lngP = CoordinatesPosition.W; } CoordinatePart lat = new CoordinatePart((int)d[0], d[1], latP); CoordinatePart lng = new CoordinatePart((int)d[3], d[4], lngP); c = new Coordinate(eg); c.Latitude = lat; c.Longitude = lng; c.Parse_Format = Parse_Format_Type.Degree_Decimal_Minute; return(true); } catch {//Parser failed try next method } } //Try DMS if (TryDegreeMinuteSecond(s, out d)) { try { //0 Lat Degree //1 Lat Minute //2 Lat Second //3 Lat Direction (0 = N, 1 = S) //4 Long Degree //5 Long Minute //6 Long Second //7 Long Direction (0 = E, 1 = W) CoordinatesPosition latP = CoordinatesPosition.N; CoordinatesPosition lngP = CoordinatesPosition.E; if (d[3] != 0) { latP = CoordinatesPosition.S; } if (d[7] != 0) { lngP = CoordinatesPosition.W; } CoordinatePart lat = new CoordinatePart((int)d[0], (int)d[1], d[2], latP); CoordinatePart lng = new CoordinatePart((int)d[4], (int)d[5], d[6], lngP); c = new Coordinate(eg); c.Latitude = lat; c.Longitude = lng; c.Parse_Format = Parse_Format_Type.Degree_Minute_Second; return(true); } catch {//Parser failed try next method } } string[] um; //Try MGRS if (TryMGRS(s, out um) || TryMGRS_Polar(s, out um)) { try { double zone = Convert.ToDouble(um[0]); double easting = Convert.ToDouble(um[3]); double northing = Convert.ToDouble(um[4]); MilitaryGridReferenceSystem mgrs = new MilitaryGridReferenceSystem(um[1], (int)zone, um[2], easting, northing); c = MilitaryGridReferenceSystem.MGRStoLatLong(mgrs); c.Parse_Format = Parse_Format_Type.MGRS; return(true); } catch {//Parser failed try next method } } //Try UTM if (TryUTM(s, out um) || TryUPS(s, out um)) { try { double zone = Convert.ToDouble(um[0]); double easting = Convert.ToDouble(um[2]); double northing = Convert.ToDouble(um[3]); UniversalTransverseMercator utm = new UniversalTransverseMercator(um[1], (int)zone, easting, northing); c = UniversalTransverseMercator.ConvertUTMtoLatLong(utm); c.Parse_Format = Parse_Format_Type.UTM; return(true); } catch {//Parser failed try next method } } //Try Cartesian if (TryCartesian(s.ToUpper().Replace("KM", "").Replace("X", "").Replace("Y", "").Replace("Z", ""), out d)) { if (ct == CartesianType.Cartesian) { try { Cartesian cart = new Cartesian(d[0], d[1], d[2]); c = Cartesian.CartesianToLatLong(cart); c.Parse_Format = Parse_Format_Type.Cartesian_Spherical; return(true); } catch {//Parser failed try next method } } if (ct == CartesianType.ECEF) { try { ECEF ecef = new ECEF(d[0], d[1], d[2]); c = ECEF.ECEFToLatLong(ecef); c.Parse_Format = Parse_Format_Type.Cartesian_ECEF; return(true); } catch {//Parser failed try next method } } } } catch (Exception ex) { //Parser exception has occurred Debug.WriteLine("PARSER EXCEPTION HANDLED: " + ex.ToString()); } c = null; return(false); }
/// <summary> /// Notify property changed /// </summary> /// <param name="propName">Property Name</param> public void NotifyPropertyChanged(string propName) { switch (propName) { case "CelestialInfo": if (!EagerLoadSettings.Celestial) { return; } //Prevent calls while eagerloading is off if (EagerLoadSettings.Celestial && celestialInfo == null) { celestialInfo = new Celestial(false); } //Create object if EagerLoading is on and object is null (EagerLoading turned on later). celestialInfo.CalculateCelestialTime(latitude.DecimalDegree, longitude.DecimalDegree, geoDate, EagerLoadSettings); break; case "UTM": if (!EagerLoadSettings.UTM_MGRS) { return; } else if (EagerLoadSettings.UTM_MGRS && utm == null) { utm = new UniversalTransverseMercator(latitude.ToDouble(), longitude.ToDouble(), this, equatorial_radius, inverse_flattening); } else { utm.ToUTM(latitude.ToDouble(), longitude.ToDouble(), utm); } break; case "utm": //Adjust case and notify of change. //Use to notify without calling ToUTM() propName = "UTM"; break; case "MGRS": if (!EagerLoadSettings.UTM_MGRS || !EagerLoadSettings.Extensions.MGRS || utm == null) { return; } else if (EagerLoadSettings.UTM_MGRS && EagerLoadSettings.Extensions.MGRS && mgrs == null) { mgrs = new MilitaryGridReferenceSystem(utm); } else { MGRS.ToMGRS(utm); } break; case "Cartesian": if (!EagerLoadSettings.Cartesian) { return; } else if (EagerLoadSettings.Cartesian && cartesian == null) { cartesian = new Cartesian(this); } else { Cartesian.ToCartesian(this); } break; case "ECEF": if (!EagerLoadSettings.ECEF) { return; } else if (EagerLoadSettings.ECEF && ecef == null) { ecef = new ECEF(this); } else { ECEF.ToECEF(this); } break; default: break; } PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName)); }
/// <summary> /// Load UTM and MGRS information (required if eager loading is turned off). /// </summary> /// <example> /// The following example shows how to Load UTM and MGRS information when eager loading is turned off. /// <code> /// EagerLoad eagerLoad = new EagerLoad(); /// eagerLoad.UTM_MGRS = false; /// Coordinate c = new Coordinate(40.0352, -74.5844, DateTime.Now, eagerLoad); /// /// //To load UTM_MGRS information when ready /// c.LoadUTM_MGRSInfo; /// </code> /// </example> public void LoadUTM_MGRS_Info() { utm = new UniversalTransverseMercator(latitude.ToDouble(), longitude.ToDouble(), this); mgrs = new MilitaryGridReferenceSystem(utm); }
/// <summary> /// Coordinate build logic goes here. /// </summary> /// <param name="lat">Signed latitude</param> /// <param name="longi">Signed longitude</param> /// <param name="date">Date at location</param> /// <param name="eagerLoad">Eagerloading settings</param> private void Coordinate_Builder(double lat, double longi, DateTime date, EagerLoad eagerLoad) { FormatOptions = new CoordinateFormatOptions(); //Use default constructor if signed degree is 0 for performance. if (lat == 0) { latitude = new CoordinatePart(CoordinateType.Lat); } else { latitude = new CoordinatePart(lat, CoordinateType.Lat); } if (longi == 0) { longitude = new CoordinatePart(CoordinateType.Long); } else { longitude = new CoordinatePart(longi, CoordinateType.Long); } //Set CoordinatePart parents latitude.parent = this; longitude.parent = this; //Set UTC date at location geoDate = date; //LOAD NEW COORDINATE SYSTEMS HERE //Load Celestial if (eagerLoad.Celestial) { celestialInfo = new Celestial(lat, longi, date); } //Load UTM MGRS if (eagerLoad.UTM_MGRS) { utm = new UniversalTransverseMercator(lat, longi, this); mgrs = new MilitaryGridReferenceSystem(utm); } //Load CARTESIAN if (eagerLoad.Cartesian) { cartesian = new Cartesian(this); } //Load ECEF if (eagerLoad.ECEF) { ecef = new ECEF(this); } //SET EagerLoading Setting EagerLoadSettings = eagerLoad; //Set Ellipsoid equatorial_radius = 6378137.0; inverse_flattening = 298.257223563; }
/// <summary> /// Creates a Coordinate object from an MGRS/NATO UTM Coordinate /// </summary> /// <param name="mgrs">MilitaryGridReferenceSystem</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); /// Console.WriteLine(c); //N 0º 33' 35.988" W 60º 0' 0.01" /// </code> /// </example> public static Coordinate MGRStoLatLong(MilitaryGridReferenceSystem mgrs) { return(MGRStoLatLong(mgrs, new EagerLoad())); }
/// <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, new Coordinate()); Coordinate c = UniversalTransverseMercator.ConvertUTMtoLatLong(utm); //Create second coordinate object to ensure MGRS integrity for return //Investigate why this happens on future releases //Works and passes unit test Coordinate nc = new Coordinate(c.Latitude.ToDouble(), c.Longitude.ToDouble()); return(nc); }
/// <summary> /// Attempts to parse a string into an MGRS coordinate. /// </summary> /// <param name="value">string</param> /// <param name="spec">Earth_Ellipsoid_Spec</param> /// <param name="mgrs">MilitaryGridReferenceSystem</param> /// <returns>MilitaryGridReferenceSystem</returns> /// <example> /// The following example attempts to parse an MGRS coordinate set with a GRS80 system ellipsoid. /// <code> /// MilitaryGridReferenceSystem mgrs; /// if(!MilitaryGridReferenceSystem.TryParse("16U EA 00872 05009", Earth_Ellipsoid_Spec.GRS80_1979, out mgrs)) /// { /// Console.WriteLine(mgrs);//16U EA 00872 05009 /// } /// </code> /// </example> public static bool TryParse(string value, Earth_Ellipsoid_Spec spec, out MilitaryGridReferenceSystem mgrs) { Earth_Ellipsoid ee = Earth_Ellipsoid.Get_Ellipsoid(spec); return(TryParse(value, ee.Equatorial_Radius, ee.Inverse_Flattening, out mgrs)); }
//Add main to Coordinate and tunnel to Format class. Add private methods to format. //WHEN PARSING NO EXCPETIONS FOR OUT OF RANGE ARGS WILL BE THROWN public static bool TryParse(string coordString, out Coordinate c) { //Turn of eagerload for efficiency EagerLoad eg = new EagerLoad(); eg.Cartesian = false; eg.Celestial = false; eg.UTM_MGRS = false; c = new Coordinate(eg); string s = coordString; s = s.Trim(); //Trim all spaces before and after string double[] d; //Try Signed Degree if (TrySignedDegree(s, out d)) { try { c = new Coordinate(d[0], d[1], eg); return(true); } catch {//Parser failed try next method } } //Try Decimal Degree if (TryDecimalDegree(s, out d)) { try { c = new Coordinate(d[0], d[1], eg); return(true); } catch {//Parser failed try next method } } //Try DDM if (TryDegreeDecimalMinute(s, out d)) { try { //0 Lat Degree //1 Lat Minute //2 Lat Direction (0 = N, 1 = S) //3 Long Degree //4 Long Minute //5 Long Direction (0 = E, 1 = W) CoordinatesPosition latP = CoordinatesPosition.N; CoordinatesPosition lngP = CoordinatesPosition.E; if (d[2] != 0) { latP = CoordinatesPosition.S; } if (d[5] != 0) { lngP = CoordinatesPosition.W; } CoordinatePart lat = new CoordinatePart((int)d[0], d[1], latP, c); CoordinatePart lng = new CoordinatePart((int)d[3], d[4], lngP, c); c = new Coordinate(eg); c.Latitude = lat; c.Longitude = lng; return(true); } catch {//Parser failed try next method } } //Try DMS if (TryDegreeMinuteSecond(s, out d)) { try { //0 Lat Degree //1 Lat Minute //2 Lat Second //3 Lat Direction (0 = N, 1 = S) //4 Long Degree //5 Long Minute //6 Long Second //7 Long Direction (0 = E, 1 = W) CoordinatesPosition latP = CoordinatesPosition.N; CoordinatesPosition lngP = CoordinatesPosition.E; if (d[3] != 0) { latP = CoordinatesPosition.S; } if (d[7] != 0) { lngP = CoordinatesPosition.W; } CoordinatePart lat = new CoordinatePart((int)d[0], (int)d[1], d[2], latP, c); CoordinatePart lng = new CoordinatePart((int)d[4], (int)d[5], d[6], lngP, c); c = new Coordinate(eg); c.Latitude = lat; c.Longitude = lng; return(true); } catch {//Parser failed try next method } } string[] um; //Try MGRS if (TryMGRS(s, out um)) { try { double zone = Convert.ToDouble(um[0]); double easting = Convert.ToDouble(um[3]); double northing = Convert.ToDouble(um[4]); MilitaryGridReferenceSystem mgrs = new MilitaryGridReferenceSystem(um[1], (int)zone, um[2], easting, northing); c = MilitaryGridReferenceSystem.MGRStoLatLong(mgrs); return(true); } catch {//Parser failed try next method } } //Try UTM if (TryUTM(s, out um)) { try { double zone = Convert.ToDouble(um[0]); double easting = Convert.ToDouble(um[2]); double northing = Convert.ToDouble(um[3]); UniversalTransverseMercator utm = new UniversalTransverseMercator(um[1], (int)zone, easting, northing); c = UniversalTransverseMercator.ConvertUTMtoLatLong(utm); return(true); } catch {//Parser failed try next method } } if (TryCartesian(s, out d)) { try { Cartesian cart = new Cartesian(d[0], d[1], d[2]); c = Cartesian.CartesianToLatLong(cart); return(true); } catch {//Parser failed try next method } } //Try Cartesian return(false); }