]>
Commit | Line | Data |
---|---|---|
f93e0210 RN |
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 ) { | |
bb77b487 | 197 | // Distance from start (along the track) |
f93e0210 RN |
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 | ||
bb77b487 | 243 | gchar *msg = g_strconcat ( values[0], values[1], values[2], values[3], values[4], values[5], values[6], values[7], values[8], NULL ); |
f93e0210 RN |
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 | } |