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.

delgpl.cc 4.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. /*
  2. DeLorme GPL Track Format.
  3. Copyright (C) 2003, 2009 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. #define MYNAME "GPL"
  18. typedef struct gpl_point {
  19. unsigned int status;
  20. unsigned int dummy1;
  21. double lat;
  22. double lon;
  23. double alt; /* in feet */
  24. double heading;
  25. double speed; /* mph */
  26. unsigned int tm;
  27. unsigned int dummy3;
  28. } gpl_point_t;
  29. static gbfile* gplfile_in;
  30. static gbfile* gplfile_out;
  31. static void
  32. gpl_rd_init(const QString& fname)
  33. {
  34. gplfile_in = gbfopen_le(fname, "rb", MYNAME);
  35. if (sizeof(struct gpl_point) != 56) {
  36. fatal(MYNAME ": gpl_point is %lu instead of 56.\n",
  37. (unsigned long) sizeof(struct gpl_point));
  38. }
  39. }
  40. static void
  41. gpl_read(void)
  42. {
  43. Waypoint* wpt_tmp;
  44. route_head* track_head;
  45. gpl_point_t gp;
  46. double alt_feet;
  47. track_head = route_head_alloc();
  48. track_add_head(track_head);
  49. while (gbfread(&gp, sizeof(gp), 1, gplfile_in) > 0) {
  50. wpt_tmp = new Waypoint;
  51. wpt_tmp->latitude = le_read_double(&gp.lat);
  52. wpt_tmp->longitude = le_read_double(&gp.lon);
  53. alt_feet = le_read_double(&gp.alt);
  54. wpt_tmp->altitude = FEET_TO_METERS(alt_feet);
  55. if (wpt_tmp->altitude <= unknown_alt + 1) {
  56. wpt_tmp->altitude = unknown_alt;
  57. }
  58. wpt_tmp->SetCreationTime(le_read32(&gp.tm));
  59. switch (le_read32(&gp.status)) {
  60. case 1:
  61. wpt_tmp->fix = fix_none;
  62. break;
  63. case 2:
  64. wpt_tmp->fix = fix_2d;
  65. break;
  66. case 3:
  67. wpt_tmp->fix = fix_3d;
  68. break;
  69. case 5:
  70. wpt_tmp->fix = fix_dgps;
  71. break;
  72. }
  73. WAYPT_SET(wpt_tmp, course, le_read_double(&gp.heading));
  74. WAYPT_SET(wpt_tmp, speed, le_read_double(&gp.speed));
  75. WAYPT_SET(wpt_tmp, speed, MILES_TO_METERS(wpt_tmp->speed)/3600);
  76. // 2008 and 2009 seem to throw track points in that go back
  77. // in time. The only thing I see "special" about those
  78. // trackpoints is that these fields are zeroed. Toss them.
  79. if ((wpt_tmp->speed == 0.0) && (wpt_tmp->course == 0.0)) {
  80. delete wpt_tmp;
  81. continue;
  82. }
  83. track_add_wpt(track_head, wpt_tmp);
  84. }
  85. }
  86. static void
  87. gpl_rd_deinit(void)
  88. {
  89. gbfclose(gplfile_in);
  90. }
  91. static void
  92. gpl_wr_init(const QString& fname)
  93. {
  94. gplfile_out = gbfopen_le(fname, "wb", MYNAME);
  95. }
  96. static void
  97. gpl_wr_deinit(void)
  98. {
  99. gbfclose(gplfile_out);
  100. }
  101. static void
  102. gpl_trackpt(const Waypoint* wpt)
  103. {
  104. double alt_feet = METERS_TO_FEET(wpt->altitude);
  105. int status = 3;
  106. gpl_point_t gp;
  107. double speed = 3600*METERS_TO_MILES(wpt->speed);
  108. double heading = wpt->course;
  109. switch (wpt->fix) {
  110. case fix_none:
  111. status = 1;
  112. break;
  113. case fix_2d:
  114. status = 2;
  115. break;
  116. case fix_3d:
  117. status = 3;
  118. break;
  119. case fix_dgps:
  120. status = 5;
  121. break;
  122. default:
  123. status = 3; // a strategic lie for fix_unknown.
  124. }
  125. memset(&gp, 0, sizeof(gp));
  126. le_write32(&gp.status, status);
  127. le_write_double(&gp.lat, wpt->latitude);
  128. le_write_double(&gp.lon, wpt->longitude);
  129. le_write_double(&gp.alt, alt_feet);
  130. le_write_double(&gp.speed, speed);
  131. le_write_double(&gp.heading, heading);
  132. le_write32(&gp.tm, wpt->GetCreationTime().toTime_t());
  133. gbfwrite(&gp, sizeof(gp), 1, gplfile_out);
  134. }
  135. static void
  136. gpl_write(void)
  137. {
  138. track_disp_all(NULL, NULL, gpl_trackpt);
  139. }
  140. ff_vecs_t gpl_vecs = {
  141. ff_type_file,
  142. { ff_cap_none, (ff_cap)(ff_cap_read | ff_cap_write), ff_cap_none },
  143. gpl_rd_init,
  144. gpl_wr_init,
  145. gpl_rd_deinit,
  146. gpl_wr_deinit,
  147. gpl_read,
  148. gpl_write,
  149. NULL,
  150. NULL,
  151. CET_CHARSET_UTF8, 1 /* there is no need to convert anything | CET-REVIEW */
  152. };