From d47077f3f089dfb90929c7a90d1ed39ab8e94098 Mon Sep 17 00:00:00 2001 From: "Gary E. Miller" Date: Mon, 28 Mar 2016 20:29:03 -0700 Subject: use more precision when outputting lat/lon. A cm level GPS needs decimal degrees to 0.0000001 --- cgps.c | 6 +++--- gpsdclient.c | 24 ++++++++++++++---------- libgps_core.c | 3 ++- 3 files changed, 19 insertions(+), 14 deletions(-) diff --git a/cgps.c b/cgps.c index f4a627cd..6395e751 100644 --- a/cgps.c +++ b/cgps.c @@ -643,9 +643,9 @@ static void usage(char *prog) " -V Show version, then exit\n" " -s Be silent (don't print raw gpsd data)\n" " -l {d|m|s} Select lat/lon format\n" - " d = DD.dddddd\n" - " m = DD MM.mmmm'\n" - " s = DD MM' SS.sss\"\n" + " d = DD.ddddddd\n" + " m = DD MM.mmmmmm'\n" + " s = DD MM' SS.sssss\"\n" " -m Display heading as the estimated magnetic heading\n" " Valid only for USA (Lower 48 + AK) and Western Europe.\n", prog); diff --git a/gpsdclient.c b/gpsdclient.c index 2ab7ff6a..b98f5265 100644 --- a/gpsdclient.c +++ b/gpsdclient.c @@ -31,9 +31,12 @@ static struct exportmethod_t exportmethods[] = { /* convert double degrees to a static string and return a pointer to it * * deg_str_type: - * deg_dd : return DD.dddddd - * deg_ddmm : return DD MM.mmmm' - * deg_ddmmss : return DD MM' SS.sss" + * deg_dd : return DD.ddddddd + * deg_ddmm : return DD MM.mmmmmm' + * deg_ddmmss : return DD MM' SS.sssss" + * + * for cm level accuracy we need degrees to 7 decimal places + * Ref: https://en.wikipedia.org/wiki/Decimal_degrees * */ char *deg_to_str(enum deg_str_type type, double f) @@ -50,27 +53,28 @@ char *deg_to_str(enum deg_str_type type, double f) fmin = modf(f, &fdeg); deg = (int)fdeg; - frac_deg = (long)(fmin * 1000000); + frac_deg = (long)(fmin * 10000000); if (deg_dd == type) { - /* DD.dddddd */ - (void)snprintf(str, sizeof(str), "%3d.%06ld", deg, frac_deg); + /* DD.ddddddd */ + /* cm level accuracy requires the %07ld */ + (void)snprintf(str, sizeof(str), "%3d.%07ld", deg, frac_deg); return str; } fsec = modf(fmin * 60, &fmin); min = (int)fmin; - sec = (int)(fsec * 10000.0); + sec = (int)(fsec * 1000000.0); if (deg_ddmm == type) { /* DD MM.mmmm */ - (void)snprintf(str, sizeof(str), "%3d %02d.%04d'", deg, min, sec); + (void)snprintf(str, sizeof(str), "%3d %02d.%06d'", deg, min, sec); return str; } /* else DD MM SS.sss */ fdsec = modf(fsec * 60, &fsec); sec = (int)fsec; - dsec = (int)(fdsec * 1000.0); - (void)snprintf(str, sizeof(str), "%3d %02d' %02d.%03d\"", deg, min, sec, + dsec = (int)(fdsec * 10000.0); + (void)snprintf(str, sizeof(str), "%3d %02d' %02d.%05d\"", deg, min, sec, dsec); return str; diff --git a/libgps_core.c b/libgps_core.c index 434ebcf1..582e2105 100644 --- a/libgps_core.c +++ b/libgps_core.c @@ -293,8 +293,9 @@ void libgps_dump_state(struct gps_data_t *collect) (void)fprintf(debugfp, "ONLINE: %lf\n", collect->online); if (collect->set & TIME_SET) (void)fprintf(debugfp, "TIME: %lf\n", collect->fix.time); + /* NOTE: %.7f needed for cm level accurate GPS */ if (collect->set & LATLON_SET) - (void)fprintf(debugfp, "LATLON: lat/lon: %lf %lf\n", + (void)fprintf(debugfp, "LATLON: lat/lon: %.7lf %.7lf\n", collect->fix.latitude, collect->fix.longitude); if (collect->set & ALTITUDE_SET) (void)fprintf(debugfp, "ALTITUDE: altitude: %lf U: climb: %lf\n", -- cgit v1.2.1