From 2a9d693c116b3d20e5444753b1a754f0e9903c68 Mon Sep 17 00:00:00 2001 From: Huidae Cho Date: Tue, 23 Feb 2021 06:01:11 -0500 Subject: [PATCH] v.colors: raster= with use=attr (#1393) * v.colors: raster= with use=attr * Remove trailing whitespaces --- vector/v.colors/local_proto.h | 11 +++--- vector/v.colors/main.c | 66 ++++++++++++++++++++--------------- vector/v.colors/read_rgb.c | 12 +++---- vector/v.colors/scan_attr.c | 32 ++++++++++------- vector/v.colors/scan_cats.c | 8 ++--- vector/v.colors/scan_z.c | 18 +++++----- vector/v.colors/v.colors.html | 16 ++++++--- vector/v.colors/write_rgb.c | 18 +++++----- 8 files changed, 102 insertions(+), 79 deletions(-) diff --git a/vector/v.colors/local_proto.h b/vector/v.colors/local_proto.h index 1f8b1a84514..c0fd9843237 100644 --- a/vector/v.colors/local_proto.h +++ b/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 *); diff --git a/vector/v.colors/main.c b/vector/v.colors/main.c index 4b55fba12db..6c4b25630f9 100644 --- a/vector/v.colors/main.c +++ b/vector/v.colors/main.c @@ -2,11 +2,12 @@ /**************************************************************** * * MODULE: v.colors - * - * AUTHOR(S): Martin Landa - * + * + * AUTHOR(S): Martin Landa , + * Huidae Cho + * * 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 ..."), 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); } diff --git a/vector/v.colors/read_rgb.c b/vector/v.colors/read_rgb.c index a39c36ea60c..3a38e0663c5 100644 --- a/vector/v.colors/read_rgb.c +++ b/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); } diff --git a/vector/v.colors/scan_attr.c b/vector/v.colors/scan_attr.c index 348fbdf7531..07f409545dd 100644 --- a/vector/v.colors/scan_attr.c +++ b/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); diff --git a/vector/v.colors/scan_cats.c b/vector/v.colors/scan_cats.c index f7ccfbc42fc..3afc53ca3c7 100644 --- a/vector/v.colors/scan_cats.c +++ b/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 diff --git a/vector/v.colors/scan_z.c b/vector/v.colors/scan_z.c index 7b7005ab268..b72ac289237 100644 --- a/vector/v.colors/scan_z.c +++ b/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 diff --git a/vector/v.colors/v.colors.html b/vector/v.colors/v.colors.html index f72fedb1443..2e2e41eabd1 100644 --- a/vector/v.colors/v.colors.html +++ b/vector/v.colors/v.colors.html @@ -12,7 +12,9 @@

DESCRIPTION

The raster option allows user to specify a raster map from which to copy the color table, similarly raster_3d option for 3D -raster map. +raster map. Without use=attr and column options, raster values +will be matched with categories. Use these two options to transfer raster +colors to vector attributes.

The rules color table type will cause v.colors to read color table specifications from given file and will build the @@ -57,7 +59,7 @@

Define color table based on attribute values

Define color table stored as RGB values in attribute table

- + Write color values to the attribute table (column GRASSRGB) instead of creating color table. @@ -94,8 +96,13 @@

Transfer raster colors to vector

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

Remove existing color table

@@ -143,7 +150,8 @@

SEE ALSO

AUTHORS

-Martin Landa, OSGeoREL, Czech Technical University in Prague, Czech Republic +Martin Landa, OSGeoREL, Czech Technical University in Prague, Czech Republic
+Huidae Cho