Pārlūkot izejas kodu

v.colors: raster= with use=attr (#1393)

* v.colors: raster= with use=attr

* Remove trailing whitespaces
Huidae Cho 4 gadi atpakaļ
vecāks
revīzija
f2526150c3

+ 6 - 5
vector/v.colors/local_proto.h

@@ -9,8 +9,10 @@ void load_colors(struct Colors *, const char *, DCELL, DCELL, int);
 
 /* scan_attr.c */
 int scan_attr(const struct Map_info *, int, const char *, const char *,
-	      const char *, const struct FPRange *, struct Colors *);
-void color_rules_to_cats(dbCatValArray *, int, struct Colors *, struct Colors *);  
+	      const char *, const struct FPRange *, struct Colors *,
+	      struct Colors *);
+void color_rules_to_cats(dbCatValArray *, int, struct Colors *,
+			 struct Colors *);
 
 /* scan_cats.c */
 void scan_cats(const struct Map_info *, int, const char *, const char *,
@@ -18,11 +20,10 @@ void scan_cats(const struct Map_info *, int, const char *, const char *,
 
 /* scan_z.c */
 void scan_z(struct Map_info *, int, const char *, const char *,
-            const struct FPRange *, struct Colors *);
+	    const struct FPRange *, struct Colors *);
 
 /* write_rgb.c */
 void write_rgb_values(const struct Map_info *, int, const char *,
 		      struct Colors *);
 /* read_rgb.c */
-void rgb2colr(const struct Map_info *, int, const char *,
-	      struct Colors *);
+void rgb2colr(const struct Map_info *, int, const char *, struct Colors *);

+ 37 - 29
vector/v.colors/main.c

@@ -2,11 +2,12 @@
 /****************************************************************
  *
  * MODULE:       v.colors
- * 
- * AUTHOR(S):    Martin Landa <landa.martin gmail.com>
- *               
+ *
+ * AUTHOR(S):    Martin Landa <landa.martin gmail.com>,
+ *               Huidae Cho <grass4u gmail.com>
+ *
  * PURPOSE:      Manage color tables for vector maps
- *               
+ *
  * COPYRIGHT:    (C) 2011-2021 by the GRASS Development Team
  *
  *               This program is free software under the GNU General
@@ -31,7 +32,7 @@ int main(int argc, char *argv[])
     struct GModule *module;
     struct {
 	struct Flag *r, *w, *l, *d, *g, *a, *n, *c;
-    } flag; 
+    } flag;
 
     struct {
 	struct Option *map, *field, *colr, *rast, *volume, *rules,
@@ -43,14 +44,14 @@ int main(int argc, char *argv[])
     const char *mapset, *cmapset;
     const char *style, *rules, *cmap, *attrcolumn, *rgbcolumn;
     char *name;
-    
+
     struct Map_info Map;
     struct FPRange range;
     struct Colors colors, colors_tmp;
     /* struct Cell_stats statf; */
-    
+
     G_gisinit(argv[0]);
-    
+
     module = G_define_module();
     G_add_keyword(_("vector"));
     G_add_keyword(_("color table"));
@@ -74,7 +75,7 @@ int main(int argc, char *argv[])
 	       _("use category values"),
 	       _("use z coordinate (3D points or centroids only)"));
     opt.use->answer = "cat";
-    
+
     opt.attrcol = G_define_standard_option(G_OPT_DB_COLUMN);
     opt.attrcol->label = _("Name of column containing numeric data");
     opt.attrcol->description = _("Required for use=attr");
@@ -115,7 +116,7 @@ int main(int argc, char *argv[])
     opt.rgbcol->key = "rgb_column";
     opt.rgbcol->label = _("Name of color column to populate RGB values");
     opt.rgbcol->description = _("If not given writes color table");
-    
+
     flag.r = G_define_flag();
     flag.r->key = 'r';
     flag.r->description = _("Remove existing color table");
@@ -158,7 +159,7 @@ int main(int argc, char *argv[])
     flag.c->key = 'c';
     flag.c->label = _("Convert color rules from RGB values to color table");
     flag.c->description = _("Option 'rgb_column' with valid RGB values required");
