Openstreetmap verwenden

notizen linux geodata

Wie kann ich mir die Daten von OpenStreetMap "spiegeln" und sie als lokalen Kartendienst oder für sonstige Zwecke nutzen?

Teil1 - Openstreetmap-Daten laden und einspielen

Openstreetmap-Daten können von verschiedenen Quellen bezogen werden, unter anderem von https://download.geofabrik.de. Hier beispielsweise die Daten von Europa im osm.pbf-Format herunterladen. Als nächstes wird eine PostgreSQL-Datenbank mit der PostGIS-Erweiterung benötigt, sowie das Import-Tool osm2pgsql: sudo apt install osm2pgsql postgresql-16 postgis osmium-tool postgresql-pgrouting osm2pgrouting postgresql-16-ogr-fdw.

Als nächstes ist die Postgres-Datenbank einzurichten, also als postgres-admin einmal alles herrichten: sudo -u postgres psql

CREATE DATABASE gisdb;

\connect gisdb;

CREATE EXTENSION postgis;
CREATE EXTENSION postgis_raster;
CREATE EXTENSION postgis_topology;
CREATE EXTENSION ogr_fdw;
CREATE EXTENSION hstore;

CREATE USER osm WITH PASSWORD 'osm';
GRANT ALL PRIVILEGES ON DATABASE gisdb TO osm;
ALTER DATABASE gisdb OWNER TO osm;

Dies legt eine Datenbank "gisdb" an, fügt dieser die erforderlichen Erweiterungen hinzu und legt zum Schluss noch einen Nutzer mit entsprechenden Berechtigungen auf der Datenbank an, mit dem dann im Weiteren gearbeitet werden kann.

Im Nächsten schritt können dann die heruntergeladenen osm.pbf-Dateien importiert werden: osm2pgsql -U osm -W -H localhost -d gisdb -s -G -K --hstore-all --hstore-add-index --number-processes 20 -C 20480 iceland-latest.osm.pbf

Hierbei sind -U osm -W -H localhost -d gisdb die Verbindungsparameter für die Datenbank (User, nach Passwort fragen, Host, Datenbankname). Im Weiteren sind die Importoptionen gelistet: -s für "slim", um temporäre Daten in der Datenbank statt im Hauptspeicher zu halten (besonders bei großen Importen sinnvoll), -G erzeugt Multipolygone (d.h. Geometrien die zum gleichen Objekt gehören werden auch zusammenhängend gespeichert), -K behält die Küstenlinien bei, die hstore-Optionen speichern alle Tags in einzelnen Spalten und erzeugen einen Index hierfür und zum Schluss noch die Anzahl der parallelen Prozesse und der zu verwendende Speicher.

Will man nach dem ersten Import noch weitere osm.pbf-Dateien in die gleiche Datenbank importieren, dann muss noch -a (für append) als Flag hinzugefügt werden, da sonst die bestehenden Daten überschrieben werden: osm2pgsql -U osm -W -H localhost -d gisdb -s -G -K --hstore-all --hstore-add-index --number-processes 20 -C 20480 -a sweden-latest.osm.pbf

Sollte beim Import ein Fehler der Art FATAL: remaining connection slots are reserved for roles with the SUPERUSER attribute auftreten, so ist der Parameter max_connections in der /etc/postgresql/16/main/postgresql.conf zu erhöhen und postgres neuzustarten.

Teil2 - Die importierten Daten in QGIS darstellen

Ein gutes Tool, um mit Kartendaten zu arbeiten ist QGIS: sudo apt install qgis

Grundlegendes Einbinden der PostGIS-Layer

Layer -> Layer hinzufügen -> PostGIS-Layer auswählen und zunächst eine neue Datenbankverbindung zur (lokalen) Postgres-Datenbank anlegen. Anschließend sich zur Datenbank verbinden und es sollten mehrere Tabellen (planet_osm_line, planet_osm_point, planet_osm_polygon und planet_osm_roads) zur Auswahl stehen, die alle zum Projekt hinzugefügt werden können. Das Ergebnis ist dann zwar sehr detailreich, aber wenig schön.

Die Daten in QGIS in "schön" darstellen, wie auf OpenStreetMap

