DEV Community

Ochwada Linda
Ochwada Linda

Posted on

2 1 1 1 1

Accessing Population Density Data via WFS using Python

Source: https://pixabay.com/photos/ilight-ilightmarine-abstract-2185506/
For geospatial analysis, demographic context is everything. Whether you're building an AI model for urban planning or visualizing accessibility in city neighborhoods, population data is key. In this post, I’ll walk you through how I downloaded Berlin’s population density data (Einwohnerdichte 2023) using the city’s official Geoportal.

We’ll use Python and OWSLib to connect to a WFS (Web Feature Service) and download the data as a GeoJSON file.

Step-by-Step: Python Function to Fetch WFS Data



from owslib.wfs import WebFeatureService
import geopandas as gpd
import os

def download_demography_data(base_url, typename, output_path):
    os.makedirs(os.path.dirname(output_path), exist_ok=True)

    print(f"🌍 Connecting to WFS: {typename}")

    try:
        wfs = WebFeatureService(url=base_url, version="2.0.0")
        response = wfs.getfeature(typename=typename, outputFormat='application/json')

        gdf = gpd.read_file(response)

        if gdf.empty:
            print("No data found.")
        else:
            gdf.to_file(output_path, driver="GeoJSON")
            print(f"Data saved to: {output_path}")

    except Exception as e:
        print(f"Failed to download: {e}")


Enter fullscreen mode Exit fullscreen mode

What’s Happening Here?

WebFeatureService: Establishes a connection to the WFS endpoint.

getfeature: Retrieves the specified layer in GeoJSON format.

GeoPandas: Loads the response and saves it locally.

os.makedirs: Ensures the output directory exists.

WFS URL and Available Layers


if __name__ == '__main__':

url = "https://gdi.berlin.de/services/wfs/ua_einwohnerdichte_2023"
wfs = WebFeatureService(url=url, version="2.0.0")

print("\nAvailable Layers:")
for layer in list(wfs.contents):
    print("🔹", layer)

Enter fullscreen mode Exit fullscreen mode

You’ll see something like:

🔹 ua_einwohnerdichte_2023:einwohnerdichte2023

Downloading the Layer


# In main

# Downloading Berlin's 2023 population density layer
base_url = "https://gdi.berlin.de/services/wfs/ua_einwohnerdichte_2023"
layer = "ua_einwohnerdichte_2023:einwohnerdichte2023"
output_path = "data/berlin_population_density.geojson"

download_demography_data(base_url, layer, output_path)


Enter fullscreen mode Exit fullscreen mode

Why This Matters

This data is incredibly useful for:

  • Urban planning
  • Accessibility mapping
  • Infrastructure development
  • AI/ML models that incorporate population variables

You now have a clean GeoJSON file with up-to-date demographic data, ready for QGIS, Python analysis, or integration into a web map.

👉 More on Blogs
👉 Reach Out

Heroku

Amplify your impact where it matters most — building exceptional apps.

Leave the infrastructure headaches to us, while you focus on pushing boundaries, realizing your vision, and making a lasting impression on your users.

Get Started

Top comments (0)

PulumiUP 2025 image

PulumiUP 2025: Cloud Innovation Starts Here

Get inspired by experts at PulumiUP. Discover the latest in platform engineering, IaC, and DevOps. Keynote, demos, panel, and Q&A with Pulumi engineers.

Register Now

👋 Kindness is contagious

Dive into this informative piece, backed by our vibrant DEV Community

Whether you’re a novice or a pro, your perspective enriches our collective insight.

A simple “thank you” can lift someone’s spirits—share your gratitude in the comments!

On DEV, the power of shared knowledge paves a smoother path and tightens our community ties. Found value here? A quick thanks to the author makes a big impact.

Okay