[GRASS-SVN] r70595 - grass/trunk/vector/v.to.points

svn_grass at osgeo.org svn_grass at osgeo.org
Wed Feb 15 21:09:41 PST 2017


Author: hcho
Date: 2017-02-15 21:09:41 -0800 (Wed, 15 Feb 2017)
New Revision: 70595

Modified:
   grass/trunk/vector/v.to.points/local_proto.h
   grass/trunk/vector/v.to.points/main.c
   grass/trunk/vector/v.to.points/v.to.points.html
   grass/trunk/vector/v.to.points/write.c
Log:
v.to.points: Add -p (percentage) and -r (reverse) flags

Modified: grass/trunk/vector/v.to.points/local_proto.h
===================================================================
--- grass/trunk/vector/v.to.points/local_proto.h	2017-02-16 03:02:38 UTC (rev 70594)
+++ grass/trunk/vector/v.to.points/local_proto.h	2017-02-16 05:09:41 UTC (rev 70595)
@@ -5,5 +5,5 @@
 void write_point(struct Map_info *, double, double, double,
 		 int, double, dbDriver *, struct field_info *);
 void write_line(struct Map_info *, struct line_pnts *, int,
-		int, int, double, dbDriver *, struct field_info *);
+		int, int, int, double, dbDriver *, struct field_info *);
 #endif

Modified: grass/trunk/vector/v.to.points/main.c
===================================================================
--- grass/trunk/vector/v.to.points/main.c	2017-02-16 03:02:38 UTC (rev 70594)
+++ grass/trunk/vector/v.to.points/main.c	2017-02-16 05:09:41 UTC (rev 70595)
@@ -8,7 +8,7 @@
  *               
  * PURPOSE:      Create points along lines 
  *               
- * COPYRIGHT:    (C) 2002-2014 by the GRASS Development Team
+ * COPYRIGHT:    (C) 2002-2017 by the GRASS Development Team
  *
  *               This program is free software under the GNU General
  *               Public License (>=v2).  Read the file COPYING that
@@ -35,7 +35,7 @@
         struct Option *input, *output, *type, *dmax, *lfield, *use;
     } opt;
     struct {
-        struct Flag *table, *inter;
+        struct Flag *table, *inter, *percent, *reverse;
     } flag;
     struct GModule *module;
     struct Map_info In, Out;
@@ -84,13 +84,20 @@
     opt.dmax->type = TYPE_DOUBLE;
     opt.dmax->required = NO;
     opt.dmax->answer = "100";
-    opt.dmax->description = _("Maximum distance between points in map units");
+    opt.dmax->description = _("Maximum distance between points in map units or percentage with -p");
 
     flag.inter = G_define_flag();
     flag.inter->key = 'i';
     flag.inter->description = _("Interpolate points between line vertices (only for use=vertex)");
-    
 
+    flag.percent = G_define_flag();
+    flag.percent->key = 'p';
+    flag.percent->description = _("Use dmax as percentage of line length");
+
+    flag.reverse = G_define_flag();
+    flag.reverse->key = 'r';
+    flag.reverse->description = _("Start from the end node");
+
     flag.table = G_define_standard_flag(G_FLG_V_TABLE);
 
     if (G_parser(argc, argv))
@@ -102,6 +109,8 @@
 
     type = Vect_option_to_types(opt.type);
     dmax = atof(opt.dmax->answer);
