public static NmeaMessage Create(string address, string data) { switch (address) { case "GPRMC": NmeaGpRmcMessage gpRmcMessage; if (NmeaGpRmcMessage.TryParse(data, out gpRmcMessage)) { return(gpRmcMessage); } throw new FormatException("Failed to parse GPRMC message data."); case "GPGGA": NmeaGpGgaMessage gpGgaMessage; if (NmeaGpGgaMessage.TryParse(data, out gpGgaMessage)) { return(gpGgaMessage); } throw new FormatException("Failed to parse GPGGA message data."); default: return(new NmeaMessage(address, data)); } }
public static bool TryParse(string data, out NmeaGpGgaMessage message) { if (data == null) { throw new ArgumentNullException(nameof(data)); } string[] values = data.Split(','); if (values.Length != 14) { message = default(NmeaGpGgaMessage); return(false); } string timeUtcString = values[0]; string latitudeString = values[1]; string latitudeNS = values[2]; string longitudeString = values[3]; string longitudeEW = values[4]; string statusString = values[5]; string satellitesUsedString = values[6]; string horizontalDilutionOfPrecisionString = values[7]; string altitudeString = values[8]; string geoidSeparationString = values[10]; DateTime dateTimeUtc; decimal? latitude = null; decimal? longitude = null; bool statusIsValid; int? satellitesUsed = null; decimal? horizontalDilutionOfPrecision = null; decimal? altitude = null; decimal? geoidSeparation = null; if (!DateTime.TryParseExact(timeUtcString, "HHmmss.ff", CultureInfo.InvariantCulture, DateTimeStyles.AssumeLocal, out dateTimeUtc)) { message = default(NmeaGpGgaMessage); return(false); } if (!string.IsNullOrWhiteSpace(latitudeString) && !string.IsNullOrWhiteSpace(latitudeNS)) { decimal latitudeValue; bool south; if (!decimal.TryParse(latitudeString, NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out latitudeValue)) { message = default(NmeaGpGgaMessage); return(false); } switch (latitudeNS) { case "N": south = false; break; case "S": south = true; break; default: message = default(NmeaGpGgaMessage); return(false); } decimal degrees = Math.Floor(latitudeValue / 100m); decimal minutes = latitudeValue % 100; latitude = (south ? -1m : 1m) * (degrees + minutes / 60m); } if (!string.IsNullOrWhiteSpace(longitudeString) && !string.IsNullOrWhiteSpace(longitudeEW)) { decimal longitudeValue; bool west; if (!decimal.TryParse(longitudeString, NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out longitudeValue)) { message = default(NmeaGpGgaMessage); return(false); } switch (longitudeEW) { case "E": west = false; break; case "W": west = true; break; default: message = default(NmeaGpGgaMessage); return(false); } decimal degrees = Math.Floor(longitudeValue / 100m); decimal minutes = longitudeValue % 100; longitude = (west ? -1m : 1m) * (degrees + minutes / 60m); } switch (statusString) { case "0": statusIsValid = false; break; case "1": statusIsValid = true; break; default: message = default(NmeaGpGgaMessage); return(false); } if (!string.IsNullOrWhiteSpace(satellitesUsedString)) { int satellitesUsedValue; if (!int.TryParse(satellitesUsedString, NumberStyles.Integer, CultureInfo.InvariantCulture, out satellitesUsedValue)) { message = default(NmeaGpGgaMessage); return(false); } satellitesUsed = satellitesUsedValue; } if (!string.IsNullOrWhiteSpace(horizontalDilutionOfPrecisionString)) { decimal horizontalDilutionOfPrecisionValue; if (!decimal.TryParse(horizontalDilutionOfPrecisionString, NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out horizontalDilutionOfPrecisionValue)) { message = default(NmeaGpGgaMessage); return(false); } horizontalDilutionOfPrecision = horizontalDilutionOfPrecisionValue; } if (!string.IsNullOrWhiteSpace(altitudeString)) { decimal altitudeValue; if (!decimal.TryParse(altitudeString, NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out altitudeValue)) { message = default(NmeaGpGgaMessage); return(false); } altitude = altitudeValue; } if (!string.IsNullOrWhiteSpace(geoidSeparationString)) { decimal geoidSeparationValue; if (!decimal.TryParse(geoidSeparationString, NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out geoidSeparationValue)) { message = default(NmeaGpGgaMessage); return(false); } geoidSeparation = geoidSeparationValue; } message = new NmeaGpGgaMessage(data, dateTimeUtc.TimeOfDay, statusIsValid, latitude, longitude, satellitesUsed, horizontalDilutionOfPrecision, altitude, geoidSeparation); return(true); }