Learning Journey - Creating Custom Map Style from OSM Data in QGIS
Posted by Mlvln on 26 March 2026 in English. Last updated on 27 March 2026.This text was written by me a couple weeks ago. In the mean time I noticed that my computer struggles with the amount of data to process. That’s why I will need to use another way how to create my map. Anyway, I did not want to scrap this diary entry. I learned already a lot of things and maybe you are curious about my map, so here it is:
Like this or similar could the map look like. This mock-up was made with the QGIS GUI and OSM data downloaded over the overpass api. bigger resolution here
In this diary post, I want to show you what I am currently working on in my free time, what my motivations and inspirations were for starting the project, and what problems I have encountered. I also want to share what I have learned and what I plan to do with the project in the future.
I was inspired by the map Straßenraumkarte by Supaplex030, which shows micromapping in the urban area of Berlin-Neukölln in great detail. The map visualizes a wide range of different OSM elements such as trees, advertising columns, manhole covers, parking lots, pedestrian and bike paths, Stolpersteine, as well as lanes and their markings.
Unfortunately, the Straßenraumkarte has not been updated in a while. Supaplex030 is currently working on a new version that covers all of Berlin but has not yet been released. Therefore, I thought I would try to render the tags I am interested in myself.
Looking at the map gives me good feedback on whether I have worked correctly or if important tags are still missing, such as the specification of the surface=.
In the upper right corner next to the e-scooter parking lot, the asphalt area is not rendered correctly (the white map background is shining through). The roadway area shown here in light red is missing a surface specification in OSM.
Details such as roadway markings, manhole covers, and trash bins (evaluates colour= and operator=)
So far, I have created the map using Overpass API queries for my neighborhood. However, I want to render the entire city of Berlin. I also aim to reduce my dependency on Overpass, as the servers are overloaded by scrapers. This has opened up a new learning opportunity for me to process OSM extracts (.osm.pbf files).
I started with the roadway areas. After downloading the OSM extract for Berlin from the Geofabrik download server, I run a Python script that saves all objects with the key area:highway into a new file using an Osmose command. I then import this file with another Python script into QGIS and process it there in a semi-automated manner.
Before I can further process the data from the extract as I am used to from the data downloaded via Overpass, I need to use the QGIS tool “Explode Hstore Field.” This tool converts the column other_tags, in which many OSM tags are stored as comma-separated list entries, into separate fields in the attribute table. I’m not so sure why the data is stored like this, if this is a general osm-extract thing or if it’s only like this with the extracts from geofabrik, but I was happy that I could find a solution quickly by searching on the internet.
before:
| area:highway | other tags |
|---|---|
| residential | “surface”=>”sett”,… |
| secondary | “surface”=>”asphalt”,”junction”=>”yes”,… |
| … | … |
after:
| area:highway | surface | junction | … |
|---|---|---|---|
| residential | sett | NULL | … |
| secondary | asphalt | yes | … |
| … | … | … | … |
In addition to a few other edits, I can already apply my styling (QGIS Layer Style File QML) from the mock up to the highway areas using a script.
All highway areas for Berlin, often still without surface tags. The blue rectangle roughly indicates the previous bounding box of my mock-up map.
I am curious whether my computer will cope with importing more and more data for the entire city into QGIS. The feature count for the area:highway objects is already just below 15,000. The count for other objects will be significantly higher. Fortunately, the data already comes as spatially indexed, which greatly speeds up the processing and display of the objects.
If everything goes as I imagine, I would like to evaluate additional objects that have not yet been rendered in my mock-up and add rules for displaying features only at specific zoom levels. Regular updates of the data should not be too complicated; I will just need to run the Python scripts. Ultimately, I will render tiles of the map. I hope then to find support for hosting and publishing the map, as this is something I have never done and not even an idea where to begin.
Preview: Area around Kottbusser Tor. It renders the subway-platforms on different layers and displays the ref of the subway entrances
Addendum: As written above. I will need to find a better way. Supaplex030 recommended that I take a look at osm2pgsql and PostGIS. Fortunately I just watched todays presentation Setup and update of an OSM-based map with osm2pgsql (on media.ccc.de; German language only) from Mathias Gröbe at FOSSGIS 2026 conference, so I have a good overview where to start.
Discussion
Comment from tordans on 28 March 2026 at 05:20
Thank you for sharing. The style that we see in your screenshots is compatible with what you could create with Maplibre. One way to set this up could be to transform you data to a pmtiles (https://docs.protomaps.com/pmtiles/) – you could use tippecanoe (https://github.com/felt/tippecanoe) – and create a small web page that renders your demo map. You can then create a map style based on this data that renders the map on this demo page. Happy to help with the last part at our next hackathon osm.wiki/Berlin_Hack_Weekend_April_2026 :-)
Comment from Mlvln on 28 March 2026 at 16:03
Thank you tordans for your recommendations! I will take a look into maplibre. Sadly I’m not able to participate in the next hackathon.