[GRASS-SVN] r56698 - grass/trunk/vector/v.to.rast

svn_grass at osgeo.org svn_grass at osgeo.org
Fri Jun 14 02:19:00 PDT 2013


Author: mmetz
Date: 2013-06-14 02:19:00 -0700 (Fri, 14 Jun 2013)
New Revision: 56698

Added:
   grass/trunk/vector/v.to.rast/dense_line.c
Modified:
   grass/trunk/vector/v.to.rast/do_lines.c
   grass/trunk/vector/v.to.rast/local.h
   grass/trunk/vector/v.to.rast/main.c
   grass/trunk/vector/v.to.rast/raster.c
   grass/trunk/vector/v.to.rast/vect2rast.c
Log:
v.to.rast: add new -d flag to create densified lines

Added: grass/trunk/vector/v.to.rast/dense_line.c
===================================================================
--- grass/trunk/vector/v.to.rast/dense_line.c	                        (rev 0)
+++ grass/trunk/vector/v.to.rast/dense_line.c	2013-06-14 09:19:00 UTC (rev 56698)
@@ -0,0 +1,280 @@
+#include <math.h>
+#include <grass/gis.h>
+#include <grass/dbmi.h>
+#include <grass/vector.h>
+#include <grass/glocale.h>
+#include "local.h"
+
+static struct state {
+    struct Cell_head window;
+    double xconv, yconv;
+    double left, right, top, bottom;
+    int ymin, ymax;
+    int dotted_fill_gap;
+
+    int (*dot)(int, int);
+} state;
+
+static struct state *st = &state;
+
+#define X(e) (st->left + st->xconv * ((e) - st->window.west))
+#define Y(n) (st->top + st->yconv * (st->window.north - (n)))
+
+#define EAST(x) (st->window.west + ((x)-st->left)/st->xconv)
+#define NORTH(y) (st->window.north - ((y)-st->top)/st->yconv)
+
+void dense_line(double x1, double y1, double x2, double y2,
+                int (*point) (int, int));
+
+static int ifloor(double x)
+{
+    int i;
+
+    i = (int)x;
+    if (i > x)
+	i--;
+    return i;
+}
+
+static int iceil(double x)
+{
+    int i;
+
+    i = (int)x;
+    if (i < x)
+	i++;
+    return i;
+}
+
+
+void setup_plot(double t, double b, double l, double r,
+		  int (*dot) (int, int))
+{
+    G_get_set_window(&st->window);
+
+    st->left = l;
+    st->right = r;
+    st->top = t;
+    st->bottom = b;
+
+    st->xconv = (st->right - st->left) / (st->window.east - st->window.west);
+    st->yconv = (st->bottom - st->top) / (st->window.north - st->window.south);
+
+    if (st->top < st->bottom) {
+	st->ymin = iceil(st->top);
+	st->ymax = ifloor(st->bottom);
+    }
+    else {
+	st->ymin = iceil(st->bottom);
+	st->ymax = ifloor(st->top);
+    }
+
+    st->dot = dot;
+}
+
+
+/* dense line plotting, alternative to G_plot_line2()
+ * x1, y1, x2, y2 are col, row numbers */
+void plot_line_dense(double east1, double north1, double east2, double north2)
+{
+    double x1, x2, y1, y2;
+
+    y1 = Y(north1);
+    y2 = Y(north2);
+
+    if (st->window.proj == PROJECTION_LL) {
+	if (east1 > east2)
+	    while ((east1 - east2) > 180)
+		east2 += 360;
+	else if (east2 > east1)
+	    while ((east2 - east1) > 180)
+		east1 += 360;
+	while (east1 > st->window.east) {
+	    east1 -= 360.0;
+	    east2 -= 360.0;
+	}
+	while (east1 < st->window.west) {
+	    east1 += 360.0;
+	    east2 += 360.0;
+	}
+	x1 = X(east1);
+	x2 = X(east2);
+
+	dense_line(x1, y1, x2, y2, st->dot);
+
+	if (east2 > st->window.east || east2 < st->window.west) {
+	    while (east2 > st->window.east) {
+		east1 -= 360.0;
+		east2 -= 360.0;
+	    }
+	    while (east2 < st->window.west) {
+		east1 += 360.0;
+		east2 += 360.0;
+	    }
+	    x1 = X(east1);
+	    x2 = X(east2);
+	    dense_line(x1, y1, x2, y2, st->dot);
+	}
+    }
+    else {
+	x1 = X(east1);
+	x2 = X(east2);
+	dense_line(x1, y1, x2, y2, st->dot);
+    }
+}
+
+/* dense line plotting, alternative to G_bresenham_line()
+ * x1, y1, x2, y2 are col, row numbers */
+void dense_line(double x1, double y1, double x2, double y2,
+                int (*point) (int, int))
+{
+    int ix1, ix2, iy1, iy2, idx, idy;
+    int xinc, yinc;
+    double dx, dy;
+
+    G_debug(2, "dense line");
+
+    if (x2 < x1) {
+	double tmp;
+	
+	tmp = x1;
+	x1 = x2;
+	x2 = tmp;
+	
+	tmp = y1;
+	y1 = y2;
+	y2 = tmp;
+    }
+
+    ix1 = (int)x1;
+    ix2 = (int)x2;
+    iy1 = (int)y1;
+    iy2 = (int)y2;
+
+    idx = ix2 - ix1;
+    idy = iy2 - iy1;
+
+    dx = x2 - x1;
+    dy = y2 - y1;
+    
+    xinc = yinc = 1;
+    
+    if (idx < 0) {
+	xinc = -1;
+	idx = -idx;
+    }
+
+    if (idy < 0) {
+	yinc = -1;
+	idy = -idy;
+    }
+    if (dx < 0)
+	dx = -dx;
+    if (dy < 0)
+	dy = -dy;
+
+    if (idx == 0) {
+	while (iy1 != iy2) {
+	    point(ix1, iy1);
+	    iy1 += yinc;
+	}
+    }
+    else if (idy == 0) {
+	while (ix1 != ix2) {
+	    point(ix1, iy1);
+	    ix1 += xinc;
+	}
+    }
+    else if (dx >= dy) {
+	double m, a, yi;
+	int xnext;
+
+	m = (y2 - y1) / (x2 - x1);
+	a = y1 - m * x1;
+	
+	/* find x for y = iy1 or y = iy1 + 1 */
+	m = (x2 - x1) / (y2 - y1);
+	a = x1 - m * y1;
+	yi = iy1;
+	if (iy1 < iy2)
+	    yi += 1;
+	xnext = a + m * yi;
+	
+
+	while (ix1 != ix2) {
+	    point(ix1, iy1);
+
+	    if (ix1 == xnext) {
+		iy1 += yinc;
+		point(ix1, iy1);
+		if (iy1 != iy2) {
+		    yi = iy1;
+		    if (iy1 < iy2)
+			yi += 1;
+		    xnext = a + m * yi;
+		}
+		else
+		    xnext = ix2;
+	    }
+
+	    ix1 += xinc;
+	}
+	if (iy1 != iy2)
+	    point(ix1, iy1);
+    }
+    else if (dx < dy) {
+	double m, a, xi;
+	int ynext;
+
+	if (y2 < y1) {
+	    double tmp;
+	    
+	    tmp = x1;
+	    x1 = x2;
+	    x2 = tmp;
+	    
+	    tmp = y1;
+	    y1 = y2;
+	    y2 = tmp;
+
+	    ix1 = (int)x1;
+	    ix2 = (int)x2;
+	    iy1 = (int)y1;
+	    iy2 = (int)y2;
+
+	    yinc = 1;
+	    xinc = 1;
+	    if (x2 < x1)
+		xinc = -1;
+	}
+
+	/* find y for x = ix1 or x = ix1 + 1 */
+	m = (y2 - y1) / (x2 - x1);
+	a = y1 - m * x1;
+	xi = ix1;
+	if (ix1 < ix2)
+	    xi += 1;
+	ynext = a + m * xi;
+
+	while (iy1 != iy2) {
+	    point(ix1, iy1);
+
+	    if (iy1 == ynext) {
+		ix1 += xinc;
+		point(ix1, iy1);
+		if (ix1 != ix2) {
+		    xi = ix1;
+		    if (ix1 < ix2)
+			xi += 1;
+		    ynext = a + m * xi;
+		}
+		else
+		    ynext = iy2;
+	    }
+	    iy1 += yinc;
+	}
+	if (ix1 != ix2)
+	    point(ix1, iy1);
+    }
+    point(ix2, iy2);
+}


