[GRASS-SVN] r58049 - grass/trunk/vector/v.segment

svn_grass at osgeo.org svn_grass at osgeo.org
Sat Oct 19 00:58:33 PDT 2013


Author: hcho
Date: 2013-10-19 00:58:33 -0700 (Sat, 19 Oct 2013)
New Revision: 58049

Modified:
   grass/trunk/vector/v.segment/main.c
   grass/trunk/vector/v.segment/v.segment.html
Log:
Added an input format for reversed & percent offsets.
* -offset  # start from the end node
* offset%  # start from offset% of the line's length
* -offset% # start from offset% of the line's end node


Modified: grass/trunk/vector/v.segment/main.c
===================================================================
--- grass/trunk/vector/v.segment/main.c	2013-10-18 18:00:26 UTC (rev 58048)
+++ grass/trunk/vector/v.segment/main.c	2013-10-19 07:58:33 UTC (rev 58049)
@@ -1,4 +1,3 @@
-
 /***************************************************************
  *
  * MODULE:       v.segment
@@ -6,10 +5,11 @@
  * AUTHOR(S):    Radim Blazek
  *               Hamish Bowman (offset bits)
  *               OGR support by Martin Landa <landa.martin gmail.com>
+ *               Reversed & percent offsets by Huidae Cho <grass4u gmail.com>
  *               
  * PURPOSE:      Generate segments or points from input map and segments read from stdin 
  *               
- * COPYRIGHT:    (C) 2002-2009 by the GRASS Development Team
+ * COPYRIGHT:    (C) 2002-2013 by the GRASS Development Team
  *
  *               This program is free software under the GNU General
  *               Public License (>=v2). Read the file COPYING that
@@ -27,6 +27,11 @@
 #include <grass/dbmi.h>
 #include <grass/glocale.h>
 
+int read_point_input(char *buf, char *stype, int *id, int *lcat, double *offset,
+		double *side_offset, int *rev, int *pct);
+int read_line_input(char *buf, char *stype, int *id, int *lcat,
+		double *offset1, double *offset2, double *side_offset,
+		int *rev1, int *pct1, int *rev2, int *pct2);
 int find_line(struct Map_info *Map, int lfield, int cat);
 void offset_pt_90(double *, double *, double, double);
 
@@ -106,6 +111,7 @@
     lines_written = 0;
 
     while (1) {
+	int rev1, rev2, pct1, pct2;
 
 	if (!file_opt->answer) {
 	    if (fgets(buf, sizeof(buf), stdin) == NULL)
@@ -124,16 +130,14 @@
 
 	switch (buf[0]) {
 	case 'P':
-	    side_offset = 0;
-	    ret =
-		sscanf(buf, "%c %d %d %lf %lf", &stype, &id, &lcat, &offset1,
-		       &side_offset);
-	    if (ret < 4) {
+	    if (!read_point_input(buf, &stype, &id, &lcat, &offset1,
+				    &side_offset, &rev1, &pct1)) {
 		G_warning(_("Unable to read input: %s"), buf);
 		break;
 	    }
 	    points_read++;
-	    G_debug(2, "point: %d %d %f %f", id, lcat, offset1, side_offset);
+	    G_debug(2, "point: %d %d %s%f%s %f", id, lcat, rev1 ? "-" : "",
+			    offset1, pct1 ? "%" : "", side_offset);
 
 
 	    /* OK, write point */
@@ -144,11 +148,16 @@
 	    }
 
 	    Vect_read_line(&In, LPoints, LCats, line);
