[GRASS-SVN] r72895 - grass/trunk/raster/r.colors

svn_grass at osgeo.org svn_grass at osgeo.org
Sun Jun 24 06:44:57 PDT 2018


Author: mmetz
Date: 2018-06-24 06:44:57 -0700 (Sun, 24 Jun 2018)
New Revision: 72895

Modified:
   grass/trunk/raster/r.colors/edit_colors.c
Log:
r.colors: add flag to print color name: description (type); code formatting

Modified: grass/trunk/raster/r.colors/edit_colors.c
===================================================================
--- grass/trunk/raster/r.colors/edit_colors.c	2018-06-24 10:15:29 UTC (rev 72894)
+++ grass/trunk/raster/r.colors/edit_colors.c	2018-06-24 13:44:57 UTC (rev 72895)
@@ -22,6 +22,22 @@
 #include <sys/types.h>
 #include "local_proto.h"
 
+
+struct colordesc
+{
+    char *name;
+    char *desc;
+    char *type;
+};
+
+int cmp_clrname(const void *a, const void *b)
+{
+    struct colordesc *ca = (struct colordesc *) a;
+    struct colordesc *cb = (struct colordesc *) b;
+
+    return (strcmp(ca->name, cb->name));
+}
+
 int edit_colors(int argc, char **argv, int type, const char *maptype,
 		const char* Maptype)
 {
@@ -42,9 +58,10 @@
     int has_fcell_type = 0;
     struct GModule *module;
     struct maps_info input_maps;
+    int stat = -1;
 
     struct {
-        struct Flag *r, *w, *l, *g, *a, *n, *e;
+        struct Flag *r, *w, *l, *d, *g, *a, *n, *e;
     } flag; 
 
     struct {
@@ -127,6 +144,13 @@
     flag.l->suppress_required = YES;
     flag.l->guisection = _("Print");
 
+    flag.d = G_define_flag();
+    flag.d->key = 'd';
+    flag.d->label = _("List available rules with description then exit");
+    flag.d->description = _("If a color rule is given, only this rule is listed");
+    flag.d->suppress_required = YES;
+    flag.d->guisection = _("Print");
+
     flag.n = G_define_flag();
     flag.n->key = 'n';
     flag.n->description = _("Invert colors");
@@ -148,9 +172,9 @@
     flag.e->guisection = _("Define");
 
     G_option_exclusive(opt.maps, opt.file, flag.l, NULL);
-    G_option_required(opt.maps, opt.file, flag.l, NULL);
+    G_option_required(opt.maps, opt.file, flag.l, flag.d, NULL);
     G_option_exclusive(opt.rast, opt.volume, NULL);
-    G_option_required(opt.rast, opt.volume, opt.colr, opt.rules, flag.r, flag.l, NULL);
+    G_option_required(opt.rast, opt.volume, opt.colr, opt.rules, flag.r, flag.l, flag.d, NULL);
     G_option_exclusive(opt.colr, opt.rules, opt.rast, opt.volume, NULL);
     G_option_exclusive(flag.g, flag.a, NULL);
 
@@ -162,6 +186,161 @@
         return EXIT_SUCCESS;
     }
 
+    if (flag.d->answer) {
+	char path[GPATH_MAX];
+	FILE *fp;
+	int ncolors;
+	struct colordesc *colordesc;
+	char **cnames;
+
+	/* load color rules */
+	G_snprintf(path, GPATH_MAX, "%s/etc/colors", G_gisbase());
+
+	ncolors = 0;
+	cnames = G_ls2(path, &ncolors);
+	colordesc = G_malloc(ncolors * sizeof(struct colordesc));
+	for (i = 0; i < ncolors; i++) {
+	    char buf[1024];
+	    double rmin, rmax;
+	    int first;
+	    int cisperc;
+
+	    colordesc[i].name = G_store(cnames[i]);
+	    colordesc[i].desc = NULL;
+	    
+	    /* open color rule file */
+	    G_snprintf(path, GPATH_MAX, "%s/etc/colors/%s", G_gisbase(),
+	               colordesc[i].name);
+	    fp = fopen(path, "r");
+	    if (!fp)
+		G_fatal_error(_("Unable to open color rule"));
+	    
+	    /* scan all lines */
+	    first = 1;
+	    rmin = rmax = 0;
+	    cisperc = 0;
+	    while (G_getl2(buf, sizeof(buf), fp)) {
+		char value[80], color[80];
+		double x;
+		char c;
+
+		G_strip(buf);
+
+		if (*buf == '\0')
+		    continue;
+		if (*buf == '#')
+		    continue;
+
+		if (sscanf(buf, "%s %[^\n]", value, color) != 2)
+		    continue;
+
+		if (G_strcasecmp(value, "default") == 0) {
+		    continue;
+		}
+
+		if (G_strcasecmp(value, "nv") == 0) {
+		    continue;
+		}
+
+		if (sscanf(value, "%lf%c", &x, &c) == 2 && c == '%') {
+		    cisperc = 1;
+		    break;
+		}
+		if (sscanf(value, "%lf", &x) == 1) {
+		    if (first) {
+			first = 0;
+			rmin = rmax = x;
+		    }
+		    else {
+			if (rmin > x)
+			    rmin = x;
+			if (rmax < x)
+			    rmax = x;
+		    }
+		}
+	    }
+	    fclose(fp);
+
+	    if (cisperc)
+		colordesc[i].type = G_store(_("relative, percent of map range"));
+	    else {
+		G_snprintf(buf, sizeof(buf) - 1, _("absolute, %g to %g"), rmin, rmax);
+		colordesc[i].type = G_store(buf);
+	    }
+	}
+	
+	qsort(colordesc, ncolors, sizeof(struct colordesc), cmp_clrname);
+
+	/* load color descriptions */
+	G_snprintf(path, GPATH_MAX, "%s/etc/colors.desc", G_gisbase());
+	fp = fopen(path, "r");
+	if (!fp)
+	    G_fatal_error(_("Unable to open color descriptions"));
+
+	for (;;) {
+	    char buf[1024];
+            char tok_buf[1024];
+	    char *cname, *cdesc;
+            int ntokens;
+            char **tokens;
+	    struct colordesc csearch, *cfound;
+
+	    if (!G_getl2(buf, sizeof(buf), fp))
+		break;
+            strcpy(tok_buf, buf);
+            tokens = G_tokenize(tok_buf, ":");
+            ntokens = G_number_of_tokens(tokens);
+	    if (ntokens != 2)
+		continue;
+
+	    cname = G_chop(tokens[0]);
+	    cdesc = G_chop(tokens[1]);
+	    
+	    csearch.name = cname;
+	    cfound = bsearch(&csearch, colordesc, ncolors,
+	                     sizeof(struct colordesc), cmp_clrname);
+
+	    if (cfound) {
+		cfound->desc = G_store(cdesc);
+	    }
+	    G_free_tokens(tokens);
+	}
+	fclose(fp);
+
+	if (opt.colr->answer) {
+	    struct colordesc csearch, *cfound;
+
+	    csearch.name = opt.colr->answer;
+	    cfound = bsearch(&csearch, colordesc, ncolors,
+	                     sizeof(struct colordesc), cmp_clrname);
+
+	    if (cfound) {
+		if (cfound->desc) {
+		    fprintf(stdout, "%s: %s (%s)\n", cfound->name,
+			    cfound->desc, cfound->type);
+		}
+		else {
+		    fprintf(stdout, "%s: (%s)\n", cfound->name,
+			    cfound->type);
+		}
+	    }
+	}
+	else {
+	    for (i = 0; i < ncolors; i++) {
+		if (colordesc[i].desc) {
+		    fprintf(stdout, "%s: %s (%s)\n", colordesc[i].name,
+			    colordesc[i].desc, colordesc[i].type);
+		}
+		else {
+		    fprintf(stdout, "%s: (%s)\n", colordesc[i].name,
+			    colordesc[i].type);
+		}
+	    }
+	}
+
+        return EXIT_SUCCESS;
+    }
+
     overwrite = !flag.w->answer;
     remove = flag.r->answer;
     style = opt.colr->answer;
@@ -179,105 +358,105 @@
 
     /* Read the map names from the infile */
     if (file) {
-		FILE *in;
+	FILE *in;
+	int num_maps = 0;
+	int max_maps = 0;
 
-		in = fopen(file, "r");
-		if (!in)
-			G_fatal_error(_("Unable to open %s file <%s>"), maptype, file);
+	in = fopen(file, "r");
+	if (!in)
+		G_fatal_error(_("Unable to open %s file <%s>"), maptype, file);
 
-		int num_maps = 0;
-		int max_maps = 0;
+	input_maps.names = (char **)G_calloc(100, sizeof(char *));
+	input_maps.mapsets = (char **)G_calloc(100, sizeof(char *));
+	input_maps.map_types = (int*)G_calloc(100, sizeof(int));
+	input_maps.min = (DCELL*)G_calloc(100, sizeof(DCELL));
+	input_maps.max = (DCELL*)G_calloc(100, sizeof(DCELL));
 
-		input_maps.names = (char **)G_calloc(100, sizeof(char *));
-		input_maps.mapsets = (char **)G_calloc(100, sizeof(char *));
-		input_maps.map_types = (int*)G_calloc(100, sizeof(int));
-		input_maps.min = (DCELL*)G_calloc(100, sizeof(DCELL));
-		input_maps.max = (DCELL*)G_calloc(100, sizeof(DCELL));
+	for (;;) {
+	    char buf[GNAME_MAX]; /* Name */
 
-		for (;;) {
-			char buf[GNAME_MAX]; /* Name */
+	    if (!G_getl2(buf, sizeof(buf), in))
+		break;
 
-			if (!G_getl2(buf, sizeof(buf), in))
-				break;
+	    name = G_chop(buf);
 
-			name = G_chop(buf);
+	    /* Ignore empty lines */
+	    if (!*name)
+		continue;
 
-			/* Ignore empty lines */
-			if (!*name)
-			continue;
+	    /* Reallocate memory */
+	    if (num_maps >= max_maps) {
+		max_maps += 100;
+		input_maps.names = (char **)G_realloc(input_maps.names, max_maps * sizeof(char *));
+		input_maps.mapsets = (char **)G_realloc(input_maps.mapsets, max_maps * sizeof(char *));
+		input_maps.map_types = (int*)G_realloc(input_maps.map_types, max_maps * sizeof(int));
+		input_maps.min = (DCELL*)G_realloc(input_maps.min, max_maps * sizeof(DCELL));
+		input_maps.max = (DCELL*)G_realloc(input_maps.max, max_maps * sizeof(DCELL));
+	    }
 
-			/* Reallocate memory */
-			if (num_maps >= max_maps) {
-				max_maps += 100;
-				input_maps.names = (char **)G_realloc(input_maps.names, max_maps * sizeof(char *));
-				input_maps.mapsets = (char **)G_realloc(input_maps.mapsets, max_maps * sizeof(char *));
-				input_maps.map_types = (int*)G_realloc(input_maps.map_types, max_maps * sizeof(int));
-				input_maps.min = (DCELL*)G_realloc(input_maps.min, max_maps * sizeof(DCELL));
-				input_maps.max = (DCELL*)G_realloc(input_maps.max, max_maps * sizeof(DCELL));
-			}
+	    /* Store the map name */
+	    input_maps.names[num_maps] = G_store(name);
 
-			/* Store the map name */
-			input_maps.names[num_maps] = G_store(name);
+	    /* Switch between raster and volume */
+	    if (type == RASTER3D_TYPE) {
+		input_maps.mapsets[num_maps] = G_store(G_find_raster3d(input_maps.names[num_maps], ""));
+	    }
+	    else {
+		input_maps.mapsets[num_maps] = G_store(G_find_raster2(input_maps.names[num_maps], ""));
+	    }
+	    if (input_maps.mapsets[num_maps] == NULL)
+		G_fatal_error(_("%s map <%s> not found"), Maptype, input_maps.names[num_maps]);
 
-		    /* Switch between raster and volume */
-		    if (type == RASTER3D_TYPE) {
-		    	input_maps.mapsets[num_maps] = G_store(G_find_raster3d(input_maps.names[num_maps], ""));
-		    } else {
-		    	input_maps.mapsets[num_maps] = G_store(G_find_raster2(input_maps.names[num_maps], ""));
-		    }
-		    if (input_maps.mapsets[num_maps] == NULL)
-		        G_fatal_error(_("%s map <%s> not found"), Maptype, input_maps.names[num_maps]);
+	    num_maps++;
+	}
 
-			num_maps++;
-		}
-
         if (num_maps < 1)
             G_fatal_error(_("No %s map name found in input file <%s>"), maptype, file);
 
-		input_maps.num = num_maps;
+	input_maps.num = num_maps;
 
         fclose(in);
     }
-    else if(opt.maps->answer) {
-		input_maps.num = 0;
-		while(opt.maps->answers[input_maps.num]) {
-			input_maps.num++;
-		}
-		input_maps.names = (char **)G_calloc(input_maps.num, sizeof(char *));
-		input_maps.mapsets = (char **)G_calloc(input_maps.num, sizeof(char *));
-		input_maps.map_types = (int*)G_calloc(input_maps.num, sizeof(int));
-		input_maps.min = (DCELL*)G_calloc(input_maps.num, sizeof(DCELL));
-		input_maps.max = (DCELL*)G_calloc(input_maps.num, sizeof(DCELL));
+    else if (opt.maps->answer) {
+	input_maps.num = 0;
+	while (opt.maps->answers[input_maps.num]) {
+		input_maps.num++;
+	}
+	input_maps.names = (char **)G_calloc(input_maps.num, sizeof(char *));
+	input_maps.mapsets = (char **)G_calloc(input_maps.num, sizeof(char *));
+	input_maps.map_types = (int*)G_calloc(input_maps.num, sizeof(int));
+	input_maps.min = (DCELL*)G_calloc(input_maps.num, sizeof(DCELL));
+	input_maps.max = (DCELL*)G_calloc(input_maps.num, sizeof(DCELL));
 
-		for(i = 0; i < input_maps.num; i++) {
-			input_maps.names[i] = G_store(opt.maps->answers[i]);
+	for (i = 0; i < input_maps.num; i++) {
+		input_maps.names[i] = G_store(opt.maps->answers[i]);
 
-		    /* Switch between raster and volume */
-		    if (type == RASTER3D_TYPE) {
-		    	input_maps.mapsets[i] = G_store(G_find_raster3d(input_maps.names[i], ""));
-		    } else {
-		    	input_maps.mapsets[i] = G_store(G_find_raster2(input_maps.names[i], ""));
-		    }
-		    if (input_maps.mapsets[i] == NULL)
-		        G_fatal_error(_("%s map <%s> not found"), Maptype, input_maps.names[i]);
-		}
+	    /* Switch between raster and volume */
+	    if (type == RASTER3D_TYPE) {
+		input_maps.mapsets[i] = G_store(G_find_raster3d(input_maps.names[i], ""));
+	    }
+	    else {
+		input_maps.mapsets[i] = G_store(G_find_raster2(input_maps.names[i], ""));
+	    }
+	    if (input_maps.mapsets[i] == NULL)
+		G_fatal_error(_("%s map <%s> not found"), Maptype, input_maps.names[i]);
+	}
     }
 
-    int stat = -1;
     if (remove) {
-    	for(i = 0; i < input_maps.num; i++) {
-    		name = input_maps.names[i];
-    		mapset = input_maps.mapsets[i];
+    	for (i = 0; i < input_maps.num; i++) {
+	    name = input_maps.names[i];
+	    mapset = input_maps.mapsets[i];
 
-			if (type == RASTER3D_TYPE) {
-				stat = Rast3d_remove_color(name);
-			} else {
-				stat = Rast_remove_colors(name, mapset);
-			}
-			if (stat < 0)
-				G_fatal_error(_("Unable to remove color table of %s map <%s>"), maptype, name);
-			if (stat == 0)
-				G_warning(_("Color table of %s map <%s> not found"), maptype, name);
+	    if (type == RASTER3D_TYPE) {
+		    stat = Rast3d_remove_color(name);
+	    } else {
+		    stat = Rast_remove_colors(name, mapset);
+	    }
+	    if (stat < 0)
+		    G_fatal_error(_("Unable to remove color table of %s map <%s>"), maptype, name);
+	    if (stat == 0)
+		    G_warning(_("Color table of %s map <%s> not found"), maptype, name);
     	}
         return EXIT_SUCCESS;
     }
@@ -284,72 +463,77 @@
 
     G_suppress_warnings(TRUE);
 
-	for(i = 0; i < input_maps.num; i++) {
-		name = input_maps.names[i];
-		mapset = input_maps.mapsets[i];
+    for (i = 0; i < input_maps.num; i++) {
+	name = input_maps.names[i];
+	mapset = input_maps.mapsets[i];
 
-		if (type == RASTER3D_TYPE) {
-			have_colors = Rast3d_read_colors(name, mapset, &colors);
-		} else {
-			have_colors = Rast_read_colors(name, mapset, &colors);
-		}
-		/*
-		  if (have_colors >= 0)
-		  Rast_free_colors(&colors);
-		 */
+	if (type == RASTER3D_TYPE) {
+	    have_colors = Rast3d_read_colors(name, mapset, &colors);
+	}
+	else {
+	    have_colors = Rast_read_colors(name, mapset, &colors);
+	}
+	/*
+	  if (have_colors >= 0)
+	  Rast_free_colors(&colors);
+	 */
 
-		if (have_colors > 0 && !overwrite) {
-			G_fatal_error(_("Color table exists for %s map <%s>. Exiting."), maptype, name);
-		}
+	if (have_colors > 0 && !overwrite) {
+	    G_fatal_error(_("Color table exists for %s map <%s>. Exiting."), maptype, name);
 	}
+    }
 
     G_suppress_warnings(FALSE);
 
     has_fcell_type = 0;
     has_cell_type = 0;
-	for(i = 0; i < input_maps.num; i++) {
-		name = input_maps.names[i];
-		mapset = input_maps.mapsets[i];
+    min = max = 0;
+    for (i = 0; i < input_maps.num; i++) {
+	name = input_maps.names[i];
+	mapset = input_maps.mapsets[i];
 
-		if (type == RASTER3D_TYPE) {
-			input_maps.map_types[i] = 1; /* 3D raster maps are always floating point */
-			has_fcell_type = 1;
-			Rast3d_read_range(name, mapset, &range);
-		} else {
-			input_maps.map_types[i] = Rast_map_is_fp(name, mapset);
-			if(input_maps.map_types[i] == 1)
-				has_fcell_type = 1;
-			else
-				has_cell_type = 1;
+	if (type == RASTER3D_TYPE) {
+	    input_maps.map_types[i] = 1; /* 3D raster maps are always floating point */
+	    has_fcell_type = 1;
+	    Rast3d_read_range(name, mapset, &range);
+	}
+	else {
+	    input_maps.map_types[i] = Rast_map_is_fp(name, mapset);
+	    if(input_maps.map_types[i] == 1)
+		has_fcell_type = 1;
+	    else
+		has_cell_type = 1;
 
-			Rast_read_fp_range(name, mapset, &range);
-		}
+	    Rast_read_fp_range(name, mapset, &range);
+	}
 
-		if(i > 0) {
-			if(has_fcell_type && has_cell_type) {
-				G_fatal_error("Input maps must have the same cell type. "
-						"Mixing of integer and floating point maps is not supported.");
-			}
-		}
+	if (i > 0) {
+	    if(has_fcell_type && has_cell_type) {
+		G_fatal_error("Input maps must have the same cell type. "
+				"Mixing of integer and floating point maps is not supported.");
+	    }
+	}
 
-		Rast_get_fp_range_min_max(&range, &input_maps.min[i], &input_maps.max[i]);
+	Rast_get_fp_range_min_max(&range, &input_maps.min[i], &input_maps.max[i]);
 
-		/* Compute min, max of all maps*/
-		if(i == 0) {
-			min = input_maps.min[i];
-			max = input_maps.max[i];
-		} else {
-			if(input_maps.min[i] < min)
-				min = input_maps.min[i];
-			if(input_maps.max[i] > max)
-				max = input_maps.max[i];
-		}
+	/* Compute min, max of all maps*/
+	if (i == 0) {
+	    min = input_maps.min[i];
+	    max = input_maps.max[i];
 	}
+	else {
+	    if(input_maps.min[i] < min)
+		min = input_maps.min[i];
+	    if(input_maps.max[i] > max)
+		max = input_maps.max[i];
+	}
+    }
 
     if (is_from_stdin) {
         if (!read_color_rules(stdin, &colors, min, max, has_fcell_type))
             exit(EXIT_FAILURE);
-    } else if (style) {
+    }
+    else if (style) {
         /* 
          * here the predefined color-table color-styles are created by GRASS library calls. 
          */
@@ -357,13 +541,15 @@
             if (has_fcell_type)
                 G_fatal_error(_("Color table 'random' is not supported for floating point %s map"), maptype);
             Rast_make_random_colors(&colors, (CELL) min, (CELL) max);
-        } else if (strcmp(style, "grey.eq") == 0) {
+        }
+	else if (strcmp(style, "grey.eq") == 0) {
             if (has_fcell_type)
                 G_fatal_error(_("Color table 'grey.eq' is not supported for floating point %s map"), maptype);
             if (!have_stats)
                 have_stats = get_stats(&input_maps, &statf);
             Rast_make_histogram_eq_colors(&colors, &statf);
-        } else if (strcmp(style, "grey.log") == 0) {
+        }
+	else if (strcmp(style, "grey.log") == 0) {
             if (has_fcell_type)
                 G_fatal_error(_("Color table 'grey.log' is not supported for floating point %s map"), maptype);
             if (!have_stats)
@@ -370,11 +556,13 @@
                 have_stats = get_stats(&input_maps, &statf);
             Rast_make_histogram_log_colors(&colors, &statf, (CELL) min,
                                            (CELL) max);
-        } else if (G_find_color_rule(style))
+        }
+	else if (G_find_color_rule(style))
             Rast_make_fp_colors(&colors, style, min, max);
         else
             G_fatal_error(_("Unknown color request '%s'"), style);
-    } else if (rules) {
+    }
+    else if (rules) {
         if (!Rast_load_fp_colors(&colors, rules, min, max)) {
             /* for backwards compatibility try as std name; remove for GRASS 7 */
             char path[GPATH_MAX];
@@ -385,7 +573,8 @@
             if (!Rast_load_fp_colors(&colors, path, min, max))
                 G_fatal_error(_("Unable to load rules file <%s>"), rules);
         }
-    } else {
+    }
+    else {
         /* use color from another map (cmap) */
         if (opt.rast->answer) {
             cmapset = G_find_raster2(cmap, "");
@@ -394,7 +583,8 @@
 
             if (Rast_read_colors(cmap, cmapset, &colors) < 0)
                 G_fatal_error(_("Unable to read color table for raster map <%s>"), cmap);
-        } else {
+        }
+	else {
             cmapset = G_find_raster3d(cmap, "");
             if (cmapset == NULL)
                 G_fatal_error(_("3D raster map <%s> not found"), cmap);
@@ -413,9 +603,11 @@
     if (flag.e->answer) {
         if (has_fcell_type && !has_cell_type) {
             struct FP_stats fpstats;
+
             get_fp_stats(&input_maps, &fpstats, min, max, flag.g->answer, flag.a->answer, type);
             Rast_histogram_eq_fp_colors(&colors_tmp, &colors, &fpstats);
-        } else {
+        }
+	else {
             if (!have_stats)
                 have_stats = get_stats(&input_maps, &statf);
             Rast_histogram_eq_colors(&colors_tmp, &colors, &statf);
@@ -433,21 +625,22 @@
         colors = colors_tmp;
     }
 
-	for(i = 0; i < input_maps.num; i++) {
-		name = input_maps.names[i];
-		mapset = input_maps.mapsets[i];
+    for (i = 0; i < input_maps.num; i++) {
+	name = input_maps.names[i];
+	mapset = input_maps.mapsets[i];
 
-		if (input_maps.map_types[i])
-			Rast_mark_colors_as_fp(&colors);
-		if (type == RASTER3D_TYPE) {
-			Rast3d_write_colors(name, mapset, &colors);
-		} else {
-			Rast_write_colors(name, mapset, &colors);
-		}
-		G_message(_("Color table for %s map <%s> set to '%s'"), maptype, name,
-				  is_from_stdin ? "rules" : style ? style : rules ? rules :
-				  cmap);
+	if (input_maps.map_types[i])
+	    Rast_mark_colors_as_fp(&colors);
+	if (type == RASTER3D_TYPE) {
+	    Rast3d_write_colors(name, mapset, &colors);
 	}
+	else {
+	    Rast_write_colors(name, mapset, &colors);
+	}
+	G_message(_("Color table for %s map <%s> set to '%s'"), maptype, name,
+		  is_from_stdin ? "rules" : style ? style : rules ? rules :
+		  cmap);
+    }
 
     exit(EXIT_SUCCESS);
 }



More information about the grass-commit mailing list