A hunt for the steep slopes in North America

Igor Kanel
6 min readNov 1, 2017

--

This article about how to find a steep slopes using topological data gathered by NASA.

Screenshot of the Google Earth Mt.Robson area (BC) with longest steep path from the summit

This article could be useful for the Mountaineers, skiers, mountain bikers, base jumpers and data lovers.

The Shuttle Radar Topography Mission (SRTM) is an international research effort that obtained digital elevation models on a near-global scale from 56° S to 60° N, to generate the most complete high-resolution digital topographic database of Earth prior to the release of the ASTER GDEM in 2009. SRTM consisted of a specially modified radar system that flew on board the Space Shuttle Endeavour during the 11-day STS-99 mission in February 2000, based on the older Spaceborne Imaging Radar-C/X-band Synthetic Aperture Radar (SIR-C/X-SAR), previously used on the Shuttle in 1994. To acquire topographic data, the SRTM payload was outfitted with two radar antennas.One antenna was located in the Shuttle’s payload bay, the other — a critical change from the SIR-C/X-SAR, allowing single-pass interferometry — on the end of a 60-meter (200-foot) mast that extended from the payload bay once the Shuttle was in space.
wiki

The main output of the mission was topological data for entire earth excluding polar area. The resolution is 30x30m for the US territory and 90x90m for the rest part of the world.

The whole data array is too huge to handle it on PC. Thankfully we can download particular chunk from the Consortium for Spatial Information website. The Data is available in ESRI GRID format which is simple heights 6000x6000 matrix plus header with metadata.

Most probably a matrix manipulation tool like Matlab is the best choice to search for steep slopes across the country, but I decided to use conventional tools like mssql and c# console application.

The task was rather simple and consisted of the following steps:

  1. Load heights data from the matrix file to MSSQL database
  2. Run mssql query to lookup the adjacent points with desired altitude difference
  3. Execute a query to build the lines from the segments collected in the previous step
  4. Use GeoNames web service to name the gathered mountains.
  5. Export lines to the KML format that could be opened by google maps or google earth.

The search criteria:

A slope must be at least 300m height and 15 degrees steep. Slopes with lesser incline are not very interesting for the hiking, mountaineering, backcountry ski and other activities.

Results

Map with all prominent slopes is here. You can switch between satellite, terrain and map view.

Screenshot of the map of the Mt Rainier area with longest path from the summit

Top 10 slopes by the vertical drop in the US mainland without Alaska

  1. Rainier Mountain 2861m/9386ft, Washington. map
  2. Folly Peak(San Jacinto) 2305m/7562ft, California. map
  3. Mount Shasta 2098m/6883ft, California. map
  4. Grant Peak(Mt Baker) 2002m/6568ft, Washington. map
  5. McGregor Mountain 1995m/6545ft, Washington. map
  6. Big Devil Peak 1983m/6506ft, Washington. map
  7. Dry Diggins Lookout 1964m/6444ft, Idaho. map
  8. Hurley Peak 1957m/6421ft, Washington. map
  9. American Border Peak 1919m/6296ft, Washington. map
  10. Colonial Peak 1919m/6296ft, Washington. map

Top 10 slopes by the vertical drop in the southern Alaska(up to 60N)

  1. Mount Fairweather 3070m/10072. map
  2. East Crillon 2023m/6637ft. map
  3. Mount Abbe 1797m/5896ft. map
  4. Mount Crillon 1717m/5633ft. map
  5. Sawyer Island 1652m/5420ft. map
  6. Lituya Mountain 1601m/5253ft. map
  7. Mount Orville 1507m/4944ft. map
  8. Mount Cooper 1485m/4872ft. map
  9. Glory Lake 1444m/4738ft. map
  10. Mount Quincy Adams 1199m/3934ft. map

Top 10 slopes by the vertical drop in Canada (up to 60N)

  1. Mount Robson 2490m/8169ft. map
  2. Blackwall Mountain 2232m/7323ft. map
  3. Chutine Peak 2194m/7198ft. map
  4. Mount Bryce 2154m/7067ft. map
  5. Stupendous Mountain 2044m/6706ft. map
  6. Icewall Creek 2009m/6591ft. map
  7. Reliance Mountain 1957m/6421ft. map
  8. Dalgleish Creek 1952m/6404ft. map
  9. Mount Sciron 1949m/6394ft. map
  10. East Toba River 1909m/6263ft. map
Steep slopes distribution by US state (Without Alaska and Islands)

An excel file containing all results is here.

Google Earth is the best option to view result. Here is a KML file containing several thousand of the most prominent slopes across US and Canada. Download and open it in the Google Earth:

Here is a folder containing a collection of the kml files for the USA and Canada.

How it is made

Disclaimer: Some boring stuff below

The Git project: https://github.com/ikanel/SlopesExplorer

