Monday, 20 November 2017

Many coordinate systems

private decimal _latitude;
public decimal Latitude
{
   get
   {
      return _latitude;
   }
   set
   {
      if (value < -90.0M || value > 90.0M)
      {
          throw new ArgumentOutOfRangeException("Latitude must be between -90.0 and 90.0.");
      }
   
       _latitude = value;
    }
}

private decimal _longitude;
public decimal Longitude
{
   get
   {
       return _longitude;
   }
   set
   {
       if (value < -180.0M || value > 180.0M)
       {
           throw new ArgumentOutOfRangeException("Longitude must be between -180.0 and 180.0.");
       }
   
   _longitude = value;
   }
}

public static GeoCoordinates FromNMEA0183(string degrees)
{
   if (string.IsNullOrEmpty(degrees))
   {
      throw new ArgumentNullException(nameof(degrees));
   }
   
   string[] coords = degrees.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
   
   if (coords.Length < 2)
   {
      throw new ArgumentException("Invalid degree coordinates.", nameof(degrees));
   }
...
   return new GeoCoordinates
   {
      Latitude = ParseLatitude(coords[0].Trim()),
      Longitude = ParseLongitude(coords[1].Trim())
   };
}

private static decimal ParseLatitude(string coords)
{
    if (!coords.EndsWith("N", StringComparison.OrdinalIgnoreCase) && !coords.EndsWith("S", StringComparison.OrdinalIgnoreCase))
    {
        throw new ArgumentException("Latitude coordinate not found.");
    }

    if (coords.Length < 4)
    {
        throw new ArgumentException("Invalid latitude format.");
    }
   
    int dd = 0;
    try
    {
        dd = int.Parse(coords.Substring(0, 2));
        if (dd > 90)
        {
            throw new ArgumentOutOfRangeException();
        }
    }
    catch when (dd > 90)
    {
        throw new ArgumentOutOfRangeException("Degrees in latitude cannot exceed 90.");
    }
    catch
    {
        throw new ArgumentException("Invalid degrees format in latitude.");
    }
   
    double mm = 0.0D;
    try
    {
        string minutes = Regex.Match(coords.Substring(2), @"(\d+).(\d+)").Value;
        mm = double.Parse(minutes);
        if ((dd == 90 && mm > 0.0D) || mm >= 60.0D)
        {
            throw new ArgumentOutOfRangeException();
        }
    }
    catch when (dd == 90 && mm > 0.0D)
    {
        throw new ArgumentOutOfRangeException("Degrees in latitude cannot exceed 90.");
    }
    catch when (mm >= 60.0D)
    {
        throw new ArgumentOutOfRangeException("Minutes in latitude cannot exceed 60.");
    }
    catch
    {
        throw new ArgumentException("Invalid minutes format in latitude.");
    }
   
    decimal latitude = Convert.ToDecimal(dd + mm / 60);
    if (coords.EndsWith("S", StringComparison.OrdinalIgnoreCase))
    {
        latitude = decimal.Negate(latitude);
    }

    return latitude;
}

dd = int.Parse(coords.Substring(0, 2));
if (dd > 90)
{
    throw new ArgumentOutOfRangeException();
}

string minutes = Regex.Match(coords.Substring(2), @"(\d+).(\d+)").Value;
mm = double.Parse(minutes);
if ((dd == 90 && mm > 0.0D) || mm >= 60.0D)
{
    throw new ArgumentOutOfRangeException();
}

private string FormatLatitudeDegrees(decimal latitude)
{
    string sign = latitude > 0 ? "N" : "S";

    latitude = Math.Abs(latitude);
    string dd = decimal.Truncate(latitude).ToString("0#");
    string mm = (decimal.Subtract(latitude, decimal.Truncate(latitude)) * 60).ToString("0#.0000");

    return $"{dd}{mm} {sign}";
}

private string FormatLongitudeDegrees(decimal longitude)
{
    string sign = longitude > 0 ? "E" : "W";

    longitude = Math.Abs(longitude);
    string dd = decimal.Truncate(longitude).ToString("00#");
    string mm = (decimal.Subtract(longitude, decimal.Truncate(longitude)) * 60).ToString("0#.0000");

    return $"{dd}{mm} {sign}";

No comments:

Post a Comment