GRASS GIS 7 Programmer's Manual  7.7.svn(2018)-r73675
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
group.c
Go to the documentation of this file.
1 
2 /****************************************************************************
3  *
4  * MODULE: imagery library
5  * AUTHOR(S): Original author(s) name(s) unknown - written by CERL
6  * PURPOSE: Image processing library
7  * COPYRIGHT: (C) 1999, 2005 by the GRASS Development Team
8  *
9  * This program is free software under the GNU General Public
10  * License (>=v2). Read the file COPYING that comes with GRASS
11  * for details.
12  *
13  *****************************************************************************/
14 
15 /**********************************************************
16 * I_get_group (group);
17 * I_put_group (group);
18 *
19 * I_get_group_ref (group, &Ref);
20 * I_put_group_ref (group, &Ref);
21 * I_get_subgroup_ref_file (group, subgroup, &Ref);
22 * I_put_subgroup_ref_file (group, subgroup, &Ref);
23 * I_add_file_to_group_ref (name, mapset, &Ref)
24 * I_transfer_group_ref_file (&Src_ref, n, &Dst_ref)
25 * I_init_group_ref (&Ref);
26 * I_free_group_ref (&Ref);
27 **********************************************************/
28 
29 #include <string.h>
30 #include <stdlib.h>
31 #include <grass/imagery.h>
32 
33 static int get_ref(const char *, const char *, const char *, struct Ref *);
34 static int set_color(const char *, const char *, const char *, struct Ref *);
35 static int put_ref(const char *, const char *, const struct Ref *);
36 
37 /* get current group name from file GROUPFILE in current mapset */
38 int I_get_group(char *group)
39 {
40  FILE *fd;
41  int stat;
42 
43  *group = 0;
45  fd = G_fopen_old("", GROUPFILE, G_mapset());
47  if (fd == NULL)
48  return 0;
49  stat = (fscanf(fd, "%s", group) == 1);
50  fclose(fd);
51  return stat;
52 }
53 
54 /* write group name to file GROUPFILE in current mapset */
55 int I_put_group(const char *group)
56 {
57  FILE *fd;
58 
59  fd = G_fopen_new("", GROUPFILE);
60  if (fd == NULL)
61  return 0;
62  fprintf(fd, "%s\n", group);
63  fclose(fd);
64  return 1;
65 }
66 
67 /* get current subgroup for group in current mapset */
68 int I_get_subgroup(const char *group, char *subgroup)
69 {
70  FILE *fd;
71  int stat;
72 
73  *subgroup = 0;
74  if (!I_find_group(group))
75  return 0;
79  if (fd == NULL)
80  return 0;
81  stat = (fscanf(fd, "%s", subgroup) == 1);
82  fclose(fd);
83  return stat;
84 }
85 
86 /* write current subgroup to group in current mapset */
87 int I_put_subgroup(const char *group, const char *subgroup)
88 {
89  FILE *fd;
90 
91  if (!I_find_group(group))
92  return 0;
94  if (fd == NULL)
95  return 0;
96  fprintf(fd, "%s\n", subgroup);
97  fclose(fd);
98  return 1;
99 }
100 
101 
102 /*!
103  * \brief read group REF file
104  *
105  * Reads the contents of the REF file for the specified <b>group</b> into
106  * the <b>ref</b> structure.
107  * Returns 1 if successful; 0 otherwise (but no error messages are printed).
108  *
109  * \param group
110  * \param ref
111  * \return int
112  */
113 
114 int I_get_group_ref(const char *group, struct Ref *ref)
115 {
116  return get_ref(group, "", NULL, ref);
117 }
118 
119 
120 /*!
121  * \brief read group REF file
122  *
123  * Reads the contents of the REF file for the specified <b>group</b> into
124  * the <b>ref</b> structure.
125  * Returns 1 if successful; 0 otherwise (but no error messages are printed).
126  *
127  * \param group
128  * \param mapset
129  * \param ref
130  * \return int
131  */
132 
133 int I_get_group_ref2(const char *group, const char *mapset, struct Ref *ref)
134 {
135  return get_ref(group, "", mapset, ref);
136 }
137 
138 
139 /*!
140  * \brief read subgroup REF file
141  *
142  * Reads the contents of the REF file for the
143  * specified <b>subgroup</b> of the specified <b>group</b> into the
144  * <b>ref</b> structure.
145  * Returns 1 if successful; 0 otherwise (but no error messages are printed).
146  *
147  * \param group
148  * \param subgroup
149  * \param ref
150  * \return int
151  */
152 
153 int I_get_subgroup_ref(const char *group,
154  const char *subgroup, struct Ref *ref)
155 {
156  return get_ref(group, subgroup, NULL, ref);
157 }
158 
159 
160 /*!
161  * \brief read subgroup REF file
162  *
163  * Reads the contents of the REF file for the
164  * specified <b>subgroup</b> of the specified <b>group</b> into the
165  * <b>ref</b> structure.
166  * Returns 1 if successful; 0 otherwise (but no error messages are printed).
167  *
168  * \param group
169  * \param subgroup
170  * \param mapset
171  * \param ref
172  * \return int
173  */
174 int I_get_subgroup_ref2(const char *group,
175  const char *subgroup, const char *mapset,
176  struct Ref *ref)
177 {
178  return get_ref(group, subgroup, mapset, ref);
179 }
180 
181 
182 static int get_ref(const char *group, const char *subgroup, const char *gmapset, struct Ref *ref)
183 {
184  int n;
185  char buf[1024];
186  char name[INAME_LEN], mapset[INAME_LEN];
187  char color[20];
188  FILE *fd;
189 
190  I_init_group_ref(ref);
191 
192  if (gmapset == NULL || *gmapset == 0)
193  gmapset = G_mapset();
194 
196  if (*subgroup == 0)
197  fd = I_fopen_group_ref_old2(group, gmapset);
198  else
199  fd = I_fopen_subgroup_ref_old2(group, subgroup, gmapset);
201  if (!fd)
202  return 0;
203 
204  while (G_getl2(buf, sizeof buf, fd)) {
205  n = sscanf(buf, "%255s %255s %15s", name, mapset, color); /* better use INAME_LEN */
206  if (n == 2 || n == 3) {
207  I_add_file_to_group_ref(name, mapset, ref);
208  if (n == 3)
209  set_color(name, mapset, color, ref);
210  }
211  }
212  /* make sure we have a color assignment */
214 
215  fclose(fd);
216  return 1;
217 }
218 
219 static int set_color(const char *name, const char *mapset, const char *color,
220  struct Ref *ref)
221 {
222  int n;
223 
224  for (n = 0; n < ref->nfiles; n++) {
225  if (strcmp(ref->file[n].name, name) == 0
226  && strcmp(ref->file[n].mapset, mapset) == 0)
227  break;
228  }
229 
230  if (n < ref->nfiles)
231  while (*color) {
232  switch (*color) {
233  case 'r':
234  case 'R':
235  if (ref->red.n < 0)
236  ref->red.n = n;
237  break;
238  case 'g':
239  case 'G':
240  if (ref->grn.n < 0)
241  ref->grn.n = n;
242  break;
243  case 'b':
244  case 'B':
245  if (ref->blu.n < 0)
246  ref->blu.n = n;
247  break;
248  }
249  color++;
250  }
251 
252  return 0;
253 }
254 
255 int I_init_ref_color_nums(struct Ref *ref)
256 {
257  ref->red.table = NULL;
258  ref->grn.table = NULL;
259  ref->blu.table = NULL;
260 
261  ref->red.index = NULL;
262  ref->grn.index = NULL;
263  ref->blu.index = NULL;
264 
265  if (ref->nfiles <= 0 || ref->red.n >= 0 || ref->blu.n >= 0 ||
266  ref->blu.n >= 0)
267  return 1;
268  switch (ref->nfiles) {
269  case 1:
270  ref->red.n = 0;
271  ref->grn.n = 0;
272  ref->blu.n = 0;
273  break;
274  case 2:
275  ref->blu.n = 0;
276  ref->grn.n = 1;
277  break;
278  case 3:
279  ref->blu.n = 0;
280  ref->grn.n = 1;
281  ref->red.n = 2;
282  break;
283  case 4:
284  ref->blu.n = 0;
285  ref->grn.n = 1;
286  ref->red.n = 3;
287  break;
288  default:
289  ref->blu.n = 1;
290  ref->grn.n = 2;
291  ref->red.n = 4;
292  break;
293  }
294 
295  return 0;
296 }
297 
298 
299 /*!
300  * \brief write group REF file
301  *
302  * Writes the contents of the <b>ref</b> structure to the REF file for
303  * the specified <b>group.</b>
304  * Returns 1 if successful; 0 otherwise (and prints a diagnostic error).
305  * <b>Note.</b> This routine will create the <b>group</b>, if it does not
306  * already exist.
307  *
308  * \param group
309  * \param ref
310  * \return int
311  */
312 
313 int I_put_group_ref(const char *group, const struct Ref *ref)
314 {
315  return put_ref(group, "", ref);
316 }
317 
318 
319 /*!
320  * \brief write subgroup REF file
321  *
322  * Writes the contents of the <b>ref</b>
323  * structure into the REF file for the specified <b>subgroup</b> of the
324  * specified <b>group.</b>
325  * Returns 1 if successful; 0 otherwise (and prints a diagnostic error).
326  * <b>Note.</b> This routine will create the <b>subgroup</b>, if it does not
327  * already exist.
328  *
329  * \param group
330  * \param subgroup
331  * \param ref
332  * \return int
333  */
334 
335 int I_put_subgroup_ref(const char *group, const char *subgroup,
336  const struct Ref *ref)
337 {
338  return put_ref(group, subgroup, ref);
339 }
340 
341 static int put_ref(const char *group, const char *subgroup,
342  const struct Ref *ref)
343 {
344  int n;
345  FILE *fd;
346 
347  if (*subgroup == 0)
348  fd = I_fopen_group_ref_new(group);
349  else
350  fd = I_fopen_subgroup_ref_new(group, subgroup);
351  if (!fd)
352  return 0;
353 
354  for (n = 0; n < ref->nfiles; n++) {
355  fprintf(fd, "%s %s", ref->file[n].name, ref->file[n].mapset);
356  if (n == ref->red.n || n == ref->grn.n || n == ref->blu.n) {
357  fprintf(fd, " ");
358  if (n == ref->red.n)
359  fprintf(fd, "r");
360  if (n == ref->grn.n)
361  fprintf(fd, "g");
362  if (n == ref->blu.n)
363  fprintf(fd, "b");
364  }
365  fprintf(fd, "\n");
366  }
367  fclose(fd);
368  return 1;
369 }
370 
371 
372 /*!
373  * \brief add file name to Ref structure
374  *
375  * This routine adds the file
376  * <b>name</b> and <b>mapset</b> to the list contained in the <b>ref</b>
377  * structure, if it is not already in the list. The <b>ref</b> structure must
378  * have been properly initialized. This routine is used by programs, such as
379  * <i>i.maxlik</i>, to add to the group new raster maps created from files
380  * already in the group.
381  * Returns the index into the <i>file</i> array within the <b>ref</b>
382  * structure for the file after insertion; see
383  * Imagery_Library_Data_Structures.
384  *
385  * \param name
386  * \param mapset
387  * \param ref
388  * \return int
389  */
390 
391 int I_add_file_to_group_ref(const char *name, const char *mapset,
392  struct Ref *ref)
393 {
394  int n;
395 
396  for (n = 0; n < ref->nfiles; n++) {
397  if (strcmp(ref->file[n].name, name) == 0
398  && strcmp(ref->file[n].mapset, mapset) == 0)
399  return n;
400  }
401 
402  if ((n = ref->nfiles++))
403  ref->file =
404  (struct Ref_Files *)G_realloc(ref->file,
405  ref->nfiles *
406  sizeof(struct Ref_Files));
407  else
408  ref->file =
409  (struct Ref_Files *)G_malloc(ref->nfiles *
410  sizeof(struct Ref_Files));
411  strcpy(ref->file[n].name, name);
412  strcpy(ref->file[n].mapset, mapset);
413  return n;
414 }
415 
416 
417 /*!
418  * \brief copy Ref lists
419  *
420  * This routine is used to copy file names from one
421  * <i>Ref</i> structure to another. The name and mapset for file <b>n</b>
422  * from the <b>src</b> structure are copied into the <b>dst</b> structure
423  * (which must be properly initialized).
424  * For example, the following code copies one <i>Ref</i> structure to another:
425  \code
426  struct Ref src,dst;
427  int n;
428  // some code to get information into <b>src</b>
429  ...
430  I_init_group_ref (&dst);
431  for (n = 0; n < src.nfiles; n++)
432  I_transfer_group_ref_file (&src, n, &dst);
433  \endcode
434  * This routine is used by <i>g.gui.gcp</i> to create the REF file for a
435  * subgroup.
436  *
437  * \param src
438  * \param n
439  * \param dst
440  * \return int
441  */
442 
443 int I_transfer_group_ref_file(const struct Ref *ref2, int n, struct Ref *ref1)
444 {
445  int k;
446 
447  /* insert old name into new ref */
448  k = I_add_file_to_group_ref(ref2->file[n].name, ref2->file[n].mapset,
449  ref1);
450 
451  /* preserve color assignment */
452  if (n == ref2->red.n)
453  ref1->red.n = k;
454  if (n == ref2->grn.n)
455  ref1->grn.n = k;
456  if (n == ref2->blu.n)
457  ref1->blu.n = k;
458 
459  return 0;
460 }
461 
462 
463 
464 /*!
465  * \brief initialize Ref
466  * structure
467  *
468  * This routine initializes the <b>ref</b> structure for other
469  * library calls which require a <i>Ref</i> structure. This routine must be
470  * called before any use of the structure can be made.
471  * <b>Note.</b> The routines I_get_group_ref and I_get_subgroup_ref call
472  * this routine automatically.
473  *
474  * \param ref
475  * \return int
476  */
477 
478 int I_init_group_ref(struct Ref *ref)
479 {
480  ref->nfiles = 0;
481  ref->red.n = ref->grn.n = ref->blu.n = -1;
482  ref->red.table = ref->grn.table = ref->blu.table = NULL;
483 
484  return 0;
485 }
486 
487 
488 /*!
489  * \brief free Ref structure
490  *
491  * This routine frees memory allocated to the <b>ref</b> structure.
492  *
493  * \param ref
494  * \return int
495  */
496 
497 int I_free_group_ref(struct Ref *ref)
498 {
499  if (ref->nfiles > 0)
500  free(ref->file);
501  ref->nfiles = 0;
502 
503  return 0;
504 }
int I_add_file_to_group_ref(const char *name, const char *mapset, struct Ref *ref)
add file name to Ref structure
Definition: group.c:391
int I_put_subgroup(const char *group, const char *subgroup)
Definition: group.c:87
char name[INAME_LEN]
Definition: imagery.h:22
int I_put_group_ref(const char *group, const struct Ref *ref)
write group REF file
Definition: group.c:313
#define INAME_LEN
Definition: imagery.h:8
int I_init_group_ref(struct Ref *ref)
initialize Ref structure
Definition: group.c:478
int I_get_subgroup_ref2(const char *group, const char *subgroup, const char *mapset, struct Ref *ref)
read subgroup REF file
Definition: group.c:174
int I_get_subgroup(const char *group, char *subgroup)
Definition: group.c:68
int I_init_ref_color_nums(struct Ref *ref)
Definition: group.c:255
Definition: imagery.h:26
void free(void *)
#define NULL
Definition: ccmath.h:32
#define GROUPFILE
Definition: imagery.h:199
int I_get_group_ref2(const char *group, const char *mapset, struct Ref *ref)
read group REF file
Definition: group.c:133
fd
Definition: d/range.c:69
int G_suppress_warnings(int flag)
Suppress printing a warning message to stderr.
Definition: gis/error.c:223
int I_get_group(char *group)
Definition: group.c:38
int I_find_group(const char *group)
does group exist?
Definition: imagery/find.c:22
int G_getl2(char *buf, int n, FILE *fd)
Gets a line of text from a file of any pedigree.
Definition: getl.c:64
char mapset[INAME_LEN]
Definition: imagery.h:23
int I_put_subgroup_ref(const char *group, const char *subgroup, const struct Ref *ref)
write subgroup REF file
Definition: group.c:335
FILE * I_fopen_subgroup_ref_new(const char *group, const char *subgroup)
Definition: ref.c:49
unsigned char * index
Definition: imagery.h:13
FILE * I_fopen_group_file_old(const char *group, const char *file)
Open group file for reading.
Definition: fopen.c:105
fclose(fd)
FILE * I_fopen_group_file_new(const char *group, const char *file)
Definition: fopen.c:70
int I_transfer_group_ref_file(const struct Ref *ref2, int n, struct Ref *ref1)
copy Ref lists
Definition: group.c:443
int nfiles
Definition: imagery.h:28
struct Ref_Files * file
Definition: imagery.h:29
unsigned char * table
Definition: imagery.h:12
FILE * G_fopen_new(const char *element, const char *name)
Open a new database file.
Definition: gis/open.c:220
struct Ref_Color red grn blu
Definition: imagery.h:30
FILE * I_fopen_subgroup_ref_old2(const char *group, const char *subgroup, const char *mapset)
Definition: ref.c:62
int I_put_group(const char *group)
Definition: group.c:55
int n
Definition: imagery.h:17
int I_get_group_ref(const char *group, struct Ref *ref)
read group REF file
Definition: group.c:114
FILE * I_fopen_group_ref_old2(const char *group, const char *mapset)
Definition: ref.c:35
int I_free_group_ref(struct Ref *ref)
free Ref structure
Definition: group.c:497
int I_get_subgroup_ref(const char *group, const char *subgroup, struct Ref *ref)
read subgroup REF file
Definition: group.c:153
const char * G_mapset(void)
Get current mapset name.
Definition: gis/mapset.c:33
FILE * G_fopen_old(const char *element, const char *name, const char *mapset)
Open a database file for reading.
Definition: gis/open.c:253
FILE * I_fopen_group_ref_new(const char *group)
Definition: ref.c:25
const char * name
Definition: named_colr.c:7
#define SUBGROUPFILE
Definition: imagery.h:200