1 /*
2 Output only format for Human Readable formats.
3
4 Copyright (C) 2004 Scott Brynen, scott (at) brynen.com
5 Copyright (C) 2002 Robert Lipe, robertlipe@usa.net
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 USA
20 */
21
22
23 #include "defs.h"
24 #include "jeeps/gpsmath.h"
25 #include <ctype.h>
26
27 static gbfile *file_out;
28 static short_handle mkshort_handle;
29
30 static char *suppresssep = NULL;
31 static char *txt_encrypt = NULL;
32 static char *includelogs = NULL;
33 static char *degformat = NULL;
34 static char *altunits = NULL;
35 static char *split_output = NULL;
36 static int waypoint_count;
37 static char *output_name;
38
39 #define MYNAME "TEXT"
40
41 static
42 arglist_t text_args[] = {
43 {
44 "nosep", &suppresssep,
45 "Suppress separator lines between waypoints",
46 NULL, ARGTYPE_BOOL, ARG_NOMINMAX
47 },
48 {
49 "encrypt", &txt_encrypt,
50 "Encrypt hints using ROT13", NULL, ARGTYPE_BOOL, ARG_NOMINMAX
51 },
52 {
53 "logs", &includelogs,
54 "Include groundspeak logs if present", NULL, ARGTYPE_BOOL, ARG_NOMINMAX
55 },
56 {
57 "degformat", °format,
58 "Degrees output as 'ddd', 'dmm'(default) or 'dms'", "dmm", ARGTYPE_STRING, ARG_NOMINMAX
59 },
60 {
61 "altunits", &altunits,
62 "Units for altitude (f)eet or (m)etres", "m", ARGTYPE_STRING, ARG_NOMINMAX
63 },
64 {
65 "splitoutput", &split_output,
66 "Write each waypoint in a separate file", NULL, ARGTYPE_BOOL, ARG_NOMINMAX
67 },
68
69 ARG_TERMINATOR
70 };
71
72
73
74 static void
wr_init(const char * fname)75 wr_init(const char *fname)
76 {
77 waypoint_count = 0;
78 output_name = xstrdup(fname);
79 if (!split_output) {
80 file_out = gbfopen(fname, "w", MYNAME);
81 }
82 mkshort_handle = mkshort_new_handle();
83 }
84
85 static void
wr_deinit(void)86 wr_deinit(void)
87 {
88 if (!split_output) {
89 gbfclose(file_out);
90 }
91 mkshort_del_handle(&mkshort_handle);
92 xfree(output_name);
93 }
94
95 static void
text_disp(const waypoint * wpt)96 text_disp(const waypoint *wpt)
97 {
98 int latint, lonint;
99 char tbuf[1024];
100 time_t tm = wpt->creation_time;
101 gbint32 utmz;
102 double utme, utmn;
103 char utmzc;
104 char *tmpout1, *tmpout2;
105 char *altout;
106 fs_xml *fs_gpx;
107
108 waypoint_count++;
109
110 if (split_output) {
111 char *thisfname;
112 xasprintf(&thisfname, "%s%d", output_name, waypoint_count);
113 file_out = gbfopen(thisfname, "w", MYNAME);
114 }
115
116 lonint = abs((int) wpt->longitude);
117 latint = abs((int) wpt->latitude);
118
119 GPS_Math_WGS84_To_UTM_EN(wpt->latitude, wpt->longitude,
120 &utme, &utmn, &utmz, &utmzc);
121
122 if (tm == 0) {
123 tm = time(NULL);
124 }
125 strftime(tbuf, sizeof(tbuf), "%d-%b-%Y", localtime(&tm));
126
127 tmpout1 = pretty_deg_format(wpt->latitude, wpt->longitude, degformat[2], " ", 0);
128 if (wpt->altitude != unknown_alt) {
129 xasprintf(&altout, " alt:%d", (int)((altunits[0]=='f')?METERS_TO_FEET(wpt->altitude):wpt->altitude));
130 } else {
131 altout = "";
132 }
133 xasprintf(&tmpout2, "%s (%d%c %6.0f %7.0f)%s", tmpout1, utmz, utmzc, utme, utmn, altout);
134 gbfprintf(file_out, "%-16s %59s\n",
135 (global_opts.synthesize_shortnames) ? mkshort_from_wpt(mkshort_handle, wpt) : wpt->shortname,
136 tmpout2);
137 xfree(tmpout2);
138 xfree(tmpout1);
139 if (altout[0]) {
140 xfree(altout);
141 }
142
143
144 if (strcmp(wpt->description, wpt->shortname)) {
145 gbfprintf(file_out, "%s", wpt->description);
146 if (wpt->gc_data->placer) {
147 gbfprintf(file_out, " by %s", wpt->gc_data->placer);
148 }
149 }
150 if (wpt->gc_data->terr) {
151 gbfprintf(file_out, " - %s / %s - (%d%s / %d%s)\n",
152 gs_get_cachetype(wpt->gc_data->type), gs_get_container(wpt->gc_data->container),
153 (int)(wpt->gc_data->diff / 10), (wpt->gc_data->diff%10)?".5":"",
154 (int)(wpt->gc_data->terr / 10), (wpt->gc_data->terr%10)?".5":"");
155 if (wpt->gc_data->desc_short.utfstring) {
156 char *stripped_html = strip_html(&wpt->gc_data->desc_short);
157 gbfprintf(file_out, "\n%s\n", stripped_html);
158 xfree(stripped_html);
159 }
160 if (wpt->gc_data->desc_long.utfstring) {
161 char *stripped_html = strip_html(&wpt->gc_data->desc_long);
162 gbfprintf(file_out, "\n%s\n", stripped_html);
163 xfree(stripped_html);
164 }
165 if (wpt->gc_data->hint) {
166 char *hint = NULL;
167 if (txt_encrypt) {
168 hint = rot13(wpt->gc_data->hint);
169 } else {
170 hint = xstrdup(wpt->gc_data->hint);
171 }
172 gbfprintf(file_out, "\nHint: %s\n", hint);
173 xfree(hint);
174 }
175 } else if (wpt->notes && (!wpt->description || strcmp(wpt->notes,wpt->description))) {
176 gbfprintf(file_out, "\n%s\n", wpt->notes);
177 }
178
179 fs_gpx = NULL;
180 if (includelogs) {
181 fs_gpx = (fs_xml *)fs_chain_find(wpt->fs, FS_GPX);
182 }
183
184 if (fs_gpx && fs_gpx->tag) {
185 xml_tag *root = fs_gpx->tag;
186 xml_tag *curlog = NULL;
187 xml_tag *logpart = NULL;
188 curlog = xml_findfirst(root, "groundspeak:log");
189 while (curlog) {
190 time_t logtime = 0;
191 struct tm *logtm = NULL;
192 gbfprintf(file_out, "\n");
193
194 logpart = xml_findfirst(curlog, "groundspeak:type");
195 if (logpart) {
196 gbfprintf(file_out, "%s by ", logpart->cdata);
197 }
198
199 logpart = xml_findfirst(curlog, "groundspeak:finder");
200 if (logpart) {
201 gbfprintf(file_out, "%s on ", logpart->cdata);
202 }
203
204 logpart = xml_findfirst(curlog, "groundspeak:date");
205 if (logpart) {
206 logtime = xml_parse_time(logpart->cdata, NULL);
207 logtm = localtime(&logtime);
208 if (logtm) {
209 gbfprintf(file_out,
210 "%4.4d-%2.2d-%2.2d\n",
211 logtm->tm_year+1900,
212 logtm->tm_mon+1,
213 logtm->tm_mday);
214 }
215 }
216
217 logpart = xml_findfirst(curlog, "groundspeak:log_wpt");
218 if (logpart) {
219 char *coordstr = NULL;
220 float lat = 0;
221 float lon = 0;
222 coordstr = xml_attribute(logpart, "lat");
223 if (coordstr) {
224 lat = atof(coordstr);
225 }
226 coordstr = xml_attribute(logpart, "lon");
227 if (coordstr) {
228 lon = atof(coordstr);
229 }
230 coordstr = pretty_deg_format(lat, lon, degformat[2], " ", 0);
231 gbfprintf(file_out, "%s\n", coordstr);
232 xfree(coordstr);
233 }
234
235 logpart = xml_findfirst(curlog, "groundspeak:text");
236 if (logpart) {
237 char *encstr = NULL;
238 char *s = NULL;
239 int encoded = 0;
240 encstr = xml_attribute(logpart, "encoded");
241 encoded = (toupper(encstr[0]) != 'F');
242
243 if (txt_encrypt && encoded) {
244 s = rot13(logpart->cdata);
245 } else {
246 s = xstrdup(logpart->cdata);
247 }
248
249 gbfprintf(file_out, "%s", s);
250 xfree(s);
251 }
252
253 gbfprintf(file_out, "\n");
254 curlog = xml_findnext(root, curlog, "groundspeak:log");
255 }
256 }
257 if (! suppresssep) {
258 gbfprintf(file_out, "\n-----------------------------------------------------------------------------\n");
259 } else {
260 gbfprintf(file_out, "\n");
261 }
262
263 if (split_output) {
264 gbfclose(file_out);
265 file_out = NULL;
266 }
267 }
268
269 static void
data_write(void)270 data_write(void)
271 {
272 if (! suppresssep && !split_output) {
273 gbfprintf(file_out, "-----------------------------------------------------------------------------\n");
274 }
275 setshort_length(mkshort_handle, 6);
276 waypt_disp_all(text_disp);
277 }
278
279
280 ff_vecs_t text_vecs = {
281 ff_type_file,
282 { ff_cap_write, ff_cap_none, ff_cap_none},
283 NULL,
284 wr_init,
285 NULL,
286 wr_deinit,
287 NULL,
288 data_write,
289 NULL,
290 text_args,
291 CET_CHARSET_ASCII, 0 /* CET-REVIEW */
292
293 };
294