Finding streets that are really steps with OSMnx
Posted by alan_gr on 8 August 2025 in English. Last updated on 17 August 2025.
This image shows the Maqueda barrio in Malaga, with streets colour-coded by estimated gradient. The flat area to the east shows up with cold colours, while the western part of the barrio, which straddles a ridge, generally has warmer colours. But why did I make this map, and what does it have to do with “streets that are really steps”?
In my wanderings around the city of Malaga, I have often come across flights of steps that are not tagged as https://wiki.openstreetmap.org/wiki/Tag:highway=steps in OpenStreetMap. Usually they are tagged as residential or footway, with misleading results for anyone using OSM-based maps or routers to find their way around the city.
Whenever this happened, I always felt there should be some more systematic way of finding these mistaggings, or at least identifying suspicious cases worth checking out. But I struggled to think of a way of doing so. Usually these are officially named streets that don’t stand out from the rest of the street network. And steps are not always obvious from aerial imagery (probably one reason they were not tagged as steps in the first place).
When I posted about this on Mastodon, somebody suggested using local elevation data to estimate street gradients. At first I felt this was way beyond my abilities. But a bit of searching led me to the OSMnx Python package, which makes it relatively easy to download a street network and calculate gradients. And I found that the official Spanish mapping body, the IGN, makes available high-resolution digital terrain model files.
After some experimentation (and distracting myself by investigating Malaga’s highest bus stops), I was able to generate the map of Maqueda shown above. (Incidentally I picked Maqueda out of curiosity. I had never been there, and until these steep gradients started showing up in my analysis, I assumed it was part of the flat plain of the Guadalhorce valley). I then narrowed the focus to street segments with a gradient above 15%, distinguishing between those already tagged as steps and all other highway types. I also separated non-steps with any kind of incline tag, as I found these have reliably been tagged following an in-person survey and can be safely assumed not to be steps.

The popup in the image shows a street tagged as an ordinary footway. Overlaying this on aerial imagery, I was fairly sure the entire street should be tagged as steps. Visiting the area just to make sure, my suspicion was correct.

Many of the streets identified by this approach are genuine footways or residential streets - gradients above 15% are not unusual in the hilly parts of the city. And some apparently high gradients are accidents of the estimation process, especially for short street segments. But I think it is genuinely useful as a way of flagging streets for further investigaton.
Using the GeoJSON file of “streets worth checking” generated by the Python script, I have now created a uMap showing steep streets in all of the city’s barrios, which I can refer to whenever I find myself in a neighbourhood that might have mistagged steps. I also downloaded the “streets that are not steps” layer from the uMap to my phone as a GPX file, and imported it to OSMAnd to make these streets even easier to find.
Yet another option, which I discovered thanks to a Mastodon thread on this topic, is to load the GeoJSON file directly into the SCEE app, where the steps in Maqueda mentioned above show up as in this screenshot:

The Python code I used is in this Codeberg repository.
Credits
- Street data copyright OpenStreetMap contributors (naturally!)
- Elevation data derived from digital terrain model files provided by the IGN (MDT02-cob2 2015-2021 CC-BY 4.0)
- Elevation calculations using the OSMnx Python package, adapted from the excellent Examples Gallery, especially Example 12.
- There is more information about OSMnx in this paper: Boeing, G. (2025). Modeling and Analyzing Urban Networks and Amenities with OSMnx. Geographical Analysis, published online ahead of print. doi:10.1111/gean.70009
Discussion
Comment from chris_debian on 8 August 2025 at 20:44
Alan,
You mentioned SCEE, and I wonder whether StreetComplete or SCEE could be more formally used. Could you engage with the StreetComplete community, to see whether it would be possible to create a Quest to improve the map based on your good work?
For example, for highlighted areas, like the SCEE import, the quest could ask “This appears to be a steep gradient, are there steps here?”
Just an idea.
Well done,
Chris
Comment from alan_gr on 8 August 2025 at 21:19
Hi Chris
Thanks for the comments.
I have had some interaction with the StreetComplete account on Mastodon on this topic. In fact that’s who suggested loading the GeoJSON into SCEE - I was only familiar with vanilla SC and didn’t know that was possible until that conversation.
In generaI I’m not sure if this approach is really scalable. One thing I mentioned in the repository documentation, but not here, is that my initial experiments with generic global elevation models weren’t very successful at discriminating elevation changes over short distances. It was only when I switched to the high resolution Spanish national data that I started getting interesting results. I’m not sure how that would translate to a global application.
Alan
Comment from chris_debian on 12 August 2025 at 09:51
Good point, Alan.
I guess there would have to be a minimal acceptable imagery resolution, for a Quest to be available.
Thanks,
Chris