[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

# Split the line vector at closest spot to each point within a  
threshold, delete superfluous points (v.net op=connect; v.edit  
# Delete added lines and nodes to leave a gap (v.to.points -n; v.edit  
# 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)

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}  
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 -- 
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

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

More information about the grass-user mailing list