main.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447
  1. /****************************************************************************
  2. *
  3. * MODULE: i.group
  4. * AUTHOR(S): Michael Shapiro (USACERL) (original contributor)
  5. * Bob Covill <bcovill tekmap.ns.ca>,
  6. * Markus Neteler <neteler itc.it>,
  7. * Bernhard Reiter <bernhard intevation.de>,
  8. * Brad Douglas <rez touchofmadness.com>,
  9. * Glynn Clements <glynn gclements.plus.com>,
  10. * Hamish Bowman <hamish_b yahoo.com>
  11. * PURPOSE: collect raster map layers into an imagery group by assigning
  12. * them to user-named subgroups or other groups
  13. * COPYRIGHT: (C) 2001-2007, 2011, 2013 by the GRASS Development Team
  14. *
  15. * This program is free software under the GNU General Public
  16. * License (>=v2). Read the file COPYING that comes with GRASS
  17. * for details.
  18. *
  19. *****************************************************************************/
  20. #include <stdlib.h>
  21. #include <string.h>
  22. #include <grass/gis.h>
  23. #include <grass/imagery.h>
  24. #include <grass/glocale.h>
  25. /* function prototypes */
  26. static int add_or_update_group(char group[INAME_LEN], char **rasters, int k);
  27. static int add_or_update_subgroup(char group[INAME_LEN],
  28. char subgroup[INAME_LEN], char **rasters,
  29. int k);
  30. static int remove_group_files(char group[INAME_LEN], char **rasters, int k);
  31. static int remove_subgroup_files(char group[INAME_LEN],
  32. char subgroup[INAME_LEN], char **rasters,
  33. int k);
  34. static void print_subgroups(char *group, int simple);
  35. int main(int argc, char *argv[])
  36. {
  37. char group[GNAME_MAX], mapset[GMAPSET_MAX];
  38. int m, k = 0;
  39. struct Option *grp, *rast, *sgrp;
  40. struct Flag *r, *l, *s, *simple_flag;
  41. struct GModule *module;
  42. G_gisinit(argv[0]);
  43. module = G_define_module();
  44. G_add_keyword(_("imagery"));
  45. G_add_keyword(_("map management"));
  46. module->description =
  47. _("Creates, edits, and lists groups of imagery data.");
  48. /* Get Args */
  49. grp = G_define_standard_option(G_OPT_I_GROUP);
  50. grp->description = _("Name of imagery group");
  51. sgrp = G_define_standard_option(G_OPT_I_SUBGROUP);
  52. sgrp->required = NO;
  53. sgrp->description = _("Name of imagery subgroup");
  54. rast = G_define_standard_option(G_OPT_R_INPUTS);
  55. rast->required = NO; /* -l flag */
  56. rast->description = _("Name of raster map(s) to include in group");
  57. rast->guisection = _("Maps");
  58. r = G_define_flag();
  59. r->key = 'r';
  60. r->description =
  61. _("Remove selected files from specified group or subgroup");
  62. r->guisection = _("Maps");
  63. l = G_define_flag();
  64. l->key = 'l';
  65. l->description = _("List files from specified (sub)group");
  66. l->guisection = _("Print");
  67. s = G_define_flag();
  68. s->key = 's';
  69. s->description = _("List subgroups from specified group");
  70. s->guisection = _("Print");
  71. simple_flag = G_define_flag();
  72. simple_flag->key = 'g';
  73. simple_flag->description = _("Print in shell script style");
  74. simple_flag->guisection = _("Print");
  75. if (G_parser(argc, argv))
  76. exit(EXIT_FAILURE);
  77. /* backward comaptibility -> simple list implied l flag list, if there was only l flag
  78. (with s flag added it is not clear, simple_flag is linked to both) */
  79. if ((simple_flag->answer && !s->answer) && !l->answer)
  80. l->answer = TRUE;
  81. /* Determine number of files to include */
  82. if (rast->answers) {
  83. for (m = 0; rast->answers[m]; m++) {
  84. k = m;
  85. }
  86. k++;
  87. }
  88. if (k < 1 && !(l->answer || s->answer)) /* remove if input is requirement */
  89. G_fatal_error(_("No input raster map(s) specified"));
  90. /* check if current mapset: (imagery libs are very lacking in this dept)
  91. - abort if not,
  92. - remove @mapset part if it is
  93. */
  94. if (G_name_is_fully_qualified(grp->answer, group, mapset)) {
  95. if (strcmp(mapset, G_mapset()))
  96. G_fatal_error(_("Group must exist in the current mapset"));
  97. }
  98. else {
  99. strcpy(group, grp->answer); /* FIXME for buffer overflow (have the parser check that?) */
  100. }
  101. if (r->answer) {
  102. /* Remove files from Group */
  103. if (I_find_group(group) == 0) {
  104. G_fatal_error(_
  105. ("Specified group does not exist in current mapset"));
  106. }
  107. if (sgrp->answer) {
  108. G_verbose_message(_("Removing raster maps from subgroup <%s>..."),
  109. sgrp->answer);
  110. remove_subgroup_files(group, sgrp->answer, rast->answers, k);
  111. }
  112. else {
  113. G_verbose_message(_("Removing raster maps from group <%s>..."),
  114. group);
  115. remove_group_files(group, rast->answers, k);
  116. }
  117. }
  118. else {
  119. if (l->answer || s->answer) {
  120. /* List raster maps in group */
  121. struct Ref ref;
  122. if (I_find_group(group) == 0) {
  123. G_fatal_error(_
  124. ("Specified group does not exist in current mapset"));
  125. }
  126. if (sgrp->answer) {
  127. /* list subgroup files */
  128. I_get_subgroup_ref(group, sgrp->answer, &ref);
  129. if (simple_flag->answer) {
  130. G_message(_
  131. ("Subgroup <%s> of group <%s> references the following raster maps:"),
  132. sgrp->answer, group);
  133. I_list_subgroup_simple(&ref, stdout);
  134. }
  135. else
  136. I_list_subgroup(group, sgrp->answer, &ref, stdout);
  137. }
  138. else if (s->answer) {
  139. print_subgroups(group, simple_flag->answer);
  140. }
  141. else {
  142. /* list group files */
  143. I_get_group_ref(group, &ref);
  144. if (simple_flag->answer) {
  145. G_message(_
  146. ("Group <%s> references the following raster maps:"),
  147. group);
  148. I_list_group_simple(&ref, stdout);
  149. }
  150. else
  151. I_list_group(group, &ref, stdout);
  152. }
  153. }
  154. else {
  155. /* Create or update Group REF */
  156. if (I_find_group(group) == 0)
  157. G_verbose_message(_
  158. ("Group <%s> does not yet exist. Creating..."),
  159. group);
  160. if (sgrp->answer) {
  161. G_verbose_message(_("Adding raster maps to group <%s>..."),
  162. group);
  163. add_or_update_group(group, rast->answers, k);
  164. G_verbose_message(_("Adding raster maps to subgroup <%s>..."),
  165. sgrp->answer);
  166. add_or_update_subgroup(group, sgrp->answer, rast->answers, k);
  167. }
  168. else {
  169. G_verbose_message(_("Adding raster maps to group <%s>..."),
  170. group);
  171. add_or_update_group(group, rast->answers, k);
  172. }
  173. }
  174. }
  175. return EXIT_SUCCESS;
  176. }
  177. static int add_or_update_group(char group[INAME_LEN], char **rasters, int k)
  178. {
  179. int m, n, skip;
  180. struct Ref ref;
  181. const char *mapset;
  182. I_get_group_ref(group, &ref);
  183. for (m = 0; m < k; m++) {
  184. skip = 0;
  185. if ((mapset = G_find_raster(rasters[m], "")) == NULL) {
  186. G_warning(_("Raster map <%s> not found. Skipped."), rasters[m]);
  187. skip = 1;
  188. continue;
  189. }
  190. G_message(_("Adding raster map <%s> to group"),
  191. G_fully_qualified_name(rasters[m], mapset));
  192. /* Go through existing files to check for duplicates */
  193. for (n = 0; n < ref.nfiles; n++) {
  194. if (strcmp(rasters[m], ref.file[n].name) == 0) {
  195. G_message(_("Raster map <%s> exists in group. Skipped."),
  196. G_fully_qualified_name(rasters[m], mapset));
  197. skip = 1;
  198. continue;
  199. }
  200. }
  201. if (skip == 0)
  202. I_add_file_to_group_ref(rasters[m], mapset, &ref);
  203. }
  204. G_debug(1, "writing group REF");
  205. I_put_group_ref(group, &ref);
  206. return 0;
  207. }
  208. static int add_or_update_subgroup(char group[INAME_LEN],
  209. char subgroup[INAME_LEN], char **rasters,
  210. int k)
  211. {
  212. int m, n, skip;
  213. struct Ref ref;
  214. const char *mapset;
  215. I_get_subgroup_ref(group, subgroup, &ref);
  216. for (m = 0; m < k; m++) {
  217. skip = 0;
  218. if ((mapset = G_find_raster(rasters[m], "")) == NULL) {
  219. G_warning(_("Raster map <%s> not found. Skipped."),
  220. rasters[m]);
  221. skip = 1;
  222. continue;
  223. }
  224. G_message(_("Adding raster map <%s> to subgroup"),
  225. G_fully_qualified_name(rasters[m], mapset));
  226. /* Go through existing files to check for duplicates */
  227. for (n = 0; n < ref.nfiles; n++) {
  228. if (strcmp(rasters[m], ref.file[n].name) == 0) {
  229. G_message(_
  230. ("Raster map <%s> exists in subgroup. Skipping..."),
  231. G_fully_qualified_name(rasters[m], mapset));
  232. skip = 1;
  233. continue;
  234. }
  235. }
  236. if (skip == 0)
  237. I_add_file_to_group_ref(rasters[m], mapset, &ref);
  238. }
  239. G_debug(1, "writing subgroup REF");
  240. I_put_subgroup_ref(group, subgroup, &ref);
  241. return 0;
  242. }
  243. static int remove_group_files(char group[INAME_LEN], char **rasters, int k)
  244. {
  245. int m, n, skip;
  246. struct Ref ref;
  247. struct Ref ref_tmp;
  248. const char *mapset;
  249. char tmp_name[INAME_LEN];
  250. char xname[GNAME_MAX], xmapset[GMAPSET_MAX];
  251. I_get_group_ref(group, &ref_tmp);
  252. I_init_group_ref(&ref);
  253. G_debug(3, "remove_group_files: ref_tmp.nfiles %d", ref_tmp.nfiles);
  254. /* Go through existing files to check for duplicates */
  255. for (m = 0; m < ref_tmp.nfiles; m++) {
  256. skip = 0;
  257. /* Parse through supplied rasters */
  258. for (n = 0; n < k; n++) {
  259. strcpy(tmp_name, rasters[n]);
  260. mapset = G_mapset();
  261. /* Parse out mapset */
  262. if (G_name_is_fully_qualified(rasters[n], xname, xmapset)) {
  263. strcpy(tmp_name, xname);
  264. mapset = xmapset;
  265. }
  266. G_debug(3, "tmp_name %s, ref_tmp.file[%d].name: %s", tmp_name, m,
  267. ref_tmp.file[m].name);
  268. if ((strcmp(tmp_name, ref_tmp.file[m].name) == 0) &&
  269. (strcmp(mapset, ref_tmp.file[m].mapset) == 0)) {
  270. G_message(_("Removing raster map <%s> from group"),
  271. G_fully_qualified_name(tmp_name, mapset));
  272. skip = 1;
  273. break;
  274. }
  275. }
  276. if (skip == 0) {
  277. I_add_file_to_group_ref(ref_tmp.file[m].name,
  278. ref_tmp.file[m].mapset, &ref);
  279. }
  280. }
  281. G_debug(1, "writing group REF");
  282. I_put_group_ref(group, &ref);
  283. if (ref.nfiles == ref_tmp.nfiles) {
  284. G_warning(_("No raster map removed"));
  285. }
  286. return 0;
  287. }
  288. static int remove_subgroup_files(char group[INAME_LEN],
  289. char subgroup[INAME_LEN], char **rasters,
  290. int k)
  291. {
  292. int m, n, skip;
  293. struct Ref ref;
  294. struct Ref ref_tmp;
  295. const char *mapset;
  296. char tmp_name[INAME_LEN];
  297. char xname[GNAME_MAX], xmapset[GMAPSET_MAX];
  298. I_get_subgroup_ref(group, subgroup, &ref_tmp);
  299. I_init_group_ref(&ref);
  300. G_debug(3, "remove_subgroup_files: ref_tmp.nfiles %d", ref_tmp.nfiles);
  301. /* Go through existing files to check for duplicates */
  302. for (m = 0; m < ref_tmp.nfiles; m++) {
  303. skip = 0;
  304. /* Parse through supplied rasters */
  305. for (n = 0; n < k; n++) {
  306. strcpy(tmp_name, rasters[n]);
  307. mapset = G_mapset();
  308. /* Parse out mapset */
  309. if (G_name_is_fully_qualified(rasters[n], xname, xmapset)) {
  310. strcpy(tmp_name, xname);
  311. mapset = xmapset;
  312. }
  313. G_debug(3, "tmp_name %s, ref_tmp.file[%d].name: %s", tmp_name, m,
  314. ref_tmp.file[m].name);
  315. G_debug(3, "mapset %s, ref_tmp.file[%d].mapset: %s", mapset, m,
  316. ref_tmp.file[m].mapset);
  317. if ((strcmp(tmp_name, ref_tmp.file[m].name) == 0) &&
  318. (strcmp(mapset, ref_tmp.file[m].mapset) == 0)) {
  319. G_message(_("Removing raster map <%s> from subgroup"),
  320. G_fully_qualified_name(tmp_name, mapset));
  321. skip = 1;
  322. break;
  323. }
  324. }
  325. if (skip == 0) {
  326. I_add_file_to_group_ref(ref_tmp.file[m].name,
  327. ref_tmp.file[m].mapset, &ref);
  328. }
  329. }
  330. G_debug(1, "writing subgroup REF");
  331. I_put_subgroup_ref(group, subgroup, &ref);
  332. if (ref.nfiles == ref_tmp.nfiles) {
  333. G_warning(_("No raster map removed"));
  334. }
  335. return 0;
  336. }
  337. static void print_subgroups(char *group, int simple)
  338. {
  339. int subgs_num, i;
  340. int len, tot_len;
  341. int max;
  342. char **subgs;
  343. subgs = I_list_subgroups(group, &subgs_num);
  344. if (simple)
  345. for (i = 0; i < subgs_num; i++)
  346. fprintf(stdout, "%s\n", subgs[i]);
  347. else {
  348. if (subgs_num <= 0) {
  349. fprintf(stdout, _("Group <%s> does not contain any subgroup.\n"),
  350. group);
  351. return;
  352. }
  353. max = 0;
  354. for (i = 0; i < subgs_num; i++) {
  355. len = strlen(subgs[i]) + 4;
  356. if (len > max)
  357. max = len;
  358. }
  359. fprintf(stdout,
  360. _("group <%s> references the following subgroups\n"), group);
  361. fprintf(stdout, "-------------\n");
  362. tot_len = 0;
  363. for (i = 0; i < subgs_num; i++) {
  364. tot_len += max;
  365. if (tot_len > 78) {
  366. fprintf(stdout, "\n");
  367. tot_len = max;
  368. }
  369. fprintf(stdout, "%-*s", max, subgs[i]);
  370. }
  371. if (tot_len)
  372. fprintf(stdout, "\n");
  373. fprintf(stdout, "-------------\n");
  374. }
  375. G_free(subgs);
  376. return;
  377. }