[GRASS-SVN] r69694 - grass/trunk/display/d.linegraph
svn_grass at osgeo.org
svn_grass at osgeo.org
Tue Oct 11 18:13:18 PDT 2016
Author: wenzeslaus
Date: 2016-10-11 18:13:18 -0700 (Tue, 11 Oct 2016)
New Revision: 69694
Modified:
grass/trunk/display/d.linegraph/Makefile
grass/trunk/display/d.linegraph/main.c
Log:
d.linegraph: draw points
Draw lines and points, points only, or workaround for thick line ends.
Color inherited from the line, secondary color from settings.
Modified: grass/trunk/display/d.linegraph/Makefile
===================================================================
--- grass/trunk/display/d.linegraph/Makefile 2016-10-11 10:56:04 UTC (rev 69693)
+++ grass/trunk/display/d.linegraph/Makefile 2016-10-12 01:13:18 UTC (rev 69694)
@@ -2,8 +2,8 @@
PGM = d.linegraph
-LIBES = $(DISPLAYLIB) $(GISLIB) $(RASTERLIB)
-DEPENDENCIES = $(DISPLAYDEP) $(GISDEP) $(RASTERDEP)
+LIBES = $(DISPLAYLIB) $(SYMBLIB) $(GISLIB) $(RASTERLIB)
+DEPENDENCIES = $(DISPLAYDEP) $(SYMBDEP) $(GISDEP) $(RASTERDEP)
include $(MODULE_TOPDIR)/include/Make/Module.make
Modified: grass/trunk/display/d.linegraph/main.c
===================================================================
--- grass/trunk/display/d.linegraph/main.c 2016-10-11 10:56:04 UTC (rev 69693)
+++ grass/trunk/display/d.linegraph/main.c 2016-10-12 01:13:18 UTC (rev 69694)
@@ -34,6 +34,7 @@
#include <stdlib.h>
#include <math.h>
+#include <dirent.h>
#include <grass/gis.h>
#include <grass/display.h>
#include <grass/colors.h>
@@ -77,6 +78,82 @@
}
}
+/* copied from d.vect */
+static int cmp(const void *a, const void *b)
+{
+ return (strcmp(*(char **)a, *(char **)b));
+}
+
+/* TODO: this should go to the library with new gisprompt and std opt */
+/* copied from d.vect, requires dirent.h */
+static char *icon_files(void)
+{
+ char **list, *ret;
+ char buf[GNAME_MAX], path[GPATH_MAX], path_i[GPATH_MAX];
+ int i, count;
+ size_t len;
+ DIR *dir, *dir_i;
+ struct dirent *d, *d_i;
+
+ list = NULL;
+ len = 0;
+ sprintf(path, "%s/etc/symbol", G_gisbase());
+
+ dir = opendir(path);
+ if (!dir)
+ return NULL;
+
+ count = 0;
+
+ /* loop over etc/symbol */
+ while ((d = readdir(dir))) {
+ if (d->d_name[0] == '.')
+ continue;
+
+ sprintf(path_i, "%s/etc/symbol/%s", G_gisbase(), d->d_name);
+ dir_i = opendir(path_i);
+
+ if (!dir_i)
+ continue;
+
+ /* loop over each directory in etc/symbols */
+ while ((d_i = readdir(dir_i))) {
+ if (d_i->d_name[0] == '.')
+ continue;
+
+ list = G_realloc(list, (count + 1) * sizeof(char *));
+
+ sprintf(buf, "%s/%s", d->d_name, d_i->d_name);
+ list[count++] = G_store(buf);
+
+ len += strlen(d->d_name) + strlen(d_i->d_name) + 2; /* '/' + ',' */
+ }
+
+ closedir(dir_i);
+ }
+
+ closedir(dir);
+
+ qsort(list, count, sizeof(char *), cmp);
+
+ if (len > 0) {
+ ret = G_malloc((len + 1) * sizeof(char)); /* \0 */
+ *ret = '\0';
+ for (i = 0; i < count; i++) {
+ if (i > 0)
+ strcat(ret, ",");
+ strcat(ret, list[i]);
+ G_free(list[i]);
+ }
+ G_free(list);
+ }
+ else {
+ ret = G_store("");
+ }
+
+ return ret;
+}
+
int main(int argc, char **argv)
{
double xoffset; /* offset for x-axis */
@@ -138,6 +215,11 @@
struct Option *t_color_opt;
struct Option *y_range_opt;
struct Option *ytics_opt;
+ struct Option *point_symbol_opt;
+ struct Option *point_size_opt;
+ struct Option *point_color2_opt;
+ struct Option *secondary_width_opt;
+ struct Flag *do_points_flg, *no_lines_flg;
/* Initialize the GIS calls */
G_gisinit(argv[0]);
@@ -235,6 +317,55 @@
ytics_opt->required = NO;
ytics_opt->multiple = YES;
+ point_symbol_opt = G_define_option();
+ /* TODO: name must be icon to get GUI dialog */
+ point_symbol_opt->key = "icon";
+ point_symbol_opt->type = TYPE_STRING;
+ point_symbol_opt->required = NO;
+ point_symbol_opt->multiple = NO;
+ point_symbol_opt->answer = "basic/circle";
+ /* This could also use ->gisprompt = "old,symbol,symbol" instead of ->options */
+ point_symbol_opt->options = icon_files();
+ point_symbol_opt->description = _("Symbol for point");
+ point_symbol_opt->guisection = _("Points");
+
+ point_size_opt = G_define_option();
+ point_size_opt->key = "point_size";
+ point_size_opt->type = TYPE_DOUBLE;
+ point_size_opt->required = NO;
+ point_size_opt->multiple = NO;
+ point_size_opt->answer = "5";
+ point_size_opt->label = _("Point size");
+ point_size_opt->guisection = _("Points");
+
+ /* theoretically for other things than points */
+ point_color2_opt = G_define_standard_option(G_OPT_CN);
+ point_color2_opt->key = "secondary_color";
+ point_color2_opt->type = TYPE_STRING;
+ point_color2_opt->required = NO;
+ point_color2_opt->multiple = NO;
+ point_color2_opt->description = _("Color for point symbol edge color");
+ point_color2_opt->guisection = _("Points");
+
+ /* theoretically for other things than points */
+ secondary_width_opt = G_define_option();
+ secondary_width_opt->key = "secondary_width";
+ secondary_width_opt->description = _("Width of point symbol lines");
+ secondary_width_opt->type = TYPE_INTEGER;
+ secondary_width_opt->required = NO;
+ secondary_width_opt->multiple = YES;
+ secondary_width_opt->answer = "0.1";
+
+ /* TODO: change this to option, use filled/empty symbol option for this */
+ do_points_flg = G_define_flag();
+ do_points_flg->key = 's';
+ do_points_flg->description = "Draw points";
+ do_points_flg->guisection = _("Points");
+
+ no_lines_flg = G_define_flag();
+ no_lines_flg->key = 'l';
+ no_lines_flg->description = "Do not draw lines";
+
if (G_parser(argc, argv))
exit(EXIT_FAILURE);
@@ -285,6 +416,58 @@
title_color = D_translate_color(t_color_opt->answer);
+ int draw_lines = TRUE;
+ int draw_points = FALSE;
+
+ if (do_points_flg->answer)
+ draw_points = TRUE;
+ if (no_lines_flg->answer)
+ draw_lines = FALSE;
+
+ SYMBOL *point_symbol = NULL;
+ double symbol_size;
+ double symbol_rotation = 0; /* not supported here */
+ int symbol_tolerance = 0; /* not supported by S_stroke */
+ double symbol_line_width;
+
+ if (point_size_opt->answer)
+ symbol_size = atof(point_size_opt->answer);
+
+ if (secondary_width_opt->answer)
+ symbol_line_width = atof(secondary_width_opt->answer);
+
+ /* TODO: symbol vs point in iface and vars */
+ /* there seems there is no free for symbol */
+ if (draw_points && point_symbol_opt->answer) {
+ point_symbol = S_read(point_symbol_opt->answer);
+ /* S_read gives warning only */
+ if (!point_symbol)
+ G_fatal_error(_("Cannot find/open symbol: '%s'"), point_symbol_opt->answer);
+ }
+ RGBA_Color primary_color;
+ RGBA_Color secondary_color;
+
+ if (draw_points) {
+ S_stroke(point_symbol, symbol_size, symbol_rotation, symbol_tolerance);
+ primary_color.a = RGBA_COLOR_OPAQUE;
+
+ if (point_color2_opt->answer) {
+ int rgb_r, rgb_g, rgb_b;
+ int ret = G_str_to_color(point_color2_opt->answer, &rgb_r, &rgb_g, &rgb_b);
+ if (ret == 0)
+ G_fatal_error(_("Color <%s> cannot for option %s be parsed"),
+ point_color2_opt->answer, point_color2_opt->key);
+ else if (ret == 2)
+ secondary_color.a = RGBA_COLOR_TRANSPARENT;
+ else
+ secondary_color.a = RGBA_COLOR_OPAQUE;
+ secondary_color.r = rgb_r;
+ secondary_color.g = rgb_g;
+ secondary_color.b = rgb_b;
+
+ }
+ }
+
/* TODO: use parser for the following and avoid -Wsign-compare */
/* I had an argument with the parser, and couldn't get a neat list of
the input colors as I thought I should. I did a quick hack to get
@@ -521,13 +704,6 @@
/* draw increment of each Y file's data */
- if (color_table_opt->answer)
- D_RGB_color(in[i].r, in[i].g, in[i].b);
- else
- D_use_color(in[i].color);
- if (line_width_opt->answer)
- D_line_width(in[i].width);
-
/* find out position of where Y should be drawn. */
/* if our minimum value of y is not negative, this is easy */
@@ -549,9 +725,40 @@
}
new_x = xoffset + (line * xscale);
+
/* draw only when we the previous point to start from */
- if (line > 0)
+ if (draw_lines && line > 0) {
+ if (color_table_opt->answer)
+ D_RGB_color(in[i].r, in[i].g, in[i].b);
+ else
+ D_use_color(in[i].color);
+ if (line_width_opt->answer)
+ D_line_width(in[i].width);
D_line_abs(prev_x, prev_y[i], new_x, new_y[i]);
+ }
+ /* draw points after lines, last point after last line */
+ if (draw_points && line > 0) {
+ if (color_table_opt->answer) {
+ primary_color.r = in[i].r;
+ primary_color.g = in[i].g;
+ primary_color.b = in[i].b;
+ }
+ else {
+ /* TODO: do this ahead. store in .r .g .b in .rgb */
+ int rgb_r, rgb_g, rgb_b;
+ D_color_number_to_RGB(in[i].color, &rgb_r, &rgb_g, &rgb_b);
+ primary_color.r = rgb_r;
+ primary_color.g = rgb_g;
+ primary_color.b = rgb_b;
+ }
+ D_line_width(symbol_line_width);
+ D_symbol2(point_symbol, prev_x, prev_y[i], &primary_color,
+ &secondary_color);
+ /* last point */
+ if (line == in[i].num_pnts - 1)
+ D_symbol2(point_symbol, new_x, new_y[i], &primary_color,
+ &secondary_color);
+ }
prev_y[i] = new_y[i];
}
}
More information about the grass-commit
mailing list