Hierzu können die folgenden Styledateien verwendet werden: https://github.com/rajo/Beautiful_OSM_in_QGIS. Herunterladen und entpacken, die qml-Dateien werden im Folgenden benötigt.

Damit es zunächst etwas flüssiger geht, ggf. die Option "Zeichnen" rechts unten in der Fußzeile von QGIS deaktivieren.

Als erstes einmal die Hintergrundfarbe auf "Meer" setzen, hierzu in Projekt -> Projekteigenschaften -> Allgemein die Hintergrundfarbe auf #b2ddf2 setzen und mit OK bestätigen.

Ländergrenzen hinzufügen

Die Grenzen aller Länder der Erde können vorgefertigt hier heruntergeladen werden: https://osmdata.openstreetmap.de/data/land-polygons.html Es gibt zum einen alle Länder "am Stück": https://osmdata.openstreetmap.de/download/land-polygons-complete-4326.zip oder in Kacheln aufgeteilt: https://osmdata.openstreetmap.de/download/land-polygons-split-4326.zip Ich habe die land-polygons-complete verwendet. Hierzu die Datei entpacken und über Layer -> Layer hinzufügen -> Vektorlayer die land_polygons.shp Datein hinzufügen. Als nächstes links unten auf den neuen Layer "land_polygons" doppelklicken und im Reiter "Symbolisierung" (sollte standardmäßig direkt angezeigt werden) unten auf Stil -> Lade Stil... klicken und als Datei land.qml aus dem o.g. github verwenden. Stil laden und mit OK bestätigen.

Die Daten aus PostGIS hinzufügen

Wie oben beschrieben, sich zur Datenbank verbinden und die folgenden PostGIS-Layer hinzufügen (sofern nicht schon geschehen). Die Layer sollten nun in der folgenden Reihenfolge angeordnet werden, damit die Karte nachher korrekt dargestellt wird:

  • planet_osm_roads
  • planet_osm_point
  • planet_osm_line
  • planet_osm_polygon
  • land_polygons
Stile hinzufügen

Genau wie bei land_polygons nun auch hier jeden Layer doppelklicken und für jeden Layer die jeweils gleichlautende qml-Datei laden und anwenden.

Nationalparks

Was der Karte noch fehlt sind Nationalparks. Hierzu im Menu Datenbank -> DB-Verwaltung -> PostGIS -> (Datenbankname wie er in QGIS angelegt wurde) auswählen und mit F2 das SQL-Fenster öffnen. Hier folgendes eingeben:

with "dumped_polygonised" as (
    SELECT "polygonised"."name" as "name", "polygonised"."boundary" as "boundary", (ST_Dump("polygonised"."polycoll"))."geom" As "polygon_geom" FROM (
        SELECT string_agg(distinct "name",' ') as "name", "boundary", ST_Polygonize("way") as "polycoll"
        FROM "planet_osm_line"
        WHERE "boundary" = 'national_park' and "highway" IS NULL group by "osm_id","boundary"
    ) as "polygonised"
)
SELECT row_number() over(order by "name") as "id", "name", "boundary", ST_Multi(ST_Collect("polygon_geom")) as "polygon_geom_multi"
FROM "dumped_polygonised"
GROUP BY "name", "boundary"
  • Ausführen
  • "Als neuen Layer laden" auswählen
  • "Spalte(n) mit eindeutigen Werten" auswählen und "id" wählen
  • Als Geometriesplate “polygon_geom_multi” auswählen
  • Einen Layernamen, z.B. “osm_polygons_from_lines” vergeben.
  • Laden

Anschließend das Datenbankfenster schließen. Dem neuen Layer dann noch einen Stil zuweisen, hier osm_polygons_from_lines.qml wählen und den Layer in die korrekte Reihenfolge bringen unterhalb von planet_osm_line.

Zum Schluss nochmals in der Fußzeile von QGIS "Zeichnen" anwählen, so dass die Layer nun auch sichtbar werden.

Quellen

https://www.cybertec-postgresql.com/en/open-street-map-to-postgis-the-basics/ https://trac.osgeo.org/postgis/wiki/UsersWikiPostGIS3UbuntuPGSQLApt https://github.com/yannos/Beautiful_OSM_in_QGIS

Vorheriger Beitrag Nächster Beitrag