/// <summary> /// Notify property changed /// </summary> /// <param name="propName">Property Name</param> public void NotifyPropertyChanged(string propName) { switch (propName) { case "CelestialInfo": if (!EagerLoadSettings.Celestial || celestialInfo == null) { return; } //Prevent Null Exceptions and calls while eagerloading is off celestialInfo.CalculateCelestialTime(latitude.DecimalDegree, longitude.DecimalDegree, geoDate); break; case "UTM": if (!EagerLoadSettings.UTM_MGRS || UTM == null) { return; } 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 || MGRS == null) { return; } MGRS.ToMGRS(utm); break; case "Cartesian": if (!EagerLoadSettings.Cartesian || Cartesian == null) { return; } Cartesian.ToCartesian(this); break; case "ECEF": if (!EagerLoadSettings.ECEF) { return; } ECEF.ToECEF(this); break; default: break; } PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName)); }
/// <summary> /// Returns a Geodetic Coordinate object based on the provided ECEF Coordinate /// </summary> /// <param name="ecef">ECEF Coordinate</param> /// <returns>Coordinate</returns> public static Coordinate ECEFToLatLong(ECEF ecef) { double[] values = ecef.ECEF_To_LatLong(ecef.X, ecef.Y, ecef.Z); Coordinate c = new Coordinate(values[0], values[1]); Distance height = new Distance(values[2]); ecef.geodetic_height = new Distance(values[2]); c.ECEF = ecef; return(c); }
/// <summary> /// Returns a Geodetic Coordinate object based on the provided ECEF Coordinate /// </summary> /// <param name="x">X</param> /// <param name="y">Y</param> /// <param name="z">Z</param> /// <returns>Coordinate</returns> public static Coordinate ECEFToLatLong(double x, double y, double z) { ECEF ecef = new ECEF(x, y, z); double[] values = ecef.ECEF_To_LatLong(x, y, z); ecef.geodetic_height = new Distance(values[2]); Coordinate c = new Coordinate(values[0], values[1]); c.ECEF = ecef; return(c); }
/// <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 ECEF coordinate. /// </summary> /// <param name="value">string</param> /// <param name="ecef">ECEF</param> /// <returns>ECEF</returns> /// <example> /// The following example attempts to parse an ECEF coordinate. /// <code> /// ECEF ecef; /// if(!ECEF.TryParse("217.206 km, -4127.862 km, 4841.101 km", out ecef)) /// { /// Console.WriteLine(ecef);//217.206 km, -4127.862 km, 4841.101 km /// } /// </code> /// </example> public static bool TryParse(string value, out ECEF ecef) { double[] vals = null; if (FormatFinder.TryCartesian(value.ToUpper().Replace("KM", "").Replace("X", "").Replace("Y", "").Replace("Z", ""), out vals)) { try { ecef = new ECEF(vals[0], vals[1], vals[2]); return(true); } catch {//Parser failed try next method } } ecef = null; return(false); }
//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 ECEF information (required if eager loading is turned off). /// </summary> /// <example> /// The following example shows how to Load ECEF information when eager loading is turned off. /// <code> /// EagerLoad eagerLoad = new EagerLoad(); /// eagerLoad.ECEF = false; /// Coordinate c = new Coordinate(40.0352, -74.5844, DateTime.Now, eagerLoad); /// /// //To load ECEF information when ready /// c.LoadECEFInfo; /// </code> /// </example> public void LoadECEFInfo() { ecef = new ECEF(this); }
/// <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; }