/// <summary> /// Parse a text to a GPS location. /// </summary> /// <param name="text">the text to parse</param> /// <param name="format">the format to use, to determine the decimal separator</param> /// <param name="result">the parsed GPS location</param> internal static bool TryParse(string text, NumberFormatInfo format, out GpsLocation result) { var parser = new GpsLocationParser(text, format); var parsed = parser.Execute(); result = parsed.Item2; return(parsed.Item1); }
private Tuple <bool, GpsLocation> Execute() { var invalid = Tuple.Create(false, new GpsLocation()); var latitude = 0.0; var longitude = 0.0; if (HasDegreeSymbol) { (var lat, var lon) = SplitOnNorthSouth(Text); var latPos = IsPositive(lat); var lonPos = IsPositive(lon); (var latDeg, var latDegRest) = SplitOnDegreeSymbol(lat); (var lonDeg, var lonDegRest) = SplitOnDegreeSymbol(lon); if (HasMinuteSymbol) { if (!TryParsePositiveInteger(latDeg, out var dLatDeg)) { return(invalid); } if (!TryParsePositiveInteger(lonDeg, out var dLonDeg)) { return(invalid); } latitude += dLatDeg; longitude += dLonDeg; (var latMin, var latMinRest) = SplitOnMinuteSymbol(latDegRest); (var lonMin, var lonMinRest) = SplitOnMinuteSymbol(lonDegRest); if (HasSecondSymbol) { if (!TryParsePositiveInteger(latMin, out var dLatMin)) { return(invalid); } if (!TryParsePositiveInteger(lonMin, out var dLonMin)) { return(invalid); } latitude += (dLatMin / 60.0); longitude += (dLonMin / 60.0); // degrees, minutes, seconds // 40° 26′ 46″ N 79° 58′ 56″ W var latSec = SplitOnSecondSymbol(latMinRest); var lonSec = SplitOnSecondSymbol(lonMinRest); if (!TryParsePositiveFloat(latSec, out var dLatSec)) { return(invalid); } if (!TryParsePositiveFloat(lonSec, out var dLonSec)) { return(invalid); } latitude += (dLatSec / 3600.0); longitude += (dLonSec / 3600.0); } else { if (!TryParsePositiveFloat(latMin, out var dLatMin)) { return(invalid); } if (!TryParsePositiveFloat(lonMin, out var dLonMin)) { return(invalid); } latitude += (dLatMin / 60.0); longitude += (dLonMin / 60.0); } } else { if (!TryParsePositiveFloat(latDeg, out var dLatDeg)) { return(invalid); } if (!TryParsePositiveFloat(lonDeg, out var dLonDeg)) { return(invalid); } latitude += dLatDeg; longitude += dLonDeg; } latitude *= latPos; longitude *= lonPos; } else { if (HasDirection) { // decimal format with direction // 40.55 N 79.95 W (var lat, var lon) = SplitOnNorthSouth(Text); var latPos = IsPositive(lat); var lonPos = IsPositive(lon); if (!TryParsePositiveFloat(lat, out latitude)) { return(invalid); } if (!TryParsePositiveFloat(lon, out longitude)) { return(invalid); } latitude *= latPos; longitude *= lonPos; } else { // decimal format with direction // -40.55 79.95 (var lat, var lon) = SplitOnSeparatorSymbol(Text); if (!TryParseFloat(lat, out latitude)) { return(invalid); } if (!TryParseFloat(lon, out longitude)) { return(invalid); } } } if (!GpsLocation.ValidateLatitude(latitude)) { return(invalid); } if (!GpsLocation.ValidateLongitude(longitude)) { return(invalid); } return(Tuple.Create(true, new GpsLocation(latitude, longitude))); }