0 Replies Latest reply on Oct 14, 2014 8:57 PM by Tom McGinn-Oracle

# Calculating GPS latitude/longitude from NMEA strings

It has long bugged me that the cgps tool shows accurate position data (longitude and latitude) that doesn't match the NMEA strings at all.

For example, suppose that the NMEA string values for a position are as follows:

3218.0489, N, 6447.5086, W

In the code examples we provided in the MOOC, we simply divided the double value of the string by 100, thinking the NMEA strings are decimal degree values.

However, plug 32.180489 N and 64.475086 W into Google maps and you end up some where in the Atlantic ocean.  Well, that's not right!

As it turns out, the NMEA strings are decimal-decimal values.  In order to turn them into decimal degree values, you have to do some math:

32 18.0489 N = 32 degrees + 18.0489 / 60 = 32.300815 N

64 47.5086 W = 64 degrees + 47.5086 / 60 = 64.79181 W

Plug those values into Google maps, and voila!  The real location is on the island of Bermuda.

Now, you may also want to represent the values using degrees/minutes/seconds. The math to do that is fairly simple:

32.300815 = 32 degrees

.300815 * 60 = 18.0489 = 18 minutes

.0489 * 60 = 2.934 seconds

Which can be written as: 32° 18' 2.9"

Here's the code to convert the NMEA decimal-decimal values to degrees/minutes/seconds:

```    /*
* Convert a NMEA decimal-decimal degree value into degrees/minutes/seconds
* First. convert the decimal-decimal value to a decimal:
* 5144.3855 (ddmm.mmmm) = 51 44.3855 = 51 + 44.3855/60 = 51.7397583 degrees
*
* Then convert the decimal to degrees, minutes seconds:
* 51 degress + .7397583 * 60 = 44.385498 = 44 minutes
* .385498 = 23.1 seconds
* Result: 51 44' 23.1"
*
* @return String value of the decimal degree, using the proper units
*/
private String decimalToDMS(double value) {
String result = null;
double degValue = value / 100;
int degrees = (int) degValue;
double decMinutesSeconds = ((degValue - degrees)) / .60;
double minuteValue = decMinutesSeconds * 60;
int minutes = (int) minuteValue;
double secsValue = (minuteValue - minutes) * 60;
result = degrees + "\u00B0" + " " + minutes + "' " + String.format("%.1f", secsValue) + "\" ";
return result;
}
```

Enjoy!

Tom