X-Git-Url: https://git.street.me.uk/andy/viking.git/blobdiff_plain/f88152fe4399c4a26ce70af5cd9154a5e1883cf9..0a25e23214e753d9190e33e58b23685783099bd5:/src/degrees_converters.c diff --git a/src/degrees_converters.c b/src/degrees_converters.c index 53fd1755..9e55a399 100644 --- a/src/degrees_converters.c +++ b/src/degrees_converters.c @@ -1,7 +1,111 @@ +/* + * viking -- GPS Data and Topo Analyzer, Explorer, and Manager + * + * Copyright (C) 2006-2007, Guilhem Bonnefille + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef HAVE_MATH_H #include -#include +#endif +#include +#include "degrees_converters.h" + +#define DEGREE_SYMBOL "\302\260" + +/** + * @param pos_c char for positive value + * @param neg_c char for negative value + */ +static gchar *convert_dec_to_ddd(gdouble dec, gchar pos_c, gchar neg_c) +{ + gchar sign_c = ' '; + gdouble val_d; + gchar *result = NULL; + + if ( dec > 0 ) + sign_c = pos_c; + else if ( dec < 0 ) + sign_c = neg_c; + else /* Nul value */ + sign_c = ' '; + + /* Degree */ + val_d = fabs(dec); + + /* Format */ + result = g_strdup_printf ( "%c%f" DEGREE_SYMBOL, sign_c, val_d ); + return result; +} + +gchar *convert_lat_dec_to_ddd(gdouble lat) +{ + return convert_dec_to_ddd(lat, 'N', 'S'); +} + +gchar *convert_lon_dec_to_ddd(gdouble lon) +{ + return convert_dec_to_ddd(lon, 'E', 'W'); +} + +/** + * @param pos_c char for positive value + * @param neg_c char for negative value + */ +static gchar *convert_dec_to_dmm(gdouble dec, gchar pos_c, gchar neg_c) +{ + gdouble tmp; + gchar sign_c = ' '; + gint val_d; + gdouble val_m; + gchar *result = NULL; -#include + if ( dec > 0 ) + sign_c = pos_c; + else if ( dec < 0 ) + sign_c = neg_c; + else /* Nul value */ + sign_c = ' '; + + /* Degree */ + tmp = fabs(dec); + val_d = (gint)tmp; + + /* Minutes */ + val_m = (tmp - val_d) * 60; + + /* Format */ + result = g_strdup_printf ( "%c%d" DEGREE_SYMBOL "%f'", + sign_c, val_d, val_m ); + return result; +} + +gchar *convert_lat_dec_to_dmm(gdouble lat) +{ + return convert_dec_to_dmm(lat, 'N', 'S'); +} + +gchar *convert_lon_dec_to_dmm(gdouble lon) +{ + return convert_dec_to_dmm(lon, 'E', 'W'); +} /** * @param pos_c char for positive value @@ -15,7 +119,6 @@ static gchar *convert_dec_to_dms(gdouble dec, gchar pos_c, gchar neg_c) gdouble val_s; gchar *result = NULL; - /* North ? South ? */ if ( dec > 0 ) sign_c = pos_c; else if ( dec < 0 ) @@ -31,12 +134,11 @@ static gchar *convert_dec_to_dms(gdouble dec, gchar pos_c, gchar neg_c) tmp = (tmp - val_d) * 60; val_m = (gint)tmp; - /* Minutes */ + /* Seconds */ val_s = (tmp - val_m) * 60; /* Format */ - /* TODO : replace "°" as UTF-8 */ - result = g_strdup_printf ( "%c%d°%d'%f\"", + result = g_strdup_printf ( "%c%d" DEGREE_SYMBOL "%d'%.4f\"", sign_c, val_d, val_m, val_s ); return result; } @@ -61,7 +163,7 @@ gdouble convert_dms_to_dec(const gchar *dms) if (dms != NULL) { int nbFloat = 0; - gchar *ptr, *endptr; + const gchar *ptr, *endptr; // Compute the sign // It is negative if: @@ -76,8 +178,13 @@ gdouble convert_dms_to_dec(const gchar *dms) gdouble value; ptr = strpbrk (endptr, "0123456789,."); if (ptr != NULL) { - value = g_strtod(ptr, &endptr); - nbFloat++; + const gchar *tmpptr = endptr; + value = g_strtod((const gchar *)ptr, (gchar **)&endptr); + // Detect when endptr hasn't changed (which may occur if no conversion took place) + // particularly if the last character is a ',' or there are multiple '.'s like '5.5.' + if ( endptr == tmpptr ) + break; + nbFloat++; switch(nbFloat) { case 1: d = value; @@ -88,6 +195,7 @@ gdouble convert_dms_to_dec(const gchar *dms) case 3: s = value; break; + default: break; } } } while (ptr != NULL && endptr != NULL);