GRASS Programmer's Manual
6.4.1(2011)
|
00001 00002 /********************************************************************** 00003 * G_write_colors (name, mapset, colors) 00004 * char *name name of map 00005 * char *mapset mapset that map belongs to 00006 * struct Colors *colors structure holding color info 00007 * 00008 * Writes the color information associated with map layer "map" 00009 * in mapset "mapset" from the structure "colors". 00010 * 00011 * returns: 1 if successful 00012 * -1 on fail 00013 * 00014 * If the environment variable FORCE_GRASS3_COLORS is set (to anything at all) 00015 * then the output format is 3.0, even if the structure contains 4.0 rules. 00016 * This allows users to create 3.0 color files for export to sites which 00017 * don't yet have 4.0 00018 ***********************************************************************/ 00019 #include <string.h> 00020 #include <stdlib.h> 00021 #include <stdio.h> 00022 #include <grass/gis.h> 00023 #define PRECISION 30 00024 #define THRESHOLD .0000000000000000000000000000005 00025 /* .5 * 10 ^(-30) */ 00026 00027 static int write_new_colors(FILE *, struct Colors *); 00028 static int write_rules(FILE *, struct _Color_Rule_ *, DCELL, DCELL); 00029 static int write_old_colors(FILE *, struct Colors *); 00030 static int forced_write_old_colors(FILE *, struct Colors *); 00031 static int format_min(char *, double); 00032 static int format_max(char *, double); 00033 00034 00077 int G_write_colors(const char *name, const char *mapset, 00078 struct Colors *colors) 00079 { 00080 char element[512]; 00081 char xname[GNAME_MAX], xmapset[GMAPSET_MAX]; 00082 FILE *fd; 00083 int stat; 00084 00085 if (G__name_is_fully_qualified(name, xname, xmapset)) { 00086 if (strcmp(xmapset, mapset) != 0) 00087 return -1; 00088 name = xname; 00089 } 00090 /* 00091 * if mapset is current mapset, remove colr2 file (created by pre 3.0 grass) 00092 * and then write original color table 00093 * else write secondary color table 00094 */ 00095 sprintf(element, "colr2/%s", mapset); 00096 if (strcmp(mapset, G_mapset()) == 0) { 00097 G_remove(element, name); /* get rid of existing colr2, if any */ 00098 strcpy(element, "colr"); 00099 } 00100 if (!(fd = G_fopen_new(element, name))) 00101 return -1; 00102 00103 stat = G__write_colors(fd, colors); 00104 fclose(fd); 00105 return stat; 00106 } 00107 00108 int G__write_colors(FILE * fd, struct Colors *colors) 00109 { 00110 if (getenv("FORCE_GRASS3_COLORS")) 00111 return forced_write_old_colors(fd, colors); 00112 else if (colors->version < 0) 00113 return write_old_colors(fd, colors); 00114 else 00115 return write_new_colors(fd, colors); 00116 } 00117 00118 static int write_new_colors(FILE * fd, struct Colors *colors) 00119 { 00120 char str1[100], str2[100]; 00121 00122 format_min(str1, (double)colors->cmin); 00123 format_max(str2, (double)colors->cmax); 00124 fprintf(fd, "%% %s %s\n", str1, str2); 00125 00126 if (colors->shift) { 00127 sprintf(str2, "%.10f", (double)colors->shift); 00128 G_trim_decimal(str2); 00129 fprintf(fd, "shift:%s\n", str2); 00130 } 00131 if (colors->invert) 00132 fprintf(fd, "invert\n"); 00133 00134 if (colors->null_set) { 00135 fprintf(fd, "nv:%d", colors->null_red); 00136 if (colors->null_red != colors->null_grn || colors->null_red 00137 != colors->null_blu) 00138 fprintf(fd, ":%d:%d", colors->null_grn, colors->null_blu); 00139 fprintf(fd, "\n"); 00140 } 00141 if (colors->undef_set) { 00142 fprintf(fd, "*:%d", colors->undef_red); 00143 if (colors->undef_red != colors->undef_grn || colors->undef_red 00144 != colors->undef_blu) 00145 fprintf(fd, ":%d:%d", colors->undef_grn, colors->undef_blu); 00146 fprintf(fd, "\n"); 00147 } 00148 if (colors->modular.rules) { 00149 fprintf(fd, "%s\n", "%%"); 00150 write_rules(fd, colors->modular.rules, colors->cmin, colors->cmax); 00151 fprintf(fd, "%s\n", "%%"); 00152 } 00153 if (colors->fixed.rules) 00154 write_rules(fd, colors->fixed.rules, colors->cmin, colors->cmax); 00155 00156 return 1; 00157 } 00158 00159 static int write_rules(FILE * fd, struct _Color_Rule_ *crules, DCELL dmin, DCELL dmax /* overall min and max data values in color table */ 00160 ) 00161 { 00162 struct _Color_Rule_ *rule; 00163 char str[100]; 00164 00165 /* find the end of the rules list */ 00166 rule = crules; 00167 while (rule->next) 00168 rule = rule->next; 00169 00170 /* write out the rules in reverse order */ 00171 for (; rule; rule = rule->prev) { 00172 if (rule->low.value == dmin) 00173 format_min(str, (double)rule->low.value); 00174 else { 00175 sprintf(str, "%.10f", (double)rule->low.value); 00176 G_trim_decimal(str); 00177 } 00178 fprintf(fd, "%s:%d", str, (int)rule->low.red); 00179 if (rule->low.red != rule->low.grn || rule->low.red != rule->low.blu) 00180 fprintf(fd, ":%d:%d", rule->low.grn, rule->low.blu); 00181 /* even if low==high, write second end when the high is dmax */ 00182 if (rule->high.value == dmax || rule->low.value != rule->high.value) { 00183 if (rule->high.value == dmax) 00184 format_max(str, (double)rule->high.value); 00185 else { 00186 sprintf(str, "%.10f", (double)rule->high.value); 00187 G_trim_decimal(str); 00188 } 00189 fprintf(fd, " %s:%d", str, (int)rule->high.red); 00190 if (rule->high.red != rule->high.grn || 00191 rule->high.red != rule->high.blu) 00192 fprintf(fd, ":%d:%d", rule->high.grn, rule->high.blu); 00193 } 00194 fprintf(fd, "\n"); 00195 } 00196 00197 return 0; 00198 } 00199 00200 static int write_old_colors(FILE * fd, struct Colors *colors) 00201 { 00202 int i, n; 00203 00204 fprintf(fd, "#%ld first color\n", (long)colors->fixed.min); 00205 if (colors->null_set) { 00206 fprintf(fd, "%d %d %d\n", 00207 (int)colors->null_red, 00208 (int)colors->null_grn, (int)colors->null_blu); 00209 } 00210 else 00211 fprintf(fd, "255 255 255\n"); /* white */ 00212 00213 n = colors->fixed.max - colors->fixed.min + 1; 00214 00215 for (i = 0; i < n; i++) { 00216 fprintf(fd, "%d", (int)colors->fixed.lookup.red[i]); 00217 if (colors->fixed.lookup.red[i] != colors->fixed.lookup.grn[i] 00218 || colors->fixed.lookup.red[i] != colors->fixed.lookup.blu[i]) 00219 fprintf(fd, " %d %d", 00220 (int)colors->fixed.lookup.grn[i], 00221 (int)colors->fixed.lookup.blu[i]); 00222 fprintf(fd, "\n"); 00223 } 00224 00225 return 1; 00226 } 00227 00228 static int forced_write_old_colors(FILE * fd, struct Colors *colors) 00229 { 00230 int red, grn, blu; 00231 CELL cat; 00232 00233 fprintf(fd, "#%ld first color\n", (long)colors->cmin); 00234 G_get_color((CELL) 0, &red, &grn, &blu, colors); 00235 fprintf(fd, "%d %d %d\n", red, grn, blu); 00236 00237 for (cat = colors->cmin; cat <= colors->cmax; cat++) { 00238 G_get_color(cat, &red, &grn, &blu, colors); 00239 fprintf(fd, "%d", red); 00240 if (red != grn || red != blu) 00241 fprintf(fd, " %d %d", grn, blu); 00242 fprintf(fd, "\n"); 00243 } 00244 00245 return 1; 00246 } 00247 00248 static int format_min(char *str, double dval) 00249 { 00250 double dtmp; 00251 00252 sprintf(str, "%.*f", PRECISION, dval); 00253 G_trim_decimal(str); 00254 sscanf(str, "%lf", &dtmp); 00255 if (dtmp != dval) { /* if no zeros after decimal point were trimmed */ 00256 sprintf(str, "%.*f", PRECISION, dval - THRESHOLD); 00257 /* because precision is probably higher than PRECISION */ 00258 } 00259 00260 return 0; 00261 } 00262 00263 static int format_max(char *str, double dval) 00264 { 00265 double dtmp; 00266 00267 sprintf(str, "%.*f", PRECISION, dval); 00268 G_trim_decimal(str); 00269 sscanf(str, "%lf", &dtmp); 00270 if (dtmp != dval) { /* if no zeros after decimal point were trimmed */ 00271 sprintf(str, "%.*f", PRECISION, dval + THRESHOLD); 00272 /* because precision is probably higher than PRECISION */ 00273 } 00274 00275 return 0; 00276 }