Skip to content

Commit

Permalink
r.category: add color option
Browse files Browse the repository at this point in the history
Signed-off-by: Nishant Bansal <[email protected]>
  • Loading branch information
NishantBansal2003 committed Jan 30, 2025
1 parent 02861c2 commit 7ff9c1b
Show file tree
Hide file tree
Showing 4 changed files with 495 additions and 12 deletions.
10 changes: 8 additions & 2 deletions raster/r.category/local_proto.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,22 @@
#include <grass/parson.h>

enum OutputFormat { PLAIN, JSON };
enum ColorOutput { NONE, RGB_OUTPUT, HEX_OUTPUT, TRIPLET_OUTPUT };

/* cats.c */
int get_cats(const char *, const char *);
int next_cat(long *);

/* main.c */
void print_json(JSON_Value *);
int print_label(long, enum OutputFormat, JSON_Array *);
int print_d_label(double, enum OutputFormat, JSON_Array *);
int print_label(long, enum OutputFormat, JSON_Array *, enum ColorOutput,
struct Colors *);
int print_d_label(double, enum OutputFormat, JSON_Array *, enum ColorOutput,
struct Colors *);
int scan_cats(const char *, long *, long *);
int scan_vals(const char *, double *);
void scan_colors(long, struct Colors *, enum ColorOutput, char *);
void scan_d_colors(double, struct Colors *, enum ColorOutput, char *);
void get_color(enum ColorOutput, int, int, int, char *);

#endif /* __LOCAL_PROTO_H__ */
112 changes: 102 additions & 10 deletions raster/r.category/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,17 @@ int main(int argc, char *argv[])
RASTER_MAP_TYPE map_type;
int i;
int from_stdin = FALSE;
struct Colors colors;
struct GModule *module;

enum OutputFormat format;
enum ColorOutput color_format;
JSON_Value *root_value;
JSON_Array *root_array;

struct {
struct Option *map, *fs, *cats, *vals, *raster, *file, *fmt_str,
*fmt_coeff, *format;
*fmt_coeff, *format, *color;
} parm;

G_gisinit(argv[0]);
Expand Down Expand Up @@ -112,6 +114,15 @@ int main(int argc, char *argv[])
parm.format->key = "output_format";
parm.format->guisection = _("Print");

parm.color = G_define_option();
parm.color->key = "color";
parm.color->type = TYPE_STRING;
parm.color->required = NO;
parm.color->multiple = NO;
parm.color->options = "none,rgb,hex,triplet";
parm.color->answer = "none";
parm.color->description = _("Color format for output values or none.");

if (G_parser(argc, argv))
exit(EXIT_FAILURE);

Expand All @@ -127,6 +138,19 @@ int main(int argc, char *argv[])
format = PLAIN;
}

if (strcmp(parm.color->answer, "rgb") == 0) {
color_format = RGB_OUTPUT;
}
else if (strcmp(parm.color->answer, "triplet") == 0) {
color_format = TRIPLET_OUTPUT;
}
else if (strcmp(parm.color->answer, "hex") == 0) {
color_format = HEX_OUTPUT;
}
else {
color_format = NONE;
}

name = parm.map->answer;

fs = G_option_to_separator(parm.fs);
Expand Down Expand Up @@ -297,13 +321,17 @@ int main(int argc, char *argv[])
name, mapset);
}

if (color_format != NONE)
if (Rast_read_colors(name, mapset, &colors) < 0)
G_fatal_error("Unable to read colors for input map %s", name);