-	
+
     /* TODO ?
     flag.e = G_define_flag();
     flag.e->key = 'e';
@@ -204,12 +205,12 @@ int main(int argc, char *argv[])
         }
     }
     G_debug(1, "use=%d", use);
-    
+
     if (!name)
         G_fatal_error(_("No vector map specified"));
 
     if (use == USE_ATTR && !attrcolumn)
-        G_fatal_error(_("Option <%s> required"), opt.attrcol->key); 
+        G_fatal_error(_("Option <%s> required"), opt.attrcol->key);
     if (use != USE_ATTR && attrcolumn) {
         G_important_message(_("Option <%s> given, assuming <use=attr>..."), opt.attrcol->key);
         use = USE_ATTR;
@@ -224,12 +225,12 @@ int main(int argc, char *argv[])
         cmap = opt.rast->answer;
     if (opt.volume->answer)
         cmap = opt.volume->answer;
-    
+
     if (!cmap && !style && !rules && !remove && !convert)
         G_fatal_error(_("One of -%c, -%c or %s=, %s= or %s= "
-			"must be specified"), flag.r->key, flag.c->key, 
+			"must be specified"), flag.r->key, flag.c->key,
 		      opt.colr->key, opt.rast->key, opt.rules->key);
-    
+
     if (!!style + !!cmap + !!rules > 1)
         G_fatal_error(_("%s=, %s= and %s= are mutually exclusive"),
 			opt.colr->key, opt.rules->key, opt.rast->key);
@@ -238,7 +239,7 @@ int main(int argc, char *argv[])
         G_fatal_error(_("-%c and -%c are mutually exclusive"),
 		      flag.g->key, flag.a->key);
 
-    if (flag.c->answer && !rgbcolumn) 
+    if (flag.c->answer && !rgbcolumn)
 	G_fatal_error(_("%s= required for -%c"),
 		      opt.rgbcol->key, flag.c->key);
 
@@ -247,7 +248,7 @@ int main(int argc, char *argv[])
     mapset = G_find_vector(name, "");
     if (!mapset)
 	G_fatal_error(_("Vector map <%s> not found"), name);
-    
+
     stat = -1;
     if (remove) {
 	stat = Vect_remove_colors(name, mapset);
@@ -275,11 +276,11 @@ int main(int argc, char *argv[])
     Vect_set_error_handler_io(&Map, NULL);
     if (use == USE_Z && !Vect_is_3d(&Map))
         G_fatal_error(_("Vector map <%s> is not 3D"), Vect_get_full_name(&Map));
-    
+
     layer = Vect_get_field_number(&Map, opt.field->answer);
     if (layer < 1)
 	G_fatal_error(_("Layer <%s> not found"), opt.field->answer);
-    
+
     if (opt.range->answer) {
 	range.min = atof(opt.range->answers[0]);
 	range.max = atof(opt.range->answers[1]);
@@ -289,10 +290,10 @@ int main(int argc, char *argv[])
     }
 
     Rast_init_colors(&colors);
-    if (style || rules) {	
+    if (style || rules) {
 	if (style && !G_find_color_rule(style))
 	    G_fatal_error(_("Color table <%s> not found"), style);
-	
+
 	if (use == USE_CAT) {
 	    scan_cats(&Map, layer, style, rules,
 		      opt.range->answer ? &range : NULL,
@@ -306,7 +307,7 @@ int main(int argc, char *argv[])
         else {
 	    scan_attr(&Map, layer, attrcolumn, style, rules,
 		      opt.range->answer ? &range : NULL,
-		      &colors);
+		      &colors, NULL);
 	}
     }
     else {
@@ -326,6 +327,13 @@ int main(int argc, char *argv[])
             if (Rast3d_read_colors(cmap, cmapset, &colors) < 0)
                 G_fatal_error(_("Unable to read color table for 3D raster map <%s>"), cmap);
         }
+
+	if (use == USE_ATTR && attrcolumn) {
+	    colors_tmp = colors;
+	    scan_attr(&Map, layer, attrcolumn, style, rules,
+		      opt.range->answer ? &range : NULL,
+		      &colors, &colors_tmp);
+	}
     }
 
     if (flag.n->answer)
@@ -350,25 +358,25 @@ int main(int argc, char *argv[])
     }
 
     G_important_message(_("Writing color rules..."));
-    
+
     if (style || rules || opt.rast->answer || opt.volume->answer) {
 	if (rgbcolumn)
 	    write_rgb_values(&Map, layer, rgbcolumn, &colors);
 	else
 	    Vect_write_colors(name, mapset, &colors);
     }
-    
+
     if (convert) {
 	/* convert RGB values to color tables */
 	rgb2colr(&Map, layer, rgbcolumn, &colors);
 	Vect_write_colors(name, mapset, &colors);
     }
     Vect_close(&Map);
