GRASS Programmer's Manual  6.5.svn(2014)-r66266
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
color_write.c
Go to the documentation of this file.
1 
2 /**********************************************************************
3  * G_write_colors (name, mapset, colors)
4  * char *name name of map
5  * char *mapset mapset that map belongs to
6  * struct Colors *colors structure holding color info
7  *
8  * Writes the color information associated with map layer "map"
9  * in mapset "mapset" from the structure "colors".
10  *
11  * returns: 1 if successful
12  * -1 on fail
13  *
14  * If the environment variable FORCE_GRASS3_COLORS is set (to anything at all)
15  * then the output format is 3.0, even if the structure contains 4.0 rules.
16  * This allows users to create 3.0 color files for export to sites which
17  * don't yet have 4.0
18  ***********************************************************************/
19 #include <string.h>
20 #include <stdlib.h>
21 #include <stdio.h>
22 #include <grass/gis.h>
23 
24 static int write_new_colors(FILE *, struct Colors *);
25 static int write_rules(FILE *, struct _Color_Rule_ *, DCELL, DCELL);
26 static int write_old_colors(FILE *, struct Colors *);
27 static int forced_write_old_colors(FILE *, struct Colors *);
28 static int format_min(char *, double);
29 static int format_max(char *, double);
30 
31 
74 int G_write_colors(const char *name, const char *mapset,
75  struct Colors *colors)
76 {
77  char element[512];
78  char xname[GNAME_MAX], xmapset[GMAPSET_MAX];
79  FILE *fd;
80  int stat;
81 
82  if (G__name_is_fully_qualified(name, xname, xmapset)) {
83  if (strcmp(xmapset, mapset) != 0)
84  return -1;
85  name = xname;
86  }
87  /*
88  * if mapset is current mapset, remove colr2 file (created by pre 3.0 grass)
89  * and then write original color table
90  * else write secondary color table
91  */
92  sprintf(element, "colr2/%s", mapset);
93  if (strcmp(mapset, G_mapset()) == 0) {
94  G_remove(element, name); /* get rid of existing colr2, if any */
95  strcpy(element, "colr");
96  }
97  if (!(fd = G_fopen_new(element, name)))
98  return -1;
99 
100  stat = G__write_colors(fd, colors);
101  fclose(fd);
102  return stat;
103 }
104 
105 int G__write_colors(FILE * fd, struct Colors *colors)
106 {
107  if (getenv("FORCE_GRASS3_COLORS"))
108  return forced_write_old_colors(fd, colors);
109  else if (colors->version < 0)
110  return write_old_colors(fd, colors);
111  else
112  return write_new_colors(fd, colors);
113 }
114 
115 static int write_new_colors(FILE * fd, struct Colors *colors)
116 {
117  char str1[100], str2[100];
118 
119  format_min(str1, (double)colors->cmin);
120  format_max(str2, (double)colors->cmax);
121  fprintf(fd, "%% %s %s\n", str1, str2);
122 
123  if (colors->shift) {
124  sprintf(str2, "%.15g", (double)colors->shift);
125  G_trim_decimal(str2);
126  fprintf(fd, "shift:%s\n", str2);
127  }
128  if (colors->invert)
129  fprintf(fd, "invert\n");
130 
131  if (colors->null_set) {
132  fprintf(fd, "nv:%d", colors->null_red);
133  if (colors->null_red != colors->null_grn || colors->null_red
134  != colors->null_blu)
135  fprintf(fd, ":%d:%d", colors->null_grn, colors->null_blu);
136  fprintf(fd, "\n");
137  }
138  if (colors->undef_set) {
139  fprintf(fd, "*:%d", colors->undef_red);
140  if (colors->undef_red != colors->undef_grn || colors->undef_red
141  != colors->undef_blu)
142  fprintf(fd, ":%d:%d", colors->undef_grn, colors->undef_blu);
143  fprintf(fd, "\n");
144  }
145  if (colors->modular.rules) {
146  fprintf(fd, "%s\n", "%%");
147  write_rules(fd, colors->modular.rules, colors->cmin, colors->cmax);
148  fprintf(fd, "%s\n", "%%");
149  }
150  if (colors->fixed.rules)
151  write_rules(fd, colors->fixed.rules, colors->cmin, colors->cmax);
152 
153  return 1;
154 }
155 
156 static int write_rules(FILE * fd, struct _Color_Rule_ *crules, DCELL dmin, DCELL dmax /* overall min and max data values in color table */
157  )
158 {
159  struct _Color_Rule_ *rule;
160  char str[100];
161 
162  /* find the end of the rules list */
163  rule = crules;
164  while (rule->next)
165  rule = rule->next;
166 
167  /* write out the rules in reverse order */
168  for (; rule; rule = rule->prev) {
169  if (rule->low.value == dmin)
170  format_min(str, (double)rule->low.value);
171  else {
172  sprintf(str, "%.15g", (double)rule->low.value);
173  G_trim_decimal(str);
174  }
175  fprintf(fd, "%s:%d", str, (int)rule->low.red);
176  if (rule->low.red != rule->low.grn || rule->low.red != rule->low.blu)
177  fprintf(fd, ":%d:%d", rule->low.grn, rule->low.blu);
178  /* even if low==high, write second end when the high is dmax */
179  if (rule->high.value == dmax || rule->low.value != rule->high.value) {
180  if (rule->high.value == dmax)
181  format_max(str, (double)rule->high.value);
182  else {
183  sprintf(str, "%.15g", (double)rule->high.value);
184  G_trim_decimal(str);
185  }
186  fprintf(fd, " %s:%d", str, (int)rule->high.red);
187  if (rule->high.red != rule->high.grn ||
188  rule->high.red != rule->high.blu)
189  fprintf(fd, ":%d:%d", rule->high.grn, rule->high.blu);
190  }
191  fprintf(fd, "\n");
192  }
193 
194  return 0;
195 }
196 
197 static int write_old_colors(FILE * fd, struct Colors *colors)
198 {
199  int i, n;
200 
201  fprintf(fd, "#%ld first color\n", (long)colors->fixed.min);
202  if (colors->null_set) {
203  fprintf(fd, "%d %d %d\n",
204  (int)colors->null_red,
205  (int)colors->null_grn, (int)colors->null_blu);
206  }
207  else
208  fprintf(fd, "255 255 255\n"); /* white */
209 
210  n = colors->fixed.max - colors->fixed.min + 1;
211 
212  for (i = 0; i < n; i++) {
213  fprintf(fd, "%d", (int)colors->fixed.lookup.red[i]);
214  if (colors->fixed.lookup.red[i] != colors->fixed.lookup.grn[i]
215  || colors->fixed.lookup.red[i] != colors->fixed.lookup.blu[i])
216  fprintf(fd, " %d %d",
217  (int)colors->fixed.lookup.grn[i],
218  (int)colors->fixed.lookup.blu[i]);
219  fprintf(fd, "\n");
220  }
221 
222  return 1;
223 }
224 
225 static int forced_write_old_colors(FILE * fd, struct Colors *colors)
226 {
227  int red, grn, blu;
228  CELL cat;
229 
230  fprintf(fd, "#%ld first color\n", (long)colors->cmin);
231  G_get_color((CELL) 0, &red, &grn, &blu, colors);
232  fprintf(fd, "%d %d %d\n", red, grn, blu);
233 
234  for (cat = colors->cmin; cat <= colors->cmax; cat++) {
235  G_get_color(cat, &red, &grn, &blu, colors);
236  fprintf(fd, "%d", red);
237  if (red != grn || red != blu)
238  fprintf(fd, " %d %d", grn, blu);
239  fprintf(fd, "\n");
240  }
241 
242  return 1;
243 }
244 
245 static int format_min(char *str, double dval)
246 {
247  double dtmp;
248 
249  sprintf(str, "%.15g", dval);
250  /* Note that G_trim_decimal() does not trim e.g. 1.0000000e-20 */
251  G_trim_decimal(str);
252  sscanf(str, "%lf", &dtmp);
253  if (dtmp != dval) { /* if no zeros after decimal point were trimmed */
254  /* lower dval by GRASS_EPSILON fraction */
255  if (dval > 0)
256  sprintf(str, "%.15g", dval * (1 - GRASS_EPSILON));
257  else
258  sprintf(str, "%.15g", dval * (1 + GRASS_EPSILON));
259  }
260 
261  return 0;
262 }
263 
264 static int format_max(char *str, double dval)
265 {
266  double dtmp;
267 
268  sprintf(str, "%.15g", dval);
269  /* Note that G_trim_decimal() does not trim e.g. 1.0000000e-20 */
270  G_trim_decimal(str);
271  sscanf(str, "%lf", &dtmp);
272  if (dtmp != dval) { /* if no zeros after decimal point were trimmed */
273  /* increase dval by by GRASS_EPSILON fraction */
274  if (dval > 0)
275  sprintf(str, "%.15g", dval * (1 + GRASS_EPSILON));
276  else
277  sprintf(str, "%.15g", dval * (1 - GRASS_EPSILON));
278  }
279 
280  return 0;
281 }
char * G_mapset(void)
current mapset name
Definition: mapset.c:31
int G_write_colors(const char *name, const char *mapset, struct Colors *colors)
write map layer color table
Definition: color_write.c:74
sprintf(buf2,"%s", G3D_CATS_ELEMENT)
char xmapset[512]
Definition: g3dcats.c:89
FILE * fd
Definition: g3dcolor.c:368
string name
Definition: render.py:1314
int G_trim_decimal(char *buf)
Removes trailing zeros from decimal number.
Definition: trim_dec.c:30
DCELL dmin
Definition: g3dcolor.c:53
char * getenv()
int stat
Definition: g3dcolor.c:369
int G_get_color(CELL n, int *red, int *grn, int *blu, struct Colors *colors)
Get a category color.
Definition: color_get.c:36
int G_remove(const char *element, const char *name)
Remove a database file.
Definition: remove.c:47
FILE * G_fopen_new(const char *element, const char *name)
Open a new database file.
Definition: gis/open.c:197
fclose(fd)
CELL cat
Definition: g3dcats.c:90
DCELL dmax
Definition: g3dcolor.c:53
char xname[512]
Definition: g3dcats.c:89
int n
Definition: dataquad.c:291
int G__write_colors(FILE *fd, struct Colors *colors)
Definition: color_write.c:105
int G__name_is_fully_qualified(const char *fullname, char *name, char *mapset)
Check if map name is fully qualified (map @ mapset)
Definition: nme_in_mps.c:57