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.

pocketfms_bc.cc 4.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. /*
  2. Read and write PocketFMS files.
  3. Copyright (C) 2009 Tobias Kretschmar, tobias.kretschmar@gmx.de
  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. #define MYNAME "PocketFMS Breadcrumbs"
  18. static char header_id[] = "BRC";
  19. typedef struct breadcrumb {
  20. // header
  21. char id[4]; // 0x42 0x52 0x43 0x00 <=> "BRC"
  22. uint16_t version; // 0x0100
  23. uint16_t reserve1; // 0x0000
  24. // data
  25. float latitude;
  26. float longitude;
  27. float altitude; // meter
  28. float speed; // m/s
  29. float course; // degrees
  30. float magvar; // degrees
  31. float separation; // meter
  32. float ehpe; // estimated horizontal position error
  33. float evpe; // estimated vertical position error
  34. float espe; // estimated speed position error
  35. uint16_t fix; // 1..none, 2..2D, 3..3D, 4..dgps, 5pps
  36. uint16_t year; // 1999..2999
  37. uint16_t month; // 1..12
  38. uint16_t day; // 0..31
  39. uint16_t hour; // 0.23
  40. uint16_t minute; // 0..59
  41. uint16_t second; // 0..59
  42. uint16_t reserve2; // 0x0000
  43. } BREADCRUMB;
  44. static gbfile* file_in, *file_out;
  45. static void
  46. rd_init(const QString& fname)
  47. {
  48. file_in = gbfopen_le(fname, "rb", MYNAME);
  49. }
  50. static void
  51. rd_deinit(void)
  52. {
  53. gbfclose(file_in);
  54. }
  55. static void
  56. wr_init(const QString& fname)
  57. {
  58. file_out = gbfopen_le(fname, "wb", MYNAME);
  59. }
  60. static void
  61. wr_deinit(void)
  62. {
  63. gbfclose(file_out);
  64. }
  65. static void
  66. read_tracks(void)
  67. {
  68. struct breadcrumb bc;
  69. route_head* trk_head = route_head_alloc();
  70. trk_head->rte_num = 1;
  71. trk_head->rte_name = "PocketFMS";
  72. trk_head->rte_desc = "Breadcrumb";
  73. trk_head->rte_url = "www.pocketfms.com";
  74. track_add_head(trk_head);
  75. while (1 == gbfread(&bc, sizeof(bc), 1, file_in)) {
  76. struct tm tm;
  77. Waypoint* wpt;
  78. if (strcmp(bc.id, header_id) != 0) {
  79. fatal(MYNAME ": invalid breadcrumb header in input file.\n");
  80. }
  81. memset(&tm, 0, sizeof(tm));
  82. tm.tm_year = le_readu16(&bc.year)-1900;
  83. tm.tm_mon = le_readu16(&bc.month)-1;
  84. tm.tm_mday = le_readu16(&bc.day);
  85. tm.tm_hour = le_readu16(&bc.hour);
  86. tm.tm_min = le_readu16(&bc.minute);
  87. tm.tm_sec = le_readu16(&bc.second);
  88. wpt = new Waypoint;
  89. wpt->latitude = le_read_float(&bc.latitude);
  90. wpt->longitude = le_read_float(&bc.longitude);
  91. wpt->altitude = FEET_TO_METERS(le_read_float(&bc.altitude));
  92. wpt->SetCreationTime(mkgmtime(&tm));
  93. wpt->hdop = le_read_float(&bc.ehpe);
  94. wpt->vdop = le_read_float(&bc.evpe);
  95. wpt->pdop = le_read_float(&bc.espe);
  96. wpt->course = le_read_float(&bc.course);
  97. wpt->speed = le_read_float(&bc.speed);
  98. wpt->fix = (fix_type)(le_readu16(&bc.fix) - 1);
  99. track_add_wpt(trk_head, wpt);
  100. }
  101. }
  102. static void
  103. route_head_noop(const route_head* wp)
  104. {
  105. }
  106. static void
  107. pocketfms_waypt_disp(const Waypoint* wpt)
  108. {
  109. struct breadcrumb bc;
  110. struct tm* tm;
  111. memset(&bc, 0, sizeof(bc));
  112. const time_t tt = wpt->GetCreationTime().toTime_t();
  113. tm = localtime(&tt);
  114. if (wpt->creation_time.isValid()) {
  115. const time_t tt = wpt->GetCreationTime().toTime_t();
  116. tm = gmtime(&tt);
  117. }
  118. strcpy(bc.id, header_id);
  119. le_write16(&bc.version, 1);
  120. le_write_float(&bc.latitude, wpt->latitude);
  121. le_write_float(&bc.longitude, wpt->longitude);
  122. le_write_float(&bc.altitude, METERS_TO_FEET(wpt->altitude));
  123. if (tm) {
  124. le_write16(&bc.year, tm->tm_year + 1900);
  125. le_write16(&bc.month, tm->tm_mon + 1);
  126. le_write16(&bc.day, tm->tm_mday);
  127. le_write16(&bc.hour, tm->tm_hour);
  128. le_write16(&bc.minute, tm->tm_min);
  129. le_write16(&bc.second, tm->tm_sec);
  130. }
  131. le_write_float(&bc.ehpe, wpt->hdop);
  132. le_write_float(&bc.evpe, wpt->vdop);
  133. le_write_float(&bc.espe, wpt->pdop);
  134. le_write_float(&bc.course, wpt->course);
  135. le_write_float(&bc.speed, wpt->speed);
  136. le_write16(&bc.fix, wpt->fix+1);
  137. gbfwrite(&bc, sizeof(bc), 1, file_out);
  138. }
  139. static void
  140. data_read(void)
  141. {
  142. read_tracks();
  143. }
  144. static void
  145. data_write(void)
  146. {
  147. track_disp_all(route_head_noop, route_head_noop, pocketfms_waypt_disp);
  148. }
  149. ff_vecs_t pocketfms_bc_vecs = {
  150. ff_type_file,
  151. {
  152. ff_cap_none, /* waypoints */
  153. (ff_cap)(ff_cap_read | ff_cap_write), /* tracks */
  154. ff_cap_none /* routes */
  155. },
  156. rd_init,
  157. wr_init,
  158. rd_deinit,
  159. wr_deinit,
  160. data_read,
  161. data_write,
  162. NULL,
  163. NULL,
  164. CET_CHARSET_ASCII, 0 /* CET-REVIEW */
  165. };