-    
-    G_message(_("Color table for vector map <%s> set to '%s'"), 
-	      G_fully_qualified_name(name, mapset), 
+
+    G_message(_("Color table for vector map <%s> set to '%s'"),
+	      G_fully_qualified_name(name, mapset),
               is_from_stdin || convert ? "rules" : style ? style : rules ? rules :
               cmap);
-    
+
     exit(EXIT_SUCCESS);
 }

+ 6 - 6
vector/v.colors/read_rgb.c

@@ -11,7 +11,7 @@ void rgb2colr(const struct Map_info *Map, int layer, const char *rgb_column,
     int i, ret, nskipped;
     int red, grn, blu;
     const char *rgb;
-    
+
     struct field_info *fi;
 
     dbDriver *driver;
@@ -28,16 +28,16 @@ void rgb2colr(const struct Map_info *Map, int layer, const char *rgb_column,
 	G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
 		      fi->database, fi->driver);
 
-    if (db_column_Ctype(driver, fi->table, rgb_column) != DB_C_TYPE_STRING)	
+    if (db_column_Ctype(driver, fi->table, rgb_column) != DB_C_TYPE_STRING)
 	G_fatal_error(_("Data type of RGB column <%s> must be char"),
 		      rgb_column);
-    
+
     if (0 > db_select_CatValArray(driver, fi->table, fi->key,
 				  rgb_column, NULL, &cvarr))
 	G_warning(_("No RGB values found"));
 
     Rast_init_colors(colors);
-    
+
     cv = NULL;
     nskipped = 0;
     for (i = 0; i < cvarr.n_values; i++) {
@@ -49,7 +49,7 @@ void rgb2colr(const struct Map_info *Map, int layer, const char *rgb_column,
             nskipped++;
             continue;
         }
-        
+
 	ret = G_str_to_color(rgb, &red, &grn, &blu);
 	if (ret != 1) {
 	    G_debug(3, "Invalid RGB value '%s'", rgb);
@@ -63,6 +63,6 @@ void rgb2colr(const struct Map_info *Map, int layer, const char *rgb_column,
 
     if (nskipped > 0)
         G_warning(_("%d invalid RGB color values skipped"), nskipped);
-    
+
     db_close_database_shutdown_driver(driver);
 }

+ 19 - 13
vector/v.colors/scan_attr.c

@@ -7,18 +7,18 @@
 
 int scan_attr(const struct Map_info *Map, int layer, const char *column_name,
 	      const char *style, const char *rules,
-	      const struct FPRange *range, struct Colors *colors)
+	      const struct FPRange *range, struct Colors *colors, struct Colors *rcolors)
 {
     int ctype, is_fp, nrec;
     double fmin, fmax;
-    
+
     struct field_info *fi;
     struct Colors vcolors;
     dbDriver *driver;
     dbCatValArray cvarr;
 
     Rast_init_colors(colors);
-    
+
     fi = Vect_get_field(Map, layer);
     if (!fi)
 	G_fatal_error(_("Database connection not defined for layer %d"),
@@ -45,7 +45,7 @@ int scan_attr(const struct Map_info *Map, int layer, const char *column_name,
 	G_important_message(_("No data selected"));
 	return 0;
     }
-    
+
     /* color table for values */
     db_CatValArray_sort_by_value(&cvarr);
     if (is_fp) {
@@ -58,7 +58,7 @@ int scan_attr(const struct Map_info *Map, int layer, const char *column_name,
 	    else
 		G_warning(_("Min value (%f) is out of range %f,%f"),
 			  range->min, fmin, fmax);
-	    
+
 	    if (range->max <= fmax && range->max >= fmin)
 		fmax = range->max;
 	    else
@@ -69,14 +69,14 @@ int scan_attr(const struct Map_info *Map, int layer, const char *column_name,
     else {
 	fmin = cvarr.value[0].val.i;
 	fmax = cvarr.value[cvarr.n_values-1].val.i;
-	
+
 	if (range) {
 	    if (range->min >= fmin && range->min <= fmax)
 		fmin = range->min;
 	    else
 		G_warning(_("Min value (%d) is out of range %d,%d"),
 			  (int) range->min, (int) fmin, (int) fmax);
-	    
+
 	    if (range->max <= fmax && range->max >= fmin)
 		fmax = range->max;
 	    else
@@ -84,13 +84,19 @@ int scan_attr(const struct Map_info *Map, int layer, const char *column_name,
 			  (int) range->max, (int) fmin, (int) fmax);
 	}
     }
-    if (style)
-	make_colors(&vcolors, style, (DCELL) fmin, (DCELL) fmax, is_fp);
-    else if (rules)
-	load_colors(&vcolors, rules, (DCELL) fmin, (DCELL) fmax, is_fp);
 
-    /* color table for categories */
-    color_rules_to_cats(&cvarr, is_fp, &vcolors, colors);
+    if (rcolors)
+	/* color table for categories */
+	color_rules_to_cats(&cvarr, is_fp, rcolors, colors);
+    else {
+	if (style)
+	    make_colors(&vcolors, style, (DCELL) fmin, (DCELL) fmax, is_fp);
+	else if (rules)
+	    load_colors(&vcolors, rules, (DCELL) fmin, (DCELL) fmax, is_fp);
+
+	/* color table for categories */
+	color_rules_to_cats(&cvarr, is_fp, &vcolors, colors);
+    }
 
     db_close_database(driver);
 

+ 4 - 4
vector/v.colors/scan_cats.c

@@ -24,9 +24,9 @@ void scan_cats(const struct Map_info *Map, int field,
 	    G_fatal_error(_("Unable to read vector map"));
 	if (ltype == -2)
 	    break; /* EOF */
-	
+
 	G_progress(++line, 1e4);
-	
+
 	scan_layer(field, Cats, &lmin, &lmax);
 
 	if (cmin == -1 || lmin <= cmin)
@@ -35,14 +35,14 @@ void scan_cats(const struct Map_info *Map, int field,
 	    cmax = lmax;
     }
     G_progress(1, 1);
-    
+
     if (range) {
 	if (range->min >= cmin && range->min <= cmax)
 	    cmin = range->min;
 	else
 	    G_warning(_("Min value (%d) is out of range %d,%d"),
 		      (int) range->min, cmin, cmax);
-	
+
 	if (range->max <= cmax && range->max >= cmin)
 	    cmax = range->max;
 	else

+ 9 - 9
vector/v.colors/scan_z.c

@@ -13,21 +13,21 @@ void scan_z(struct Map_info *Map, int field,
     double zmin = 0, zmax = 0;
     struct line_pnts *Points;
     struct line_cats *Cats;
-    
+
     struct Colors vcolors;
-    
+
     dbCatValArray cvarr;
 
     Points = Vect_new_line_struct();
     Cats = Vect_new_cats_struct();
-    
+
     items_alloc = 0;
     db_CatValArray_init(&cvarr);
     cvarr.ctype = DB_C_TYPE_DOUBLE;
 
     Vect_set_constraint_field(Map, field);
     Vect_set_constraint_type(Map, GV_POINTS); /* points, centroids or kernels only) */
-        
+
     G_message(_("Reading features..."));
     line = i = found = 0;
     while(TRUE) {
@@ -38,10 +38,10 @@ void scan_z(struct Map_info *Map, int field,
 	    break; /* EOF */
 
 	G_progress(++line, 1e4);
-        
+
         if (Vect_cat_get(Cats, field, &cat) == -1)
             continue; /* skip features without category */
-        
+
         /* add item into cat-value array */
         if (i >= items_alloc) {
             items_alloc += 1000;
@@ -58,17 +58,17 @@ void scan_z(struct Map_info *Map, int field,
 	found = 1;
     }
     G_progress(1, 1);
-    
+
     /* sort array by z-coordinate */
     db_CatValArray_sort_by_value(&cvarr);
-    
+
     if (range) {
 	if (!found || (range->min >= zmin && range->min <= zmax))
 	    zmin = range->min;
 	else
 	    G_warning(_("Min value (%f) is out of range %f,%f"),
 		      range->min, zmin, zmax);
-	
+
 	if (!found || (range->max <= zmax && range->max >= zmin))
 	    zmax = range->max;
 	else

+ 12 - 4
vector/v.colors/v.colors.html

@@ -12,7 +12,9 @@ vector lines are not supported.
 
 <p>The <b>raster</b> option allows user to specify a raster map from
 which to copy the color table, similarly <b>raster_3d</b> option for 3D
-raster map.
+raster map. Without <b>use=attr</b> and <b>column</b> options, raster values
+will be matched with categories. Use these two options to transfer raster
+colors to vector attributes.
 
 <p>The <b>rules</b> color table type will cause <em>v.colors</em> to
 read color table specifications from given file and will build the
@@ -57,7 +59,7 @@ v.colors map=soils_general layer=1 color=wave use=attr column=AREA
 </pre></div>
 
 <h3>Define color table stored as RGB values in attribute table</h3>
-  
+
 Write color values to the attribute table (column <tt>GRASSRGB</tt>)
 instead of creating color table.
 
@@ -94,8 +96,13 @@ g.region vector=censusblk_swwake res=10 -ap
 v.to.rast input=censusblk_swwake use=attr attribute_column=TOTAL_POP output=censusblk_swwake_total_pop
 r.colors -e map=censusblk_swwake_total_pop color=blues
 
-# transfer raster colors to vector using an attribute column
+# transfer raster colors to vector attributes (raster values to attributes)
 r.colors.out map=censusblk_swwake_total_pop rules=- | v.colors map=censusblk_swwake use=attr column=TOTAL_POP rules=-
+# equivalent, but simpler
+v.colors map=censusblk_swwake use=attr column=TOTAL_POP raster=censusblk_swwake_total_pop
+
+# transfer raster colors to vector categories (raster values to categories)
+v.colors map=censusblk_swwake raster=censusblk_swwake_total_pop
 </pre></div>
 
 <h3>Remove existing color table</h3>
@@ -143,7 +150,8 @@ help people select good color schemes for maps and other graphics.
 
 <h2>AUTHORS</h2>
 
-Martin Landa, OSGeoREL, Czech Technical University in Prague, Czech Republic
+Martin Landa, OSGeoREL, Czech Technical University in Prague, Czech Republic<br>
+Huidae Cho
 
 <!--
 <p>

+ 9 - 9
vector/v.colors/write_rgb.c

@@ -27,7 +27,7 @@ void write_rgb_values(const struct Map_info *Map, int layer, const char *column_
     db_set_error_handler_driver(driver);
 
     db_init_string(&stmt);
-    
+
     ctype = db_column_Ctype(driver, fi->table, column_name);
     if (ctype == -1) {
 	sprintf(buf, "ALTER TABLE \"%s\" ADD COLUMN \"%s\" VARCHAR(11)",
@@ -39,16 +39,16 @@ void write_rgb_values(const struct Map_info *Map, int layer, const char *column_
 
 	/*
 	  db_add_column needs to be implemented for DB drivers first...
-	  
+
 	  dbString table;
 	  dbColumn column;
-	  
+
 	  db_init_column(&column);
 	  db_set_column_name(&column, column_name);
 	  db_set_column_sqltype(&column, DB_SQL_TYPE_CHARACTER);
 	  db_set_column_null_allowed(&column);
 	  db_set_column_length(&column, 11);
-	  
+
 	  db_init_string(&table);
 	  db_set_string(&table, fi->table);
 	  if (db_add_column(driver, &table, &column) != DB_OK)
@@ -62,15 +62,15 @@ void write_rgb_values(const struct Map_info *Map, int layer, const char *column_
     }
     else if (ctype != DB_C_TYPE_STRING)
 	G_fatal_error(_("Data type of column <%s> must be char"), column_name);
-	
+
     nrec = db_select_int(driver, fi->table, fi->key, NULL, &pval);
     if (nrec < 1) {
 	G_warning(_("No categories found"));
 	return;
     }
-    
+
     db_begin_transaction(driver);
-    
+
     for (i = 0; i < nrec; i++) {
 	G_percent(i, nrec, 2);
 	if (Rast_get_c_color((const CELL *) &(pval[i]), &red, &grn, &blu,
@@ -86,8 +86,8 @@ void write_rgb_values(const struct Map_info *Map, int layer, const char *column_
 	    G_fatal_error(_("Unable to update RGB values"));
     }
     G_percent(1, 1, 1);
-    
+
     db_commit_transaction(driver);
-    
+
     db_close_database_shutdown_driver(driver);
 }