[GRASS-SVN] r69134 - grass/trunk/display/d.vect.thematic
svn_grass at osgeo.org
svn_grass at osgeo.org
Sun Aug 14 19:35:45 PDT 2016
Author: annakrat
Date: 2016-08-14 19:35:45 -0700 (Sun, 14 Aug 2016)
New Revision: 69134
Added:
grass/trunk/display/d.vect.thematic/display.c
Modified:
grass/trunk/display/d.vect.thematic/Makefile
grass/trunk/display/d.vect.thematic/local_proto.h
grass/trunk/display/d.vect.thematic/main.c
Log:
d.vect.thematic: support also lines and points, author Adam Laza
Modified: grass/trunk/display/d.vect.thematic/Makefile
===================================================================
--- grass/trunk/display/d.vect.thematic/Makefile 2016-08-15 02:04:01 UTC (rev 69133)
+++ grass/trunk/display/d.vect.thematic/Makefile 2016-08-15 02:35:45 UTC (rev 69134)
@@ -3,8 +3,8 @@
PGM = d.vect.thematic
-LIBES = $(ARRAYSTATSLIB) $(DISPLAYLIB) $(VECTORLIB) $(DBMILIB) $(GISLIB)
-DEPENDENCIES = $(ARRAYSTATSDEP) $(DISPLAYDEP) $(VECTORDEP) $(DBMIDEP) $(GISDEP)
+LIBES = $(ARRAYSTATSLIB) $(DISPLAYLIB) $(VECTORLIB) $(DBMILIB) $(GISLIB) $(SYMBLIB)
+DEPENDENCIES = $(ARRAYSTATSDEP) $(DISPLAYDEP) $(VECTORDEP) $(DBMIDEP) $(GISDEP) $(SYMBDEP)
EXTRA_INC = $(VECT_INC)
EXTRA_CFLAGS = $(VECT_CFLAGS)
Added: grass/trunk/display/d.vect.thematic/display.c
===================================================================
--- grass/trunk/display/d.vect.thematic/display.c (rev 0)
+++ grass/trunk/display/d.vect.thematic/display.c 2016-08-15 02:35:45 UTC (rev 69134)
@@ -0,0 +1,230 @@
+/* Author: Adam Laza, GSoC 2016
+ * based on d.vect.thematic/area.c
+ *
+ */
+
+#include <string.h>
+#include <stdlib.h>
+#include <math.h>
+#include <grass/gis.h>
+#include <grass/symbol.h>
+#include <grass/vector.h>
+#include <grass/display.h>
+#include <grass/colors.h>
+#include <grass/dbmi.h>
+#include <grass/glocale.h>
+#include "plot.h"
+#include "local_proto.h"
+
+int display_lines(struct Map_info *Map, struct cat_list *Clist,
+ int chcat, const char *symbol_name, double size,
+ int default_width, dbCatValArray * cvarr, double *breaks,
+ int nbreaks, const struct color_rgb *colors)
+{
+ int ltype, line, nlines;
+ struct line_pnts *Points;
+ struct line_cats *Cats;
+
+ int n_points, n_lines, n_centroids, n_boundaries, n_faces;
+ RGBA_Color *primary_color, *sec_color;
+ SYMBOL *Symb;
+
+ Symb = NULL;
+
+ double breakval = 0.0;
+ int cat;
+ dbCatVal *cv = NULL;
+ int i;
+
+ primary_color = G_malloc(sizeof(RGBA_Color));
+ primary_color->a = RGBA_COLOR_OPAQUE;
+
+ Points = Vect_new_line_struct();
+ Cats = Vect_new_cats_struct();
+
+ /* dynamic symbols for points */
+ Symb = S_read(symbol_name);
+ if (!Symb)
+ G_warning(_("Unable to read symbol <%s>, unable to display points"),
+ symbol_name);
+ else
+ S_stroke(Symb, size, 0.0, 0);
+
+ Vect_rewind(Map);
+
+ nlines = -1;
+ line = 0;
+ n_points = n_lines = 0;
+ n_centroids = n_boundaries = 0;
+ n_faces = 0;
+ while (TRUE) {
+ line++;
+
+ if (nlines > -1) {
+ if (line > nlines)
+ break;
+ ltype = Vect_read_line(Map, Points, Cats, line);
+ }
+ else {
+ ltype = Vect_read_next_line(Map, Points, Cats);
+
+ if (ltype == -1) {
+ G_fatal_error(_("Unable to read vector map"));
+ }
+ else if ((ltype == -2)) { /* EOF */
+ break;
+ }
+ }
+
+ cat = *Cats->cat;
+ if (cat >= 0) {
+ G_debug(3, "display line %d, cat %d", line, cat);
+ /* Get value of data for this area */
+ if (db_CatValArray_get_value(cvarr, cat, &cv) != DB_OK) {
+ G_debug(3, "No value found for cat %i", cat);
+ }
+ else {
+ db_CatValArray_get_value(cvarr, cat, &cv);
+ breakval = (cvarr->ctype == 2 ? cv->val.i : cv->val.d);
+ }
+ }
+
+ /* find out into which class breakval falls */
+ i = 0;
+ while (breakval > breaks[i] && i < nbreaks)
+ i++;
+ primary_color->r = colors[i].r;
+ primary_color->g = colors[i].g;
+ primary_color->b = colors[i].b;
+
+ draw_line(ltype, line, Points, Cats, chcat, size, default_width,
+ Clist, Symb, primary_color, &n_points, &n_lines,
+ &n_centroids, &n_boundaries, &n_faces);
+ }
+
+ if (n_points > 0)
+ G_verbose_message(n_
+ ("%d point plotted", "%d points plotted", n_points),
+ n_points);
+ if (n_lines > 0)
+ G_verbose_message(n_("%d line plotted", "%d lines plotted", n_lines),
+ n_lines);
+ if (n_centroids > 0)
+ G_verbose_message(n_
+ ("%d centroid plotted", "%d centroids plotted",
+ n_centroids), n_centroids);
+ if (n_boundaries > 0)
+ G_verbose_message(n_
+ ("%d boundary plotted", "%d boundaries plotted",
+ n_boundaries), n_boundaries);
+ if (n_faces > 0)
+ G_verbose_message(n_("%d face plotted", "%d faces plotted", n_faces),
+ n_faces);
+
+ Vect_destroy_line_struct(Points);
+ Vect_destroy_cats_struct(Cats);
+ G_free(primary_color);
+
+ return 0;
+}
+
+int draw_line(int ltype, int line,
+ const struct line_pnts *Points, const struct line_cats *Cats,
+ int chcat, double size, int default_width,
+ const struct cat_list *Clist, SYMBOL * Symb,
+ RGBA_Color * primary_color,
+ int *n_points, int *n_lines, int *n_centroids,
+ int *n_boundaries, int *n_faces)
+{
+ double var_size, rotation;
+ int i;
+ double x0, y0;
+ double *x, *y;
+ int found, cat;
+
+ rotation = 0.0;
+ var_size = size;
+ cat = -1;
+
+ if (!ltype)
+ return 0;
+
+ if (Points->n_points == 0)
+ return 0;
+
+ found = FALSE;
+ if (chcat) {
+ for (i = 0; i < Cats->n_cats; i++) {
+ if (Cats->field[i] == Clist->field &&
+ Vect_cat_in_cat_list(Cats->cat[i], Clist)) {
+ found = TRUE;
+ break;
+ }
+ }
+ if (!found)
+ return 0;
+ }
+ else if (Clist->field > 0) {
+ for (i = 0; i < Cats->n_cats; i++) {
+ if (Cats->field[i] == Clist->field) {
+ found = TRUE;
+ break;
+ }
+ }
+ /* lines with no category will be displayed */
+ if (Cats->n_cats > 0 && !found)
+ return 0;
+ }
+
+ G_debug(3, "\tdisplay feature %d, cat %d", line, cat);
+
+
+ /* enough of the prep work, lets start plotting stuff */
+ x = Points->x;
+ y = Points->y;
+
+ if ((ltype & GV_POINTS)) {
+ x0 = x[0];
+ y0 = y[0];
+
+ /* skip if the point is outside of the display window */
+ /* xy < 0 tests make it go ever-so-slightly faster */
+ if (x0 > D_get_u_east() || x0 < D_get_u_west() ||
+ y0 < D_get_u_south() || y0 > D_get_u_north())
+ return 0;
+
+ D_line_width(default_width);
+ D_symbol(Symb, x0, y0, primary_color, primary_color);
+ }
+ else {
+ /* Plot the lines */
+ D_line_width(default_width);
+ D_RGB_color(primary_color->r, primary_color->g, primary_color->b);
+ if (Points->n_points == 1) /* line with one coor */
+ D_polydots_abs(x, y, Points->n_points);
+ else /* use different user defined render methods */
+ D_polyline_abs(x, y, Points->n_points);
+ }
+
+ switch (ltype) {
+ case GV_POINT:
+ (*n_points)++;
+ break;
+ case GV_LINE:
+ (*n_lines)++;
+ break;
+ case GV_CENTROID:
+ (*n_centroids)++;
+ break;
+ case GV_BOUNDARY:
+ (*n_boundaries)++;
+ break;
+ case GV_FACE:
+ (*n_faces)++;
+ break;
+ default:
+ break;
+ }
+
+ return 1;
+}
Property changes on: grass/trunk/display/d.vect.thematic/display.c
___________________________________________________________________
Added: svn:mime-type
+ text/x-csrc
Added: svn:eol-style
+ native
Modified: grass/trunk/display/d.vect.thematic/local_proto.h
===================================================================
--- grass/trunk/display/d.vect.thematic/local_proto.h 2016-08-15 02:04:01 UTC (rev 69133)
+++ grass/trunk/display/d.vect.thematic/local_proto.h 2016-08-15 02:35:45 UTC (rev 69134)
@@ -12,3 +12,19 @@
const struct color_rgb *, int, struct Cell_head *, int);
int dcmp(const void *, const void *);
+static int cmp(const void *, const void *);
+static char *icon_files(void);
+
+/* display.c */
+int draw_line(int ltype, int line,
+ const struct line_pnts *Points, const struct line_cats *Cats,
+ int chcat, double size, int default_width,
+ const struct cat_list *Clist, SYMBOL *Symb,
+ RGBA_Color *primary_color, int *n_points, int *n_lines,
+ int *n_centroids, int *n_boundaries, int *n_faces);
+
+int display_lines(struct Map_info *, struct cat_list *, int,
+ const char *, double, int, dbCatValArray *, double *, int,
+ const struct color_rgb *);
+
+
Modified: grass/trunk/display/d.vect.thematic/main.c
===================================================================
--- grass/trunk/display/d.vect.thematic/main.c 2016-08-15 02:04:01 UTC (rev 69133)
+++ grass/trunk/display/d.vect.thematic/main.c 2016-08-15 02:35:45 UTC (rev 69134)
@@ -30,7 +30,6 @@
#include "plot.h"
#include "local_proto.h"
-
int main(int argc, char **argv)
{
int ret, level;
@@ -55,6 +54,8 @@
struct Option *where_opt;
struct Option *field_opt;
struct Option *legend_file_opt;
+ struct Option *icon_opt;
+ struct Option *size_opt;
struct Flag *legend_flag, *algoinfo_flag, *nodraw_flag;
char *desc;
@@ -70,6 +71,7 @@
double overlap, *breakpoints, *data = NULL, class_info = 0.0;
struct GASTATS stats;
FILE *fd;
+ double size;
/* Initialize the GIS calls */
G_gisinit(argv[0]);
@@ -159,6 +161,25 @@
legend_file_opt->required = NO;
legend_file_opt->guisection = _("Legend");
+ /* Symbols */
+ icon_opt = G_define_option();
+ icon_opt->key = "icon";
+ icon_opt->type = TYPE_STRING;
+ icon_opt->required = NO;
+ icon_opt->multiple = NO;
+ icon_opt->guisection = _("Symbols");
+ icon_opt->answer = "basic/x";
+ /* This could also use ->gisprompt = "old,symbol,symbol" instead of ->options */
+ icon_opt->options = icon_files();
+ icon_opt->description = _("Point and centroid symbol");
+
+ size_opt = G_define_option();
+ size_opt->key = "size";
+ size_opt->type = TYPE_DOUBLE;
+ size_opt->answer = "5";
+ size_opt->guisection = _("Symbols");
+ size_opt->label = _("Symbol size");
+
legend_flag = G_define_flag();
legend_flag->key = 'l';
legend_flag->description =
@@ -185,6 +206,8 @@
G_get_set_window(&window);
+ size = atof(size_opt->answer);
+
/* Read map options */
strcpy(map_name, map_opt->answer);
@@ -400,13 +423,19 @@
/* default line width */
D_line_width(default_width);
-
+ if (Vect_get_num_primitives(&Map, GV_BOUNDARY) > 0)
stat =
dareatheme(&Map, Clist, &cvarr, breakpoints, nbreaks, colors,
has_color ? &bcolor : NULL, chcat, &window,
default_width);
+ else if ((Vect_get_num_primitives(&Map, GV_POINT) > 0) ||
+ (Vect_get_num_primitives(&Map, GV_LINE) > 0)){
+ stat = display_lines(&Map, Clist, chcat, icon_opt->answer, size,
+ default_width, &cvarr, breakpoints, nbreaks, colors);
+ }
+
/* reset line width: Do we need to get line width from display
* driver (not implemented)? It will help restore previous line
* width (not just 0) determined by another module (e.g.,
@@ -527,3 +556,77 @@
exit(stat);
}
+
+int cmp(const void *a, const void *b)
+{
+ return (strcmp(*(char **)a, *(char **)b));
+}
+
+/* adopted from r.colors */
+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;
+}
More information about the grass-commit
mailing list