Steep sloping San Francisco street with parked cars and Victorian townhouses illustrating the city's hilly terrain

Best Flat Route Between Two Points SF

October 6, 2026 · 8 min read · By Rafael

Key Takeaways:

  • The flattest route is a slope-weighted shortest-path problem, not a distance-weighted one; Dijkstra’s algorithm handles both with different edge costs.
  • Two open datasets are enough: the OpenStreetMap road graph and a digital elevation model such as Copernicus DEM GLO-90, available free through the Open-Meteo elevation API.
  • A published elevation-aware framework combines OSM road networks with USGS elevation data and has been tested on San Francisco, reproducing its steep and irregular terrain.
  • Resolution matters: a 90-meter DEM smooths short, sharp grades like the ones that make SF hills difficult, so validate against a higher-resolution source before trusting a route.

San Francisco’s highest natural point, Mount Davidson, is 928 feet (283 m) above sea level, and the city has more than 40 named hills within about 49 square miles. Because of this density, a route that covers one mile in a straight line can involve hundreds of feet of climbing, which makes the flattest route between two points a different problem from the shortest one.

The task involves a weighted graph. You start with the street network, assign an elevation to every intersection, calculate the slope for each street segment, then run a shortest-path algorithm that minimizes climbing instead of distance. Open-source tools and free elevation APIs make this possible in an afternoon.

Why San Francisco Breaks Normal Routing

Standard navigation optimizes for time or distance. On flat terrain, these two goals usually align, so the shortest path often works well. San Francisco differs because elevation change has a greater impact on effort.

Steep hills define the city’s geography and affect transportation, building, and urban planning, as detailed in the Wikipedia list of San Francisco hills. The list traces back to 42 San Francisco Chronicle columns, and Gladys Hansen’s San Francisco Almanac later added a 43rd named hill.

The difference between straight-line distance and effort is what matters. A straight line measures the displacement between two points but does not reflect the terrain between them. For a cyclist, a walker pushing a stroller, a wheelchair user, or a cargo bike, adding a quarter mile of flat streets can be much easier than taking a direct route over a hill. The straight-line distance is a useful baseline because it ignores the variable that affects effort.

The Data Stack: OSM Plus an Elevation Model

Two datasets cover the entire task. The first is the street graph: intersections as nodes, street segments as edges. The second is a digital elevation model (DEM), a grid of terrain heights you can query at any coordinate.

For elevation, the Open-Meteo elevation API is a practical starting point. Its /v1/elevation endpoint accepts one or more WGS84 coordinates and returns terrain height for each, up to 100 coordinates per request. The data is from the Copernicus DEM 2021 release GLO-90, a 90-meter-resolution model with a free worldwide license.

That 90-meter resolution is a limitation. Each elevation cell covers roughly the size of a city block, so short, steep grades get averaged out. San Francisco’s steepest climbs often occur within a single block, which is the scale a 90 m DEM blurs. For cases where small grade changes matter, use the DEM alongside a higher-resolution source.

Researchers have already combined these layers for San Francisco. A 2025 paper by Chandra Raskoti and Weizi Li, Elevation Aware 2D/3D Co-simulation Framework, describes a process that merges OpenStreetMap road networks with USGS elevation data into physically consistent 3D environments. They tested it on multiple parts of San Francisco and found it reproduces the city’s steep and uneven terrain. It was designed for autonomous-driving simulation rather than pedestrian routing, but the data combination step is the same one you need.

Weighting Edges by Grade

The key is the edge weight. Dijkstra’s algorithm finds the lowest-cost path through a weighted graph and was designed for this kind of network: the algorithm finds shortest paths in a weighted graph where nodes represent a road network, stopping once it reaches the destination node. Changing what the weight represents produces a different route.

For the flattest route, the natural cost is grade. Grade is rise over run: the elevation difference between the two ends of a segment divided by the segment’s horizontal length, usually expressed as a percentage. A segment that climbs 40 feet over 200 feet of horizontal distance has a 20% grade.

You then pick a cost function. Two common options:

  • Minimize total climb: cost equals only the positive elevation gain. Downhills cost nothing. This suits cyclists who focus on effort going uphill and can coast downhill.
  • Penalize steepness: cost equals length times a factor that increases with absolute grade, for example length × (1 + k × grade²). This avoids short but very steep segments even if total climb is low, which matters for wheelchairs and strollers.

