Navigating Wilderness Areas with GRASS (Where 2.0 Presentation)
Jun 14, 2006 metroadminPre-processing, and GRASS commands used to locate optimal routes as presented in the talk this afternoon. Presentation can be found here. Hints and comments are inline with commands. Looks like there was some coverage of this talk in the Wired Online Magazine .
General concept: want to plan a wilderness trip, deviating from the main trail, hoping to visit numerous lakes. In the notes, the lakes that will be visited are called points of interest (poi). We would like to automatically locate the paths between points of interest and the trail which require the least amount of effort: i.e. minimizing the total change in slope encountered while walking. This makes sense, as we all know that walking uphill or down steep hills is hard. Furthermore, walking a long way up or down a steep slope is even harder. Thus, a simple slope map can be used as a travel "friction" map for the input to the command r.cost. Additional sources of "travel friction" can be added to this slope map as follows:
- traversing lakes is not acceptable (extreme "travel friction" added to slope map)
- traversing wooded areas is faster due to shading (moderate "travel friction" subtracted from slope map)
Note that these features can be automatically extracted from our USGS topo map (Figures 2 and 3). Figure 4 depicts this composite travel "friction" map. By specifying start and stop points (one lake to another, or from the main trail to a lake), along with our composite travel friction map we can compute the least-cost path between these points via the GRASS commands r.cost and r.drain. Figure 5 demonstrates the output from r.cost and r.drain, in this 3D rendition it is possible to see how r.drain is actually simulating the flow of a drop of water down an elevation surface: an energy minimizing style operation. However in this case, the elevation surface is actually a travel cost map (computed by r.cost). The path of the theoretical drop of water represents the least-cost route from the starting point to the end point. Note that the starting point for r.cost (point of origin) is actually the ending point for r.drain. See code examples below for details. Notice that by specifying very large travel costs for traversing lakes (peaks in Figure 5), and slightly lower travel costs for wooded areas, the computed lease cost path in Figure 5 goes "around" lakes and "through" wooded areas. Figure 6 depicts the new trail network (red lines) for the wilderness area, connecting Park Service trails (black) and our points of interest (yellow boxes).
A final, press-ready map was produced by GMT suitable for printing and taking out into the field for assisting with navigation. UTM ticks are useful in associating realtime GPS positional data with the printed map. This map can be downloaded here as a PDF. The script used to produce the map can be found here. Note that this is a slightly modified r.out.gmt script. I will post these changes back to the GRASS wikki for integration into the main codebase.
Figure 1: area of interest
Figure 2: Lake Features
Figure 3: wooded areas
Figure 4: composite friction map
Figure 5: least-cost path
Figure 6: vectorized least-cost trails
Download and Process DRG data (USGS Topo Maps)
Extract wooded areas and lakes from topo maps:
Create travel "friction" map:
### reset the res to that of the slope map:
g.region align=slope
#
#update our slope map, to include traversing water features, and prefering wooded areas
#add a "cost" of 1000 to lake areas
r.mapcalc "new_slope = if(isnull(lakes) == 0, 1000.0+slope, slope)"
#
#subtract a small amount of cost for wodded areas:
r.mapcalc "new_slope = if(isnull(trees_final) == 0, abs(new_slope - 10.0), new_slope)"
Compute least-cost paths:
Combine all least-cost paths and vectorize: