/// <summary> /// Parses the Position based on the given indizes and the Words array. /// </summary> /// <param name="latitudeValuePosition">Position of the latitude value inside the Words array.</param> /// <param name="latitudeHemispherePosition">Position of the latitude hemisphere inside the Words array.</param> /// <param name="longitudeValuePosition">Position of the longitude value inside the Words array.</param> /// <param name="longitudeHemispherePosition">Position of the longitude hemisphere inside the Words array.</param> /// <returns>Position.Invalid, if the Words array is to short or at least one of the fields is empty.</returns> protected Position ParsePosition(int latitudeValuePosition, int latitudeHemispherePosition, int longitudeValuePosition, int longitudeHemispherePosition) { List <int> positions = new List <int> { latitudeValuePosition, latitudeHemispherePosition, longitudeValuePosition, longitudeHemispherePosition }; if (Words.Length <= positions.Max() || positions.Any(pos => Words[pos].Length < 1)) //not enough words or empty field result in invalid position { return(Position.Invalid); } // Parse the latitude string latitudeWord = Words[latitudeValuePosition]; int latitudeHours = int.Parse(latitudeWord.Substring(0, 2), NmeaCultureInfo); double latitudeDecimalMinutes = double.Parse(latitudeWord.Substring(2), NmeaCultureInfo); LatitudeHemisphere latitudeHemisphere = Words[latitudeHemispherePosition].Equals("N", StringComparison.Ordinal) ? LatitudeHemisphere.North : LatitudeHemisphere.South; // Parse the longitude string longitudeWord = Words[longitudeValuePosition]; int longitudeHours = int.Parse(longitudeWord.Substring(0, 3), NmeaCultureInfo); double longitudeDecimalMinutes = double.Parse(longitudeWord.Substring(3), NmeaCultureInfo); LongitudeHemisphere longitudeHemisphere = Words[longitudeHemispherePosition].Equals("E", StringComparison.Ordinal) ? LongitudeHemisphere.East : LongitudeHemisphere.West; return(new Position(new Latitude(latitudeHours, latitudeDecimalMinutes, latitudeHemisphere), new Longitude(longitudeHours, longitudeDecimalMinutes, longitudeHemisphere))); }
private static void DecodeMicEDestinationAddress( string data, out Latitude latitude, out short longitudeOffset, out LongitudeHemisphere longitudeHemisphere, out MicEMessageType micEMessageType) { if (string.IsNullOrEmpty(data) || data.Length != 6) { throw new ArgumentException("Data must be a six character string", nameof(data)); } var sbLatitude = new StringBuilder(); var sbMicEMessageCode = new StringBuilder(); var isStandardMessage = false; var isCustomMessage = false; var latitudeHemisphere = default(LatitudeHemisphere); //latitude = null; longitudeOffset = 0; longitudeHemisphere = default; //micEMessageType = MicEMessageType.Unknown; for (var p = 0; p < 6; p++) { var c = data[p]; if (c >= '0' && c <= '9' || c == 'L') { if (c == 'L') { sbLatitude.Append(" "); } else { sbLatitude.Append(c - '0'); } if (p < 3) { sbMicEMessageCode.Append('0'); } else { switch (p) { case 3: latitudeHemisphere = LatitudeHemisphere.South; break; case 4: longitudeOffset = 0; break; case 5: longitudeHemisphere = LongitudeHemisphere.East; break; } } } else if (c >= 'A' && c <= 'K') { if (c == 'K') { sbLatitude.Append(" "); } else { sbLatitude.Append(c - 'A'); } if (p < 3) { sbMicEMessageCode.Append(1); isCustomMessage = true; } else { throw new ArgumentException("Invalid data: " + data); } } else if (c >= 'P' && c <= 'Z') { if (c == 'Z') { sbLatitude.Append(" "); } else { sbLatitude.Append(c - 'P'); } if (p < 3) { sbMicEMessageCode.Append(1); isStandardMessage = true; } else { switch (p) { case 3: latitudeHemisphere = LatitudeHemisphere.North; break; case 4: longitudeOffset = 100; break; case 5: longitudeHemisphere = LongitudeHemisphere.West; break; } } } else { throw new ArgumentException("Invalid data: " + data); } } short degrees, minutes; double seconds; short latitudeAmbiguity; ParseLatitudeValue(sbLatitude.ToString(), out degrees, out minutes, out seconds, out latitudeAmbiguity); latitude = new Latitude(degrees, minutes, seconds, latitudeHemisphere, latitudeAmbiguity); if (isStandardMessage && isCustomMessage) { micEMessageType = MicEMessageType.Unknown; } else if (isStandardMessage) { if (!Constants.Maps.StandardMicEMessageTypeMap.TryGetValue(sbMicEMessageCode.ToString(), out micEMessageType)) { throw new InvalidOperationException("Invalid MicE Message Code: " + sbMicEMessageCode); } } else if (isCustomMessage) { if (!Constants.Maps.CustomMicEMessageTypeMap.TryGetValue(sbMicEMessageCode.ToString(), out micEMessageType)) { throw new InvalidOperationException("Invalid MicE Message Code: " + sbMicEMessageCode); } } else { micEMessageType = MicEMessageType.Emergency; } }
/// <summary> /// OnSentanceChanged event handler /// </summary> protected override void OnSentenceChanged() { base.OnSentenceChanged(); // Cache the sentence words string[] words = Words; int wordCount = words.Length; /* * Garmin produces several embedded GPS systems. They are easy to setup because Garmin provides a nice utility for uploading configuration data to the GPS. You first load the utility to a PC. Connect the PC to the GPS through one of the serial ports. The utility will check each baud rate until it communicates with the GPS. * * The common configuration parameters are output sentences from the GPS unit, the communication baud rate with a host, and the required pulse per second. * * Each sentence is preceded with a ‘$’ symbol and ends with a line-feed character. At one sentence per second, the following is out put in four seconds: * * $PGRMF, 223, 424798, 041203, 215945, 13, 0000.0000, N, 00000.0000, W, A, 2, 0, 62, 2, 1*3B * $PGRMF, 223, 424799, 041203, 215946, 13, 00000.0000, N, 00000.0000, W, A, 2, 0, 62, 2, 1*39 * $PGRMF, 223, 424800, 041203, 215947, 13, 00000.0000, N, 00000.0000, W, A, 2, 0, 62, 2, 1*34 * $PGRMF, 223, 424801, 041203, 215948, 13, 00000.0000, N, 00000.0000, W, A, 2, 0, 62, 2, 1*35 * * The sentence is proprietary to the Garmin GPS Global Positioning System and is translated below. * * $PGRMF * <1>GPS Week Number(0-1023) * <2>GPS Seconds (0 - 604799) * <3>UTC Date of position fix, ddmmyy format * <4>UTC time of position fix, hhmmss format * <5>GPS leap second count * <6>Latitude, ddmm.mmmm format (leading zeros transmitted) * <7>Latitude hemisphere N or S * <8>Longitude, ddmm.mmmm format (leading zeros transmitted) * <9>Longitude hemisphere N or S * <10>Mode M = Manual, A automatic * <11>Fix type 0 = No Fix, 1 = 2D Fix, 2 = 3D fix * <12>Speed over ground, 0 to 359 degrees true * <13>Course over ground, 0 to 9 (rounded to nearest intvalue) * <14>Time dilution of precision, 0 to 9 (rnded nearest int val) * <15>Time dilution of precision, 0 to 9 (rnded nearest int val) * hh <CR><LF> */ // TODO: Convert GPS week number/seconds to UTC date/time // Do we have enough words to parse the fix status? if (wordCount >= 4 && words[2].Length != 0 && words[3].Length != 0) { // Build a UTC date/time object. _utcDateTime = new DateTime( int.Parse(words[2].Substring(4, 2), NmeaCultureInfo) + 2000, // Year int.Parse(words[2].Substring(2, 2), NmeaCultureInfo), // Month int.Parse(words[2].Substring(0, 2), NmeaCultureInfo), // Day int.Parse(words[3].Substring(0, 2), NmeaCultureInfo), // Hour int.Parse(words[3].Substring(2, 2), NmeaCultureInfo), // Minute int.Parse(words[3].Substring(4, 2), NmeaCultureInfo), // Second DateTimeKind.Utc); } #region Position // Can we parse the latitude and longitude? if (wordCount >= 8 && words[5].Length != 0 && words[6].Length != 0 && words[7].Length != 0 && words[8].Length != 0) { #region Parse the latitude string latitudeWord = words[5]; int latitudeHours = int.Parse(latitudeWord.Substring(0, 2), NmeaCultureInfo); double latitudeDecimalMinutes = double.Parse(latitudeWord.Substring(2), NmeaCultureInfo); LatitudeHemisphere latitudeHemisphere = words[6].Equals("N", StringComparison.Ordinal) ? LatitudeHemisphere.North : LatitudeHemisphere.South; #endregion Parse the latitude #region Parse the longitude string longitudeWord = words[7]; int longitudeHours = int.Parse(longitudeWord.Substring(0, 3), NmeaCultureInfo); double longitudeDecimalMinutes = double.Parse(longitudeWord.Substring(3), NmeaCultureInfo); LongitudeHemisphere longitudeHemisphere = words[8].Equals("E", StringComparison.Ordinal) ? LongitudeHemisphere.East : LongitudeHemisphere.West; #endregion Parse the longitude #region Build a Position from the latitude and longitude _position = new Position( new Latitude(latitudeHours, latitudeDecimalMinutes, latitudeHemisphere), new Longitude(longitudeHours, longitudeDecimalMinutes, longitudeHemisphere)); #endregion Build a Position from the latitude and longitude } else { _position = Position.Invalid; } #endregion Position #region Fix Mode if (wordCount >= 9 && words[9].Length != 0) { _fixMode = words[9] == "A" ? FixMode.Automatic : FixMode.Manual; } else { _fixMode = FixMode.Unknown; } #endregion Fix Mode #region Fix Quality // Do we have enough data for fix quality? if (wordCount >= 10 && words[10].Length != 0) { switch (int.Parse(words[10], NmeaCultureInfo)) { case 0: _fixQuality = FixQuality.NoFix; break; case 1: _fixQuality = FixQuality.GpsFix; break; case 2: _fixQuality = FixQuality.DifferentialGpsFix; break; case 3: _fixQuality = FixQuality.PulsePerSecond; break; case 4: _fixQuality = FixQuality.FixedRealTimeKinematic; break; case 5: _fixQuality = FixQuality.FloatRealTimeKinematic; break; case 6: _fixQuality = FixQuality.Estimated; break; case 7: _fixQuality = FixQuality.ManualInput; break; case 8: _fixQuality = FixQuality.Simulated; break; default: _fixQuality = FixQuality.Unknown; break; } } else { // This fix quality is invalid _fixQuality = FixQuality.Unknown; } #endregion Fix Quality #region Bearing // Do we have enough data for fix quality? if (wordCount >= 13 && words[12].Length != 0) { _bearing = new Azimuth(words[12], NmeaCultureInfo); } else { _bearing = Azimuth.Invalid; } #endregion Bearing #region Speed // Do we have enough data for fix quality? if (wordCount >= 12 && words[11].Length != 0) { _speed = Speed.FromKilometersPerHour(double.Parse(words[11], NmeaCultureInfo)); } else { _speed = Speed.Invalid; } #endregion Speed #region Position Dilution of Precision // Do we have enough data for fix quality? if (wordCount >= 13 && words[13].Length != 0) { _positionDop = new DilutionOfPrecision(float.Parse(words[13], NmeaCultureInfo)); } else { _positionDop = DilutionOfPrecision.Invalid; } #endregion Position Dilution of Precision }
public Longitude(short degrees, short minutes, double seconds, LongitudeHemisphere hemisphere, short ambiguity) : base(hemisphere == LongitudeHemisphere.East ? PositionSign.Positive : PositionSign.Negative, degrees, minutes, seconds, ambiguity) { }
public Longitude(short degrees, short minutes, LongitudeHemisphere hemisphere) : this(degrees, minutes, 0, hemisphere) { }
public Longitude(short degrees, double minutes, LongitudeHemisphere hemisphere) : base(hemisphere == LongitudeHemisphere.East ? PositionSign.Positive : PositionSign.Negative, degrees, (short)Math.Floor(minutes), (minutes - Math.Floor(minutes)) * 60) { }
protected override void OnSentenceChanged() { // First, process the basic info for the sentence base.OnSentenceChanged(); // Cache the sentence words string[] words = base.Words; int wordCount = words.Length; /* * $GPRMC * * Recommended minimum specific GPS/Transit data * * eg1. $GPRMC,081836,A,3751.65,S,14507.36,E,000.0,360.0,130998,011.3,E*62 * eg2. $GPRMC,225446,A,4916.45,N,12311.12,W,000.5,054.7,191194,020.3,E*68 * * * 225446 Time of fix 22:54:46 UTC * A Navigation receiver warning A = OK, V = warning * 4916.45,N Latitude 49 deg. 16.45 min North * 12311.12,W Longitude 123 deg. 11.12 min West * 000.5 Speed over ground, Knots * 054.7 Course Made Good, True * 191194 Date of fix 19 November 1994 * 020.3,E Magnetic variation 20.3 deg East * 68 mandatory checksum * * * eg3. $GPRMC,220516,A,5133.82,N,00042.24,W,173.8,231.8,130694,004.2,W*70 * 1 2 3 4 5 6 7 8 9 10 11 12 * * * 1 220516 Time Stamp * 2 A validity - A-ok, V-invalid * 3 5133.82 current Latitude * 4 N North/South * 5 00042.24 current Longitude * 6 W East/West * 7 173.8 Speed in knots * 8 231.8 True course * 9 130694 Date Stamp * 10 004.2 Variation * 11 W East/West * 12 *70 checksum * * * eg4. $GPRMC,hhmmss.ss,A,llll.ll,a,yyyyy.yy,a,x.x,x.x,ddmmyy,x.x,a*hh * 1 = UTC of position fix * 2 = Data status (V=navigation receiver warning) * 3 = Latitude of fix * 4 = N or S * 5 = Longitude of fix * 6 = E or W * 7 = Speed over ground in knots * 8 = Track made good in degrees True * 9 = UT date * 10 = Magnetic variation degrees (Easterly var. subtracts from true course) * 11 = E or W * 12 = Checksum */ // Do we have enough words to parse the fix status? if (wordCount >= 2 && words[1].Length != 0) { #region Fix status // Get the fix flag _FixStatus = words[1].Equals("A", StringComparison.OrdinalIgnoreCase) ? FixStatus.Fix : FixStatus.NoFix; #endregion } else { // The fix status is invalid _FixStatus = FixStatus.Unknown; } // Do we have enough words to parse the UTC date/time? if (wordCount >= 9 && words[0].Length != 0 && words[8].Length != 0) { #region Parse the UTC time string utcTimeWord = words[0]; int utcHours = int.Parse(utcTimeWord.Substring(0, 2), NmeaCultureInfo); // AA int utcMinutes = int.Parse(utcTimeWord.Substring(2, 2), NmeaCultureInfo); // BB int utcSeconds = int.Parse(utcTimeWord.Substring(4, 2), NmeaCultureInfo); // CC int utcMilliseconds = 0; if (utcTimeWord.Length > 6) { utcMilliseconds = Convert.ToInt32(float.Parse(utcTimeWord.Substring(6), NmeaCultureInfo) * 1000, NmeaCultureInfo); // DDDD } #endregion #region Parse the UTC date string utcDateWord = words[8]; int utcDay = int.Parse(utcDateWord.Substring(0, 2), NmeaCultureInfo); int utcMonth = int.Parse(utcDateWord.Substring(2, 2), NmeaCultureInfo); int utcYear = int.Parse(utcDateWord.Substring(4, 2), NmeaCultureInfo) + 2000; #endregion #region Build a UTC date/time _UtcDateTime = new DateTime(utcYear, utcMonth, utcDay, utcHours, utcMinutes, utcSeconds, utcMilliseconds, DateTimeKind.Utc); #endregion } else { // The UTC date/time is invalid _UtcDateTime = DateTime.MinValue; } // Do we have enough data to parse the location? if (wordCount >= 6 && words[2].Length != 0 && words[3].Length != 0 && words[4].Length != 0 && words[5].Length != 0) { #region Parse the latitude string latitudeWord = words[2]; int latitudeHours = int.Parse(latitudeWord.Substring(0, 2), NmeaCultureInfo); double latitudeDecimalMinutes = double.Parse(latitudeWord.Substring(2), NmeaCultureInfo); LatitudeHemisphere latitudeHemisphere = words[3].Equals("N", StringComparison.Ordinal) ? LatitudeHemisphere.North : LatitudeHemisphere.South; #endregion #region Parse the longitude string longitudeWord = words[4]; int longitudeHours = int.Parse(longitudeWord.Substring(0, 3), NmeaCultureInfo); double longitudeDecimalMinutes = double.Parse(longitudeWord.Substring(3), NmeaCultureInfo); LongitudeHemisphere longitudeHemisphere = words[5].Equals("E", StringComparison.Ordinal) ? LongitudeHemisphere.East : LongitudeHemisphere.West; #endregion #region Build a Position from the latitude and longitude _Position = new Position( new Latitude(latitudeHours, latitudeDecimalMinutes, latitudeHemisphere), new Longitude(longitudeHours, longitudeDecimalMinutes, longitudeHemisphere)); #endregion } else { _Position = Position.Invalid; } // Do we have enough info to process speed? if (wordCount >= 7 && words[6].Length != 0) { #region Speed // The speed is the sixth word, expressed in knots _Speed = new Speed(double.Parse(words[6], NmeaCultureInfo), SpeedUnit.Knots); #endregion } else { // The speed is invalid _Speed = Speed.Invalid; } // do we have enough info to process the bearing? if (wordCount >= 8 && words[7].Length != 0) { #region Bearing // The bearing is the seventh word _Bearing = new Azimuth(double.Parse(words[7], NmeaCultureInfo)); #endregion } else { // The bearing is invalid _Bearing = Azimuth.Invalid; } // Do we have enough info for magnetic variation? if (wordCount >= 10 && words[9].Length != 0) { // Parse the value _MagneticVariation = new Longitude(double.Parse(words[9], NmeaCultureInfo)); } else { // The magnetic variation is invalid _MagneticVariation = Longitude.Invalid; } }
/// <summary> /// Called when [sentence changed]. /// </summary> /// <remarks></remarks> protected override void OnSentenceChanged() { // Parse the basic sentence information base.OnSentenceChanged(); // Cache the words string[] words = Words; int wordCount = words.Length; // Do we have enough data to process the UTC time? if (wordCount >= 1 && words[0].Length != 0) { #region UTC Time string utcTimeWord = words[0]; int utcHours = 0; int utcMinutes = 0; int utcSeconds = 0; int utcMilliseconds = 0; if (utcTimeWord.Length >= 6) { int.TryParse(utcTimeWord.Substring(0, 2), out utcHours); int.TryParse(utcTimeWord.Substring(2, 2), out utcMinutes); int.TryParse(utcTimeWord.Substring(4, 2), out utcSeconds); } if (utcTimeWord.Length > 6) { try { utcMilliseconds = Convert.ToInt32(float.Parse(utcTimeWord.Substring(6), NmeaCultureInfo) * 1000, NmeaCultureInfo); } catch (Exception) { } } // Build a TimeSpan for this value _utcTime = new TimeSpan(0, utcHours, utcMinutes, utcSeconds, utcMilliseconds); #endregion UTC Time } else { // The UTC time is invalid _utcTime = TimeSpan.MinValue; } // Do we have enough data for locations? if (wordCount >= 5 && words[1].Length != 0 && words[2].Length != 0 && words[3].Length != 0 && words[4].Length != 0) { #region Latitude string latitudeWord = words[1]; int latitudeHours = 0; double latitudeDecimalMinutes = 0.0; if (latitudeWord.Length > 3) { int.TryParse(latitudeWord.Substring(0, 2), out latitudeHours); double.TryParse(latitudeWord.Substring(2), out latitudeDecimalMinutes); } LatitudeHemisphere latitudeHemisphere = words[2].Equals("N", StringComparison.OrdinalIgnoreCase) ? LatitudeHemisphere.North : LatitudeHemisphere.South; #endregion Latitude #region Longitude string longitudeWord = words[3]; int longitudeHours = 0; double longitudeDecimalMinutes = 0.0; if (longitudeWord.Length > 4) { int.TryParse(longitudeWord.Substring(0, 3), out longitudeHours); double.TryParse(longitudeWord.Substring(3), out longitudeDecimalMinutes); } LongitudeHemisphere longitudeHemisphere = words[4].Equals("E", StringComparison.OrdinalIgnoreCase) ? LongitudeHemisphere.East : LongitudeHemisphere.West; #endregion Longitude #region Position _position = new Position( new Latitude(latitudeHours, latitudeDecimalMinutes, latitudeHemisphere), new Longitude(longitudeHours, longitudeDecimalMinutes, longitudeHemisphere)); #endregion Position } else { _position = Position.Invalid; } // Do we have enough data for fix quality? if (wordCount >= 6 && words[5].Length != 0) { #region Fix Quality int fixQual = -1; int.TryParse(words[5], out fixQual); switch (fixQual) { case 0: _fixQuality = FixQuality.NoFix; break; case 1: _fixQuality = FixQuality.GpsFix; break; case 2: _fixQuality = FixQuality.DifferentialGpsFix; break; case 3: _fixQuality = FixQuality.PulsePerSecond; break; case 4: _fixQuality = FixQuality.FixedRealTimeKinematic; break; case 5: _fixQuality = FixQuality.FloatRealTimeKinematic; break; case 6: _fixQuality = FixQuality.Estimated; break; case 7: _fixQuality = FixQuality.ManualInput; break; case 8: _fixQuality = FixQuality.Simulated; break; default: _fixQuality = FixQuality.Unknown; break; } #endregion Fix Quality } else { // This fix quality is invalid _fixQuality = FixQuality.Unknown; } // Number of satellites in view is skipped. We'll work off of GPGSV data. if (wordCount >= 7 && words[6].Length != 0) { int.TryParse(words[6], out _fixedSatelliteCount); } // Is there enough information to process horizontal dilution of precision? if (wordCount >= 8 && words[7].Length != 0) { #region Horizontal Dilution of Precision try { _horizontalDilutionOfPrecision = new DilutionOfPrecision(float.Parse(words[7], NmeaCultureInfo)); } catch (Exception) { _horizontalDilutionOfPrecision = DilutionOfPrecision.Invalid; } #endregion Horizontal Dilution of Precision } else { // The HDOP is invalid _horizontalDilutionOfPrecision = DilutionOfPrecision.Invalid; } // Is there enough information to process altitude? if (wordCount >= 9 && words[8].Length != 0) { #region Altitude try { // Altitude is the 8th NMEA word _altitude = new Distance(float.Parse(words[8], NmeaCultureInfo), DistanceUnit.Meters); } catch (Exception) { _altitude = Distance.Invalid; } #endregion Altitude } else { // The altitude is invalid _altitude = Distance.Invalid; } // Is there enough information to process geoidal separation? if (wordCount >= 11 && words[10].Length != 0) { #region Geoidal Separation try { // Parse the geoidal separation _geoidalSeparation = new Distance(float.Parse(words[10], NmeaCultureInfo), DistanceUnit.Meters); } catch (Exception) { _geoidalSeparation = Distance.Invalid; } #endregion Geoidal Separation } else { // The geoidal separation is invalid _geoidalSeparation = Distance.Invalid; } // Is there enough info to process Differential GPS info? if (wordCount >= 14 && words[12].Length != 0 && words[13].Length != 0) { #region Differential GPS information try { _differentialGpsAge = words[12].Length != 0 ? TimeSpan.FromSeconds(float.Parse(words[12], NmeaCultureInfo)) : TimeSpan.MinValue; } catch (Exception) { } if (words[13].Length != 0) { if (!int.TryParse(words[13], out _differentialGpsStationID)) { _differentialGpsStationID = -1; } } else { _differentialGpsStationID = -1; } #endregion Differential GPS information } else { _differentialGpsStationID = -1; _differentialGpsAge = TimeSpan.MinValue; } }
protected override void OnSentenceChanged() { // Parse the basic sentence information base.OnSentenceChanged(); // Cache the words string[] words = base.Words; int wordCount = words.Length; // Do we have enough words to make a lat/long location? if (wordCount >= 4 && words[0].Length != 0 && words[1].Length != 0 && words[2].Length != 0 && words[3].Length != 0) { #region Latitude string latitudeWord = words[0]; int latitudeHours = int.Parse(latitudeWord.Substring(0, 2), NmeaCultureInfo); double latitudeDecimalMinutes = double.Parse(latitudeWord.Substring(2), NmeaCultureInfo); LatitudeHemisphere latitudeHemisphere = words[1].Equals("N", StringComparison.OrdinalIgnoreCase) ? LatitudeHemisphere.North : LatitudeHemisphere.South; #endregion #region Longitude string longitudeWord = words[2]; int longitudeHours = int.Parse(longitudeWord.Substring(0, 3), NmeaCultureInfo); double longitudeDecimalMinutes = double.Parse(longitudeWord.Substring(3), NmeaCultureInfo); LongitudeHemisphere longitudeHemisphere = words[3].Equals("E", StringComparison.OrdinalIgnoreCase) ? LongitudeHemisphere.East : LongitudeHemisphere.West; #endregion #region Position _Position = new Position( new Latitude(latitudeHours, latitudeDecimalMinutes, latitudeHemisphere), new Longitude(longitudeHours, longitudeDecimalMinutes, longitudeHemisphere)); #endregion } // Do we have enough data to process the UTC time? if (wordCount >= 5 && words[4].Length != 0) { #region UTC Time string utcTimeWord = words[4]; int utcHours = int.Parse(utcTimeWord.Substring(0, 2), NmeaCultureInfo); int utcMinutes = int.Parse(utcTimeWord.Substring(2, 2), NmeaCultureInfo); int utcSeconds = int.Parse(utcTimeWord.Substring(4, 2), NmeaCultureInfo); int utcMilliseconds = 0; if (utcTimeWord.Length > 6) { utcMilliseconds = Convert.ToInt32(float.Parse(utcTimeWord.Substring(6), NmeaCultureInfo) * 1000, NmeaCultureInfo); } // Build a TimeSpan for this value _UtcTime = new TimeSpan(0, utcHours, utcMinutes, utcSeconds, utcMilliseconds); #endregion } else { // The UTC time is invalid _UtcTime = TimeSpan.MinValue; } // Do we have enough data to get the fix status? if (wordCount >= 6 && words[5].Length != 0) { #region Fix Status // An "A" means a valid fix _FixStatus = words[5].Equals("A", StringComparison.OrdinalIgnoreCase) ? FixStatus.Fix : FixStatus.NoFix; #endregion } else { // The fix status is invalid _FixStatus = FixStatus.Unknown; } }
/// <summary> /// Called when [sentence changed]. /// </summary> /// <remarks></remarks> protected override void OnSentenceChanged() { // Process the basic sentence elements base.OnSentenceChanged(); // Cache the word array string[] words = Words; int wordCount = words.Length; // Do we have enough words to parse the UTC date/time? if (wordCount >= 2 && words[0].Length != 0 && words[1].Length != 0) { #region Parse the UTC time string utcTimeWord = words[0]; int utcHours = 0; int utcMinutes = 0; int utcSeconds = 0; int utcMilliseconds = 0; int.TryParse(utcTimeWord.Substring(0, 2), out utcHours); int.TryParse(utcTimeWord.Substring(2, 2), out utcMinutes); int.TryParse(utcTimeWord.Substring(4, 2), out utcSeconds); try { utcMilliseconds = Convert.ToInt32(float.Parse(utcTimeWord.Substring(6), NmeaCultureInfo) * 1000, NmeaCultureInfo); } catch (Exception) { } #endregion Parse the UTC time #region Parse the UTC date string utcDateWord = words[1]; int utcMonth = 0; int utcDay = 0; int utcYear = 0; int.TryParse(utcDateWord.Substring(0, 2), out utcMonth); int.TryParse(utcDateWord.Substring(2, 2), out utcDay); int.TryParse(utcDateWord.Substring(4, 2), out utcYear); utcYear += 2000; #endregion Parse the UTC date #region Build a UTC date/time _utcDateTime = new DateTime(utcYear, utcMonth, utcDay, utcHours, utcMinutes, utcSeconds, utcMilliseconds, DateTimeKind.Utc); #endregion Build a UTC date/time } else { // The UTC date/time is invalid _utcDateTime = DateTime.MinValue; } // Do we have enough data to parse the location? if (wordCount >= 6 && words[2].Length != 0 && words[3].Length != 0 && words[4].Length != 0 && words[5].Length != 0) { #region Parse the latitude string latitudeWord = words[2]; int latitudeHours = 0; double latitudeDecimalMinutes = 0.0; int.TryParse(latitudeWord.Substring(0, 2), out latitudeHours); double.TryParse(latitudeWord.Substring(2), out latitudeDecimalMinutes); LatitudeHemisphere latitudeHemisphere = words[3].Equals("N", StringComparison.OrdinalIgnoreCase) ? LatitudeHemisphere.North : LatitudeHemisphere.South; #endregion Parse the latitude #region Parse the longitude string longitudeWord = words[4]; int longitudeHours = 0; double longitudeDecimalMinutes = 0.0; int.TryParse(longitudeWord.Substring(0, 3), out longitudeHours); double.TryParse(longitudeWord.Substring(3), out longitudeDecimalMinutes); LongitudeHemisphere longitudeHemisphere = words[5].Equals("E", StringComparison.OrdinalIgnoreCase) ? LongitudeHemisphere.East : LongitudeHemisphere.West; #endregion Parse the longitude #region Build a Position from the latitude and longitude _position = new Position( new Latitude(latitudeHours, latitudeDecimalMinutes, latitudeHemisphere), new Longitude(longitudeHours, longitudeDecimalMinutes, longitudeHemisphere)); #endregion Build a Position from the latitude and longitude } // Do we have enough data for the fix quality? if (wordCount > 7 && words[7].Length != 0) { switch (Convert.ToInt32(words[7], NmeaCultureInfo)) { case 0: _fixQuality = FixQuality.NoFix; break; case 1: _fixQuality = FixQuality.GpsFix; break; case 2: _fixQuality = FixQuality.DifferentialGpsFix; break; case 3: _fixQuality = FixQuality.PulsePerSecond; break; case 4: _fixQuality = FixQuality.FixedRealTimeKinematic; break; case 5: _fixQuality = FixQuality.FloatRealTimeKinematic; break; case 6: _fixQuality = FixQuality.Estimated; break; case 7: _fixQuality = FixQuality.ManualInput; break; case 8: _fixQuality = FixQuality.Simulated; break; default: _fixQuality = FixQuality.Unknown; break; } } else { // The fix quality is invalid _fixQuality = FixQuality.Unknown; } // Process the fixed satellite count //_fixedSatelliteCount = wordCount > 8 ? int.Parse(Words[8], NmeaCultureInfo) : 0; // Process the mean DOP if (wordCount > 9 && Words[9].Length != 0) { try { _meanDilutionOfPrecision = new DilutionOfPrecision(float.Parse(Words[9], NmeaCultureInfo)); } catch (Exception) { _meanDilutionOfPrecision = DilutionOfPrecision.Maximum; } } else { _meanDilutionOfPrecision = DilutionOfPrecision.Maximum; } // Altitude above ellipsoid if (wordCount > 10 && Words[10].Length != 0) { try { _altitudeAboveEllipsoid = new Distance(double.Parse(Words[10], NmeaCultureInfo), DistanceUnit.Meters).ToLocalUnitType(); } catch (Exception) { _altitudeAboveEllipsoid = Distance.Empty; } } else { _altitudeAboveEllipsoid = Distance.Empty; } }