Nominatim ist ein Open-Source Geocoder für OpenStreetMap-Daten (OSM). Das System kann Orts-, Straßen- und Adressangaben in Koordinaten umwandeln (Geocoding) und umgekehrt aus Koordinaten eine möglichst passende Adresse ableiten (Reverse Geocoding). Nominatim indiziert OSM Daten für Suchanfragen. Dabei werden Namen, Adressen, administrative Grenzen und weitere OSM-Merkmale verarbeitet, damit Suchbegriffe effizient in räumliche Treffer übersetzt werden können. Für Reverse Geocoding erzeugt Nominatim synthetische Adressen auf Basis der umliegenden OSM-Daten. Somit unterstützt Nominatim auch Suchanfragen nach Objekttypen, etwa nach Hotels, Pubs oder Kirchen.
Nominatim wird sowohl als öffentliche Web-API betrieben als auch als Software zur Selbstinstallation angeboten.
Siehe OpenStreetMap
Demo https://nominatim.openstreetmap.org/search?format=jsonv2&q=Stephansplatz
Die Web-API von Nominatim stellt unter anderem folgende Endpunkte bereit: /search, /reverse, /lookup, /status und /details. Der Endpunkt /search dient zur textuellen Suche, /reverse zur Adressauflösung aus Koordinaten und /lookup zur Abfrage anhand von OSM-Objekt-IDs.
Mit /search können freie oder strukturierte Suchanfragen gestellt werden. Nominatim unterstützt sowohl Freitext als auch strukturierte Parameter wie Straße, Stadt oder Postleitzahl. Zusätzlich können bestimmte Begriffe als sogenannte special phrases interpretiert werden, um nach Objekttypen zu suchen.
Beispiel:
https://nominatim.openstreetmap.org/search?q=Stephansplatz+Wien&format=jsonv2
import requests def search_place(query: str, limit: int = 1) -> list[dict]: url = "https://nominatim.openstreetmap.org/search" params = { "q": query, "format": "jsonv2", "limit": limit } headers = { "User-Agent": "mein-technik-wiki-beispiel/1.0 (kontakt@example.org)" } response = requests.get(url, params=params, headers=headers, timeout=10) response.raise_for_status() return response.json() results = search_place("Stephansplatz, Wien") for place in results: print(place["display_name"]) print(place["lat"], place["lon"])
Mit /reverse wird zu einem Koordinatenpaar ein passender OSM-Ort bzw. eine Adresse gesucht.
Beispiel:
https://nominatim.openstreetmap.org/reverse?lat=48.20849&lon=16.37208&format=jsonv2
import requests def reverse_geocode(lat: float, lon: float) -> dict: url = "https://nominatim.openstreetmap.org/reverse" params = { "lat": lat, "lon": lon, "format": "jsonv2", "addressdetails": 1 } headers = { "User-Agent": "mein-dokuwiki/1.0" } response = requests.get(url, params=params, headers=headers, timeout=10) response.raise_for_status() return response.json() result = reverse_geocode(48.20849, 16.37208) print(result["display_name"])
Mit /lookup lassen sich Detailinformationen zu bekannten OSM-Objekten abrufen, wenn deren Objekt-ID vorliegt.
Persistent
docker run -it \ -e PBF_URL=https://download.geofabrik.de/europe/austria-latest.osm.pbf \ -e REPLICATION_URL=https://download.geofabrik.de/europe/austria-updates \ -e IMPORT_STYLE=full \ -p 8080:8080 \ --name nominatim-at \ -v nominatim-data:/var/lib/postgresql/16/main \ mediagis/nominatim:5.2
Non persistent
#!/usr/bin/env bash set -euo pipefail NOM_USER="nominatim" WEB_DB_USER="www-data" NOM_HOME="/srv/nominatim" NOM_VENV="/srv/nominatim-venv" NOM_PROJECT_DIR="/srv/nominatim/project" NOM_PBF_DOWNLOAD="https://download.geofabrik.de/europe/austria-latest.osm.pbf" NOM_PBF_FILE="/home/austria.osm.pbf" IMPORT_THREADS="4" IMPORT_OSM2PGSQL_CACHE="1024" PG_VERSION="16" if [[ "$(id -u)" -ne 0 ]]; then echo "Run this script as root." exit 1 fi if [[ -n "${NOM_PBF_DOWNLOAD}" ]]; then echo "Downloading ${NOM_PBF_DOWNLOAD} to ${NOM_PBF_FILE}" curl -L "$NOM_PBF_DOWNLOAD" -o "$NOM_PBF_FILE" fi if [[ ! -f "${NOM_PBF_FILE}" ]]; then echo "PBF not found: ${NOM_PBF_FILE}" exit 1 fi export DEBIAN_FRONTEND=noninteractive echo "[1/7] Installing packages..." apt-get update apt-get install -y \ postgresql postgresql-contrib postgresql-server-dev-all \ postgis postgresql-${PG_VERSION}-postgis-3 \ osm2pgsql osmium-tool \ build-essential cmake pkg-config git curl wget unzip sudo \ libboost-dev libexpat1-dev zlib1g-dev libbz2-dev libpq-dev libicu-dev \ python3 python3-pip python3-venv python3-dev echo "[2/7] Starting PostgreSQL..." service postgresql start echo "[3/7] Resetting DB roles..." sudo -u postgres dropdb --if-exists nominatim sudo -u postgres dropuser --if-exists "${NOM_USER}" || true sudo -u postgres dropuser --if-exists "${WEB_DB_USER}" || true sudo -u postgres createuser -s "${NOM_USER}" sudo -u postgres createuser "${WEB_DB_USER}" echo "[4/7] Creating Linux user and directories..." id -u "${NOM_USER}" >/dev/null 2>&1 || useradd --system --create-home --home-dir "${NOM_HOME}" --shell /bin/bash "${NOM_USER}" mkdir -p "${NOM_HOME}" "${NOM_PROJECT_DIR}" rm -rf "${NOM_VENV}" python3 -m venv "${NOM_VENV}" chown -R "${NOM_USER}:${NOM_USER}" "${NOM_HOME}" "${NOM_PROJECT_DIR}" "${NOM_VENV}" echo "[5/7] Installing Python packages..." sudo -u "${NOM_USER}" "${NOM_VENV}/bin/pip" install --upgrade pip wheel setuptools sudo -u "${NOM_USER}" "${NOM_VENV}/bin/pip" install \ nominatim-db nominatim-api falcon uvicorn gunicorn osmium echo "[6/7] Writing project environment..." cat > "${NOM_PROJECT_DIR}/.env" <<EOF NOMINATIM_DEFAULT_LANGUAGE=de,en EOF chown "${NOM_USER}:${NOM_USER}" "${NOM_PROJECT_DIR}/.env" chmod 640 "${NOM_PROJECT_DIR}/.env" echo "[7/7] Importing Austria..." sudo -u "${NOM_USER}" "${NOM_VENV}/bin/nominatim" import \ --project-dir "${NOM_PROJECT_DIR}" \ --osm-file "${NOM_PBF_FILE}" \ --threads "${IMPORT_THREADS}" \ --osm2pgsql-cache "${IMPORT_OSM2PGSQL_CACHE}" echo echo "Import finished." echo echo "Start API with:" echo "sudo -u ${NOM_USER} bash -lc 'cd ${NOM_PROJECT_DIR} && ${NOM_VENV}/bin/gunicorn -b 127.0.0.1:8080 -w 2 -k uvicorn.workers.UvicornWorker \"nominatim_api.server.falcon.server:run_wsgi()\"'"