[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