/* describe the category labels */
/* if no cats requested, use r.describe to get the cats */
if (parm.cats->answer == NULL) {
if (map_type == CELL_TYPE) {
get_cats(name, mapset);
while (next_cat(&x))
print_label(x, format, root_array);
print_label(x, format, root_array, color_format, &colors);
if (format == JSON) {
print_json(root_value);
}
Expand All @@ -324,7 +352,7 @@ int main(int argc, char *argv[])
for (i = 0; parm.cats->answers[i]; i++) {
scan_cats(parm.cats->answers[i], &x, &y);
while (x <= y)
print_label(x++, format, root_array);
print_label(x++, format, root_array, color_format, &colors);
}
if (format == JSON) {
print_json(root_value);
Expand All @@ -342,7 +370,7 @@ int main(int argc, char *argv[])
}
for (i = 0; parm.vals->answers[i]; i++) {
scan_vals(parm.vals->answers[i], &dx);
print_d_label(dx, format, root_array);
print_d_label(dx, format, root_array, color_format, &colors);
}

if (format == JSON) {
Expand All @@ -364,33 +392,44 @@ void print_json(JSON_Value *root_value)
json_value_free(root_value);
}

int print_label(long x, enum OutputFormat format, JSON_Array *root_array)
int print_label(long x, enum OutputFormat format, JSON_Array *root_array,
enum ColorOutput color_format, struct Colors *colors)
{
char *label;
char *label, color[30];
JSON_Value *category_value;
JSON_Object *category;

G_squeeze(label = Rast_get_c_cat((CELL *)&x, &cats));

switch (format) {
case PLAIN:
fprintf(stdout, "%ld%s%s\n", x, fs, label);
fprintf(stdout, "%ld%s%s", x, fs, label);
if (color_format != NONE) {
scan_colors(x, colors, color_format, color);
fprintf(stdout, "%s%s", fs, color);
}
fprintf(stdout, "\n");
break;
case JSON:
category_value = json_value_init_object();
category = json_object(category_value);
json_object_set_number(category, "category", x);
json_object_set_string(category, "description", label);
if (color_format != NONE) {
scan_colors(x, colors, color_format, color);
json_object_set_string(category, "color", color);
}
json_array_append_value(root_array, category_value);
break;
}

return 0;
}

int print_d_label(double x, enum OutputFormat format, JSON_Array *root_array)
int print_d_label(double x, enum OutputFormat format, JSON_Array *root_array,
enum ColorOutput color_format, struct Colors *colors)
{
char *label, tmp[40];
char *label, tmp[40], color[30];
DCELL dtmp;
JSON_Value *category_value;
JSON_Object *category;
Expand All @@ -402,13 +441,22 @@ int print_d_label(double x, enum OutputFormat format, JSON_Array *root_array)
case PLAIN:
sprintf(tmp, "%.10f", x);
G_trim_decimal(tmp);
fprintf(stdout, "%s%s%s\n", tmp, fs, label);
fprintf(stdout, "%s%s%s", tmp, fs, label);
if (color_format != NONE) {
scan_d_colors(x, colors, color_format, color);
fprintf(stdout, "%s%s", fs, color);
}
fprintf(stdout, "\n");
break;
case JSON:
category_value = json_value_init_object();
category = json_object(category_value);
json_object_set_number(category, "category", x);
json_object_set_string(category, "description", label);
if (color_format != NONE) {
scan_d_colors(x, colors, color_format, color);
json_object_set_string(category, "color", color);
}
json_array_append_value(root_array, category_value);
break;
}
Expand Down Expand Up @@ -440,3 +488,47 @@ int scan_vals(const char *s, double *x)
return 1;
return 0;
}

void get_color(enum ColorOutput color_format, int red, int grn, int blu,
char *color)
{
switch (color_format) {
case RGB_OUTPUT:
snprintf(color, 30, "rgb(%d, %d, %d)", red, grn, blu);
break;

case HEX_OUTPUT:
snprintf(color, 30, "#%02X%02X%02X", red, grn, blu);
break;

case TRIPLET_OUTPUT:
snprintf(color, 30, "%d:%d:%d", red, grn, blu);
break;
case NONE:
break;
}
}

void scan_colors(long x, struct Colors *colors, enum ColorOutput color_format,
char *color)
{
int red, grn, blu;

if (!Rast_get_c_color((CELL *)&x, &red, &grn, &blu, colors)) {
strcpy(color, "*");
}
else
get_color(color_format, red, grn, blu, color);
}

void scan_d_colors(double x, struct Colors *colors,
enum ColorOutput color_format, char *color)
{
int red, grn, blu;

if (!Rast_get_d_color((DCELL *)&x, &red, &grn, &blu, colors)) {
strcpy(color, "*");
}
else
get_color(color_format, red, grn, blu, color);
}
27 changes: 27 additions & 0 deletions raster/r.category/tests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
"""Fixture for r.category test"""

import os
import pytest
import grass.script as gs


@pytest.fixture
def simple_dataset(tmp_path):
"""Set up a GRASS session and create test rasters with color rules."""
project = tmp_path / "raster_color_project"
gs.create_project(project)
with gs.setup.init(project, env=os.environ.copy()) as session:
gs.run_command(
"g.region",
s=0,
n=100,
w=0,
e=100,
res=10,
env=session.env,
)
gs.mapcalc("test = if(col() < 3, col(), 2)", env=session.env)
gs.mapcalc("test_1 = if(col() < 5, col(), 4)", env=session.env)
gs.mapcalc("test_d = if(col() < 5, col() / 2., 4.5)", env=session.env)

yield session
Loading

0 comments on commit 7ff9c1b

Please sign in to comment.