parse.c 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  1. #include <stdlib.h>
  2. #include <string.h>
  3. #include <unistd.h>
  4. #include <grass/glocale.h>
  5. #include "global.h"
  6. int parse_command_line(int argc, char *argv[])
  7. {
  8. char pl_desc[256];
  9. char pw_desc[256];
  10. int i;
  11. char *desc;
  12. struct
  13. {
  14. struct Option *cell;
  15. struct Option *units;
  16. struct Option *pl; /* page length */
  17. struct Option *pw; /* page width */
  18. struct Option *outfile;
  19. struct Option *nv;
  20. struct Option *nsteps;
  21. struct Option *sort;
  22. } parms;
  23. struct
  24. {
  25. struct Flag *f;
  26. struct Flag *m;
  27. struct Flag *h;
  28. struct Flag *q;
  29. struct Flag *e;
  30. struct Flag *n;
  31. struct Flag *N;
  32. struct Flag *i; /* use quant rules for fp map,
  33. i.e. read it as int */
  34. struct Flag *C; /* report for fp ranges in Cats file
  35. (fp maps only) */
  36. } flags;
  37. parms.cell = G_define_standard_option(G_OPT_R_MAPS);
  38. parms.cell->description = _("Name of raster map(s) to report on");
  39. parms.units = G_define_option();
  40. parms.units->key = "units";
  41. parms.units->type = TYPE_STRING;
  42. parms.units->required = NO;
  43. parms.units->multiple = YES;
  44. parms.units->description = _("Units to report");
  45. desc = NULL;
  46. G_asprintf(&desc,
  47. "mi;%s;me;%s;k;%s;a;%s;h;%s;c;%s;p;%s",
  48. _("area in square miles"),
  49. _("area in square meters"),
  50. _("area in square kilometers"),
  51. _("area in acres"),
  52. _("area in hectares"),
  53. _("number of cells"),
  54. _("percent cover"));
  55. parms.units->descriptions = desc;
  56. parms.units->options = "mi,me,k,a,h,c,p";
  57. parms.units->guisection = _("Statistics");
  58. parms.outfile = G_define_standard_option(G_OPT_F_OUTPUT);
  59. parms.outfile->required = NO;
  60. parms.outfile->label =
  61. _("Name for output file to hold the report");
  62. parms.outfile->description =
  63. _("If no output given report is printed to standard output");
  64. parms.nv = G_define_option();
  65. parms.nv->key = "null";
  66. parms.nv->type = TYPE_STRING;
  67. parms.nv->required = NO;
  68. parms.nv->multiple = NO;
  69. parms.nv->answer = "*";
  70. parms.nv->description = _("String representing no data cell value");
  71. parms.nv->guisection = _("Formatting");
  72. parms.pl = G_define_option();
  73. parms.pl->key = "pl";
  74. parms.pl->type = TYPE_INTEGER;
  75. parms.pl->required = NO;
  76. sprintf(pl_desc, _("Page length (default: %d lines)"),
  77. DEFAULT_PAGE_LENGTH);
  78. parms.pl->description = pl_desc;
  79. parms.pl->guisection = _("Formatting");
  80. parms.pw = G_define_option();
  81. parms.pw->key = "pw";
  82. parms.pw->type = TYPE_INTEGER;
  83. parms.pw->required = NO;
  84. sprintf(pw_desc, _("Page width (default: %d characters)"),
  85. DEFAULT_PAGE_WIDTH);
  86. parms.pw->description = pw_desc;
  87. parms.pw->guisection = _("Formatting");
  88. parms.nsteps = G_define_option();
  89. parms.nsteps->key = "nsteps";
  90. parms.nsteps->type = TYPE_INTEGER;
  91. parms.nsteps->required = NO;
  92. parms.nsteps->multiple = NO;
  93. parms.nsteps->answer = "255";
  94. parms.nsteps->description =
  95. _("Number of floating-point subranges to collect stats from");
  96. parms.nsteps->guisection = _("Floating point");
  97. parms.sort = G_define_option();
  98. parms.sort->key = "sort";
  99. parms.sort->type = TYPE_STRING;
  100. parms.sort->required = NO;
  101. parms.sort->multiple = NO;
  102. parms.sort->label = _("Sort output statistics by cell counts");
  103. parms.sort->description = _("Default: sorted by categories or intervals");
  104. parms.sort->options = "asc,desc";
  105. G_asprintf((char **)&(parms.sort->descriptions),
  106. "asc;%s;desc;%s",
  107. _("Sort by cell counts in ascending order"),
  108. _("Sort by cell counts in descending order"));
  109. parms.sort->guisection = _("Formatting");
  110. flags.h = G_define_flag();
  111. flags.h->key = 'h';
  112. flags.h->description = _("Suppress page headers");
  113. flags.h->guisection = _("Formatting");
  114. flags.f = G_define_flag();
  115. flags.f->key = 'f';
  116. flags.f->description = _("Use formfeeds between pages");
  117. flags.f->guisection = _("Formatting");
  118. flags.e = G_define_flag();
  119. flags.e->key = 'e';
  120. flags.e->description = _("Scientific format");
  121. flags.e->guisection = _("Formatting");
  122. flags.n = G_define_flag();
  123. flags.n->key = 'n';
  124. flags.n->description = _("Do not report no data value");
  125. flags.n->guisection = _("No data");
  126. flags.N = G_define_flag();
  127. flags.N->key = 'N';
  128. flags.N->description = _("Do not report cells where all maps have no data");
  129. flags.N->guisection = _("No data");
  130. flags.C = G_define_flag();
  131. flags.C->key = 'C';
  132. flags.C->description = _("Report for cats floating-point ranges (floating-point maps only)");
  133. flags.C->guisection = _("Floating point");
  134. flags.i = G_define_flag();
  135. flags.i->key = 'i';
  136. flags.i->description =
  137. _("Read floating-point map as integer (use map's quant rules)");
  138. flags.i->guisection = _("Floating point");
  139. /* hidden feature.
  140. * if first arg is >file just run r.stats into this file and quit
  141. * if first arg is <file, run report from stats in file
  142. * (this feature is for the interactive version of this program -
  143. * to get more than one report without re-running r.stats)
  144. */
  145. stats_flag = EVERYTHING;
  146. if (argc > 1) {
  147. if (argv[1][0] == '<' || argv[1][0] == '>') {
  148. stats_file = argv[1] + 1;
  149. if (argv[1][0] == '<')
  150. stats_flag = REPORT_ONLY;
  151. else {
  152. unlink(stats_file);
  153. stats_flag = STATS_ONLY;
  154. }
  155. argc--;
  156. argv++;
  157. }
  158. }
  159. if (G_parser(argc, argv))
  160. exit(EXIT_FAILURE);
  161. use_formfeed = flags.f->answer;
  162. with_headers = !flags.h->answer;
  163. e_format = flags.e->answer;
  164. no_nulls = flags.n->answer;
  165. no_nulls_all = flags.N->answer;
  166. cat_ranges = flags.C->answer;
  167. as_int = flags.i->answer;
  168. for (i = 0; parms.cell->answers[i]; i++)
  169. parse_layer(parms.cell->answers[i]);
  170. if (parms.units->answers)
  171. for (i = 0; parms.units->answers[i]; i++)
  172. parse_units(parms.units->answers[i]);
  173. sscanf(parms.nsteps->answer, "%d", &nsteps);
  174. if (nsteps <= 0) {
  175. G_warning(_("nsteps has to be > 0; using nsteps=255"));
  176. nsteps = 255;
  177. }
  178. if (parms.pl->answer) {
  179. if (sscanf(parms.pl->answer, "%d", &page_length) != 1 ||
  180. page_length < 0) {
  181. G_fatal_error(_("Illegal page length"));
  182. }
  183. }
  184. if (parms.pw->answer) {
  185. if (sscanf(parms.pw->answer, "%d", &page_width) != 1 ||
  186. page_width < 1) {
  187. G_fatal_error(_("Illegal page width"));
  188. }
  189. }
  190. if (parms.outfile->answer) {
  191. if (freopen(parms.outfile->answer, "w", stdout) == NULL) {
  192. perror(parms.outfile->answer);
  193. exit(EXIT_FAILURE);
  194. }
  195. }
  196. no_data_str = parms.nv->answer;
  197. /* determine sorting method */
  198. do_sort = SORT_DEFAULT; /* sort by cats by default */
  199. if (parms.sort->answer) {
  200. switch(parms.sort->answer[0]) {
  201. case 'a':
  202. do_sort = SORT_ASC;
  203. break;
  204. case 'd':
  205. do_sort = SORT_DESC;
  206. break;
  207. default:
  208. G_debug(1, "Sorting by '%s' not supported", parms.sort->answer);
  209. break;
  210. }
  211. }
  212. return 0;
  213. }
  214. int parse_units(char *s)
  215. {
  216. int x;
  217. if (match(s, "miles", 2))
  218. x = SQ_MILES;
  219. else if (match(s, "meters", 2))
  220. x = SQ_METERS;
  221. else if (match(s, "kilometers", 1))
  222. x = SQ_KILOMETERS;
  223. else if (match(s, "acres", 1))
  224. x = ACRES;
  225. else if (match(s, "hectares", 1))
  226. x = HECTARES;
  227. else if (match(s, "cell_counts", 1))
  228. x = CELL_COUNTS;
  229. else if (match(s, "counts", 1))
  230. x = CELL_COUNTS;
  231. else if (match(s, "percent_cover", 1))
  232. x = PERCENT_COVER;
  233. else {
  234. G_usage();
  235. exit(EXIT_FAILURE);
  236. }
  237. if (nunits >= MAX_UNITS) {
  238. G_fatal_error(_("Only %d unit%s allowed"),
  239. MAX_UNITS, MAX_UNITS == 1 ? "" : "s");
  240. }
  241. unit[nunits].type = x;
  242. nunits++;
  243. return 0;
  244. }
  245. int parse_layer(char *s)
  246. {
  247. char name[GNAME_MAX];
  248. const char *mapset;
  249. struct FPRange fp_range;
  250. int n;
  251. strcpy(name, s);
  252. mapset = G_find_raster2(name, "");
  253. if (mapset == NULL)
  254. G_fatal_error(_("Raster map <%s> not found"), s);
  255. n = nlayers++;
  256. layers = (LAYER *) G_realloc(layers, nlayers * sizeof(LAYER));
  257. is_fp = (int *)G_realloc(is_fp, (nlayers + 1) * sizeof(int));
  258. DMAX = (DCELL *) G_realloc(DMAX, (nlayers + 1) * sizeof(DCELL));
  259. DMIN = (DCELL *) G_realloc(DMIN, (nlayers + 1) * sizeof(DCELL));
  260. if (!as_int)
  261. is_fp[n] = Rast_map_is_fp(name, mapset);
  262. else
  263. is_fp[n] = 0;
  264. if (is_fp[n]) {
  265. if (Rast_read_fp_range(name, mapset, &fp_range) < 0)
  266. G_fatal_error(_("Unable to read fp range for raster map <%s>"),
  267. name);
  268. Rast_get_fp_range_min_max(&fp_range, &DMIN[n], &DMAX[n]);
  269. }
  270. layers[n].name = G_store(name);
  271. layers[n].mapset = mapset;
  272. if (Rast_read_cats(name, mapset, &layers[n].labels) < 0)
  273. G_fatal_error(_("Unable to read category file of raster map <%s@%s>"),
  274. name, mapset);
  275. return 0;
  276. }
  277. int match(char *s, char *key, int min)
  278. {
  279. size_t len;
  280. len = strlen(s);
  281. if ((int) len < min)
  282. return 0;
  283. return strncmp(s, key, len) == 0;
  284. }