+    if (dmax <= 0)
+	G_fatal_error(_("Option %s must be positive"), opt.dmax->key);
 
     vertex_type = 0;
     if (opt.use->answer) {
@@ -134,6 +143,7 @@
     Vect_hist_command(&Out);
 
     /* Table */
+    driver = NULL;
     Fi = NULL;
     if (!flag.table->answer) {
 	struct field_info *Fin;
@@ -222,9 +232,13 @@
 		write_point(&Out, LPoints->x[0], LPoints->y[0], LPoints->z[0],
 			    cat, 0.0, driver, Fi);
 	    }
-	    else {		/* lines */
-		write_line(&Out, LPoints, cat, vertex_type,
-			   flag.inter->answer, dmax, driver, Fi);
+	    else if (flag.percent->answer) {		/* lines */
+		double dmaxlen = Vect_line_length(LPoints) * dmax / 100.0;
+		write_line(&Out, LPoints, cat, vertex_type, flag.inter->answer,
+			   flag.reverse->answer, dmaxlen, driver, Fi);
+	    } else {
+		write_line(&Out, LPoints, cat, vertex_type, flag.inter->answer,
+			   flag.reverse->answer, dmax, driver, Fi);
 	    }
 	}
 
@@ -254,8 +268,14 @@
 
 	    Vect_get_area_points(&In, area, LPoints);
 
-	    write_line(&Out, LPoints, cat, vertex_type, flag.inter->answer,
-		       dmax, driver, Fi);
+	    if (flag.percent->answer) {
+		double dmaxlen = Vect_line_length(LPoints) * dmax / 100.0;
+		write_line(&Out, LPoints, cat, vertex_type, flag.inter->answer,
+			   flag.reverse->answer, dmaxlen, driver, Fi);
+	    } else {
+		write_line(&Out, LPoints, cat, vertex_type, flag.inter->answer,
+			   flag.reverse->answer, dmax, driver, Fi);
+	    }
 
 	    nisles = Vect_get_area_num_isles(&In, area);
 
@@ -263,8 +283,16 @@
 		isle = Vect_get_area_isle(&In, area, i);
 		Vect_get_isle_points(&In, isle, LPoints);
 
-		write_line(&Out, LPoints, cat, vertex_type,
-			   flag.inter->answer, dmax, driver, Fi);
+		if (flag.percent->answer) {
+		    double dmaxlen = Vect_line_length(LPoints) * dmax / 100.0;
+		    write_line(&Out, LPoints, cat, vertex_type,
+			       flag.inter->answer, flag.reverse->answer,
+			       dmaxlen, driver, Fi);
+		} else {
+		    write_line(&Out, LPoints, cat, vertex_type,
+			       flag.inter->answer, flag.reverse->answer, dmax,
+			       driver, Fi);
+		}
 	    }
 	}
     }

Modified: grass/trunk/vector/v.to.points/v.to.points.html
===================================================================
--- grass/trunk/vector/v.to.points/v.to.points.html	2017-02-16 03:02:38 UTC (rev 70594)
+++ grass/trunk/vector/v.to.points/v.to.points.html	2017-02-16 05:09:41 UTC (rev 70595)
@@ -70,24 +70,27 @@
 used.
 
 <p>
-If the <b>-i</b> flag is used in conjunction with
-the <b>use=vertex</b> option,
+If the <b>-i</b> flag is used in conjunction with the <b>use=vertex</b> option,
 <em>v.to.points</em> will digitize points on the line vertices, as
 well as interpolate points between line vertices using <b>dmax</b> as
 the maximum allowable spacing.
 
 <p>
-To get points created for the beginning, middle and end only, use
-the <b>-i</b> flag and set <b>dmax</b> so that:
+Use the <b>-p</b> flag to treat <b>dmax</b> as a percentage of each line
+length.  For example, to get points created for the beginning, middle and end
+only, use the <b>-p</b> flag and set <b>dmax</b> so that:
 
 <div class="code"><pre>
- (length of input line / 2) <= <em>dmax</em> <= length of input line
+ 50 < <em>dmax</em> <= 100
 </pre></div>
 
 Hence, if <b>dmax</b> is between 0.5x and 1.0x the line length, you will
 always get points created at exactly the beginning, middle and end of
 the input line.
 
+<p>
+Use the <b>-r</b> flag to create points starting from the end node.
+
 <h2>EXAMPLE</h2>
 
 In this example, the 'railroads' vector lines map of the North Carolina

Modified: grass/trunk/vector/v.to.points/write.c
===================================================================
--- grass/trunk/vector/v.to.points/write.c	2017-02-16 03:02:38 UTC (rev 70594)
+++ grass/trunk/vector/v.to.points/write.c	2017-02-16 05:09:41 UTC (rev 70595)
@@ -9,6 +9,11 @@
 static struct line_pnts *PPoints;
 static int point_cat = 1;
 
