GRASS GIS 7 Programmer's Manual  7.5.svn(2017)-r71915
 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 *, 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, "", ref);
117 }
118 
119 
120 /*!
121  * \brief read subgroup REF file
122  *
123  * Reads the contents of the REF file for the
124  * specified <b>subgroup</b> of the specified <b>group</b> into the
125  * <b>ref</b> structure.
126  * Returns 1 if successful; 0 otherwise (but no error messages are printed).
127  *
128  * \param group
129  * \param subgroup
130  * \param ref
131  * \return int
132  */
133 
134 int I_get_subgroup_ref(const char *group,
135  const char *subgroup, struct Ref *ref)
136 {
137  return get_ref(group, subgroup, ref);
138 }
139 
140 static int get_ref(const char *group, const char *subgroup, struct Ref *ref)
141 {
142  int n;
143  char buf[1024];
144  char name[INAME_LEN], mapset[INAME_LEN];
145  char color[20];
146  FILE *fd;
147 
148  I_init_group_ref(ref);
149 
151  if (*subgroup == 0)
152  fd = I_fopen_group_ref_old(group);
153  else
154  fd = I_fopen_subgroup_ref_old(group, subgroup);
156  if (!fd)
157  return 0;
158 
159  while (G_getl2(buf, sizeof buf, fd)) {
160  n = sscanf(buf, "%255s %255s %15s", name, mapset, color); /* better use INAME_LEN */
161  if (n == 2 || n == 3) {
162  I_add_file_to_group_ref(name, mapset, ref);
163  if (n == 3)
164  set_color(name, mapset, color, ref);
165  }
166  }
167  /* make sure we have a color assignment */
169 
170  fclose(fd);
171  return 1;
172 }
173 
174 static int set_color(const char *name, const char *mapset, const char *color,
175  struct Ref *ref)
176 {
177  int n;
178 
179  for (n = 0; n < ref->nfiles; n++) {
180  if (strcmp(ref->file[n].name, name) == 0
181  && strcmp(ref->file[n].mapset, mapset) == 0)
182  break;
183  }
184 
185  if (n < ref->nfiles)
186  while (*color) {
187  switch (*color) {
188  case 'r':
189  case 'R':
190  if (ref->red.n < 0)
191  ref->red.n = n;
192  break;
193  case 'g':
194  case 'G':
195  if (ref->grn.n < 0)
196  ref->grn.n = n;
197  break;
198  case 'b':
199  case 'B':
200  if (ref->blu.n < 0)
201  ref->blu.n = n;
202  break;
203  }
204  color++;
205  }
206 
207  return 0;
208 }
209 
210 int I_init_ref_color_nums(struct Ref *ref)
211 {
212  ref->red.table = NULL;
213  ref->grn.table = NULL;
214  ref->blu.table = NULL;
215 
216  ref->red.index = NULL;
217  ref->grn.index = NULL;
218  ref->blu.index = NULL;
219 
220  if (ref->nfiles <= 0 || ref->red.n >= 0 || ref->blu.n >= 0 ||
221  ref->blu.n >= 0)
222  return 1;
223  switch (ref->nfiles) {
224  case 1:
225  ref->red.n = 0;
226  ref->grn.n = 0;
227  ref->blu.n = 0;
228  break;
229  case 2:
230  ref->blu.n = 0;
231  ref->grn.n = 1;
232  break;
233  case 3:
234  ref->blu.n = 0;
235  ref->grn.n = 1;
236  ref->red.n = 2;
237  break;
238  case 4:
239  ref->blu.n = 0;
240  ref->grn.n = 1;
241  ref->red.n = 3;
242  break;
243  default:
244  ref->blu.n = 1;
245  ref->grn.n = 2;
246  ref->red.n = 4;
247  break;
248  }
249 
250  return 0;
251 }
252 
253 
254 /*!
255  * \brief write group REF file
256  *
257  * Writes the contents of the <b>ref</b> structure to the REF file for
258  * the specified <b>group.</b>
259  * Returns 1 if successful; 0 otherwise (and prints a diagnostic error).
260  * <b>Note.</b> This routine will create the <b>group</b>, if it does not
261  * already exist.
262  *
263  * \param group
264  * \param ref
265  * \return int
266  */
267 
268 int I_put_group_ref(const char *group, const struct Ref *ref)
269 {
270  return put_ref(group, "", ref);
271 }
272 
273 
274 /*!
275  * \brief write subgroup REF file
276  *
277  * Writes the contents of the <b>ref</b>
278  * structure into the REF file for the specified <b>subgroup</b> of the
279  * specified <b>group.</b>
280  * Returns 1 if successful; 0 otherwise (and prints a diagnostic error).
281  * <b>Note.</b> This routine will create the <b>subgroup</b>, if it does not
282  * already exist.
283  *
284  * \param group
285  * \param subgroup
286  * \param ref
287  * \return int
288  */
289 
290 int I_put_subgroup_ref(const char *group, const char *subgroup,
291  const struct Ref *ref)
292 {
293  return put_ref(group, subgroup, ref);
294 }
295 
296 static int put_ref(const char *group, const char *subgroup,
297  const struct Ref *ref)
298 {
299  int n;
300  FILE *fd;
301 
302  if (*subgroup == 0)
303  fd = I_fopen_group_ref_new(group);
304  else
305  fd = I_fopen_subgroup_ref_new(group, subgroup);
306  if (!fd)
307  return 0;
308 
309  for (n = 0; n < ref->nfiles; n++) {
310  fprintf(fd, "%s %s", ref->file[n].name, ref->file[n].mapset);
311  if (n == ref->red.n || n == ref->grn.n || n == ref->blu.n) {
312  fprintf(fd, " ");
313  if (n == ref->red.n)
314  fprintf(fd, "r");
315  if (n == ref->grn.n)
316  fprintf(fd, "g");
317  if (n == ref->blu.n)
318  fprintf(fd, "b");
319  }
320  fprintf(fd, "\n");
321  }
322  fclose(fd);
323  return 1;
324 }
325 
326 
327 /*!
328  * \brief add file name to Ref structure
329  *
330  * This routine adds the file
331  * <b>name</b> and <b>mapset</b> to the list contained in the <b>ref</b>
332  * structure, if it is not already in the list. The <b>ref</b> structure must
333  * have been properly initialized. This routine is used by programs, such as
334  * <i>i.maxlik</i>, to add to the group new raster maps created from files
335  * already in the group.
336  * Returns the index into the <i>file</i> array within the <b>ref</b>
337  * structure for the file after insertion; see
338  * Imagery_Library_Data_Structures.
339  *
340  * \param name
341  * \param mapset
342  * \param ref
343  * \return int
344  */
345 
346 int I_add_file_to_group_ref(const char *name, const char *mapset,
347  struct Ref *ref)
348 {
349  int n;
350 
351  for (n = 0; n < ref->nfiles; n++) {
352  if (strcmp(ref->file[n].name, name) == 0
353  && strcmp(ref->file[n].mapset, mapset) == 0)
354  return n;
355  }
356 
357  if ((n = ref->nfiles++))
358  ref->file =
359  (struct Ref_Files *)G_realloc(ref->file,
360  ref->nfiles *
361  sizeof(struct Ref_Files));
362  else
363  ref->file =
364  (struct Ref_Files *)G_malloc(ref->nfiles *
365  sizeof(struct Ref_Files));
366  strcpy(ref->file[n].name, name);
367  strcpy(ref->file[n].mapset, mapset);
368  return n;
369 }
370 
371 
372 /*!
373  * \brief copy Ref lists
374  *
375  * This routine is used to copy file names from one
376  * <i>Ref</i> structure to another. The name and mapset for file <b>n</b>
377  * from the <b>src</b> structure are copied into the <b>dst</b> structure
378  * (which must be properly initialized).
379  * For example, the following code copies one <i>Ref</i> structure to another:
380  \code
381  struct Ref src,dst;
382  int n;
383  // some code to get information into <b>src</b>
384  ...
385  I_init_group_ref (&dst);
386  for (n = 0; n < src.nfiles; n++)
387  I_transfer_group_ref_file (&src, n, &dst);
388  \endcode
389  * This routine is used by <i>g.gui.gcp</i> to create the REF file for a
390  * subgroup.
391  *
392  * \param src
393  * \param n
394  * \param dst
395  * \return int
396  */
397 
398 int I_transfer_group_ref_file(const struct Ref *ref2, int n, struct Ref *ref1)
399 {
400  int k;
401 
402  /* insert old name into new ref */
403  k = I_add_file_to_group_ref(ref2->file[n].name, ref2->file[n].mapset,
404  ref1);
405 
406  /* preserve color assignment */
407  if (n == ref2->red.n)
408  ref1->red.n = k;
409  if (n == ref2->grn.n)
410  ref1->grn.n = k;
411  if (n == ref2->blu.n)
412  ref1->blu.n = k;
413 
414  return 0;
415 }
416 
417 
418 
419 /*!
420  * \brief initialize Ref
421  * structure
422  *
423  * This routine initializes the <b>ref</b> structure for other
424  * library calls which require a <i>Ref</i> structure. This routine must be
425  * called before any use of the structure can be made.
426  * <b>Note.</b> The routines I_get_group_ref and I_get_subgroup_ref call
427  * this routine automatically.
428  *
429  * \param ref
430  * \return int
431  */
432 
433 int I_init_group_ref(struct Ref *ref)
434 {
435  ref->nfiles = 0;
436  ref->red.n = ref->grn.n = ref->blu.n = -1;
437  ref->red.table = ref->grn.table = ref->blu.table = NULL;
438 
439  return 0;
440 }
441 
442 
443 /*!
444  * \brief free Ref structure
445  *
446  * This routine frees memory allocated to the <b>ref</b> structure.
447  *
448  * \param ref
449  * \return int
450  */
451 
452 int I_free_group_ref(struct Ref *ref)
453 {
454  if (ref->nfiles > 0)
455  free(ref->file);
456  ref->nfiles = 0;
457 
458  return 0;
459 }
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:346
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:268
#define INAME_LEN
Definition: imagery.h:8
int I_init_group_ref(struct Ref *ref)
initialize Ref structure
Definition: group.c:433
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:210
Definition: imagery.h:26
void free(void *)
#define NULL
Definition: ccmath.h:32
#define GROUPFILE
Definition: imagery.h:199
fd
Definition: d/range.c:69
int G_suppress_warnings(int flag)
Suppress printing a warning message to stderr.
Definition: gis/error.c:222
int I_get_group(char *group)
Definition: group.c:38
int I_find_group(const char *group)
does group exist?
Definition: imagery/find.c:21
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:290
FILE * I_fopen_subgroup_ref_new(const char *group, const char *subgroup)
Definition: ref.c:44
unsigned char * index
Definition: imagery.h:13
FILE * I_fopen_group_file_old(const char *group, const char *file)
Definition: fopen.c:43
fclose(fd)
FILE * I_fopen_group_file_new(const char *group, const char *file)
Definition: fopen.c:17
FILE * I_fopen_group_ref_old(const char *group)
Definition: ref.c:30
int I_transfer_group_ref_file(const struct Ref *ref2, int n, struct Ref *ref1)
copy Ref lists
Definition: group.c:398
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
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
int I_free_group_ref(struct Ref *ref)
free Ref structure
Definition: group.c:452
int I_get_subgroup_ref(const char *group, const char *subgroup, struct Ref *ref)
read subgroup REF file
Definition: group.c:134
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
FILE * I_fopen_subgroup_ref_old(const char *group, const char *subgroup)
Definition: ref.c:49
#define SUBGROUPFILE
Definition: imagery.h:200