I used SqlClient.SqlBulkCopy to import all data from the text file to MSSQL. It is much more faster than using conventional sql commands. Do not forget do disable all indexes prior to mass load. It improves performance a lot.

Next we have to find chunks of the slopes. Adjacent point with proper difference in elevation. Initially I tried to join the table on itself using such query:

select * from Points p1 JOIN Points p2 ON p1.row<>p2.row and p1.[Column]<>p2.[Column] AND p2.row between p1.row-1 and p1.Row+1 and p2.[Column] between p1.[Column]-1 and p1.[Column]+1

However, on table with 36 000 000 records such query has intolerable slow performance. I never had enough patience to wait until it finishes. The simplest solution is always most effective.

I’ve added an additional column with counter to the table with rows,columns and heights. Matrix has a fixed number of rows and columns. So we can use following table to search around the point ID:

ID-6002 ID-6001 ID-6000ID-1  ID  ID+1ID+6000 ID+6001 ID+6002

Using such approach the query became much more effective. Only PK is required to seek the adjacent points.

select * from Points p1 join Points p2 on (p2.id in (p1.id-6000–2,p1.id-6000–1,p1.id-6000,p1.id-1,p1.id+1,p1.id+6000 ,p1.id+6000+1,p1.id+6000+2)) WHERE p1.Elevation-p2.Elevation>X

Now it takes less than 15 minutes to process the whole matrix.

The next step is to join scattered chunks in to the continuous line.

A recursive CTE was initially used to build the lines:

with chains (id,id1,id2,level,parentID,alt)
AS
( select c1.id,c1.id1,c1.id2,0 as level,c1.id as parentID, c1.alt1 as alt from candidates c1 where not exists (select * from candidates c2 where c2.id2=c1.id1) and exists(select * from candidates c2 where c2.id1=c1.id2) UNION ALL select c1.id,c1.id1,c1.id2, level+1 as level,c2.id as parentID,c1.alt2 as alt from candidates c1 join chains c2 on c1.id1=c2.id2 ) select distinct p.*,level,ParentID from chains c1 join candidates c2 on c1.id=c2.id join Points p on p.ID=c2.id1 or p.id=c2.id2

It works perfect for the plain regions, but extremely slow for the mountain areas (BC, Washington, Alaska).

So, I had to replace CTE with simple loop:

INSERT INTO Chunks(id1,id2,parentID,alt,level) SELECT c1.id1,c1.id2,c1.id1, c1.alt1 ,0 FROM candidates c1 WHERE NOT EXISTS (SELECT * FROM candidates c2 WHERE c2.id2=c1.id1)
AND EXISTS(SELECT * FROM candidates c2 WHERE c2.id1=c1.id2)
select @level=max(level) from chunks
WHILE 1=1
BEGIN
INSERT INTO [dbo].chunks ([id1],[id2],[parentID],[alt],[level])
select distinct c.[id1],c.[id2],t.[parentID],c.[alt1],t.[level]+1 from chunks t join Candidates c on c.id1=t.id2 where t.level=@level and not exists (select id1 from chunks tt where tt.id1=c.id1 and tt.id2=c.id2 and tt.level=t.level+1 and tt.parentID=t.parentID)
set @rows=@@rowcount
SET @level=@level+1
if @rows=0 break
else continue
end

Now we have to apply some filtering to get only the best slope for each mountain. We have to find only one point with lowest altitude for each “parent” and select all segments of the line using recursive CTE

WITH res (id1,id2,level,parentID,alt,rt)
AS
(select top 1 id1,id2,level,parentID,alt,1 from Chunks where ParentID=@parentID order by alt asc
UNION ALL
SELECT c1.id1,c1.id2,c1.level,c1.parentID,c1.alt,cast(row_number() OVER (ORDER BY (SELECT 0)) as int)
FROM Chunks c1 INNER JOIN res c2 ON c1.id2=c2.id1 where c1.level=c2.level -1 and c1.parentID=@parentID and c1.alt>c2.alt)
SELECT p.Lat,p.Lng, p.Row,p.Col, p.Elevation as alt,p.ID from points p where id in (select top (@l) id1 from res where rt=1)
union
select * from Points where id=@id

All slopes have been identified at this step. Now we have to name it. We can do it using google maps, but it is not so easy to process thousands of summits.

So, i decided to use GeoNames.com rest service was used for this purpose. It has a couple of very useful services to get name, country and state of any point.

To get the name of the mountain:

http://api.geonames.org/findNearbyJSON?lat=58.907&lng=-137.52&username=demo

To get the country and state where the mountain is located:

http://api.geonames.org/countrySubdivisionJSON?lat=58.907&lng=-137.52&username=demo

Please note, that service throttling request for the free accounts. No more than 2000 requests per hour and 30000 per day.

Export to KML is very easy with SharpKml library. You should create a Placemark object that owns Linestring object containing all points gathered from the previous steps.

--

--