GRASS GIS 8 Programmer's Manual  8.2.2dev(2023)-3d2c704037
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 xname[GNAME_MAX], xmapset[GMAPSET_MAX];
188  char color[20];
189  FILE *fd;
190 
191  I_init_group_ref(ref);
192 
193  G_unqualified_name(group, gmapset, xname, xmapset);
194  group = xname;
195  gmapset = xmapset;
196 
197  if (gmapset == NULL || *gmapset == 0)
198  gmapset = G_mapset();
199 
201  if (*subgroup == 0)
202  fd = I_fopen_group_ref_old2(group, gmapset);
203  else
204  fd = I_fopen_subgroup_ref_old2(group, subgroup, gmapset);
206  if (!fd)
207  return 0;
208 
209  while (G_getl2(buf, sizeof buf, fd)) {
210  n = sscanf(buf, "%255s %255s %15s", name, mapset, color); /* better use INAME_LEN */
211  if (n == 2 || n == 3) {
212  I_add_file_to_group_ref(name, mapset, ref);
213  if (n == 3)
214  set_color(name, mapset, color, ref);
215  }
216  }
217  /* make sure we have a color assignment */
219 
220  fclose(fd);
221  return 1;
222 }
223 
224 static int set_color(const char *name, const char *mapset, const char *color,
225  struct Ref *ref)
226 {
227  int n;
228 
229  for (n = 0; n < ref->nfiles; n++) {
230  if (strcmp(ref->file[n].name, name) == 0
231  && strcmp(ref->file[n].mapset, mapset) == 0)
232  break;
233  }
234 
235  if (n < ref->nfiles)
236  while (*color) {
237  switch (*color) {
238  case 'r':
239  case 'R':
240  if (ref->red.n < 0)
241  ref->red.n = n;
242  break;
243  case 'g':
244  case 'G':
245  if (ref->grn.n < 0)
246  ref->grn.n = n;
247  break;
248  case 'b':
249  case 'B':
250  if (ref->blu.n < 0)
251  ref->blu.n = n;
252  break;
253  }
254  color++;
255  }
256 
257  return 0;
258 }
259 
260 int I_init_ref_color_nums(struct Ref *ref)
261 {
262  ref->red.table = NULL;
263  ref->grn.table = NULL;
264  ref->blu.table = NULL;
265 
266  ref->red.index = NULL;
267  ref->grn.index = NULL;
268  ref->blu.index = NULL;
269 
270  if (ref->nfiles <= 0 || ref->red.n >= 0 || ref->blu.n >= 0 ||
271  ref->blu.n >= 0)
272  return 1;
273  switch (ref->nfiles) {
274  case 1:
275  ref->red.n = 0;
276  ref->grn.n = 0;
277  ref->blu.n = 0;
278  break;
279  case 2:
280  ref->blu.n = 0;
281  ref->grn.n = 1;
282  break;
283  case 3:
284  ref->blu.n = 0;
285  ref->grn.n = 1;
286  ref->red.n = 2;
287  break;
288  case 4:
289  ref->blu.n = 0;
290  ref->grn.n = 1;
291  ref->red.n = 3;
292  break;
293  default:
294  ref->blu.n = 1;
295  ref->grn.n = 2;
296  ref->red.n = 4;
297  break;
298  }
299 
300  return 0;
301 }
302 
303 
304 /*!
305  * \brief write group REF file
306  *
307  * Writes the contents of the <b>ref</b> structure to the REF file for
308  * the specified <b>group.</b>
309  * Returns 1 if successful; 0 otherwise (and prints a diagnostic error).
310  * <b>Note.</b> This routine will create the <b>group</b>, if it does not
311  * already exist.
312  *
313  * \param group
314  * \param ref
315  * \return int
316  */
317 
318 int I_put_group_ref(const char *group, const struct Ref *ref)
319 {
320  return put_ref(group, "", ref);
321 }
322 
323 
324 /*!
325  * \brief write subgroup REF file
326  *
327  * Writes the contents of the <b>ref</b>
328  * structure into the REF file for the specified <b>subgroup</b> of the
329  * specified <b>group.</b>
330  * Returns 1 if successful; 0 otherwise (and prints a diagnostic error).
331  * <b>Note.</b> This routine will create the <b>subgroup</b>, if it does not
332  * already exist.
333  *
334  * \param group
335  * \param subgroup
336  * \param ref
337  * \return int
338  */
339 
340 int I_put_subgroup_ref(const char *group, const char *subgroup,
341  const struct Ref *ref)
342 {
343  return put_ref(group, subgroup, ref);
344 }
345 
346 static int put_ref(const char *group, const char *subgroup,
347  const struct Ref *ref)
348 {
349  int n;
350  FILE *fd;
351 
352  if (*subgroup == 0)
353  fd = I_fopen_group_ref_new(group);
354  else
355  fd = I_fopen_subgroup_ref_new(group, subgroup);
356  if (!fd)
357  return 0;
358 
359  for (n = 0; n < ref->nfiles; n++) {
360  fprintf(fd, "%s %s", ref->file[n].name, ref->file[n].mapset);
361  if (n == ref->red.n || n == ref->grn.n || n == ref->blu.n) {
362  fprintf(fd, " ");
363  if (n == ref->red.n)
364  fprintf(fd, "r");
365  if (n == ref->grn.n)
366  fprintf(fd, "g");
367  if (n == ref->blu.n)
368  fprintf(fd, "b");
369  }
370  fprintf(fd, "\n");
371  }
372  fclose(fd);
373  return 1;
374 }
375 
376 
377 /*!
378  * \brief add file name to Ref structure
379  *
380  * This routine adds the file
381  * <b>name</b> and <b>mapset</b> to the list contained in the <b>ref</b>
382  * structure, if it is not already in the list. The <b>ref</b> structure must
383  * have been properly initialized. This routine is used by programs, such as
384  * <i>i.maxlik</i>, to add to the group new raster maps created from files
385  * already in the group.
386  * Returns the index into the <i>file</i> array within the <b>ref</b>
387  * structure for the file after insertion; see
388  * Imagery_Library_Data_Structures.
389  *
390  * \param name
391  * \param mapset
392  * \param ref
393  * \return int
394  */
395 
396 int I_add_file_to_group_ref(const char *name, const char *mapset,
397  struct Ref *ref)
398 {
399  int n;
400 
401  for (n = 0; n < ref->nfiles; n++) {
402  if (strcmp(ref->file[n].name, name) == 0
403  && strcmp(ref->file[n].mapset, mapset) == 0)
404  return n;
405  }
406 
407  if ((n = ref->nfiles++))
408  ref->file =
409  (struct Ref_Files *)G_realloc(ref->file,
410  ref->nfiles *
411  sizeof(struct Ref_Files));
412  else
413  ref->file =
414  (struct Ref_Files *)G_malloc(ref->nfiles *
415  sizeof(struct Ref_Files));
416  strcpy(ref->file[n].name, name);
417  strcpy(ref->file[n].mapset, mapset);
418  return n;
419 }
420 
421 
422 /*!
423  * \brief copy Ref lists
424  *
425  * This routine is used to copy file names from one
426  * <i>Ref</i> structure to another. The name and mapset for file <b>n</b>
427  * from the <b>src</b> structure are copied into the <b>dst</b> structure
428  * (which must be properly initialized).
429  * For example, the following code copies one <i>Ref</i> structure to another:
430  \code
431  struct Ref src,dst;
432  int n;
433  // some code to get information into <b>src</b>
434  ...
435  I_init_group_ref (&dst);
436  for (n = 0; n < src.nfiles; n++)
437  I_transfer_group_ref_file (&src, n, &dst);
438  \endcode
439  * This routine is used by <i>g.gui.gcp</i> to create the REF file for a
440  * subgroup.
441  *
442  * \param src
443  * \param n
444  * \param dst
445  * \return int
446  */
447 
448 int I_transfer_group_ref_file(const struct Ref *ref2, int n, struct Ref *ref1)
449 {
450  int k;
451 
452  /* insert old name into new ref */
453  k = I_add_file_to_group_ref(ref2->file[n].name, ref2->file[n].mapset,
454  ref1);
455 
456  /* preserve color assignment */
457  if (n == ref2->red.n)
458  ref1->red.n = k;
459  if (n == ref2->grn.n)
460  ref1->grn.n = k;
461  if (n == ref2->blu.n)
462  ref1->blu.n = k;
463 
464  return 0;
465 }
466 
467 
468 
469 /*!
470  * \brief initialize Ref
471  * structure
472  *
473  * This routine initializes the <b>ref</b> structure for other
474  * library calls which require a <i>Ref</i> structure. This routine must be
475  * called before any use of the structure can be made.
476  * <b>Note.</b> The routines I_get_group_ref and I_get_subgroup_ref call
477  * this routine automatically.
478  *
479  * \param ref
480  * \return int
481  */
482 
483 int I_init_group_ref(struct Ref *ref)
484 {
485  ref->nfiles = 0;
486  ref->red.n = ref->grn.n = ref->blu.n = -1;
487  ref->red.table = ref->grn.table = ref->blu.table = NULL;
488 
489  return 0;
490 }
491 
492 
493 /*!
494  * \brief free Ref structure
495  *
496  * This routine frees memory allocated to the <b>ref</b> structure.
497  *
498  * \param ref
499  * \return int
500  */
501 
502 int I_free_group_ref(struct Ref *ref)
503 {
504  if (ref->nfiles > 0)
505  free(ref->file);
506  ref->nfiles = 0;
507 
508  return 0;
509 }
int G_getl2(char *, int, FILE *)
Gets a line of text from a file of any pedigree.
Definition: getl.c:64
#define G_malloc(n)
Definition: defs/gis.h:112
int I_find_group(const char *)
does group exist?
Definition: imagery/find.c:22
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:396
int I_put_subgroup(const char *group, const char *subgroup)
Definition: group.c:87
FILE * I_fopen_group_ref_old2(const char *, const char *)
Definition: ref.c:35
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:318
#define GMAPSET_MAX
Definition: gis.h:178
#define INAME_LEN
Definition: imagery.h:8
int I_init_group_ref(struct Ref *ref)
initialize Ref structure
Definition: group.c:483
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:260
int G_unqualified_name(const char *, const char *, char *, char *)
Returns unqualified map name (without @ mapset)
Definition: nme_in_mps.c:134
FILE * I_fopen_group_file_old(const char *, const char *)
Open group file for reading.
Definition: fopen.c:105
Definition: imagery.h:26
FILE * I_fopen_group_ref_new(const char *)
Definition: ref.c:25
void free(void *)
#define NULL
Definition: ccmath.h:32
FILE * I_fopen_subgroup_ref_old2(const char *, const char *, const char *)
Definition: ref.c:62
#define GROUPFILE
Definition: imagery.h:213
int I_get_group_ref2(const char *group, const char *mapset, struct Ref *ref)
read group REF file
Definition: group.c:133
int I_get_group(char *group)
Definition: group.c:38
FILE * G_fopen_new(const char *, const char *)
Open a new database file.
Definition: gis/open.c:220
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:340
unsigned char * index
Definition: imagery.h:13
void int G_suppress_warnings(int)
Suppress printing a warning message to stderr.
Definition: gis/error.c:223
FILE * G_fopen_old(const char *, const char *, const char *)
Open a database file for reading.
Definition: gis/open.c:253
int I_transfer_group_ref_file(const struct Ref *ref2, int n, struct Ref *ref1)
copy Ref lists
Definition: group.c:448
int nfiles
Definition: imagery.h:28
struct Ref_Files * file
Definition: imagery.h:29
unsigned char * table
Definition: imagery.h:12
struct Ref_Color red grn blu
Definition: imagery.h:30
FILE * I_fopen_group_file_new(const char *, const char *)
Definition: fopen.c:70
const char * G_mapset(void)
Get current mapset name.
Definition: gis/mapset.c:33
#define GNAME_MAX
Definition: gis.h:177
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
#define G_realloc(p, n)
Definition: defs/gis.h:114
int I_free_group_ref(struct Ref *ref)
free Ref structure
Definition: group.c:502
FILE * I_fopen_subgroup_ref_new(const char *, const char *)
Definition: ref.c:49
int I_get_subgroup_ref(const char *group, const char *subgroup, struct Ref *ref)
read subgroup REF file
Definition: group.c:153
const char * name
Definition: named_colr.c:7
#define SUBGROUPFILE
Definition: imagery.h:214