# [GRASS-user] Forcing polyline nodes through a point

Dwight Needels needels at translucida.com
Wed Jun 3 13:48:44 EDT 2009

```On May 28, 2009, at 10:04 PM, Dwight Needels wrote:

> I am trying to create a map of hiking trails based on GPS data. If
> anyone can point me to a tutorial that discusses the techniques and
> issues involved, I would appreciate it. Meanwhile, a couple of
> specific questions.
>
> I have a series of GPS tracks that have been brought into GRASS as
> polylines, and a series of time-averaged waypoints that have been
> brought into GRASS as points. The lines represent segments of color-
> blazed trails, and the waypoints represent higher-quality
> measurements of trail termini and intersections.

My questions were about how to force a vector line to pass exactly
through specified points in such a way that they would continue to
pass through those points after smoothing.

Thank you Hamish for pointing out several very useful tools for me to
concentrate on learning. Also, thank you Moritz for the awk magic
required to pipe point coordinates from one vector into the v.edit
command operating on a second vector. With your indispensable help I
was able to come up with something that does almost exactly what I
want. If anybody can see any "gotchas" or better ways to accomplish
these steps, I would appreciate the feedback.

Thanks, -Dwight

Starting with a line (track) vector and a point (waypoint) vector,
modify the line vector so that it passes exactly through each point.
This handles three cases; 1) where a vector line terminus undershoots
the defined terminus point, 2) where a vector line terminus overshoots
the defined terminus point, and 3) where the vector line passes within
the threshold of a point somewhere in the middle of the line (a fork,
hard curve or switchback).

Threshold (distance from points) should be chosen to include at least
two vertices for each line segment of interest, without including
vertices from other line segments.

Line vector: trail
Point vector: trail_nodes
Resulting line vector: trail_clean

Summary:
# Split the line vector at closest spot to each point within a
threshold, delete superfluous points (v.net op=connect; v.edit
tool=delete)
# Delete added lines and nodes to leave a gap (v.to.points -n; v.edit
tool=vertexdel)
# Bridge the gaps, but have each bridge pass through one of the
original points (v.distance -a; v.edit tool=copy)
# Remove zero length lines, merge bridges across the gaps in the line
vector (v.clean tool=rmline; v.edit tool=merge)
# Add back a node at each of the original points, remove zero length
lines (v.net op=connect; v.clean tool=rmline)
# Clean up intermediate vectors (g.remove)

Steps:
v.net trail points=trail_nodes out=trail_net op=connect thresh=100 --o
v.edit tool=delete map=trail_net layer=2 cats=1-9999
v.to.points -n in=trail_net out=trail_net_nodes --o
v.edit trail_net tool=vertexdel coords=`v.to.db -p trail_net_nodes
layer=2 option=coor --quiet | awk -F"|" '{printf"%f,%f,",\$2,\$3}
END{printf"\n"}'`
v.distance -p -a from=trail_nodes to=trail_net from_type=point
to_type=line output=trail_bridges dmax=100 upload=dist column=dist --
overwrite
v.edit map=trail_net tool=copy bgmap=trail_bridges ids=1-9999
v.clean input=trail_net output=trail_net_clean type=line tool=rmline
thresh=-1 --o
v.edit tool=merge map=trail_net_clean ids=1-9999
v.net trail_net_clean points=trail_nodes out=trail_plus_nodes
op=connect thresh=100 --o
v.clean input=trail_plus_nodes output=trail_clean type=line
tool=rmline thresh=-1 --o
g.remove
vect
=
trail_net,trail_net_clean,trail_bridges,trail_net_nodes,trail_plus_nodes

Nodes were added back (the polyline was split at each of the original
points) so that the trail could be smoothed while still guaranteeing
that the vector will pass through the original points.

# Smooth/straighten (v.generalize, method=snakes)
v.generalize input=trail_clean output=trail_smooth method=snakes
alpha=1 beta=1 --o

```