[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