Property changes on: grass/trunk/vector/v.to.rast/dense_line.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Modified: grass/trunk/vector/v.to.rast/do_lines.c
===================================================================
--- grass/trunk/vector/v.to.rast/do_lines.c	2013-06-14 09:15:29 UTC (rev 56697)
+++ grass/trunk/vector/v.to.rast/do_lines.c	2013-06-14 09:19:00 UTC (rev 56698)
@@ -7,7 +7,7 @@
 
 
 /* function prototypes */
-static int plot_line(double *, double *, int, int);
+static int plot_line(double *, double *, int, int, int);
 static int plot_points(double *, double *, int);
 static double v2angle(double *, double *, double, double);
 static double deg_angle(double, double, double, double);
@@ -16,7 +16,7 @@
 int do_lines(struct Map_info *Map, struct line_pnts *Points,
 	     dbCatValArray * Cvarr, int ctype, int field,
 	     struct cat_list *cat_list, int use, double value,
-	     int value_type, int feature_type, int *count_all)
+	     int value_type, int feature_type, int *count_all, int dense)
 {
     double min = 0, max, u;
     int nlines, type, cat, no_contour = 0;
@@ -120,7 +120,7 @@
 	}
 
 	if ((type & GV_LINES)) {
-	    plot_line(Points->x, Points->y, Points->n_points, use);
+	    plot_line(Points->x, Points->y, Points->n_points, use, dense);
 	    count++;
 	}
 	else if (type & GV_POINTS) {
@@ -139,17 +139,29 @@
 }
 
 
