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

Google AI Education track image

Build Apps with Google AI Studio 🧱

This track will guide you through Google AI Studio's new "Build apps with Gemini" feature, where you can turn a simple text prompt into a fully functional, deployed web application in minutes.

Read more →

Top comments (0)

Feature flag article image

Create a feature flag in your IDE in 5 minutes with LaunchDarkly’s MCP server 🏁

How to create, evaluate, and modify flags from within your IDE or AI client using natural language with LaunchDarkly's new MCP server. Follow along with this tutorial for step by step instructions.

Read full post