You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

text.cc 7.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  1. /*
  2. Output only format for Human Readable formats.
  3. Copyright (C) 2004 Scott Brynen, scott (at) brynen.com
  4. Copyright (C) 2002-2014 Robert Lipe, robertlipe+source@gpsbabel.org
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
  16. */
  17. #include "defs.h"
  18. #include "jeeps/gpsmath.h"
  19. #include "src/core/xmltag.h"
  20. #include <ctype.h>
  21. #include <stdlib.h>
  22. static gbfile* file_out;
  23. static short_handle mkshort_handle;
  24. static char* suppresssep = NULL;
  25. static char* txt_encrypt = NULL;
  26. static char* includelogs = NULL;
  27. static char* degformat = NULL;
  28. static char* altunits = NULL;
  29. static char* split_output = NULL;
  30. static int waypoint_count;
  31. static QString output_name;
  32. #define MYNAME "TEXT"
  33. static
  34. arglist_t text_args[] = {
  35. {
  36. "nosep", &suppresssep,
  37. "Suppress separator lines between waypoints",
  38. NULL, ARGTYPE_BOOL, ARG_NOMINMAX
  39. },
  40. {
  41. "encrypt", &txt_encrypt,
  42. "Encrypt hints using ROT13", NULL, ARGTYPE_BOOL, ARG_NOMINMAX
  43. },
  44. {
  45. "logs", &includelogs,
  46. "Include groundspeak logs if present", NULL, ARGTYPE_BOOL, ARG_NOMINMAX
  47. },
  48. {
  49. "degformat", &degformat,
  50. "Degrees output as 'ddd', 'dmm'(default) or 'dms'", "dmm", ARGTYPE_STRING, ARG_NOMINMAX
  51. },
  52. {
  53. "altunits", &altunits,
  54. "Units for altitude (f)eet or (m)etres", "m", ARGTYPE_STRING, ARG_NOMINMAX
  55. },
  56. {
  57. "splitoutput", &split_output,
  58. "Write each waypoint in a separate file", NULL, ARGTYPE_BOOL, ARG_NOMINMAX
  59. },
  60. ARG_TERMINATOR
  61. };
  62. static void
  63. wr_init(const QString& fname)
  64. {
  65. waypoint_count = 0;
  66. output_name = fname;
  67. if (!split_output) {
  68. file_out = gbfopen(fname, "w", MYNAME);
  69. }
  70. mkshort_handle = mkshort_new_handle();
  71. }
  72. static void
  73. wr_deinit(void)
  74. {
  75. if (!split_output) {
  76. gbfclose(file_out);
  77. }
  78. mkshort_del_handle(&mkshort_handle);
  79. output_name.clear();
  80. }
  81. static void
  82. text_disp(const Waypoint* wpt)
  83. {
  84. int32_t utmz;
  85. double utme, utmn;
  86. char utmzc;
  87. char* tmpout1, *tmpout2;
  88. char* altout;
  89. fs_xml* fs_gpx;
  90. waypoint_count++;
  91. if (split_output) {
  92. QString thisfname(output_name);
  93. thisfname += QString::number(waypoint_count);
  94. file_out = gbfopen(thisfname, "w", MYNAME);
  95. }
  96. GPS_Math_WGS84_To_UTM_EN(wpt->latitude, wpt->longitude,
  97. &utme, &utmn, &utmz, &utmzc);
  98. tmpout1 = pretty_deg_format(wpt->latitude, wpt->longitude, degformat[2], " ", 0);
  99. if (wpt->altitude != unknown_alt) {
  100. xasprintf(&altout, " alt:%d", (int)((altunits[0]=='f')?METERS_TO_FEET(wpt->altitude):wpt->altitude));
  101. } else {
  102. altout = (char*) "";
  103. }
  104. xasprintf(&tmpout2, "%s (%d%c %6.0f %7.0f)%s", tmpout1, utmz, utmzc, utme, utmn, altout);
  105. gbfprintf(file_out, "%-16s %59s\n",
  106. (global_opts.synthesize_shortnames) ? CSTRc(mkshort_from_wpt(mkshort_handle, wpt)) : CSTRc(wpt->shortname),
  107. tmpout2);
  108. xfree(tmpout2);
  109. xfree(tmpout1);
  110. if (altout[0]) {
  111. xfree(altout);
  112. }
  113. if (wpt->description != wpt->shortname) {
  114. gbfputs(wpt->description, file_out);
  115. if (!wpt->gc_data->placer.isEmpty()) {
  116. gbfputs(" by ", file_out);
  117. gbfputs(wpt->gc_data->placer, file_out);
  118. }
  119. }
  120. if (wpt->gc_data->terr) {
  121. gbfprintf(file_out, " - %s / %s - (%d%s / %d%s)\n",
  122. gs_get_cachetype(wpt->gc_data->type), gs_get_container(wpt->gc_data->container),
  123. (int)(wpt->gc_data->diff / 10), (wpt->gc_data->diff%10)?".5":"",
  124. (int)(wpt->gc_data->terr / 10), (wpt->gc_data->terr%10)?".5":"");
  125. if (!wpt->gc_data->desc_short.utfstring.isEmpty()) {
  126. char* stripped_html = strip_html(&wpt->gc_data->desc_short);
  127. gbfprintf(file_out, "\n%s\n", stripped_html);
  128. xfree(stripped_html);
  129. }
  130. if (!wpt->gc_data->desc_long.utfstring.isEmpty()) {
  131. char* stripped_html = strip_html(&wpt->gc_data->desc_long);
  132. gbfprintf(file_out, "\n%s\n", stripped_html);
  133. xfree(stripped_html);
  134. }
  135. if (!wpt->gc_data->hint.isEmpty()) {
  136. QString hint;
  137. if (txt_encrypt) {
  138. hint = rot13(wpt->gc_data->hint);
  139. } else {
  140. hint = wpt->gc_data->hint;
  141. }
  142. gbfprintf(file_out, "\nHint: %s\n", CSTR(hint));
  143. }
  144. } else if (!wpt->notes.isEmpty() && (wpt->description.isEmpty() || wpt->notes != wpt->description)) {
  145. gbfputs("\n", file_out);
  146. gbfputs(wpt->notes, file_out);
  147. gbfputs("\n", file_out);
  148. }
  149. fs_gpx = NULL;
  150. if (includelogs) {
  151. fs_gpx = (fs_xml*)fs_chain_find(wpt->fs, FS_GPX);
  152. }
  153. if (fs_gpx && fs_gpx->tag) {
  154. xml_tag* root = fs_gpx->tag;
  155. xml_tag* curlog = NULL;
  156. xml_tag* logpart = NULL;
  157. curlog = xml_findfirst(root, "groundspeak:log");
  158. while (curlog) {
  159. time_t logtime = 0;
  160. struct tm* logtm = NULL;
  161. gbfprintf(file_out, "\n");
  162. logpart = xml_findfirst(curlog, "groundspeak:type");
  163. if (logpart) {
  164. gbfputs(logpart->cdata, file_out);
  165. gbfputs(" by ", file_out);
  166. }
  167. logpart = xml_findfirst(curlog, "groundspeak:finder");
  168. if (logpart) {
  169. gbfputs(logpart->cdata, file_out);
  170. gbfputs(" on ", file_out);
  171. }
  172. logpart = xml_findfirst(curlog, "groundspeak:date");
  173. if (logpart) {
  174. logtime = xml_parse_time(logpart->cdata).toTime_t();
  175. logtm = localtime(&logtime);
  176. if (logtm) {
  177. gbfprintf(file_out,
  178. "%4.4d-%2.2d-%2.2d\n",
  179. logtm->tm_year+1900,
  180. logtm->tm_mon+1,
  181. logtm->tm_mday);
  182. }
  183. }
  184. logpart = xml_findfirst(curlog, "groundspeak:log_wpt");
  185. if (logpart) {
  186. char* coordstr = NULL;
  187. double lat = 0;
  188. double lon = 0;
  189. coordstr = xml_attribute(logpart, "lat");
  190. if (coordstr) {
  191. lat = atof(coordstr);
  192. }
  193. coordstr = xml_attribute(logpart, "lon");
  194. if (coordstr) {
  195. lon = atof(coordstr);
  196. }
  197. coordstr = pretty_deg_format(lat, lon, degformat[2], " ", 0);
  198. gbfprintf(file_out, "%s\n", coordstr);
  199. xfree(coordstr);
  200. }
  201. logpart = xml_findfirst(curlog, "groundspeak:text");
  202. if (logpart) {
  203. char* encstr = NULL;
  204. int encoded = 0;
  205. encstr = xml_attribute(logpart, "encoded");
  206. encoded = (toupper(encstr[0]) != 'F');
  207. QString s;
  208. if (txt_encrypt && encoded) {
  209. s = rot13(logpart->cdata);
  210. } else {
  211. s = logpart->cdata;
  212. }
  213. gbfputs(s, file_out);
  214. }
  215. gbfprintf(file_out, "\n");
  216. curlog = xml_findnext(root, curlog, "groundspeak:log");
  217. }
  218. }
  219. if (! suppresssep) {
  220. gbfprintf(file_out, "\n-----------------------------------------------------------------------------\n");
  221. } else {
  222. gbfprintf(file_out, "\n");
  223. }
  224. if (split_output) {
  225. gbfclose(file_out);
  226. file_out = NULL;
  227. }
  228. }
  229. static void
  230. data_write(void)
  231. {
  232. if (! suppresssep && !split_output) {
  233. gbfprintf(file_out, "-----------------------------------------------------------------------------\n");
  234. }
  235. setshort_length(mkshort_handle, 6);
  236. waypt_disp_all(text_disp);
  237. }
  238. ff_vecs_t text_vecs = {
  239. ff_type_file,
  240. { ff_cap_write, ff_cap_none, ff_cap_none},
  241. NULL,
  242. wr_init,
  243. NULL,
  244. wr_deinit,
  245. NULL,
  246. data_write,
  247. NULL,
  248. text_args,
  249. CET_CHARSET_ASCII, 0 /* CET-REVIEW */
  250. };