Skip to content

Commit

Permalink
v.colors: Backport OSGeo#1393 and OSGeo#1389 (Resolve OSGeo#1297)
Browse files Browse the repository at this point in the history
  • Loading branch information
HuidaeCho committed Mar 7, 2021
1 parent 18803e7 commit 55a3a45
Show file tree
Hide file tree
Showing 9 changed files with 127 additions and 97 deletions.
11 changes: 6 additions & 5 deletions vector/v.colors/local_proto.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,21 @@ 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 *,
const struct FPRange *, struct Colors *);

/* 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 *);
76 changes: 38 additions & 38 deletions vector/v.colors/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@
/****************************************************************
*
* 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-2014 by the GRASS Development Team
*
* COPYRIGHT: (C) 2011-2021 by the GRASS Development Team
*
* This program is free software under the GNU General
* Public License (>=v2). Read the file COPYING that
Expand All @@ -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,
Expand All @@ -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"));
Expand All @@ -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");
Expand Down Expand Up @@ -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");
Expand Down Expand Up @@ -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';
Expand Down Expand Up @@ -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;
Expand All @@ -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);
Expand All @@ -238,18 +239,16 @@ 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);

is_from_stdin = rules && strcmp(rules, "-") == 0;
if (is_from_stdin)
G_fatal_error(_("Reading rules from standard input is not implemented yet, please provide path to rules file instead."));

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);
Expand Down Expand Up @@ -277,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]);
Expand All @@ -291,16 +290,10 @@ int main(int argc, char *argv[])
}

Rast_init_colors(&colors);
if (is_from_stdin) {
G_fatal_error(_("Reading color rules from standard input is currently not supported"));
/*
if (!read_color_rules(stdin, &colors, min, max, fp))
exit(EXIT_FAILURE);
*/
} else 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,
Expand All @@ -314,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 {
Expand All @@ -334,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)
Expand All @@ -358,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 changes: 4 additions & 2 deletions vector/v.colors/make_colors.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,10 @@ void make_colors(struct Colors *colors, const char *style, DCELL min, DCELL max,
void load_colors(struct Colors *colors, const char *rules, DCELL min, DCELL max, int is_fp)
{
int ret;

if (is_fp)

if (rules[0] == '-' && rules[1] == 0)
ret = Rast_read_color_rules(colors, min, max, Rast_read_color_rule, stdin);
else if (is_fp)
ret = Rast_load_fp_colors(colors, rules, (DCELL) min, (DCELL) max);
else
ret = Rast_load_colors(colors, rules, (CELL) min, (CELL) max);
Expand Down
12 changes: 6 additions & 6 deletions vector/v.colors/read_rgb.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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++) {
Expand All @@ -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);
Expand All @@ -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);
}
32 changes: 19 additions & 13 deletions vector/v.colors/scan_attr.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"),
Expand All @@ -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) {
Expand All @@ -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
Expand All @@ -69,28 +69,34 @@ 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
G_warning(_("Max value (%d) is out of range %d,%d"),
(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);

Expand Down
Loading

0 comments on commit 55a3a45

Please sign in to comment.