+static void write_line_forward(struct Map_info *, struct line_pnts *, int, int,
+			       int, double, dbDriver *, struct field_info *);
+static void write_line_backward(struct Map_info *, struct line_pnts *, int, int,
+				int, double, dbDriver *, struct field_info *);
+
 void write_point(struct Map_info *Out, double x, double y, double z,
 		 int line_cat, double along, dbDriver *driver, struct field_info *Fi)
 {
@@ -57,9 +62,22 @@
 }
 
 void write_line(struct Map_info *Out, struct line_pnts *LPoints, int cat,
-		int vertex, int interpolate, double dmax,
-                dbDriver *driver, struct field_info *Fi)
+		int vertex, int interpolate, int reverse, double dmax,
+		dbDriver *driver, struct field_info *Fi)
 {
+    if (reverse == 0)
+	write_line_forward(Out, LPoints, cat, vertex, interpolate, dmax,
+			   driver, Fi);
+    else
+	write_line_backward(Out, LPoints, cat, vertex, interpolate, dmax,
+			    driver, Fi);
+}
+
+static void write_line_forward(struct Map_info *Out, struct line_pnts *LPoints,
+			       int cat, int vertex, int interpolate,
+			       double dmax, dbDriver *driver,
+			       struct field_info *Fi)
+{
     if (vertex == GV_VERTEX || vertex == GV_NODE) {	/* use line vertices */
 	double along;
 	int vert;
@@ -71,6 +89,8 @@
 	    if (vertex == GV_VERTEX ||
 		(vertex == GV_NODE &&
 		 (vert == 0 || vert == LPoints->n_points - 1))) {
+		if (vert == LPoints->n_points - 1)
+		    along = Vect_line_length(LPoints);
 		write_point(Out, LPoints->x[vert], LPoints->y[vert],
 			    LPoints->z[vert], cat, along, driver, Fi);
 	    }
@@ -84,7 +104,7 @@
 		len = hypot(hypot(dx, dy), dz);
 
 		/* interpolate segment */
-		if (vertex == GV_VERTEX && interpolate) {
+		if (interpolate && vertex == GV_VERTEX) {
 		    int i, n;
 		    double x, y, z, dlen;
 
@@ -143,3 +163,94 @@
 	}
     }
 }
+
+static void write_line_backward(struct Map_info *Out, struct line_pnts *LPoints,
+				int cat, int vertex, int interpolate,
+				double dmax, dbDriver *driver,
+				struct field_info *Fi)
+{
+    if (vertex == GV_VERTEX || vertex == GV_NODE) {	/* use line vertices */
+	double along;
+	int vert;
+
+	along = Vect_line_length(LPoints);
+	for (vert = LPoints->n_points - 1; vert >= 0; vert--) {
+	    G_debug(3, "vert = %d", vert);
+
+	    if (vertex == GV_VERTEX ||
+		(vertex == GV_NODE &&
+		 (vert == 0 || vert == LPoints->n_points - 1))) {
+		if (vert == 0)
+		    along = 0;
+		write_point(Out, LPoints->x[vert], LPoints->y[vert],
+			    LPoints->z[vert], cat, along, driver, Fi);
+	    }
+
+	    if (vert > 0) {
+		double dx, dy, dz, len;
+
+		dx = LPoints->x[vert - 1] - LPoints->x[vert];
+		dy = LPoints->y[vert - 1] - LPoints->y[vert];
+		dz = LPoints->z[vert - 1] - LPoints->z[vert];
+		len = hypot(hypot(dx, dy), dz);
+
+		/* interpolate segment */
+		if (interpolate && vertex == GV_VERTEX) {
+		    int i, n;
+		    double x, y, z, dlen;
+
+		    if (len > dmax) {
+			n = len / dmax + 1;	/* number of segments */
+			dx /= n;
+			dy /= n;
+			dz /= n;
+			dlen = len / n;
+
+			for (i = 1; i < n; i++) {
+			    x = LPoints->x[vert] + i * dx;
+			    y = LPoints->y[vert] + i * dy;
+			    z = LPoints->z[vert] + i * dz;
+
+			    write_point(Out, x, y, z, cat, along - i * dlen,
+					driver, Fi);
+			}
+		    }
+		}
+		along -= len;
+	    }
+	}
+    }
+    else {			/* do not use vertices */
+	int i, n;
+	double len, dlen, along, x, y, z;
+
+	len = Vect_line_length(LPoints);
+	n = len / dmax + 1;	/* number of segments */
+	dlen = len / n;		/* length of segment */
+
+	G_debug(3, "n = %d len = %f dlen = %f", n, len, dlen);
+
+	for (i = 0; i <= n; i++) {
+	    if (i > 0 && i < n) {
+		along = len - i * dlen;
+		Vect_point_on_line(LPoints, along, &x, &y, &z, NULL, NULL);
+	    }
+	    else {		/* first and last vertex */
+		if (i == 0) {
+		    along = len;
+		    x = LPoints->x[LPoints->n_points - 1];
+		    y = LPoints->y[LPoints->n_points - 1];
+		    z = LPoints->z[LPoints->n_points - 1];
+		}
+		else {		/* last */
+		    along = 0;
+		    x = LPoints->x[0];
+		    y = LPoints->y[0];
+		    z = LPoints->z[0];
+		}
+	    }
+	    G_debug(3, "  i = %d along = %f", i, along);
+	    write_point(Out, x, y, z, cat, along, driver, Fi);
+	}
+    }
+}



More information about the grass-commit mailing list