|
@@ -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;
|
|
|
+}
|