'Convert Integer Formatted Degrees Decimal Minutes to Decimal Degrees (strange usecase)
I have a radio with GPS APRS that's storing a fixed location as a 4 byte integer and I'm trying to retrieve them back as decimal degrees.
The software for the radio will display the value as a unintuitive decimal. e.g 12° 34.567 is displayed as 12.34567. Which makes it look like it's in decimal degrees, but it's really degrees decimal minutes.
Ideally I want to read the 4 bytes as an int32 and convert them back to DDM, then to DD and back to int32 to pass to the radio. I have managed to do just that but there is cases where it doesn't return the correct value. I've tried dividing the integer based on number of digits. 1234567 / 100000 = 12.34567 or 123456 / 10000 = 12.3456 but that doesn't always work.
Sample code will generate a random set of DD co-ordinates, convert them to the Int32 format the radio uses and then attempts to get the DD co-ordinates back.. which works about 50% of the time.
Using substrings obviously isn't the way to go about it but as mention, I have tried using division and can get the same results as the code below but still fails too often to be reliable. I'm probably overlooking something simple but trying to get a decimal from an integer when it can be 1.0, 10.0 or 100.0 doesn't seem very intuitive :)
//Generate a random set of DD co-ordinates
double Lat_DD = Math.Round(GetRandomNumber(-89.99999, 89.99999), 5); textBox2.Text = Lat_DD.ToString();
double Long_DD = Math.Round(GetRandomNumber(-179.99999, 179.99999), 5); textBox3.Text = Long_DD.ToString();
//Get N_S_E_W direction
string Lat_N_S = (Lat_DD >= 0 ? "N" : "S");
string Long_E_W = (Long_DD >= 0 ? "E" : "W");
//Make negative co-ordinate positive
Lat_DD = Math.Abs(Lat_DD);
Long_DD = Math.Abs(Long_DD);
//Get degrees
int lat_degrees = (int)Math.Truncate(Lat_DD);
int long_degrees = (int)Math.Truncate(Long_DD);
//Get decimal minutes
double lat_decimal_minutes = Math.Truncate(Math.Round((Lat_DD - lat_degrees) * 60.0, 3) * 100.0);
double long_decimal_minutes = Math.Truncate(Math.Round((Long_DD - long_degrees) * 60.0, 3) * 100.0);
//Format degrees + decimal minutes as int32
int lat_ddm = Convert.ToInt32(string.Format("{0}{1}", lat_degrees, lat_decimal_minutes));
int lon_ddm = Convert.ToInt32(string.Format("{0}{1}", long_degrees, long_decimal_minutes));
//Show the result in textboxes
textBox4.Text = lat_ddm + " " + Lat_N_S;
textBox5.Text = lon_ddm + " " + Long_E_W;
//Get decimal minutes from the int32 DDM - probably not the way to do it :)
double latddm = Convert.ToDouble(lat_ddm.ToString().Substring(lat_ddm.ToString().Length - 4, 4));
double londdm = Convert.ToDouble(lon_ddm.ToString().Substring(lon_ddm.ToString().Length - 4, 4));
//Left over values = degrees
double latd = Convert.ToDouble(lat_ddm.ToString().Replace(latddm.ToString(),""));
double lond = Convert.ToDouble(lon_ddm.ToString().Replace(londdm.ToString(), ""));
//Calculate decimal
latddm = Math.Truncate(Math.Round((latddm / 60.0), 3) * 1000.0);
londdm = Math.Truncate(Math.Round((londdm / 60.0), 3) * 1000.0);
//Make degrees negative if S or W
if (Lat_N_S=="S") latd = latd * -1;
if (Long_E_W == "W") lond = lond * -1;
//Show the decimal degrees result
textBox6.Text = string.Format("{0}.{1}", latd, latddm);
textBox7.Text = string.Format("{0}.{1}", lond, londdm);
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