-	    ret =
-		Vect_point_on_line(LPoints, offset1, &x, &y, &z, &angle,
-				   NULL);
+
+	    len = Vect_line_length(LPoints);
+	    if (pct1)
+		offset1 = len * offset1 / 100.0;
+	    if (rev1)
+		offset1 = len - offset1;
+
+	    ret = Vect_point_on_line(LPoints, offset1, &x, &y, &z, &angle,
+			    NULL);
 	    if (ret == 0) {
-		len = Vect_line_length(LPoints);
 		G_warning(_("Unable to get point on line: cat = %d offset = %f "
 			   "(line length = %.15g)\n%s"), lcat, offset1, len,
 			  buf);
@@ -165,16 +174,16 @@
 	    points_written++;
 	    break;
 	case 'L':
-	    side_offset = 0;
-	    ret = sscanf(buf, "%c %d %d %lf %lf %lf", &stype, &id, &lcat,
-			 &offset1, &offset2, &side_offset);
-	    if (ret < 5) {
+	    if (!read_line_input(buf, &stype, &id, &lcat, &offset1, &offset2,
+				    &side_offset, &rev1, &pct1, &rev2, &pct2)) {
 		G_warning(_("Unable to read input: %s"), buf);
 		break;
 	    }
 	    lines_read++;
-	    G_debug(2, "line: %d %d %f %f %f", id, lcat, offset1, offset2,
-		    side_offset);
+	    G_debug(2, "line: %d %d %s%f%s %s%f%s %f", id, lcat,
+			    rev1 ? "-" : "", offset1, pct1 ? "%" : "",
+			    rev2 ? "-" : "", offset2, pct2 ? "%" : "",
+			    side_offset);
 
 	    line = find_line(&In, lfield, lcat);
 	    if (line == 0) {
@@ -185,6 +194,23 @@
 	    Vect_read_line(&In, LPoints, LCats, line);
 
 	    len = Vect_line_length(LPoints);
+	    if (pct1)
+	        offset1 = len * offset1 / 100.0;
+	    if (rev1)
+	        offset1 = len - offset1;
+	    if (pct2)
+	        offset2 = len * offset2 / 100.0;
+	    if (rev2)
+	        offset2 = len - offset2;
+
+	    if (offset1 > offset2) {
+		double tmp;
+
+		tmp = offset1;
+		offset1 = offset2;
+		offset2 = tmp;
+	    }
+
 	    if (offset2 > len) {
 		G_warning(_("End of segment > line length -> cut"));
 		offset2 = len;
@@ -237,7 +263,90 @@
     exit(EXIT_SUCCESS);
 }
 
+int read_point_input(char *buf, char *stype, int *id, int *lcat, double *offset,
+		double *side_offset, int *rev, int *pct)
+{
+    char offsetbuf[100];
+    int ret;
+    char *p;
 
+    *side_offset = 0;
+    *rev = 0;
+    *pct = 0;
+
+    ret = sscanf(buf, "%c %d %d %[.0-9%-] %lf", stype, id, lcat, offsetbuf,
+		    side_offset);
+    
+    if (ret < 4) {
+	return 0;
+    }
+
+    p = offsetbuf;
+    if (offsetbuf[0] == '-') {
+        *rev = 1;
+        p++;
+    }
+    if (offsetbuf[strlen(offsetbuf)-1] == '%') {
+        *pct = 1;
+        offsetbuf[strlen(offsetbuf)-1] = '\0';
+    }
+    if (sscanf(p, "%lf", offset) != 1) {
+        return 0;
+    }
+
+    return 1;
+}
+
+int read_line_input(char *buf, char *stype, int *id, int *lcat,
+		double *offset1, double *offset2, double *side_offset,
+		int *rev1, int *pct1, int *rev2, int *pct2)
+{
+    char offset1buf[100];
+    char offset2buf[100];
+    int ret;
+    char *p;
+
+    *side_offset = 0;
+    *rev1 = 0;
+    *pct1 = 0;
+    *rev2 = 0;
+    *pct2 = 0;
+
+    ret = sscanf(buf, "%c %d %d %[.0-9%-] %[.0-9%-] %lf", stype, id, lcat,
+		    offset1buf, offset2buf, side_offset);
+    if (ret < 5) {
+        return 0;
+    }
+
+    p = offset1buf;
+    if (offset1buf[0] == '-') {
+        *rev1 = 1;
+        p++;
+    }
+    if (offset1buf[strlen(offset1buf)-1] == '%') {
+        *pct1 = 1;
+        offset1buf[strlen(offset1buf)-1] = '\0';
+    }
+    if (sscanf(p, "%lf", offset1) != 1) {
+        return 0;
+    }
+
+    p = offset2buf;
+    if (offset2buf[0] == '-') {
+        *rev2 = 1;
+        p++;
+    }
+    if (offset2buf[strlen(offset2buf)-1] == '%') {
+        *pct2 = 1;
+        offset2buf[strlen(offset2buf)-1] = '\0';
+    }
+    if (sscanf(p, "%lf", offset2) != 1) {
+        return 0;
+    }
+
+    return 1;
+}
+
 /* Find line by cat, returns 0 if not found */
 int find_line(struct Map_info *Map, int lfield, int lcat)
 {

Modified: grass/trunk/vector/v.segment/v.segment.html
===================================================================
--- grass/trunk/vector/v.segment/v.segment.html	2013-10-18 18:00:26 UTC (rev 58048)
+++ grass/trunk/vector/v.segment/v.segment.html	2013-10-19 07:58:33 UTC (rev 58049)
@@ -9,12 +9,18 @@
 L <segment id> <line cat> <start offset> <end offset> [<side offset>]
 </pre></div>
 
+The offsets can be percent values of the line length. If the offsets are
+negative, they start from the end node of the line. -0 means the end of the
+line.
+
 <h3>EXAMPLE</h3>
 
 The user could send to <tt>stdin</tt> something like:
 <div class="code"><pre>
 P 1 356 24.56
 P 2 495 12.31
+P 3 500 -12.31
+P 4 510 -20%
 ...
 </pre></div>
 (pipe or redirect from file into the command).<br>
@@ -23,18 +29,20 @@
 <h2>NOTES</h2>
 
 A segment is only created for the first line found of the specified category.
-<p>Points are generated along the lines at the given distance(s) from the
-beginning of the vector line.
+<p>Points are generated along the lines at the given distance(s) or percent(s)
+of the line length from the beginning or end, if offsets are negative, of the
+vector line.
 <p>The side offset is the orthogonal distance from the line. Positive side
 offsets are to the right side of the line going forward, negative offsets
 are to the left (<em>d.vect</em> with <em>display=shape,dir</em> shows
 the direction of vector lines). As the segment distance is measured along the
 original line, side-offset lines will be longer than the start-end segment distance
 for outside corners of curving lines, and shorter for inside corners.
-<p>All offsets are measured in map units (see "<em>g.proj -p</em>").
-<p>To place a point in the middle of a line, the <em>v.to.db</em> module may be
-used to find the line's length. Then half of that distance can be used as the
-along-line offset.
+<p>All offsets are measured in map units (see "<em>g.proj -p</em>") or percents
+of the line length, if followed by a % character.
+<p>To place a point in the middle of a line, 50% offset can be used or the
+<em>v.to.db</em> module may be used to find the line's length. Then half of
+that distance can be used as the along-line offset.
 
 
 <h2>EXAMPLES</h2>
@@ -97,6 +105,17 @@
 P 4 1 7000 500
 EOF
 d.vect myrailroads_pt2kmO500m icon=basic/circle color=aqua fcolor=aqua size=5
+
+# A series of points, spaced every 10% of the line's length along the tracks from the end of the line up to the middle point, offset 500m to the right
+v.segment myrailroads out=myrailroads_pt10pctO500m << EOF
+P 1 1  -0% 500
+P 1 1 -10% 500
+P 2 1 -20% 500
+P 3 1 -30% 500
+P 4 1 -40% 500
+P 4 1 -50% 500
+EOF
+d.vect myrailroads_pt10pctO500m icon=basic/circle color=red fcolor=black size=5
 </pre></div>
 
 



More information about the grass-commit mailing list