]> git.street.me.uk Git - andy/viking.git/blob - src/degrees_converters.c
add dec -> DMM conversion
[andy/viking.git] / src / degrees_converters.c
1 #include <math.h>
2 #include <glib.h>
3 #include <stdio.h>
4 #include <string.h>
5
6 /**
7  * @param pos_c char for positive value
8  * @param neg_c char for negative value
9  */
10 static gchar *convert_dec_to_dmm(gdouble dec, gchar pos_c, gchar neg_c)
11 {
12   gdouble tmp;
13   gchar sign_c = ' ';
14   gint val_d;
15   gdouble val_m;
16   gchar *result = NULL;
17
18   if ( dec > 0 )
19     sign_c = pos_c;
20   else if ( dec < 0 )
21     sign_c = neg_c;
22   else /* Nul value */
23     sign_c = ' ';
24
25   /* Degree */
26   tmp = fabs(dec);
27   val_d = (gint)tmp;
28
29   /* Minutes */
30   val_m = (tmp - val_d) * 60;
31
32   /* Format */
33   /* TODO : replace "°" as UTF-8 */
34   result = g_strdup_printf ( "%c%d°%f'",
35                              sign_c, val_d, val_m );
36   return result;
37 }
38
39 gchar *convert_lat_dec_to_dmm(gdouble lat)
40 {
41   return convert_dec_to_dmm(lat, 'N', 'S');
42 }
43
44 gchar *convert_lon_dec_to_dmm(gdouble lon)
45 {
46   return convert_dec_to_dmm(lon, 'E', 'W');
47 }
48
49 /**
50  * @param pos_c char for positive value
51  * @param neg_c char for negative value
52  */
53 static gchar *convert_dec_to_dms(gdouble dec, gchar pos_c, gchar neg_c)
54 {
55   gdouble tmp;
56   gchar sign_c = ' ';
57   gint val_d, val_m;
58   gdouble val_s;
59   gchar *result = NULL;
60
61   if ( dec > 0 )
62     sign_c = pos_c;
63   else if ( dec < 0 )
64     sign_c = neg_c;
65   else /* Nul value */
66     sign_c = ' ';
67
68   /* Degree */
69   tmp = fabs(dec);
70   val_d = (gint)tmp;
71
72   /* Minutes */
73   tmp = (tmp - val_d) * 60;
74   val_m = (gint)tmp;
75
76   /* Minutes */
77   val_s = (tmp - val_m) * 60;
78
79   /* Format */
80   /* TODO : replace "°" as UTF-8 */
81   result = g_strdup_printf ( "%c%d°%d'%f\"",
82                              sign_c, val_d, val_m, val_s );
83   return result;
84 }
85
86 gchar *convert_lat_dec_to_dms(gdouble lat)
87 {
88   return convert_dec_to_dms(lat, 'N', 'S');
89 }
90
91 gchar *convert_lon_dec_to_dms(gdouble lon)
92 {
93   return convert_dec_to_dms(lon, 'E', 'W');
94 }
95
96 gdouble convert_dms_to_dec(const gchar *dms)
97 {
98         gdouble d = 0.0; /* Degree */
99         gdouble m = 0.0; /* Minutes */
100         gdouble s = 0.0; /* Seconds */
101         gint neg = FALSE;
102         gdouble result;
103         
104         if (dms != NULL) {
105                 int nbFloat = 0;
106                 const gchar *ptr, *endptr;
107
108                 // Compute the sign
109                 // It is negative if:
110                 // - the '-' sign occurs
111                 // - it is a west longitude or south latitude
112                 if (strpbrk (dms, "-wWsS") != NULL)
113                     neg = TRUE;
114
115                 // Peek the différent components
116                 endptr = dms;
117                 do {
118                         gdouble value;
119                         ptr = strpbrk (endptr, "0123456789,.");
120                         if (ptr != NULL) {
121                                 value = g_strtod(ptr, &endptr);
122                         nbFloat++;
123                 switch(nbFloat) {
124                         case 1:
125                                 d = value;
126                                 break;
127                         case 2:
128                                 m = value;
129                                 break;
130                         case 3:
131                                 s = value;
132                                 break;
133                 }
134                         }
135                 } while (ptr != NULL && endptr != NULL);
136         }
137         
138         // Compute the result
139         result = d + m/60 + s/3600;
140         
141         if (neg) result = - result;
142         
143         return result;
144 }