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.

filter_vecs.cc 8.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390
  1. /*
  2. Describe vectors containing filter operations.
  3. Copyright (C) 2002-2014 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 "filterdefs.h"
  18. #include "inifile.h"
  19. #include "gbversion.h"
  20. #include <QtCore/QStringList>
  21. #include <stdlib.h> // qsort
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. typedef struct {
  25. filter_vecs_t* vec;
  26. const char* name;
  27. const char* desc;
  28. } fl_vecs_t;
  29. extern filter_vecs_t bend_vecs;
  30. extern filter_vecs_t position_vecs;
  31. extern filter_vecs_t radius_vecs;
  32. extern filter_vecs_t duplicate_vecs;
  33. extern filter_vecs_t arcdist_vecs;
  34. extern filter_vecs_t polygon_vecs;
  35. extern filter_vecs_t routesimple_vecs;
  36. extern filter_vecs_t reverse_route_vecs;
  37. extern filter_vecs_t sort_vecs;
  38. extern filter_vecs_t stackfilt_vecs;
  39. extern filter_vecs_t trackfilter_vecs;
  40. extern filter_vecs_t discard_vecs;
  41. extern filter_vecs_t nuke_vecs;
  42. extern filter_vecs_t interpolatefilt_vecs;
  43. extern filter_vecs_t transform_vecs;
  44. extern filter_vecs_t height_vecs;
  45. extern filter_vecs_t swapdata_vecs;
  46. extern filter_vecs_t validate_vecs;
  47. static
  48. fl_vecs_t filter_vec_list[] = {
  49. #if FILTERS_ENABLED
  50. {
  51. &arcdist_vecs,
  52. "arc",
  53. "Include Only Points Within Distance of Arc",
  54. },
  55. {
  56. &bend_vecs,
  57. "bend",
  58. "Add points before and after bends in routes"
  59. },
  60. {
  61. &discard_vecs,
  62. "discard",
  63. "Remove unreliable points with high hdop or vdop"
  64. },
  65. {
  66. &duplicate_vecs,
  67. "duplicate",
  68. "Remove Duplicates",
  69. },
  70. {
  71. &interpolatefilt_vecs,
  72. "interpolate",
  73. "Interpolate between trackpoints"
  74. },
  75. {
  76. &nuke_vecs,
  77. "nuketypes",
  78. "Remove all waypoints, tracks, or routes"
  79. },
  80. {
  81. &polygon_vecs,
  82. "polygon",
  83. "Include Only Points Inside Polygon",
  84. },
  85. {
  86. &position_vecs,
  87. "position",
  88. "Remove Points Within Distance",
  89. },
  90. {
  91. &radius_vecs,
  92. "radius",
  93. "Include Only Points Within Radius",
  94. },
  95. {
  96. &routesimple_vecs,
  97. "simplify",
  98. "Simplify routes",
  99. },
  100. {
  101. &sort_vecs,
  102. "sort",
  103. "Rearrange waypoints by resorting",
  104. },
  105. {
  106. &stackfilt_vecs,
  107. "stack",
  108. "Save and restore waypoint lists"
  109. },
  110. {
  111. &reverse_route_vecs,
  112. "reverse",
  113. "Reverse stops within routes",
  114. },
  115. {
  116. &trackfilter_vecs,
  117. "track",
  118. "Manipulate track lists"
  119. },
  120. {
  121. &transform_vecs,
  122. "transform",
  123. "Transform waypoints into a route, tracks into routes, ..."
  124. },
  125. {
  126. &height_vecs,
  127. "height",
  128. "Manipulate altitudes"
  129. },
  130. {
  131. &swapdata_vecs,
  132. "swap",
  133. "Swap latitude and longitude of all loaded points"
  134. },
  135. {
  136. &validate_vecs,
  137. "validate",
  138. "Validate internal data structures"
  139. },
  140. #elif defined (MINIMAL_FILTERS)
  141. {
  142. &trackfilter_vecs,
  143. "track",
  144. "Manipulate track lists"
  145. },
  146. #endif
  147. {
  148. NULL,
  149. NULL,
  150. NULL
  151. }
  152. };
  153. filter_vecs_t*
  154. find_filter_vec(char* const vecname, char** opts)
  155. {
  156. fl_vecs_t* vec = filter_vec_list;
  157. char* v = xstrdup(vecname);
  158. QString svecname = QString(v).split(",")[0];
  159. int found = 0;
  160. while (vec->vec) {
  161. arglist_t* ap;
  162. char* res;
  163. if (svecname.compare(vec->name, Qt::CaseInsensitive)) {
  164. vec++;
  165. continue;
  166. }
  167. /* step 1: initialize by inifile or default values */
  168. if (vec->vec->args) {
  169. for (ap = vec->vec->args; ap->argstring; ap++) {
  170. const char* temp;
  171. temp = inifile_readstr(global_opts.inifile, vec->name, ap->argstring);
  172. if (temp == NULL) {
  173. temp = inifile_readstr(global_opts.inifile, "Common filter settings", ap->argstring);
  174. }
  175. if (temp == NULL) {
  176. temp = ap->defaultvalue;
  177. }
  178. assign_option(vec->name, ap, temp);
  179. }
  180. }
  181. /* step 2: override settings with command-line values */
  182. res = strchr(vecname, ',');
  183. if (res) {
  184. *opts = res+1;
  185. if (vec->vec->args) {
  186. for (ap = vec->vec->args; ap->argstring; ap++) {
  187. char* opt;
  188. opt = get_option(*opts, ap->argstring);
  189. if (opt) {
  190. found = 1;
  191. assign_option(vec->name, ap, opt);
  192. xfree(opt);
  193. }
  194. }
  195. }
  196. } else {
  197. *opts = NULL;
  198. }
  199. if (opts && opts[0] && !found) {
  200. warning("'%s' is an unknown option to %s.\n", *opts, vec->name);
  201. }
  202. if (global_opts.debug_level >= 1) {
  203. disp_vec_options(vec->name, vec->vec->args);
  204. }
  205. xfree(v);
  206. return vec->vec;
  207. }
  208. xfree(v);
  209. return NULL;
  210. }
  211. void
  212. free_filter_vec(filter_vecs_t* fvec)
  213. {
  214. arglist_t* ap;
  215. if (fvec->args) {
  216. for (ap = fvec->args; ap->argstring; ap++) {
  217. if (ap->argvalptr) {
  218. xfree(ap->argvalptr);
  219. ap->argvalptr = *ap->argval = NULL;
  220. }
  221. }
  222. }
  223. }
  224. void
  225. init_filter_vecs(void)
  226. {
  227. fl_vecs_t* vec = filter_vec_list;
  228. while (vec->vec) {
  229. arglist_t* ap;
  230. if (vec->vec->args) {
  231. for (ap = vec->vec->args; ap->argstring; ap++) {
  232. ap->argvalptr = NULL;
  233. }
  234. }
  235. vec++;
  236. }
  237. }
  238. void
  239. exit_filter_vecs(void)
  240. {
  241. fl_vecs_t* vec = filter_vec_list;
  242. while (vec->vec) {
  243. if (vec->vec->f_exit) {
  244. (vec->vec->f_exit)();
  245. }
  246. vec++;
  247. }
  248. }
  249. /*
  250. * Display the available formats in a format that's easy for humans to
  251. * parse for help on available command line options.
  252. */
  253. void
  254. disp_filter_vecs(void)
  255. {
  256. fl_vecs_t* vec;
  257. arglist_t* ap;
  258. for (vec = filter_vec_list; vec->vec; vec++) {
  259. printf(" %-20.20s %-50.50s\n",
  260. vec->name, vec->desc);
  261. for (ap = vec->vec->args; ap && ap->argstring; ap++) {
  262. if (!(ap->argtype & ARGTYPE_HIDDEN))
  263. printf(" %-18.18s %-.50s %s\n",
  264. ap->argstring, ap->helpstring,
  265. (ap->argtype&ARGTYPE_REQUIRED)?"(required)":"");
  266. }
  267. }
  268. }
  269. void
  270. disp_filter_vec(const char* vecname)
  271. {
  272. fl_vecs_t* vec;
  273. arglist_t* ap;
  274. for (vec = filter_vec_list; vec->vec; vec++) {
  275. if (case_ignore_strcmp(vec->name, vecname)) {
  276. continue;
  277. }
  278. printf(" %-20.20s %-50.50s\n",
  279. vec->name, vec->desc);
  280. for (ap = vec->vec->args; ap && ap->argstring; ap++) {
  281. if (!(ap->argtype & ARGTYPE_HIDDEN))
  282. printf(" %-18.18s %-.50s %s\n",
  283. ap->argstring, ap->helpstring,
  284. (ap->argtype&ARGTYPE_REQUIRED)?"(required)":"");
  285. }
  286. }
  287. }
  288. static signed int
  289. alpha(const void* a, const void* b)
  290. {
  291. const fl_vecs_t* const ap = (const fl_vecs_t*) a;
  292. const fl_vecs_t* const bp = (const fl_vecs_t*) b;
  293. return case_ignore_strcmp(ap->desc , bp->desc);
  294. }
  295. static
  296. void disp_help_url(const fl_vecs_t* vec, arglist_t* arg)
  297. {
  298. printf("\t" WEB_DOC_DIR "/fmt_%s.html", vec->name);
  299. if (arg) {
  300. printf("#fmt_%s_o_%s",vec->name, arg->argstring);
  301. }
  302. }
  303. static void
  304. disp_v1(const fl_vecs_t* vec)
  305. {
  306. arglist_t* ap;
  307. disp_help_url(vec, NULL);
  308. printf("\n");
  309. for (ap = vec->vec->args; ap && ap->argstring; ap++) {
  310. if (!(ap->argtype & ARGTYPE_HIDDEN)) {
  311. printf("option\t%s\t%s\t%s\t%s\t%s\t%s\t%s",
  312. vec->name,
  313. ap->argstring,
  314. ap->helpstring,
  315. name_option(ap->argtype),
  316. ap->defaultvalue? ap->defaultvalue : "",
  317. ap->minvalue? ap->minvalue : "",
  318. ap->maxvalue? ap->maxvalue : "");
  319. disp_help_url(vec, ap);
  320. printf("\n");
  321. }
  322. }
  323. }
  324. /*
  325. * Display the available formats in a format that's easy to machine
  326. * parse. Typically invoked by programs like graphical wrappers to
  327. * determine what formats are supported.
  328. */
  329. void
  330. disp_filters(int version)
  331. {
  332. fl_vecs_t* vec;
  333. qsort(filter_vec_list,
  334. sizeof(filter_vec_list) / sizeof(filter_vec_list[0]) - 1,
  335. sizeof(filter_vec_list[0]),
  336. alpha);
  337. switch (version) {
  338. case 0:
  339. case 1:
  340. for (vec = filter_vec_list; vec->vec; vec++) {
  341. if (version == 0) {
  342. printf("%s\t%s\n", vec->name, vec->desc);
  343. } else {
  344. printf("%s\t%s", vec->name, vec->desc);
  345. disp_v1(vec);
  346. }
  347. }
  348. break;
  349. default:
  350. ;
  351. }
  352. }