Getting administrative boundaries from Open Street Map (OSM) using PyOsmium

Maksym Kozlenko 🇺🇦
3 min readApr 26, 2022

--

Country administrative boundaries play an important role for geospatial data analysis and visualisation. Lots of countries, like Australia, made this data available for download for free.

But what you can do if you need it for a country which doesn’t have this data available? Open Street Map (OSM) is an answer. This community maintained map covers the whole planet and allows you to download data and use it.

As described in my previous post, data could be loaded for a single country or whole continent from Geofabrik.de. I will use Ukraine, the country where I was born, as an example.

Administrative boundaries on OSM

Let’s have a look at the definition for OSM relation with ID 60199 for Ukraine at https://www.openstreetmap.org/relation/60199

Ukraine administrative boundary on OSM

Each relation on OSM has a unique ID and number of tags. Tags describe this object. For example it’s type “boundary” = “administrative” and “admin_level”=”2". 2 is the “country” level used in OSM. Within each country, the administrative level hierarchy could be different. In the case of Ukraine, the next admin_level, which contains its regions is level 4.

Kyiv Oblast (Kyiv region) is Level 4 admin area and has Relation ID 7122 https://www.openstreetmap.org/relation/71248

Kyiv region relation in OSM

Processing data

We will process data from file ukraine-latest.osm.pbf downloaded from http://download.geofabrik.de/europe/ukraine.html

Install osmium using pip

pip install osmium

AdminAreaHandler adds all areas having the tag “admin_level” to an array of dict objects containing ID, geometry and all tags.

Next step is to create GeoDataFrame containing these areas

Result looks like this:

Geo column contains admin area geometry as MULTIPOLYGON.

As you can see results contain administrative areas not only from Ukraine, but also from neighbouring countries. So we can filter areas located within the Ukraine country boundary by using the GeoPandas within() method which checks if area geometry is located inside the country border.

in_ukraine = gdf.within(gdf[gdf.admin_level == "2"].geo.iloc[0])

Now we can plot Ukraine regions with their name in English

Ukraine’s regions with admin_level=4 with coastal waters and with coastal waters removed

Plotting other administrative area levels, for example Level 7, is also possible with minor code changes:

Ukraine’s regions with admin_level=7

Finally you can save administrative boundaries data as a CSV file:

gdf.to_csv("ukraine_admin_boundaries.csv")

Complete code example with OSM data file is available on Kaggle.

UPDATE: I’ve modified code example on Kaggle to remove coastal waters using areas with tag “place” = “sea”, so it matches coast line.

Check also:
Extracting Open Street Map (OSM) street data from data files using PyOsmium

--

--

Maksym Kozlenko 🇺🇦
Maksym Kozlenko 🇺🇦

Responses (1)