Skip to article frontmatterSkip to article content

Flood areas in Saarland

Visualizing Generalized Flood Areas for HQ100 Event and relate to an existing flooding event.

Simula Research Laboratory
Urban Data Portal Logo

Introduction

Flood areas in Saarland

Saarland, located in southwestern Germany, is particularly vulnerable to flooding due to its dense river network and hilly terrain. Periodic heavy rainfall and overflowing rivers like the Saar and Blies can lead to widespread inundation, especially in low-lying urban and industrial zones. The HQ100 flood areas represent regions statistically likely to flood once every 100 years, serving as critical indicators for urban planning, risk management, and environmental protection. Mapping these zones is essential for identifying vulnerable communities and infrastructure, including industrial facilities that may pose additional environmental risks during extreme flood events.

Purpose

Visualizing Generalized Flood Areas and Environmental Risk Sites in Saarland

This Jupyter notebook provides an interactive visualization of the generalized flood areas (Area100_generalized) associated with a 100-year flood event (HQ100) in Saarland. It integrates spatial data from the Hamburg Urban Data Portal and the Geoportal Saarland, as well as the geolocation of a Wikimedia Commons photo illustrating flood conditions.

🌊 About the HQ100 Flood Area Dataset
  • Event type: HQ100 (statistical 100-year flood)
  • Layer: Area100_generalized
  • Data source: Hamburg Urban Data Portal
  • Coordinate system: WGS84 (EPSG:4326)
  • Date: 01.06.2018
  • Coverage:
    • SW corner: 6.31°E, 49.1°N
    • NE corner: 7.41°E, 49.64°N

This dataset shows flood-prone areas and is useful for planning, disaster risk assessment, and climate adaptation studies.

🏭 IED (IVU) Facilities in Flood-Prone Zones

We additionally integrate data from the Geoportal Saarland on IED-regulated industrial facilities that could pose environmental risks during floods. These facilities are categorized under the EU’s IVU (Integrated Pollution Prevention and Control) directive, which mandates special precautions for pollution control.

  • Dataset: Hochwasserrisiko – IED-Betriebe des Saarlandes
  • Attributes:
    • GEWAESSER: River name
    • BETRIEB: Facility name
    • GEMEINDE, GEMARKUNG: Municipality & land registry info
    • GEWKZ: River code
  • Coordinate system: WGS84
  • Timeliness:
    • Created: 10.07.2012
    • Last updated: 01.06.2018
  • Download options:

License: Creative Commons Attribution 4.0 International (CC BY 4.0)
Attribution: © GDI-SL (2018)
Contact: poststelle@umwelt.saarland.de

📸 Image Location Reference

A geotagged image from Wikimedia Commons showing flood impact is added for visual context. This demonstrates how photo evidence can complement official geospatial data in public awareness or participatory science initiatives.

Requirements

Start installing and importing the necessary libraries

Install Python Packages

pip install geopandas matplotlib pillow

Import Python Packages

import json
import os
from io import BytesIO

import geopandas as gpd
import matplotlib.pyplot as plt
import requests
from jupytergis import GISDocument
from PIL import Image as PILImage

Define functions

def get_data_from_wfs(wfs_url, params):
    try:
        # Fetch data
        r = requests.get(wfs_url, params=params)
        r.raise_for_status()  # Check for HTTP errors

        # Read GML directly into GeoDataFrame
        gml_data = BytesIO(r.content)
        data = gpd.read_file(gml_data, driver="GML")
        return data

    except requests.exceptions.RequestException as e:
        print(f"Request failed: {e}")
    except Exception as e:
        print(f"Failed to parse GML: {e}")
def get_image_metadata(filename):
    gps_lat = None
    gps_lon = None
    extmetadata = None
    image_url = None

    url = "https://commons.wikimedia.org/w/api.php"
    params = {
        "action": "query",
        "titles": f"File:{filename}",
        "prop": "imageinfo",
        "iiprop": "extmetadata|url",
        "format": "json",
    }

    response = requests.get(url, params=params)
    response.raise_for_status()
    data = response.json()

    pages = data.get("query", {}).get("pages", {})
    for page in pages.values():
        imageinfo = page.get("imageinfo", [{}])[0]
        extmetadata = imageinfo.get("extmetadata", {})
        image_url = imageinfo.get("url", None)

        # GPS data if available and convertible
        lat_str = extmetadata.get("GPSLatitude", {}).get("value", None)
        lon_str = extmetadata.get("GPSLongitude", {}).get("value", None)

        gps_lat = float(lat_str) if lat_str else None
        gps_lon = float(lon_str) if lon_str else None

        return gps_lon, gps_lat, extmetadata, image_url
def show_image_from_url(image_url):
    headers = {
        "User-Agent": "MyOpenSourceBot/1.0 (https://example.org/mybot; myemail@example.org)"
    }
    response = requests.get(image_url, headers=headers)
    response.raise_for_status()

    image = PILImage.open(BytesIO(response.content))
    plt.imshow(image)
    plt.axis("off")
    plt.title("Image from Wikimedia Commons")
    plt.show()

