main.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379
  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 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. int main(int argc, char *argv[])
  35. {
  36. char group[GNAME_MAX], mapset[GMAPSET_MAX];
  37. int m, k = 0;
  38. struct Option *grp, *rast, *sgrp;
  39. struct Flag *r, *l, *simple_flag;
  40. struct GModule *module;
  41. G_gisinit(argv[0]);
  42. module = G_define_module();
  43. G_add_keyword(_("imagery"));
  44. module->description =
  45. _("Creates, edits, and lists groups and subgroups of imagery files.");
  46. /* Get Args */
  47. grp = G_define_standard_option(G_OPT_I_GROUP);
  48. grp->description = _("Name of imagery group");
  49. sgrp = G_define_option();
  50. sgrp->key = "subgroup";
  51. sgrp->type = TYPE_STRING;
  52. sgrp->required = NO;
  53. sgrp->description = _("Name of imagery sub-group");
  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. r = G_define_flag();
  58. r->key = 'r';
  59. r->description = _("Remove selected files from specified group");
  60. l = G_define_flag();
  61. l->key = 'l';
  62. l->description = _("List files from specified (sub)group (fancy)");
  63. l->guisection = _("Print");
  64. simple_flag = G_define_flag();
  65. simple_flag->key = 'g';
  66. simple_flag->description =
  67. _("List files from specified (sub)group (shell script style)");
  68. simple_flag->guisection = _("Print");
  69. if (G_parser(argc, argv))
  70. exit(EXIT_FAILURE);
  71. /* simple list implies list */
  72. if (simple_flag->answer && !l->answer)
  73. l->answer = TRUE;
  74. /* Determine number of files to include */
  75. if (rast->answers) {
  76. for (m = 0; rast->answers[m]; m++) {
  77. k = m;
  78. }
  79. k++;
  80. }
  81. if (k < 1 && !l->answer) /* remove if input is requirement */
  82. G_fatal_error(_("No input raster map(s) specified"));
  83. /* check if current mapset: (imagery libs are very lacking in this dept)
  84. - abort if not,
  85. - remove @mapset part if it is
  86. */
  87. if (G_name_is_fully_qualified(grp->answer, group, mapset)) {
  88. if (strcmp(mapset, G_mapset()))
  89. G_fatal_error(_("Group must exist in the current mapset"));
  90. }
  91. else {
  92. strcpy(group, grp->answer); /* FIXME for buffer overflow (have the parser check that?) */
  93. }
  94. if (r->answer) {
  95. /* Remove files from Group */
  96. if (I_find_group(group) == 0) {
  97. G_fatal_error(_("Specified group does not exist in current mapset"));
  98. }
  99. if (sgrp->answer) {
  100. G_verbose_message(_("Removing raster maps from subgroup <%s>..."),
  101. sgrp->answer);
  102. remove_subgroup_files(group, sgrp->answer, rast->answers, k);
  103. }
  104. else {
  105. G_verbose_message(_("Removing raster maps from group <%s>..."),
  106. group);
  107. remove_group_files(group, rast->answers, k);
  108. }
  109. }
  110. else {
  111. if (l->answer) {
  112. /* List raster maps in group */
  113. struct Ref ref;
  114. if (I_find_group(group) == 0) {
  115. G_fatal_error(_("Specified group does not exist in current mapset"));
  116. }
  117. if (sgrp->answer) {
  118. /* list subgroup files */
  119. I_get_subgroup_ref(group, sgrp->answer, &ref);
  120. if (simple_flag->answer)
  121. I_list_subgroup_simple(&ref, stdout);
  122. else
  123. I_list_subgroup(group, sgrp->answer, &ref, stdout);
  124. }
  125. else {
  126. /* list group files */
  127. I_get_group_ref(group, &ref);
  128. if (simple_flag->answer)
  129. I_list_group_simple(&ref, stdout);
  130. else
  131. I_list_group(group, &ref, stdout);
  132. }
  133. }
  134. else {
  135. /* Create or update Group REF */
  136. if (I_find_group(group) == 0)
  137. G_verbose_message(_("Group <%s> does not yet exist. Creating..."),
  138. group);
  139. if (sgrp->answer) {
  140. G_verbose_message(_("Adding raster maps to group <%s>..."),
  141. group);
  142. add_or_update_group(group, rast->answers, k);
  143. G_verbose_message(_("Adding raster maps to subgroup <%s>..."),
  144. sgrp->answer);
  145. add_or_update_subgroup(group, sgrp->answer, rast->answers, k);
  146. }
  147. else {
  148. G_verbose_message(_("Adding raster maps to group <%s>..."),
  149. group);
  150. add_or_update_group(group, rast->answers, k);
  151. }
  152. }
  153. }
  154. G_done_msg(" ");
  155. return EXIT_SUCCESS;
  156. }
  157. static int add_or_update_group(char group[INAME_LEN], char **rasters, int k)
  158. {
  159. int m, n, skip;
  160. struct Ref ref;
  161. const char *mapset;
  162. I_get_group_ref(group, &ref);
  163. for (m = 0; m < k; m++) {
  164. skip = 0;
  165. if ((mapset = G_find_raster(rasters[m], "")) == NULL)
  166. G_fatal_error(_("Raster map <%s> not found"), rasters[m]);
  167. G_message(_("Adding raster map <%s> to group"),
  168. G_fully_qualified_name(rasters[m], mapset));
  169. /* Go through existing files to check for duplicates */
  170. for (n = 0; n < ref.nfiles; n++) {
  171. if (strcmp(rasters[m], ref.file[n].name) == 0) {
  172. G_message(_("Raster map <%s> exists in group. Skipping..."),
  173. G_fully_qualified_name(rasters[m], mapset));
  174. skip = 1;
  175. continue;
  176. }
  177. }
  178. if (skip == 0)
  179. I_add_file_to_group_ref(rasters[m], mapset, &ref);
  180. }
  181. G_debug(1, "writing group REF");
  182. I_put_group_ref(group, &ref);
  183. return 0;
  184. }
  185. static int add_or_update_subgroup(char group[INAME_LEN],
  186. char subgroup[INAME_LEN], char **rasters,
  187. int k)
  188. {
  189. int m, n, skip;
  190. struct Ref ref;
  191. const char *mapset;
  192. I_get_subgroup_ref(group, subgroup, &ref);
  193. for (m = 0; m < k; m++) {
  194. skip = 0;
  195. if ((mapset = G_find_raster(rasters[m], "")) == NULL)
  196. G_fatal_error(_("Raster map <%s> not found"),
  197. G_fully_qualified_name(rasters[m], mapset));
  198. G_message(_("Adding raster map <%s> to subgroup"),
  199. G_fully_qualified_name(rasters[m], mapset));
  200. /* Go through existing files to check for duplicates */
  201. for (n = 0; n < ref.nfiles; n++) {
  202. if (strcmp(rasters[m], ref.file[n].name) == 0) {
  203. G_message(_("Raster map <%s> exists in subgroup. Skipping..."),
  204. G_fully_qualified_name(rasters[m], mapset));
  205. skip = 1;
  206. continue;
  207. }
  208. }
  209. if (skip == 0)
  210. I_add_file_to_group_ref(rasters[m], mapset, &ref);
  211. }
  212. G_debug(1, "writing subgroup REF");
  213. I_put_subgroup_ref(group, subgroup, &ref);
  214. return 0;
  215. }
  216. static int remove_group_files(char group[INAME_LEN], char **rasters, int k)
  217. {
  218. int m, n, skip;
  219. struct Ref ref;
  220. struct Ref ref_tmp;
  221. const char *mapset;
  222. char tmp_name[INAME_LEN];
  223. char xname[GNAME_MAX], xmapset[GMAPSET_MAX];
  224. I_get_group_ref(group, &ref_tmp);
  225. I_init_group_ref(&ref);
  226. G_debug(3, "remove_group_files: ref_tmp.nfiles %d", ref_tmp.nfiles);
  227. /* Go through existing files to check for duplicates */
  228. for (m = 0; m < ref_tmp.nfiles; m++) {
  229. skip = 0;
  230. /* Parse through supplied rasters */
  231. for (n = 0; n < k; n++) {
  232. strcpy(tmp_name, rasters[n]);
  233. mapset = G_mapset();
  234. /* Parse out mapset */
  235. if (G_name_is_fully_qualified(rasters[n], xname, xmapset)) {
  236. strcpy(tmp_name, xname);
  237. mapset = xmapset;
  238. }
  239. G_debug(3, "tmp_name %s, ref_tmp.file[%d].name: %s", tmp_name, m,
  240. ref_tmp.file[m].name);
  241. if ((strcmp(tmp_name, ref_tmp.file[m].name) == 0) &&
  242. (strcmp(mapset, ref_tmp.file[m].mapset) == 0)) {
  243. G_message(_("Removing raster map <%s> from group"),
  244. G_fully_qualified_name(tmp_name, mapset));
  245. skip = 1;
  246. break;
  247. }
  248. }
  249. if (skip == 0) {
  250. I_add_file_to_group_ref(ref_tmp.file[m].name,
  251. ref_tmp.file[m].mapset, &ref);
  252. }
  253. }
  254. G_debug(1, "writing group REF");
  255. I_put_group_ref(group, &ref);
  256. if (ref.nfiles == ref_tmp.nfiles) {
  257. G_warning(_("No raster map removed"));
  258. }
  259. return 0;
  260. }
  261. static int remove_subgroup_files(char group[INAME_LEN],
  262. char subgroup[INAME_LEN], char **rasters,
  263. int k)
  264. {
  265. int m, n, skip;
  266. struct Ref ref;
  267. struct Ref ref_tmp;
  268. const char *mapset;
  269. char tmp_name[INAME_LEN];
  270. char xname[GNAME_MAX], xmapset[GMAPSET_MAX];
  271. I_get_subgroup_ref(group, subgroup, &ref_tmp);
  272. I_init_group_ref(&ref);
  273. G_debug(3, "remove_subgroup_files: ref_tmp.nfiles %d", ref_tmp.nfiles);
  274. /* Go through existing files to check for duplicates */
  275. for (m = 0; m < ref_tmp.nfiles; m++) {
  276. skip = 0;
  277. /* Parse through supplied rasters */
  278. for (n = 0; n < k; n++) {
  279. strcpy(tmp_name, rasters[n]);
  280. mapset = G_mapset();
  281. /* Parse out mapset */
  282. if (G_name_is_fully_qualified(rasters[n], xname, xmapset)) {
  283. strcpy(tmp_name, xname);
  284. mapset = xmapset;
  285. }
  286. G_debug(3, "tmp_name %s, ref_tmp.file[%d].name: %s", tmp_name, m,
  287. ref_tmp.file[m].name);
  288. G_debug(3, "mapset %s, ref_tmp.file[%d].mapset: %s", mapset, m,
  289. ref_tmp.file[m].mapset);
  290. if ((strcmp(tmp_name, ref_tmp.file[m].name) == 0) &&
  291. (strcmp(mapset, ref_tmp.file[m].mapset) == 0)) {
  292. G_message(_("Removing raster map <%s> from subgroup"),
  293. G_fully_qualified_name(tmp_name, mapset));
  294. skip = 1;
  295. break;
  296. }
  297. }
  298. if (skip == 0) {
  299. I_add_file_to_group_ref(ref_tmp.file[m].name,
  300. ref_tmp.file[m].mapset, &ref);
  301. }
  302. }
  303. G_debug(1, "writing subgroup REF");
  304. I_put_subgroup_ref(group, subgroup, &ref);
  305. if (ref.nfiles == ref_tmp.nfiles) {
  306. G_warning(_("No raster map removed"));
  307. }
  308. return 0;
  309. }