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.

207 lines
4.6KB

  1. /*
  2. Write points to Franson Technology GpsGate simulator
  3. Copyright (C) 2006 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 <math.h>
  18. #include <stdlib.h>
  19. #include <stdio.h>
  20. #define MYNAME "gpssim"
  21. static gbfile* fout;
  22. static char* wayptspd;
  23. static char* splitfiles_opt;
  24. static int splitfiles;
  25. static QString fnamestr;
  26. static int trk_count;
  27. static int doing_tracks;
  28. static
  29. arglist_t gpssim_args[] = {
  30. {
  31. "wayptspd", &wayptspd, "Default speed for waypoints (knots/hr)",
  32. NULL, ARGTYPE_FLOAT, ARG_NOMINMAX
  33. },
  34. {
  35. "split", &splitfiles_opt, "Split input into separate files",
  36. "0", ARGTYPE_BOOL, ARG_NOMINMAX
  37. },
  38. ARG_TERMINATOR
  39. };
  40. /*
  41. * The only thing kind of odd about this format is the "split"
  42. * option. There's some trashing about with the 'splitfiles' toggle
  43. * to ensure that waypoints land in one file and each track and each
  44. * route land in files of their own.
  45. */
  46. static void
  47. gpssim_wr_init(const QString& fname)
  48. {
  49. fnamestr = fname;
  50. trk_count = 0;
  51. splitfiles = splitfiles_opt ? atoi(splitfiles_opt) : 0;
  52. /* If writing to stdout, never split files */
  53. if (0 == strcmp("-",splitfiles_opt)) {
  54. splitfiles = 0;
  55. }
  56. if (!splitfiles) {
  57. fout = gbfopen(fname, "wb", MYNAME);
  58. }
  59. }
  60. static void
  61. gpssim_wr_deinit(void)
  62. {
  63. if (fout) {
  64. gbfclose(fout);
  65. fout = NULL;
  66. }
  67. fnamestr.clear();
  68. }
  69. /*
  70. * All these files are written in binary mode, so put CR/NL pairs
  71. * in them explictly in case we're writing from a UNIX-like host.
  72. */
  73. static void
  74. gpssim_write_sentence(const char* const s)
  75. {
  76. gbfprintf(fout, "$%s*%02X\r\n", s, nmea_cksum(s));
  77. }
  78. static void
  79. gpssim_write_spd(double knotsperhour)
  80. {
  81. char obuf[1024];
  82. snprintf(obuf, sizeof(obuf), "FRSPD,%.2f", knotsperhour);
  83. gpssim_write_sentence(obuf);
  84. }
  85. static void
  86. gpssim_write_pt(const Waypoint* wpt)
  87. {
  88. char obuf[1024];
  89. double lat, lon;
  90. if WAYPT_HAS(wpt, speed) {
  91. gpssim_write_spd(MPS_TO_KNOTS(wpt->speed));
  92. }
  93. lat = degrees2ddmm(wpt->latitude);
  94. lon = degrees2ddmm(wpt->longitude);
  95. snprintf(obuf, sizeof(obuf), "FRWPT,%10.5f,%c,%011.5f,%c,%.1f",
  96. fabs(lat), lat < 0 ? 'S' : 'N',
  97. fabs(lon), lon < 0 ? 'W' : 'E',
  98. wpt->altitude == unknown_alt ? 0 : wpt->altitude
  99. );
  100. if (wpt->creation_time.isValid()) {
  101. char tbuf[20];
  102. int hms, ymd;
  103. struct tm* tm;
  104. const time_t tt = wpt->GetCreationTime().toTime_t();
  105. tm = gmtime(&tt);
  106. hms = tm->tm_hour * 10000 + tm->tm_min * 100 + tm->tm_sec;
  107. ymd = tm->tm_mday * 10000 + tm->tm_mon * 100 + tm->tm_year;
  108. snprintf(tbuf, sizeof(tbuf), ",%d,%d",ymd, hms);
  109. strcat(obuf, tbuf);
  110. }
  111. gpssim_write_sentence(obuf);
  112. }
  113. static void
  114. gpssim_trk_hdr(const route_head* rh)
  115. {
  116. if (splitfiles) {
  117. if (fout) {
  118. fatal(MYNAME ": output file already open.\n");
  119. }
  120. QString ofname = QString("%1%2%3.gpssim").arg(fnamestr).arg(doing_tracks ? "-track" : "-route").arg(trk_count++, 4, 10, QChar('0'));
  121. fout = gbfopen(ofname, "wb", MYNAME);
  122. }
  123. track_recompute(rh, NULL);
  124. }
  125. static void
  126. gpssim_trk_ftr(const route_head* rh)
  127. {
  128. if (splitfiles) {
  129. gbfclose(fout);
  130. fout = NULL;
  131. }
  132. }
  133. static void
  134. gpssim_write(void)
  135. {
  136. if (waypt_count()) {
  137. if (splitfiles) {
  138. QString ofname = fnamestr + "-waypoints.gpssim";
  139. fout = gbfopen(ofname, "wb", MYNAME);
  140. }
  141. if (wayptspd && wayptspd[0]) {
  142. gpssim_write_spd(atof(wayptspd));
  143. }
  144. waypt_disp_all(gpssim_write_pt);
  145. if (splitfiles) {
  146. gbfclose(fout);
  147. fout = NULL;
  148. }
  149. }
  150. doing_tracks = 1;
  151. track_disp_all(gpssim_trk_hdr, gpssim_trk_ftr, gpssim_write_pt);
  152. trk_count = 0;
  153. doing_tracks = 0;
  154. route_disp_all(gpssim_trk_hdr, gpssim_trk_ftr, gpssim_write_pt);
  155. }
  156. ff_vecs_t gpssim_vecs = {
  157. ff_type_file,
  158. { ff_cap_write, ff_cap_write, ff_cap_write },
  159. NULL,
  160. gpssim_wr_init,
  161. NULL,
  162. gpssim_wr_deinit,
  163. NULL,
  164. gpssim_write,
  165. NULL,
  166. gpssim_args,
  167. CET_CHARSET_ASCII, 0
  168. };