Input data required

Set input parameters for getting data

Generalized flood areas in a HQ100 event
  • Data from the Hamburg Urban Data Portal HQ100 Area100 generalized
  • The HQ100 represents the land use of the flooded areas during events. Area100_generalized
  • Timeliness of the data set: 01.06.2018
Flood risk - IED companies in Saarland
# WFS URL for HQ100
wfs_url_hq100: str = (
    "https://geoportal.saarland.de/arcgis/services/Internet/Hochwasser_WFS/MapServer/WFSServer?&request=GetCapabilities&VERSION=1.1.0&SERVICE=WFS"
)

# Feature type
feature_typename_hq100: str = "Hochwasser_WFS:Flaeche100_generalisiert"

# Output file name (Geojson)
filename_hq100: str = "HQ100_Flaeche100_generalisiert_4326.geojson"

# WFS URL for IED
wfs_url_ied: str = (
    "https://geoportal.saarland.de/arcgis/services/Internet/Hochwasser_WFS/MapServer/WFSServer?&request=GetCapabilities&VERSION=1.1.0&SERVICE=WFS"
)

# Feature type
feature_typename_ied: str = "Hochwasser_WFS:Betr_EW"

# Output file name (Geojson)
filename_ied: str = "Hochwasser_WFS_Betr_EW_4326.geojson"

# wikimedia common artefact (picture)
wikimedia_filename: str = "20240517_Flood_Saarland_07.jpg"
wikimedia_artefact_location_filename: str = "artefact_location.geojson"

# JupyterGIS output filename
jupytergis_filename: str = "Saarland_flood_20240517.jGIS"

Get data from the Hamburg Urban Data Portal using WFS

# Specify parameters
params_hq100 = {
    "service": "WFS",
    "request": "GetFeature",
    "typeName": feature_typename_hq100,
}

dset_hq100 = get_data_from_wfs(wfs_url_hq100, params_hq100)
# Specify parameters
params_ied = {
    "service": "WFS",
    "request": "GetFeature",
    "typeName": feature_typename_ied,
}

dset_ied = get_data_from_wfs(wfs_url_ied, params_ied)

Save to geojson with WSG84 (epsg:4326) projection

if os.path.exists(filename_hq100):
    print("Skipped creation: file already exists.")
else:
    dset_hq100.to_crs(4326).to_file(filename_hq100, encoding="utf-8")
if os.path.exists(filename_ied):
    print("Skipped creation: file already exists.")
else:
    dset_ied.to_crs(4326).to_file(filename_ied, encoding="utf-8")

Get location of picture from Wikimedia Commons

gps_lon, gps_lat, all_metadata, image_url = get_image_metadata(wikimedia_filename)

print("Image URL: ", image_url)
print("GPS Coordinates:", gps_lon, gps_lat)
print("metadata:", all_metadata)

Create geojson for picture location

artefact_location = {
    "type": "FeatureCollection",
    "features": [
        {
            "type": "Feature",
            "properties": {
                "id": "camera_location",
                "description": all_metadata["ImageDescription"]["value"],
            },
            "geometry": {"type": "Point", "coordinates": [gps_lon, gps_lat]},
        }
    ],
}

Save geosjon to file

with open(wikimedia_artefact_location_filename, "w") as f:
    json.dump(artefact_location, f)

Show Wikimedia photo

show_image_from_url(image_url)

Create JupyterGIS map

Open Jupyter notebook

doc = GISDocument(
    jupytergis_filename,
    latitude=gps_lat,
    longitude=gps_lon,
    zoom=6,
)
doc

Add basemap layer

doc.add_raster_layer(
    url="https://mt1.google.com/vt/lyrs=y&x={x}&y={y}&z={z}",
    name="Google Satellite",
    attribution="Google",
    opacity=0.6,
)
doc.layers

Add HQ100 Flood Area Layer

doc.add_geojson_layer(
    path=filename_hq100,
    name="HQ100 generalized flood zones",
    color_expr={
        "fill-color": "#00f2ff",
        "stroke-width": 4.25,
        "stroke-color": "#0400ff",
    },
)

Add the locations of companies at risk of flooding in Saarland.

doc.add_geojson_layer(
    path=filename_ied,
    name="Businesses at risk in Saarland",
    type="circle",
    color_expr={
        "circle-radius": 9,
        "circle-stroke-width": 4.25,
        "circle-stroke-color": "#d400ff",
        "circle-fill-color": "#ffb700",
    },
)

Add location of the picture from Wikimedia Commons

doc.add_geojson_layer(
    path=wikimedia_artefact_location_filename,
    name="Artefact Location",
    type="circle",
    color_expr={
        "circle-radius": 10,
        "circle-stroke-width": 5.25,
        "circle-stroke-color": "#ff3700",
        "circle-fill-color": "#fff700",
    },
)