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.

467 lines
11KB

  1. /*
  2. Support for "GeoGrid Viewer ascii overlay files".
  3. Copyright (C) 2008 Olaf Klein (o.b.klein@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 "cet_util.h"
  18. #include "inifile.h"
  19. #include "grtcirc.h"
  20. #include <cmath>
  21. #include <stdlib.h>
  22. #include <stdio.h>
  23. #define MYNAME "ggv_ovl"
  24. static
  25. arglist_t ggv_ovl_args[] = {
  26. ARG_TERMINATOR
  27. };
  28. typedef enum {
  29. OVL_SYMBOL_BITMAP = 1,
  30. OVL_SYMBOL_TEXT,
  31. OVL_SYMBOL_LINE,
  32. OVL_SYMBOL_POLYGON,
  33. OVL_SYMBOL_RECTANGLE,
  34. OVL_SYMBOL_CIRCLE,
  35. OVL_SYMBOL_TRIANGLE
  36. } OVL_SYMBOL_TYP;
  37. typedef enum {
  38. OVL_COLOR_RED = 1, /* = 1 */
  39. OVL_COLOR_LIME, /* = 2 */
  40. OVL_COLOR_BLUE, /* = 3 */
  41. OVL_COLOR_YELLOW, /* = 4 */
  42. OVL_COLOR_BLACK, /* = 5 */
  43. OVL_COLOR_WHITE, /* = 6 */
  44. OVL_COLOR_7, /* = 7 (draws only a simple line) */
  45. OVL_COLOR_FUCHSIA, /* = 8 */
  46. OVL_COLOR_AQUA, /* = 9 */
  47. } OVL_COLOR_TYP;
  48. /* some hints:
  49. # "col": color
  50. # "group": 1 means NO GROUP
  51. # "size": size in pixels PLUS 100
  52. # "with":
  53. # "zoom":
  54. # "art": line-style
  55. */
  56. static inifile_t* inifile;
  57. static gbfile* fout;
  58. static int symbol_ct; /* Number of symbols written */
  59. static int group_ct; /* Group number during write */
  60. static int track_ct, route_ct;
  61. static bounds all_bounds;
  62. static OVL_COLOR_TYP color;
  63. /*******************************************************************************
  64. * %%% global callbacks called by gpsbabel main process %%% *
  65. *******************************************************************************/
  66. static void
  67. ggv_ovl_rd_init(const QString& fname)
  68. {
  69. inifile = inifile_init(qPrintable(fname), MYNAME);
  70. if (inifile->unicode) {
  71. cet_convert_init(CET_CHARSET_UTF8, 1);
  72. }
  73. route_ct = 0;
  74. track_ct = 0;
  75. }
  76. static void
  77. ggv_ovl_rd_deinit(void)
  78. {
  79. inifile_done(inifile);
  80. }
  81. static void
  82. ggv_ovl_read(void)
  83. {
  84. int symbols;
  85. int i;
  86. symbols = inifile_readint_def(inifile, "Overlay", "Symbols", -1);
  87. for (i = 1; i <= symbols; i++) {
  88. int points;
  89. OVL_SYMBOL_TYP type;
  90. char symbol[32];
  91. snprintf(symbol, sizeof(symbol), "Symbol %d", i);
  92. type = (OVL_SYMBOL_TYP) inifile_readint_def(inifile, symbol, "Typ", 0);
  93. points = inifile_readint_def(inifile, symbol, "Punkte", -1);
  94. switch (type) {
  95. char coord[32];
  96. Waypoint* wpt;
  97. char* cx;
  98. int group;
  99. case OVL_SYMBOL_LINE:
  100. case OVL_SYMBOL_POLYGON:
  101. if (!inifile_readint(inifile, symbol, "Group", &group)) {
  102. group = -1;
  103. }
  104. if (points > 0) {
  105. int j;
  106. route_head* rte, *trk;
  107. rte = trk = route_head_alloc();
  108. if (group > 1) {
  109. route_add_head(rte);
  110. route_ct++;
  111. rte->rte_name = QString("Route %1").arg(route_ct);
  112. } else {
  113. track_add_head(trk);
  114. track_ct++;
  115. trk->rte_name = QString("Track %1").arg(track_ct);
  116. }
  117. for (j = 0; j < points; j++) {
  118. wpt = new Waypoint;
  119. snprintf(coord, sizeof(coord), "YKoord%d", j);
  120. if ((cx = inifile_readstr(inifile, symbol, coord))) {
  121. wpt->latitude = atof(cx);
  122. } else {
  123. continue;
  124. }
  125. snprintf(coord, sizeof(coord), "XKoord%d", j);
  126. if ((cx = inifile_readstr(inifile, symbol, coord))) {
  127. wpt->longitude = atof(cx);
  128. } else {
  129. continue;
  130. }
  131. if (group > 1) {
  132. route_add_wpt(rte, wpt);
  133. } else {
  134. track_add_wpt(trk, wpt);
  135. }
  136. }
  137. }
  138. break;
  139. case OVL_SYMBOL_CIRCLE:
  140. case OVL_SYMBOL_TRIANGLE:
  141. wpt = new Waypoint;
  142. wpt->shortname = symbol;
  143. if ((cx = inifile_readstr(inifile, symbol, "YKoord"))) {
  144. wpt->latitude = atof(cx);
  145. } else {
  146. continue;
  147. }
  148. if ((cx = inifile_readstr(inifile, symbol, "XKoord"))) {
  149. wpt->longitude = atof(cx);
  150. } else {
  151. continue;
  152. }
  153. waypt_add(wpt);
  154. break;
  155. case OVL_SYMBOL_BITMAP:
  156. case OVL_SYMBOL_TEXT:
  157. case OVL_SYMBOL_RECTANGLE:
  158. break;
  159. }
  160. }
  161. }
  162. /**************************************************************************/
  163. /* prototypes used in main functions */
  164. static void waypt_disp_cb(const Waypoint* wpt);
  165. static void track_disp_cb(const route_head* trk);
  166. static void route_disp_cb(const route_head* rte);
  167. static void write_bounds(void);
  168. static void draw_symbol_basics(const OVL_SYMBOL_TYP typ, const int art, const OVL_COLOR_TYP color, const Waypoint* wpt);
  169. static int get_direction(const Waypoint* A, const Waypoint* B);
  170. // static void draw_symbol_text(const char *text, const waypoint *reference);
  171. /* -----------------------------------------------------------------------*/
  172. static void
  173. ggv_ovl_wr_init(const QString& fname)
  174. {
  175. fout = gbfopen(fname, "w", MYNAME);
  176. symbol_ct = 0;
  177. }
  178. static void
  179. ggv_ovl_wr_deinit(void)
  180. {
  181. gbfclose(fout);
  182. }
  183. static void
  184. ggv_ovl_write(void)
  185. {
  186. group_ct = 1; /* tracks are not grouped */
  187. color = OVL_COLOR_FUCHSIA;
  188. track_disp_all(track_disp_cb, NULL, NULL);
  189. group_ct++;
  190. color = OVL_COLOR_AQUA;
  191. route_disp_all(route_disp_cb, NULL, NULL);
  192. group_ct++;
  193. color = OVL_COLOR_LIME;
  194. waypt_disp_all(waypt_disp_cb);
  195. gbfprintf(fout, "[Overlay]\n");
  196. gbfprintf(fout, "Symbols=%d\n", symbol_ct);
  197. gbfprintf(fout, "[MapLage]\n");
  198. gbfprintf(fout, "MapName=Bundesrepublik 1:1 Mio\n");
  199. gbfprintf(fout, "DimmFc=100\n");
  200. gbfprintf(fout, "ZoomFc=100\n");
  201. write_bounds();
  202. gbfprintf(fout, "RefOn=0\n"); /* no reference point */
  203. }
  204. /**************************************************************************/
  205. static void
  206. waypt_disp_cb(const Waypoint* wpt)
  207. {
  208. draw_symbol_basics(OVL_SYMBOL_CIRCLE, 1, color, wpt);
  209. gbfprintf(fout, "Width=20\n");
  210. gbfprintf(fout, "Height=20\n");
  211. gbfprintf(fout, "Dir=100\n");
  212. gbfprintf(fout, "Zoom=1\n");
  213. gbfprintf(fout, "Size=102\n");
  214. gbfprintf(fout, "Area=2\n");
  215. // draw_symbol_text(wpt->shortname, wpt);
  216. }
  217. /* -----------------------------------------------------------------------*/
  218. static void
  219. track_disp_cb(const route_head* trk)
  220. {
  221. int i;
  222. queue* elem, *tmp;
  223. int waypt_ct = trk->rte_waypt_ct;
  224. if (waypt_ct <= 0) {
  225. return;
  226. }
  227. draw_symbol_basics(OVL_SYMBOL_LINE, 1, color, NULL);
  228. gbfprintf(fout, "Zoom=1\n");
  229. gbfprintf(fout, "Size=105\n");
  230. gbfprintf(fout, "Punkte=%d\n", waypt_ct);
  231. i = 0;
  232. QUEUE_FOR_EACH(&(trk->waypoint_list), elem, tmp) {
  233. Waypoint* wpt = (Waypoint*) elem;
  234. gbfprintf(fout, "XKoord%d=%0.8f\n", i, wpt->longitude);
  235. gbfprintf(fout, "YKoord%d=%0.8f\n", i, wpt->latitude);
  236. i++;
  237. }
  238. }
  239. /* -----------------------------------------------------------------------*/
  240. static void
  241. route_disp_cb(const route_head* rte)
  242. {
  243. int i;
  244. queue* elem, *tmp;
  245. Waypoint* prev;
  246. int waypt_ct = rte->rte_waypt_ct;
  247. if (waypt_ct <= 0) {
  248. return;
  249. }
  250. track_disp_cb(rte); /* draw a line as tracks */
  251. color = OVL_COLOR_RED;
  252. i = 0;
  253. prev = NULL;
  254. QUEUE_FOR_EACH(&(rte->waypoint_list), elem, tmp) {
  255. Waypoint* wpt = (Waypoint*) elem;
  256. if (prev != NULL) {
  257. draw_symbol_basics(OVL_SYMBOL_TRIANGLE, 1, (OVL_COLOR_TYP)9 /* color */, prev);
  258. gbfprintf(fout, "Width=12\n");
  259. gbfprintf(fout, "Height=8\n");
  260. gbfprintf(fout, "Dir=%d\n", 100 + get_direction(prev, wpt));
  261. gbfprintf(fout, "Zoom=1\n");
  262. gbfprintf(fout, "Size=101\n");
  263. gbfprintf(fout, "Area=2\n");
  264. }
  265. i++;
  266. prev = wpt;
  267. }
  268. }
  269. /* -----------------------------------------------------------------------*/
  270. static void
  271. waypt_bound_calc(const Waypoint* waypointp)
  272. {
  273. waypt_add_to_bounds(&all_bounds, waypointp);
  274. }
  275. static void
  276. write_bounds(void)
  277. {
  278. waypt_init_bounds(&all_bounds);
  279. waypt_disp_all(waypt_bound_calc);
  280. route_disp_all(NULL, NULL, waypt_bound_calc);
  281. track_disp_all(NULL, NULL, waypt_bound_calc);
  282. if (waypt_bounds_valid(&all_bounds)) {
  283. double cx = all_bounds.min_lat + ((all_bounds.max_lat - all_bounds.min_lat) / 2);
  284. double cy = all_bounds.min_lon + ((all_bounds.max_lon - all_bounds.min_lon) / 2);
  285. gbfprintf(fout, "CenterLat=%0.8f\n", cx);
  286. gbfprintf(fout, "CenterLong=%0.8f\n", cy);
  287. } else {
  288. gbfprintf(fout, "CenterLong=10.52374295\n");
  289. gbfprintf(fout, "CenterLat=52.26474445\n");
  290. }
  291. }
  292. static void
  293. draw_symbol_basics(const OVL_SYMBOL_TYP typ, const int art, const OVL_COLOR_TYP color, const Waypoint* wpt)
  294. {
  295. symbol_ct++;
  296. gbfprintf(fout, "[Symbol %d]\n", symbol_ct);
  297. gbfprintf(fout, "Typ=%d\n", typ);
  298. gbfprintf(fout, "Group=%d\n", group_ct);
  299. gbfprintf(fout, "Col=%d\n", color);
  300. if (art >= 0) {
  301. gbfprintf(fout, "Art=%d\n", art);
  302. }
  303. if (wpt) {
  304. gbfprintf(fout, "XKoord=%.8f\n", wpt->longitude);
  305. gbfprintf(fout, "YKoord=%.8f\n", wpt->latitude);
  306. }
  307. }
  308. /* the following code comes from first overlay module */
  309. static int
  310. get_direction(const Waypoint* A, const Waypoint* B)
  311. {
  312. double lata, lona, latb, lonb;
  313. double dist, dir;
  314. int res;
  315. lata = RAD(A->latitude);
  316. lona = RAD(A->longitude);
  317. latb = RAD(B->latitude);
  318. lonb = RAD(B->longitude);
  319. dist = gcdist(lata, lona, latb, lonb);
  320. dir = acos((sin(latb) - sin(lata) * cos(dist)) / (cos(lata) * sin(dist)));
  321. if (lonb < lona) {
  322. dir = -dir;
  323. }
  324. res = (int) DEG(dir);
  325. res = 360 - (res + 270);
  326. if (res < 0) {
  327. res += 360;
  328. } else if (res > 360) {
  329. res -= 360.0;
  330. }
  331. return res;
  332. }
  333. #if 0
  334. static void
  335. draw_symbol_text(const char* text, const Waypoint* reference)
  336. {
  337. Waypoint wpt;
  338. if ((reference == NULL) || (text == NULL)) {
  339. return;
  340. }
  341. if (*text == '\0') {
  342. return;
  343. }
  344. wpt = *reference;
  345. wpt.latitude = wpt.latitude + 0.015;
  346. wpt.longitude = wpt.longitude + 0.015;
  347. draw_symbol_basics(OVL_SYMBOL_TEXT, -1, OVL_COLOR_BLACK, &wpt);
  348. gbfprintf(fout, "Area=1\n");
  349. gbfprintf(fout, "Zoom=1\n");
  350. gbfprintf(fout, "Size=120\n");
  351. gbfprintf(fout, "Font=3\n");
  352. gbfprintf(fout, "Dir=100\n");
  353. gbfprintf(fout, "Text=%s\n", text);
  354. }
  355. #endif
  356. /**************************************************************************/
  357. ff_vecs_t ggv_ovl_vecs = {
  358. ff_type_file,
  359. FF_CAP_RW_ALL,
  360. ggv_ovl_rd_init,
  361. ggv_ovl_wr_init,
  362. ggv_ovl_rd_deinit,
  363. ggv_ovl_wr_deinit,
  364. ggv_ovl_read,
  365. ggv_ovl_write,
  366. NULL,
  367. ggv_ovl_args,
  368. CET_CHARSET_MS_ANSI, 0
  369. };
  370. /**************************************************************************/