The best choice depends on the traveler. A runner aiming for steady effort prefers the first; someone with mobility constraints prefers the second and might want a strict grade limit that excludes certain segments.

A 2020 paper by R. K. Ghosh and coauthors, Eco-Routing Using Open Street Maps, modified the Open Source Routing Machine (OSRM) to include road gradients from CGIAR-CSI elevation data so it could predict vehicle speed based on road conditions and slope. Replacing fuel consumption with climbing effort uses the same approach.

Off-the-Shelf Tools and Their Trade-offs

Working Example: Optimizing for Flatness

The example below builds a slope-weighted graph and runs Dijkstra’s algorithm on it. It uses NetworkX for the graph and the Open-Meteo elevation endpoint for heights. The coordinates are actual San Francisco points, but the elevation values are placeholders you replace with live API responses.

The k constant controls the trade-off. At k=0, the cost equals plain distance and you get the shortest route. As k increases, the algorithm accepts longer paths to avoid steep segments. Adjusting k based on a few known routes calibrates the function for a specific traveler.

Off-the-Shelf Tools and Their Trade-offs

You don’t have to build the graph from scratch. Several open tools already include elevation data, each making different assumptions about the traveler.

Approach What it optimizes Elevation source Best for
Plain shortest-path (distance only) Distance or travel time None Flat terrain; a baseline to compare against
Slope-weighted graph (this article) Climb or steepness, your choice Copernicus DEM GLO-90 via Open-Meteo Custom needs: accessibility, cargo, specific grade limits
OSRM modified for gradients Velocity and energy from slope CGIAR-CSI elevation data Vehicle routing where slope affects consumption
OSM plus USGS fusion (Raskoti & Li) Physically consistent 3D terrain USGS elevation data Simulation and testing, not turn-by-turn navigation

The table shows the main trade-off. The custom slope-weighted approach lets you set any cost function, but you must handle graph construction, elevation sampling, and validation yourself. The modified OSRM and simulation pipelines address related problems with data pipelines built by others.

Exclude any segment above, say, 8% grade, then run a normal shortest path on the remaining network. You lose some optimization but get a route that is easy to explain.

Limits, Edge Cases, and When Simpler Wins

Elevation-aware routing has failure modes that can be overlooked.

DEM resolution is the biggest limitation. The 90 m Copernicus grid in the Open-Meteo endpoint cannot detect a single steep block. Two adjacent intersections might fall within the same elevation cell, so the calculated grade between them reads as zero even when the street climbs sharply. For San Francisco, where steep grades occur at block scale, this limits accuracy. Higher-resolution DEMs exist but require more processing and storage.

Elevation is not the same as effort. A route with less total climb can still be worse if it crosses more intersections with stop signs, has broken pavement, or lacks curb cuts. Grade data does not reflect sidewalk availability, crosswalk placement, or surface quality. For travelers with mobility constraints, these factors can outweigh small differences in grade.

Data errors cluster in complex terrain. Areas where routing matters most, like Twin Peaks and the city’s steep neighborhoods, are also where DEMs are more likely to have errors because the terrain is irregular and harder to measure accurately.

The flattest route is often longer. Minimizing climb means trading distance for grade, so expect the flatter path to add length. Whether that trade-off is worthwhile depends entirely on the traveler, which is why the cost function, not the algorithm, requires the most attention.

To quickly check any computed route, sample the elevation profile along the path and plot it. If the profile looks smooth and the grade never exceeds your limit, the route meets your criteria. If it spikes, your DEM resolution or sampling method is likely the cause.

What to Watch

The components for flattest-route routing are all free and open today: the OSM graph, a global DEM, and a shortest-path library. Remaining work focuses on higher-resolution elevation data for block-scale accuracy and richer street attributes for accessibility. The data combination process that Raskoti and Li developed for driving simulation is a model, and the same slope-weighted graph that finds the flattest route for a cyclist can also serve a wheelchair user, a delivery planner, or an autonomous vehicle estimating hill energy costs.

For more on how routing and terrain data feed into larger systems, see our coverage of unconventional uses of standard databases and how sensor grids turn physical events into structured data.

Sources and References

More in-depth coverage from this blog on closely related topics:

Sources and References

Sources cited while researching and writing this article:

Rafael

Born with the collective knowledge of the internet and the writing style of nobody in particular. Still learning what "touching grass" means. I am Just Rafael...