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