]> git.street.me.uk Git - andy/viking.git/blob - src/vikutils.c
Remove compiler warning on 32bit systems.
[andy/viking.git] / src / vikutils.c
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2 /*
3  * viking -- GPS Data and Topo Analyzer, Explorer, and Manager
4  *
5  * Copyright (C) 2013, Rob Norris <rw_norris@hotmail.com>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  *
21  */
22 #include <math.h>
23 #include <glib/gi18n.h>
24
25 #include "viking.h"
26 #include "vikutils.h"
27
28 #define FMT_MAX_NUMBER_CODES 9
29
30 /**
31  * vu_trackpoint_formatted_message:
32  * @format_code:  String describing the message to generate
33  * @trkpt:        The trackpoint for which the message is generated about
34  * @trkpt_prev:   A trackpoint (presumed previous) for interpolating values with the other trackpoint (such as speed)
35  * @trk:          The track in which the trackpoints reside
36  *
37  *  TODO: One day replace this cryptic format code with some kind of tokenizer parsing
38  *    thus would make it more user friendly and maybe even GUI controlable.
39  * However for now at least there is some semblance of user control
40  */
41 gchar* vu_trackpoint_formatted_message ( gchar *format_code, VikTrackpoint *trkpt, VikTrackpoint *trkpt_prev, VikTrack *trk )
42 {
43         if ( !trkpt )
44                 return NULL;
45
46         gint len = 0;
47         if ( format_code )
48                 len = strlen ( format_code );
49         if ( len > FMT_MAX_NUMBER_CODES )
50                 len = FMT_MAX_NUMBER_CODES;
51
52         gchar* values[FMT_MAX_NUMBER_CODES];
53         int i;
54         for ( i = 0; i < FMT_MAX_NUMBER_CODES; i++ ) {
55                 values[i] = '\0';
56         }
57
58         gchar *speed_units_str = NULL;
59         vik_units_speed_t speed_units = a_vik_get_units_speed ();
60         switch (speed_units) {
61         case VIK_UNITS_SPEED_MILES_PER_HOUR:
62                 speed_units_str = g_strdup ( _("mph") );
63                 break;
64         case VIK_UNITS_SPEED_METRES_PER_SECOND:
65                 speed_units_str = g_strdup ( _("m/s") );
66                 break;
67         case VIK_UNITS_SPEED_KNOTS:
68                 speed_units_str = g_strdup ( _("knots") );
69                 break;
70         default:
71                 // VIK_UNITS_SPEED_KILOMETRES_PER_HOUR:
72                 speed_units_str = g_strdup ( _("km/h") );
73                 break;
74         }
75
76         gchar *separator = g_strdup ( " | " );
77
78         for ( i = 0; i < len; i++ ) {
79                 switch ( g_ascii_toupper ( format_code[i] ) ) {
80                 case 'G': values[i] = g_strdup ( _("GPSD") ); break; // GPS Preamble
81                 case 'K': values[i] = g_strdup ( _("Trkpt") ); break; // Trkpt Preamble
82
83                 case 'S': {
84                         gdouble speed = 0.0;
85                         gchar *speedtype = NULL;
86                         if ( !isnan(trkpt->speed) && trkpt_prev ) {
87                                 if ( trkpt->has_timestamp && trkpt_prev->has_timestamp ) {
88                                         if ( trkpt->timestamp == trkpt_prev->timestamp ) {
89
90                                                 // Work out from previous trackpoint location and time difference
91                                                 speed = vik_coord_diff(&(trkpt->coord), &(trkpt_prev->coord)) / ABS(trkpt->timestamp - trkpt_prev->timestamp);
92
93                                                 switch (speed_units) {
94                                                 case VIK_UNITS_SPEED_KILOMETRES_PER_HOUR:
95                                                         speed = VIK_MPS_TO_KPH(speed);
96                                                         break;
97                                                 case VIK_UNITS_SPEED_MILES_PER_HOUR:
98                                                         speed = VIK_MPS_TO_MPH(speed);
99                                                         break;
100                                                 case VIK_UNITS_SPEED_KNOTS:
101                                                         speed = VIK_MPS_TO_KNOTS(speed);
102                                                         break;
103                                                 default:
104                                                         // VIK_UNITS_SPEED_METRES_PER_SECOND:
105                                                         // Already in m/s so nothing to do
106                                                         break;
107                                                 }
108                                                 speedtype = g_strdup ( "*" ); // Interpolated
109                                         }
110                                         else
111                                                 speedtype = g_strdup ( "**" );
112                                 }
113                                 else
114                                         speedtype = g_strdup ( "**" );
115                         }
116                         else {
117                                 speed = trkpt->speed;
118                                 speedtype = g_strdup ( "" );
119                         }
120
121                         values[i] = g_strdup_printf ( _("%sSpeed%s %.1f%s"), separator, speedtype, speed, speed_units_str );
122                         g_free ( speedtype );
123                         break;
124                 }
125
126                 case 'A': {
127                         vik_units_height_t height_units = a_vik_get_units_height ();
128                         switch (height_units) {
129                         case VIK_UNITS_HEIGHT_FEET:
130                                 values[i] = g_strdup_printf ( _("%sAlt %dfeet"), separator, (int)round(VIK_METERS_TO_FEET(trkpt->altitude)) );
131                                 break;
132                         default:
133                                 //VIK_UNITS_HEIGHT_METRES:
134                                 values[i] = g_strdup_printf ( _("%sAlt %dm"), separator, (int)round(trkpt->altitude) );
135                                 break;
136                         }
137                         break;
138                 }
139
140                 case 'C': {
141                         gint heading = isnan(trkpt->course) ? 0 : (gint)round(trkpt->course);
142                         values[i] = g_strdup_printf ( _("%sCourse %03d\302\260" ), separator, heading );
143                         break;
144                 }
145
146                 case 'P': {
147                         if ( trkpt_prev ) {
148                                 gint diff = (gint) round ( vik_coord_diff ( &(trkpt->coord), &(trkpt_prev->coord) ) );
149
150                                 gchar *dist_units_str = NULL;
151                                 vik_units_distance_t dist_units = a_vik_get_units_distance ();
152                                 // expect the difference between track points to be small hence use metres or yards
153                                 switch (dist_units) {
154                                 case VIK_UNITS_DISTANCE_MILES:
155                                         dist_units_str = g_strdup ( _("yards") );
156                                         break;
157                                 default:
158                                         // VIK_UNITS_DISTANCE_KILOMETRES:
159                                         dist_units_str = g_strdup ( _("m") );
160                                         break;
161                                 }
162
163                                 values[i] = g_strdup_printf ( _("%sDistance diff %d%s"), separator, diff, dist_units_str );
164
165                                 g_free ( dist_units_str );
166                         }
167                         break;
168                 }
169
170                 case 'T': {
171                         gchar tmp[64];
172                         tmp[0] = '\0';
173                         if ( trkpt->has_timestamp ) {
174                                 // Compact date time format
175                                 strftime (tmp, sizeof(tmp), "%x %X", localtime(&(trkpt->timestamp)));
176                         }
177                         else
178                                 g_snprintf (tmp, sizeof(tmp), "--");
179                         values[i] = g_strdup_printf ( _("%sTime %s"), separator, tmp );
180                         break;
181                 }
182
183                 case 'M': {
184                         if ( trkpt_prev ) {
185                                 if ( trkpt->has_timestamp && trkpt_prev->has_timestamp ) {
186                                         time_t t_diff = trkpt->timestamp - trkpt_prev->timestamp;
187                                         values[i] = g_strdup_printf ( _("%sTime diff %lds"), separator, t_diff );
188                                 }
189                         }
190                         break;
191                 }
192
193                 case 'X': values[i] = g_strdup_printf ( _("%sNo. of Sats %d"), separator, trkpt->nsats ); break;
194
195                 case 'D': {
196                         if ( trk ) {
197                                 // Distance from start (along the track)
198                                 gdouble distd = vik_track_get_length_to_trackpoint (trk, trkpt);
199                                 gchar *dist_units_str = NULL;
200                                 vik_units_distance_t dist_units = a_vik_get_units_distance ();
201                                 // expect the difference between track points to be small hence use metres or yards
202                                 switch (dist_units) {
203                                 case VIK_UNITS_DISTANCE_MILES:
204                                         dist_units_str = g_strdup ( _("miles") );
205                                         distd = VIK_METERS_TO_MILES(distd);
206                                         break;
207                                 default:
208                                         // VIK_UNITS_DISTANCE_KILOMETRES:
209                                         dist_units_str = g_strdup ( _("km") );
210                                         distd = distd / 1000.0;
211                                         break;
212                                 }
213                                 values[i] = g_strdup_printf ( _("%sDistance along %.2f%s"), separator, distd, dist_units_str );
214                                 g_free ( dist_units_str );
215                         }
216                         break;
217                 }
218
219                 case 'L': {
220                         // Location (Lat/Long)
221                         gchar *lat = NULL, *lon = NULL;
222                         struct LatLon ll;
223                         vik_coord_to_latlon (&(trkpt->coord), &ll);
224                         a_coords_latlon_to_string ( &ll, &lat, &lon );
225                         values[i] = g_strdup_printf ( "%s%s %s", separator, lat, lon );
226                         g_free ( lat );
227                         g_free ( lon );
228                         break;
229                 }
230
231                 case 'N': // Name of track
232                         values[i] = g_strdup_printf ( _("%sTrack: %s"), separator, trk->name );
233                         break;
234
235                 default:
236                         break;
237                 }
238         }
239
240         g_free ( separator );
241         g_free ( speed_units_str );
242
243         gchar *msg = g_strconcat ( values[0], values[1], values[2], values[3], values[4], values[5], values[6], values[7], values[8], NULL );
244
245         for ( i = 0; i < FMT_MAX_NUMBER_CODES; i++ ) {
246                 if ( values[i] != '\0' )
247                         g_free ( values[i] );
248         }
249         
250         return msg;
251 }