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.

hiketech.cc 7.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  1. /*
  2. Access Hiketech XML data files.
  3. Copyright (C) 2004,2005 Robert Lipe, robertlipe+source@gpsbabel.org
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
  15. */
  16. #include "defs.h"
  17. #include "xmlgeneric.h"
  18. #include "src/core/xmlstreamwriter.h"
  19. #include <QtCore/QXmlStreamAttributes>
  20. #include <stdio.h>
  21. static gbfile* ofd;
  22. static QString ostring;
  23. static gpsbabel::XmlStreamWriter writer(&ostring);
  24. static Waypoint* wpt_tmp;
  25. static route_head* trk_head;
  26. #define MYNAME "hiketech"
  27. static
  28. arglist_t hiketech_args[] = {
  29. ARG_TERMINATOR
  30. };
  31. /* Waypoints */
  32. static xg_callback ht_wpt_s;
  33. static xg_callback ht_wpt_e;
  34. static xg_callback ht_ident;
  35. static xg_callback ht_sym;
  36. static xg_callback ht_lat;
  37. static xg_callback ht_long;
  38. static xg_callback ht_alt;
  39. /* Tracks */
  40. static xg_callback ht_trk_s, ht_trk_e;
  41. static xg_callback ht_trk_ident;
  42. static xg_callback ht_trk_pnt_s, ht_trk_pnt_e;
  43. static xg_callback ht_trk_utc;
  44. static xg_callback ht_trk_lat;
  45. static xg_callback ht_trk_long;
  46. static xg_callback ht_trk_alt;
  47. static xg_tag_mapping ht_map[] = {
  48. { ht_wpt_s, cb_start, "/hiketech/gpsdata/wpt" },
  49. { ht_wpt_e, cb_end, "/hiketech/gpsdata/wpt" },
  50. { ht_ident, cb_cdata, "/hiketech/gpsdata/wpt/ident" },
  51. { ht_sym, cb_cdata, "/hiketech/gpsdata/wpt/sym" },
  52. { ht_lat, cb_cdata, "/hiketech/gpsdata/wpt/lat" },
  53. { ht_long, cb_cdata, "/hiketech/gpsdata/wpt/long" },
  54. { ht_alt, cb_cdata, "/hiketech/gpsdata/wpt/alt" },
  55. { ht_trk_s, cb_start, "/hiketech/gpsdata/trk" },
  56. { ht_trk_e, cb_end, "/hiketech/gpsdata/trk" },
  57. { ht_trk_ident, cb_cdata, "/hiketech/gpsdata/trk/ident" },
  58. { ht_trk_pnt_s, cb_start, "/hiketech/gpsdata/trk/pnt" },
  59. { ht_trk_pnt_e, cb_end, "/hiketech/gpsdata/trk/pnt" },
  60. { ht_trk_utc, cb_cdata, "/hiketech/gpsdata/trk/pnt/utc" },
  61. { ht_trk_lat, cb_cdata, "/hiketech/gpsdata/trk/pnt/lat" },
  62. { ht_trk_long, cb_cdata, "/hiketech/gpsdata/trk/pnt/long" },
  63. { ht_trk_alt, cb_cdata, "/hiketech/gpsdata/trk/pnt/alt" },
  64. { NULL, (xg_cb_type)0, NULL}
  65. };
  66. static void
  67. hiketech_rd_init(const QString& fname)
  68. {
  69. xml_init(fname, ht_map, NULL);
  70. }
  71. static void
  72. hiketech_read(void)
  73. {
  74. xml_read();
  75. }
  76. static void
  77. hiketech_rd_deinit(void)
  78. {
  79. xml_deinit();
  80. }
  81. static void
  82. hiketech_wr_init(const QString& fname)
  83. {
  84. ofd = gbfopen(fname, "w", MYNAME);
  85. }
  86. static void
  87. hiketech_wr_deinit(void)
  88. {
  89. writer.writeEndDocument();
  90. gbfputs(ostring, ofd);
  91. gbfclose(ofd);
  92. ofd = NULL;
  93. }
  94. static void
  95. hiketech_trk_hdr(const route_head* rte)
  96. {
  97. writer.writeStartElement("trk");
  98. writer.setAutoFormattingIndent(1);
  99. writer.writeOptionalTextElement("ident", rte->rte_name);
  100. }
  101. static void
  102. hiketech_trk_tlr(const route_head* rte)
  103. {
  104. writer.writeEndElement(); // trk
  105. }
  106. static QString
  107. hiketech_format_time(const QDateTime& t)
  108. {
  109. // FIXME: Find out why these two blocks of code aren't equivalent.
  110. // it produces times that are 12 hours too late. Double TZ bump?
  111. // for now, just go back to the way we've done it for a decade. -- robert
  112. #if 0
  113. return t.toString("yyyy-MM-dd hh:mm:ss");
  114. #else
  115. char tbuf[80];
  116. time_t tm = t.toTime_t();
  117. strftime(tbuf, sizeof(tbuf), "%Y-%m-%d %I:%M:%S", gmtime(&tm));
  118. return QString(tbuf);
  119. #endif
  120. }
  121. static void
  122. hiketech_trkpt_pr(const Waypoint* waypointp)
  123. {
  124. writer.writeStartElement("pnt");
  125. if (waypointp->creation_time.isValid()) {
  126. writer.writeTextElement("utc",
  127. hiketech_format_time(waypointp->GetCreationTime()));
  128. }
  129. writer.writeTextElement("lat", QString::number(waypointp->latitude,'f', 6));
  130. writer.writeTextElement("long", QString::number(waypointp->longitude,'f', 6));
  131. if (waypointp->altitude != unknown_alt) {
  132. writer.writeTextElement("alt", QString::number(waypointp->altitude,'f', 6));
  133. }
  134. writer.writeEndElement(); // png
  135. }
  136. static void
  137. hiketech_waypt_pr(const Waypoint* wpt)
  138. {
  139. writer.writeStartElement("wpt");
  140. writer.setAutoFormattingIndent(-1);
  141. writer.writeTextElement("ident", wpt->shortname);
  142. writer.writeTextElement("sym", wpt->icon_descr);
  143. writer.writeTextElement("lat", QString::number(wpt->latitude, 'f', 6));
  144. writer.writeTextElement("long", QString::number(wpt->longitude, 'f', 6));
  145. writer.writeStartElement("color");
  146. writer.writeTextElement("lbl", "FAFFB4");
  147. writer.writeTextElement("obj", "FF8000");
  148. writer.writeEndElement(); // color
  149. writer.writeEndElement(); // wpt
  150. }
  151. static void
  152. hiketech_write(void)
  153. {
  154. writer.writeStartElement("hiketech");
  155. writer.writeAttribute("version", "1.2");
  156. writer.writeAttribute("url", "http://www.hiketech.com");
  157. writer.setAutoFormatting(true);
  158. writer.writeStartElement("gpsdata");
  159. track_disp_all(hiketech_trk_hdr, hiketech_trk_tlr, hiketech_trkpt_pr);
  160. track_disp_all(NULL, NULL, hiketech_trkpt_pr);
  161. waypt_disp_all(hiketech_waypt_pr);
  162. writer.writeEndElement(); // gpsdata
  163. writer.writeEndElement(); // hiketech
  164. }
  165. static
  166. void ht_wpt_s(xg_string args, const QXmlStreamAttributes*)
  167. {
  168. wpt_tmp = new Waypoint;
  169. }
  170. static
  171. void ht_ident(xg_string args, const QXmlStreamAttributes*)
  172. {
  173. wpt_tmp->shortname = args;
  174. }
  175. static
  176. void ht_sym(xg_string args, const QXmlStreamAttributes*)
  177. {
  178. wpt_tmp->icon_descr = args;
  179. }
  180. static
  181. void ht_lat(xg_string args, const QXmlStreamAttributes*)
  182. {
  183. wpt_tmp->latitude = args.toDouble();
  184. }
  185. static
  186. void ht_long(xg_string args, const QXmlStreamAttributes*)
  187. {
  188. wpt_tmp->longitude = args.toDouble();
  189. }
  190. static
  191. void ht_alt(xg_string args, const QXmlStreamAttributes*)
  192. {
  193. wpt_tmp->altitude = args.toDouble();
  194. }
  195. static
  196. void ht_wpt_e(xg_string args, const QXmlStreamAttributes*)
  197. {
  198. waypt_add(wpt_tmp);
  199. wpt_tmp = NULL;
  200. }
  201. static
  202. void ht_trk_s(xg_string args, const QXmlStreamAttributes*)
  203. {
  204. trk_head = route_head_alloc();
  205. track_add_head(trk_head);
  206. }
  207. static
  208. void ht_trk_e(xg_string args, const QXmlStreamAttributes*)
  209. {
  210. }
  211. static
  212. void ht_trk_ident(xg_string args, const QXmlStreamAttributes*)
  213. {
  214. trk_head->rte_name = args;
  215. }
  216. static
  217. void ht_trk_pnt_s(xg_string args, const QXmlStreamAttributes*)
  218. {
  219. wpt_tmp = new Waypoint;
  220. }
  221. static
  222. void ht_trk_pnt_e(xg_string args, const QXmlStreamAttributes*)
  223. {
  224. track_add_wpt(trk_head, wpt_tmp);
  225. }
  226. static
  227. void ht_trk_utc(xg_string args, const QXmlStreamAttributes*)
  228. {
  229. struct tm tm;
  230. time_t utc;
  231. sscanf(CSTRc(args), "%d-%d-%d %d:%d:%d",
  232. &tm.tm_year, &tm.tm_mon,
  233. &tm.tm_mday, &tm.tm_hour,
  234. &tm.tm_min, &tm.tm_sec);
  235. tm.tm_mon -= 1;
  236. tm.tm_year -= 1900;
  237. tm.tm_isdst = 0;
  238. utc = mkgmtime(&tm);
  239. wpt_tmp->SetCreationTime(utc);
  240. }
  241. static
  242. void ht_trk_lat(xg_string args, const QXmlStreamAttributes*)
  243. {
  244. wpt_tmp->latitude = args.toDouble();
  245. }
  246. static
  247. void ht_trk_long(xg_string args, const QXmlStreamAttributes*)
  248. {
  249. wpt_tmp->longitude = args.toDouble();
  250. }
  251. static
  252. void ht_trk_alt(xg_string args, const QXmlStreamAttributes*)
  253. {
  254. wpt_tmp->altitude = args.toDouble();
  255. }
  256. ff_vecs_t hiketech_vecs = {
  257. ff_type_file,
  258. { (ff_cap)(ff_cap_read | ff_cap_write), (ff_cap)(ff_cap_read | ff_cap_write) },
  259. hiketech_rd_init,
  260. hiketech_wr_init,
  261. hiketech_rd_deinit,
  262. hiketech_wr_deinit,
  263. hiketech_read,
  264. hiketech_write,
  265. NULL,
  266. hiketech_args,
  267. CET_CHARSET_ASCII, 0 /* CET-REVIEW */
  268. };