]> git.street.me.uk Git - andy/viking.git/blob - src/degrees_converters.c
Diasable buttons on Track Properties Dialog when not needed.
[andy/viking.git] / src / degrees_converters.c
1 /*
2  * viking -- GPS Data and Topo Analyzer, Explorer, and Manager
3  *
4  * Copyright (C) 2006-2007, Guilhem Bonnefille <guilhem.bonnefille@gmail.com>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  */
21
22 #include <math.h>
23 #include <glib.h>
24 #include <stdio.h>
25 #include <string.h>
26
27 /**
28  * @param pos_c char for positive value
29  * @param neg_c char for negative value
30  */
31 static gchar *convert_dec_to_ddd(gdouble dec, gchar pos_c, gchar neg_c)
32 {
33   gchar sign_c = ' ';
34   gdouble val_d;
35   gchar *result = NULL;
36
37   if ( dec > 0 )
38     sign_c = pos_c;
39   else if ( dec < 0 )
40     sign_c = neg_c;
41   else /* Nul value */
42     sign_c = ' ';
43
44   /* Degree */
45   val_d = fabs(dec);
46
47   /* Format */
48   /* TODO : replace "°" as UTF-8 */
49   result = g_strdup_printf ( "%c%f°", sign_c, val_d );
50   return result;
51 }
52
53 gchar *convert_lat_dec_to_ddd(gdouble lat)
54 {
55   return convert_dec_to_ddd(lat, 'N', 'S');
56 }
57
58 gchar *convert_lon_dec_to_ddd(gdouble lon)
59 {
60   return convert_dec_to_ddd(lon, 'E', 'W');
61 }
62
63 /**
64  * @param pos_c char for positive value
65  * @param neg_c char for negative value
66  */
67 static gchar *convert_dec_to_dmm(gdouble dec, gchar pos_c, gchar neg_c)
68 {
69   gdouble tmp;
70   gchar sign_c = ' ';
71   gint val_d;
72   gdouble val_m;
73   gchar *result = NULL;
74
75   if ( dec > 0 )
76     sign_c = pos_c;
77   else if ( dec < 0 )
78     sign_c = neg_c;
79   else /* Nul value */
80     sign_c = ' ';
81
82   /* Degree */
83   tmp = fabs(dec);
84   val_d = (gint)tmp;
85
86   /* Minutes */
87   val_m = (tmp - val_d) * 60;
88
89   /* Format */
90   /* TODO : replace "°" as UTF-8 */
91   result = g_strdup_printf ( "%c%d°%f'",
92                              sign_c, val_d, val_m );
93   return result;
94 }
95
96 gchar *convert_lat_dec_to_dmm(gdouble lat)
97 {
98   return convert_dec_to_dmm(lat, 'N', 'S');
99 }
100
101 gchar *convert_lon_dec_to_dmm(gdouble lon)
102 {
103   return convert_dec_to_dmm(lon, 'E', 'W');
104 }
105
106 /**
107  * @param pos_c char for positive value
108  * @param neg_c char for negative value
109  */
110 static gchar *convert_dec_to_dms(gdouble dec, gchar pos_c, gchar neg_c)
111 {
112   gdouble tmp;
113   gchar sign_c = ' ';
114   gint val_d, val_m;
115   gdouble val_s;
116   gchar *result = NULL;
117
118   if ( dec > 0 )
119     sign_c = pos_c;
120   else if ( dec < 0 )
121     sign_c = neg_c;
122   else /* Nul value */
123     sign_c = ' ';
124
125   /* Degree */
126   tmp = fabs(dec);
127   val_d = (gint)tmp;
128
129   /* Minutes */
130   tmp = (tmp - val_d) * 60;
131   val_m = (gint)tmp;
132
133   /* Minutes */
134   val_s = (tmp - val_m) * 60;
135
136   /* Format */
137   /* TODO : replace "°" as UTF-8 */
138   result = g_strdup_printf ( "%c%d°%d'%f\"",
139                              sign_c, val_d, val_m, val_s );
140   return result;
141 }
142
143 gchar *convert_lat_dec_to_dms(gdouble lat)
144 {
145   return convert_dec_to_dms(lat, 'N', 'S');
146 }
147
148 gchar *convert_lon_dec_to_dms(gdouble lon)
149 {
150   return convert_dec_to_dms(lon, 'E', 'W');
151 }
152
153 gdouble convert_dms_to_dec(const gchar *dms)
154 {
155         gdouble d = 0.0; /* Degree */
156         gdouble m = 0.0; /* Minutes */
157         gdouble s = 0.0; /* Seconds */
158         gint neg = FALSE;
159         gdouble result;
160         
161         if (dms != NULL) {
162                 int nbFloat = 0;
163                 const gchar *ptr, *endptr;
164
165                 // Compute the sign
166                 // It is negative if:
167                 // - the '-' sign occurs
168                 // - it is a west longitude or south latitude
169                 if (strpbrk (dms, "-wWsS") != NULL)
170                     neg = TRUE;
171
172                 // Peek the différent components
173                 endptr = dms;
174                 do {
175                         gdouble value;
176                         ptr = strpbrk (endptr, "0123456789,.");
177                         if (ptr != NULL) {
178                                 value = g_strtod(ptr, &endptr);
179                         nbFloat++;
180                 switch(nbFloat) {
181                         case 1:
182                                 d = value;
183                                 break;
184                         case 2:
185                                 m = value;
186                                 break;
187                         case 3:
188                                 s = value;
189                                 break;
190                 }
191                         }
192                 } while (ptr != NULL && endptr != NULL);
193         }
194         
195         // Compute the result
196         result = d + m/60 + s/3600;
197         
198         if (neg) result = - result;
199         
200         return result;
201 }