For this yearâs #30DayMapChallenge day one points, I wanted to do something lightweight:
just take one of those never-ending Excel tables that everyone in GIS seems to have lying around and turn it into a map.
No heavy software, no complicated setup â just Python, a cup of coffee, and curiosity.
The starting point
I had this table with road section data, the so called Mauttabelle â IDs, names, coordinates â the usual.
Something like this:
| Abschnitts-ID | Von | Nach | Länge | BundesfernstraĂe | Bundesland | Breite Von | Länge Von | Breite Nach | Länge Nach |
|---|---|---|---|---|---|---|---|---|---|
| 6259 | Heiligenhafen-Ost | Heiligenhafen-Mitte | 3.1 | A1 | SH | 54.36280 | 11.00980 | 54.36110 | 10.96360 |
| 6231 | Heiligenhafen-Mitte | Gremersdorf | 3.8 | A1 | SH | 54.36110 | 10.96360 | 54.33170 | 10.93340 |
The first hiccup
When I first ran the script, Python threw a KeyError for âLänge Vonâ.
I instantly thought: âHa! Must be the Umlaut again.â
But nope. The real reason? The Excel file had a first line describing the dataset version â something like:
Version 157, gĂźltig ab 01.10.2025
A quick detour: Whatâs the Mauttabelle anyway?
If youâre not from Germany, the word âMauttabelleâ probably sounds like something between mathematics and motorways â and honestly, thatâs not too far off.
In short, the Mauttabelle is Germanyâs official toll table for highways (Bundesautobahnen) and major roads (BundesstraĂen).
It lists every road segment where truck tolls apply â including details like:
| Column | Meaning |
|---|---|
| Abschnitts-ID | The unique ID of the road segment |
| Von / Nach | The start and end locations (often junction names or exits) |
| Länge | Length of the segment in kilometers |
| BundesfernstraĂe | The official road number (like âA1â or âB27â) |
| Bundesland | The federal state where the segment is located |
| Breite Von / Länge Von | Coordinates of the segmentâs starting point (latitude/longitude) |
| Breite Nach / Länge Nach | Coordinates of the segmentâs endpoint |
The fixed code
Hereâs the version that worked perfectly â and itâs still just a few lines long.
import pandas as pd
import geopandas as gpd
from shapely.geometry import Point
# file paths
excel_path = "./data.xlsx"
output_geojson = "./points.geojson"
# read the Excel file, skipping the first row with metadata
df = pd.read_excel(excel_path, skiprows=1)
# show the columns so we know whatâs inside
print("Columns: ", df.columns.tolist())
# create a GeoDataFrame using longitude (Länge) and latitude (Breite)
gdf = gpd.GeoDataFrame(
df,
geometry=gpd.points_from_xy(df["Länge Von"], df["Breite Von"]),
crs="EPSG:4326"
)
# export to GeoJSON
gdf.to_file(output_geojson, driver="GeoJSON")
print("success: ", output_geojson)
Quick install reminder
If youâre new to this, make sure you have the right Python packages installed:
pip install pandas geopandas shapely openpyxl
Thatâs it. Now youâve got everything you need to turn an Excel sheet into a map layer.
The best part â seeing it come alive
After running the script, I opened points.geojson in QGIS â
and suddenly all those 137101 lines of Excel data were dots along the major streets in Germany
Itâs such a small thing, but that moment when your table becomes geography⌠thatâs the spark that keeps us all in GIS, isnât it?

Final thoughts
What I love about these small #30DayMapChallenge projects is how they remind me that GIS doesnât have to be heavy or intimidating.
Sometimes itâs just a quick Python script and a bit of data wrangling â and you end up learning something along the way (like, oh, always check for that sneaky first line in Excel files đ
).
So if youâve got some coordinate columns lying around, give it a go.
Turn them into a map.
Youâll be surprised how satisfying it is.