Trails and Graph Theory 11: Add Connections

We have built tools to find a fairly long circuit in the Gila National Forest, without repeating any trail segments. We can make a few improvements.

  • Add forest roads, or even a cross-country route if necessary, to connect the Aldo Leopold Wilderness trail system to the rest of the Gila.
  • Add forest roads, paved roads, and BLM trails to get near resupply towns: Silver City, Pie Town, Alma/Glenwood, Gila Hot Springs (Doc Campbell’s), and perhaps others.
  • Include trails in the Gila Cliff Dwellings. Since this is a national monument, its trails were not added when we imported Gila National Forest trails.
  • When trails enter short sections of non-USFS land, such as private or state trust, add connections for those areas, since they would not be included in the original Gila import command.
  • Perhaps add part of Bursum Road, NM 159. It is one of my favorite road walks of the Grand Enchantment Trail, and connects several trails together.
  • Add the Continental Divide Wilderness Study Area, south of Pie Town, that contains a good span of the CDT and connects two northern protrusions of the Gila National Forest.
  • Add several brief road-walks that are part of the Continental Divide Trail and Grand Enchantment Trail, that would not be imported if we only add foot-paths.

The OSMnx library does not allow us a direct way to import GPX files of specific routes, since we need to use the node values already defined in OpenStreetMaps. As far as I know, OSMnx does not support importing specific trails or roads by name. We can import a rectangular region into a graph, and then merge it with our existing Gila trail graph.

As an example, Alma and Glenwood are near Mineral Creek Trail (quite an interesting route with a lot of history and geology) but this trail would normally be excluded from our loop because it dead-ends at a trailhead. By connecting Mineral Creek Trail with short road-walks to Alma (good cafe and small convenience store) and Glenwood (post office and maybe convenience store) and then to Little Whitewater Creek Trail (or Whitewater Creek Trail with the Catwalk), we can include these trails in our loop.

To add these roads, which might include other roads we do not care about, we can get away with a single rectangle.

# custom filter imports roads AND foot-paths
cf_add_routes = '["highway"~"path | footway | 
    motorway | motorway_link | trunk | primary | secondary | 
    tertiary | unclassified | residential | living_street | 
    residential | service | track"]'

n,s,e,w = 33.42443, 33.26350, -108.78571, -108.92392
GT = ox.graph_from_bbox(n,s,e,w,simplify=False,truncate_by_edge=True,
    retain_all=True,custom_filter=cf_add_routes)
# merge with existing graph G
G2 = nx.compose(GT,G2)

Whenever we add a connection, we add code for a test to make sure any roads and trails that we add properly connect to each other.

description = 'glenwood mineral creek to little whitewater'
Point1 = (33.42070, -108.82503)
Point2 = (33.32292, -108.81121)

node1 = ox.nearest_nodes(T,Point1[1], Point1[0])
node2 = ox.nearest_nodes(T,Point2[1], Point2[0])
try:
    path_length = nx.shortest_path_length(T,node1,node2,weight='length')
except:
    print('no path found: ', description)
else:
    print(description,' distance(miles): ', str(round(path_length*meters_to_mile,1)))
glenwood mineral creek to little whitewater  distance(miles):  14.7

For Silver City, the CDT connects to the city going northwest on a long road walk, and there is a network of trails about 5 miles to the east at Arenas Valley. Corre Caminos bus line goes from Silver City to Arenas Valley a few times each weekday, so we will include these connecting roads to pass through Silver City.

Several short roads connect between trails in the Aldo Leopold Wilderness and Gila Wilderness. When importing only trails into NetworkX, these paths would be interpreted as disconnected. Fixing this might include more of the Aldo. (However, the Aldo is blocked on the south and east, and to the north has few connected trails going out to the rest of the Gila, aside from the CDT, so the effect may be limited.)

We will not detail all the other route additions here, but they are documented in the source code, available for download below. Pie Town did not seem to have a loop opportunity, so that trail town will be added as an optional supply route.

An option was added to our draw() command to display all the connection rectangles we added. This was essential for debugging.

Finding and adding all the brief road connections for the CDT was very tedious and took many iterations, and I am still not finished. When one is making this many additions by hand, it is usually a sign that the problem should be solved another way.

Might it be possible to write a script that finds these gaps? And speaking of added connections, might it be possible to write a program to find forest roads that connect the ends of trails, and span less than 0.5 miles in length or so, and automagically add those road segments to our network?

That will be the subject of the next blog post.

Download the source code, available here. (For illustrative purposes only, because I am sure there is a better solution.)

Related Posts:

Author: Jim, Sagebrush

Jim (trail-name Sagebrush) codes audio software for Windows, Linux, Android, and embedded systems. When not working at sagebrush.com, he enjoys backpacking, which this blog is about.