-static int plot_line(double *x, double *y, int n, int use)
+static int plot_line(double *x, double *y, int n, int use, int dense)
 {
-    while (--n > 0) {
-	if (use == USE_D)
-	    set_dcat((DCELL) deg_angle(x[1], y[1], x[0], y[0]));
+    if (dense) {
+	while (--n > 0) {
+	    if (use == USE_D)
+		set_dcat((DCELL) deg_angle(x[1], y[1], x[0], y[0]));
 
-	G_plot_line2(x[0], y[0], x[1], y[1]);
-	x++;
-	y++;
+	    plot_line_dense(x[0], y[0], x[1], y[1]);
+	    x++;
+	    y++;
+	}
     }
+    else {
+	while (--n > 0) {
+	    if (use == USE_D)
+		set_dcat((DCELL) deg_angle(x[1], y[1], x[0], y[0]));
 
+	    G_plot_line2(x[0], y[0], x[1], y[1]);
+	    x++;
+	    y++;
+	}
+    }
+
     return 0;
 }
 

Modified: grass/trunk/vector/v.to.rast/local.h
===================================================================
--- grass/trunk/vector/v.to.rast/local.h	2013-06-14 09:15:29 UTC (rev 56697)
+++ grass/trunk/vector/v.to.rast/local.h	2013-06-14 09:19:00 UTC (rev 56698)
@@ -33,10 +33,14 @@
 
 /* do_lines.c */
 int do_lines(struct Map_info *, struct line_pnts *, dbCatValArray *, int, int,
-	     struct cat_list *, int, double, int, int, int *);
+	     struct cat_list *, int, double, int, int, int *, int);
 
+void plot_line_dense(double, double, double, double);
+void setup_plot(double, double, double, double, int (*dot) (int, int));
+
+
 /* raster.c */
-int begin_rasterization(int, int);
+int begin_rasterization(int, int, int);
 int output_raster(int);
 int set_cat(CELL);
 int set_dcat(DCELL);
@@ -51,6 +55,6 @@
 
 /* vect2rast.c */
 int vect_to_rast(const char *, const char *, const char *, const char *, int, int,
-		 double, int, const char *, const char *, int, char *, char *);
+		 double, int, const char *, const char *, int, char *, char *, int);
 
 #endif

Modified: grass/trunk/vector/v.to.rast/main.c
===================================================================
--- grass/trunk/vector/v.to.rast/main.c	2013-06-14 09:15:29 UTC (rev 56697)
+++ grass/trunk/vector/v.to.rast/main.c	2013-06-14 09:19:00 UTC (rev 56698)
@@ -33,6 +33,7 @@
     struct Option *input, *output, *rows, *col, *use_opt, *val_opt,
 		  *field_opt, *type_opt, *where_opt, *cats_opt,
 	          *rgbcol_opt, *label_opt;
+    struct Flag *dense_flag;
     int nrows, use, value_type, type;
     double value;
     char *desc;
@@ -114,6 +115,12 @@
     rows->answer = "4096";
     rows->description = _("Number of rows to hold in memory");
 
+    dense_flag = G_define_flag();
+    dense_flag->key = 'd';
+    dense_flag->label = _("Create densified lines (default: thin lines)");
+    dense_flag->description = _("All cells touched by the line will be set, "
+                                "not only those on the render path");
+
     if (G_parser(argc, argv))
 	exit(EXIT_FAILURE);
 
@@ -155,7 +162,7 @@
     if (vect_to_rast(input->answer, output->answer, field_opt->answer,
 		     col->answer, nrows, use, value, value_type,
 		     rgbcol_opt->answer, label_opt->answer, type,
-		     where_opt->answer, cats_opt->answer)) {
+		     where_opt->answer, cats_opt->answer, dense_flag->answer)) {
 	exit(EXIT_FAILURE);
     }
 

Modified: grass/trunk/vector/v.to.rast/raster.c
===================================================================
--- grass/trunk/vector/v.to.rast/raster.c	2013-06-14 09:15:29 UTC (rev 56697)
+++ grass/trunk/vector/v.to.rast/raster.c	2013-06-14 09:19:00 UTC (rev 56698)
@@ -18,6 +18,7 @@
 static DCELL dcat;
 static int cur_x, cur_y;
 static int format;
+static int dense;
 static CELL *cell;
 static DCELL *dcell;
 static char **null_flags;
@@ -32,11 +33,13 @@
 static int (*dot) (int, int);
 
 
-int begin_rasterization(int nrows, int f)
+int begin_rasterization(int nrows, int f, int do_dense)
 {
     int i, size;
     int pages;
 
+    dense = (do_dense != 0);
+
     /* otherwise get complaints about window changes */
     G_suppress_warnings(1);
 
@@ -127,7 +130,10 @@
     G_set_window(&page);
 
     /* configure the plot routines */
-    G_setup_plot(-0.5, page.rows - 0.5, -0.5, page.cols - 0.5, move, cont);
+    if (dense)
+	setup_plot(0, page.rows, 0, page.cols, dot);
+    else
+	G_setup_plot(-0.5, page.rows - 0.5, -0.5, page.cols - 0.5, move, cont);
 
     return 0;
 }

Modified: grass/trunk/vector/v.to.rast/vect2rast.c
===================================================================
--- grass/trunk/vector/v.to.rast/vect2rast.c	2013-06-14 09:15:29 UTC (rev 56697)
+++ grass/trunk/vector/v.to.rast/vect2rast.c	2013-06-14 09:19:00 UTC (rev 56698)
@@ -10,7 +10,7 @@
 int vect_to_rast(const char *vector_map, const char *raster_map, const char *field_name,
 		 const char *column, int nrows, int use, double value,
 		 int value_type, const char *rgbcolumn, const char *labelcolumn,
-		 int ftype, char *where, char *cats)
+		 int ftype, char *where, char *cats, int dense)
 {
     struct Map_info Map;
     struct line_pnts *Points;
@@ -142,7 +142,7 @@
     }
 
     nlines = 1;
-    npasses = begin_rasterization(nrows, format);
+    npasses = begin_rasterization(nrows, format, dense);
     pass = 0;
 
     nareas_all = Vect_get_num_areas(&Map);
@@ -170,7 +170,7 @@
 	    if ((nlines =
 		 do_lines(&Map, Points, &cvarr, ctype, field, cat_list, 
 		          use, value, value_type, ftype,
-			  &nplines_all)) < 0) {
+			  &nplines_all, dense)) < 0) {
 		G_warning(_("Problem processing lines from vector map <%s>, continuing..."),
 			  vector_map);
 		stat = -1;



More information about the grass-commit mailing list