Software-Tipps
Q(GIS)&A – Wie erstelle ich Sichten in einer GeoPackage?
Datenbanken haben sich für die Arbeit mit Vektordaten in einem Desktop-GIS etabliert. Neben den serverbasierten Datenbanken (wie z.B. PostGIS), die insbesondere für die konsistente Datennutzung und -bearbeitung durch mehrere Personen geeignet sind, sollte man auch die dateibasierten Datenbanken wie z.B. GeoPackage und SpatiaLite für die Datenhaltung lokal auf dem Rechner dem Shape-Format auf jeden Fall vorziehen.
Typische Schlagwörter bei der Verwendung von Datenbanken sind z.B. SQL, eine Sprache zur Definition, Abfrage und Bearbeitung von Datenstrukturen, und Sichten (englisch Views). Darunter kann man sich eine Art virtuelle Tabelle vorstellen, die das Ergebnis einer SQL-Abfrage darstellt. Bei einer Sicht werden keine Daten, sondern nur die Abfrage gespeichert - diese wird bei jedem Aufruf neu berechnet. Eine Sicht gibt also immer den aktuellen Datenbestand wieder und aktualisiert sich automatisch, wenn eine der zugrunde liegenden Tabellen bearbeitet wird. Gerade für sehr umfangreiche Datensätze bieten sich Sichten an, um bei Bedarf konsistent mit fest definierten Teilmengen übersichtlich arbeiten zu können.
In QGIS können mit der Kern-Erweiterung DB Manager SQL-Befehle für Datenbanken ausgeführt werden. Die Erstellung von Sichten ist damit auf den ersten Blick einfach möglich: Abfrage der Form SELECT - FROM - WHERE eintragen, auf die Schaltfläche Sicht erstellen klicken, einen Namen vergeben und fertig. Das funktioniert für PostGIS und SpatiaLite - doch bei einer GeoPackage fehlt diese Funktion.
Die Annahme, GeoPackage unterstütze nicht das Prinzip von Sichten und deshalb fehle die Schaltfläche, ist falsch. Räumliche Sichten benötigen jedoch spezielle Einträge in den Metadaten der Datenbank, damit sie reibungslos funktionieren. PostGIS erstellt diese automatisch - GeoPackage leider nicht.
In meinen QGIS-Schulungen empfehle ich als dateibasiertes Datenbankformat dennoch GeoPackage, da in diesem z.B. auch Rasterdaten und QGIS-Projekte gespeichert werden können, was bei SpatiaLite nicht möglich ist. Der Bedarf, möglichst einfach Sichten zu erzeugen, ist für Teilnehmende jedoch ebenfalls ein wichtiges Anliegen und dementsprechend ein Minuspunkt für das Format - jedoch nur scheinbar. In diesem Q(GIS)&A zeige ich, wie ihr auch in einer GeoPackage Sichten erzeugen könnt. Man benötigt dafür ein bisschen Kenntnis über den Aufbau einer GeoPackage, weiterführende SQL-Kenntnisse und etwas Mehraufwand.
Download der Daten
Zur Demonstration verwende ich insbesondere Daten von Natura2000. Ich habe den europaweiten Datensatz der Schutzgebietsflächen auf das Bundesland Sachsen zugeschnitten und gemeinsam mit der dazugehörigen geometrielosen Artentabelle und den Verwaltungsgrenzen auf Kreisebene in eine GeoPackage abgespeichert. Diesen Datensatz könnt ihr hier herunterladen, um meine Beispiele auszuprobieren. Zusätzlich zum Datensatz findet ihr eine Textdatei, in welcher ich die allgemeine Syntax der benötigten SQL-Befehle gesammelt habe. Ich beschreibe sie im Folgenden ausführlich. (Der vollständige Natura2000-Datensatz lässt sich hier frei herunterladen.)
Die DB-Verwaltung
Startet ein leeres QGIS-Projekt und öffnet die DB-Verwaltung (Menü Datenbank). Sollte der Eintrag nicht vorhanden sein, ist vermutlich die Kern-Erweiterung nicht aktiviert - schaut in die Erweiterungsübersicht (Menü Erweiterungen > Erweiterungen verwalten und installieren... > Reiter Installiert) und setzt den Haken bei DB Manager.
In der DB-Verwaltung muss zunächst eine Verbindung zur heruntergeladenen GeoPackage hergestellt werden. Dazu klickt ihr mit der rechten Maustaste auf GeoPackage > Neue Verbindung... und sucht dann die Datei heraus. Ist die Verbindung da, kann die Datei aufgeklappt werden und der Inhalt wird sichtbar. Mit Doppelklick können die Datensätze von hier auch zum Projekt hinzugefügt werden.
Ihr könnt direkt in der DB-Verwaltung auch eine Vorschau eurer Daten erhalten, ohne diese zum QGIS-Projekt hinzufügen zu müssen. Klickt dazu den gewünschten Datensatz mit einem Linksklick an (z.B. "natura2000") und wählt dann den Reiter Tabelle bzw. Vorschau. Gerade der Blick in die Sachdaten wird für uns später noch sehr nützlich sein. Jetzt wechseln wir aber erst einmal in den SQL-Bereich, den ihr mit der 2. Schaltfläche von links (rot umrandet in Abbildung 2) öffnet.
Hier können nun SQL-Befehle geschrieben und ausgeführt werden. Ich starte mit einer ganz einfachen Abfrage:
SELECT *
FROM natura2000
WHERE SITETYPE = 'A'
Wenn ihr die Abfrage einfügt und ausführt, erhaltet ihr als Ergebnis einen Auszug der Tabelle "natura2000" (FROM), in diesem Fall mit allen Spalten (SELECT *) und nur die Einträge, in denen im Attribut "SITETYPE" der Wert "A" steht (WHERE). Damit werden Vogelschutzgebiete gekennzeichnet, 80 davon sind in unserem Datensatz vorhanden.
Um daraus eine räumliche Sicht zu erstellen, ist nun etwas mehr Schreibarbeit notwendig. Zunächst ergänzen wir vor der Abfrage den entsprechenden SQL-Befehl:
CREATE VIEW sicht_vogelschutz AS
SELECT *
FROM natura2000
WHERE SITETYPE = 'A'
Es soll eine Sicht mit dem Namen "sicht_vogelschutz" aus der zuvor getesteten Abfrage erstellt werden. Führt man diesen SQL-Befehl aus, erscheint keine Tabelle - nicht wundern, das ist korrekt so. Solange keine Fehlermeldung erscheint und oberhalb des nun leeren Ergebnisfensters "0 Zeilen, ... Sekunden" steht, hat grundsätzlich alles funktioniert. Die Sicht ist nun erzeugt, jedoch fehlen noch die vorhin angesprochenen speziellen Einträge in die Metadaten, weshalb sie noch nicht nutzbar ist.
Zugriff auf die GeoPackage-Metadaten
Auch wenn die DB-Verwaltung mir nur drei verfügbare Tabellen in meiner GeoPackage anzeigt, sind es doch in Wirklichkeit einige mehr, die im Hintergrund dafür sorgen, dass die Datei funktioniert. Diese Metadaten-Tabellen verstecken sich in QGIS, ihr Inhalt lässt sich aber mit SQL anzeigen und bearbeiten. Wir benötigen zwei dieser Tabellen, um unsere Sicht lauffähig zu machen: gpkg_contents und gpkg_geometry_columns. Schauen wir doch mal in eine dieser Tabellen rein:
SELECT *
FROM gpkg_contents
Wir sehen in dieser Tabelle jeweils einen Eintrag für jeden Datensatz unserer GeoPackage, u.a. mit Namen, dem Zeitpunkt der letzten Änderung, der geometrischen Ausdehnung und dem Koordinatenbezugssystem. Unsere Aufgabe ist nun, einen solchen Eintrag auch für unsere Sicht zu erstellen. Das ist zum Glück nicht kompliziert, denn dafür können wir grundsätzlich den Eintrag der zugrunde liegenden Tabelle - hier also "natura2000" - verwenden. Mit SQL machen wir folgendes:
INSERT INTO gpkg_contents
SELECT 'sicht_vogelschutz', data_type, 'sicht_vogelschutz', '', last_change, min_x, min_y, max_x, max_y, srs_id
FROM gpkg_contents
WHERE table_name='natura2000'
INSERT INTO dient dem Hinzufügen einer neuen Zeile zur dahinter genannten Tabelle. Danach folgt wieder ein SELECT-Befehl. Schaut man sich diesen genauer an, erkennt man, dass wir hauptsächlich den Eintrag von "natura2000" der gleichen Tabelle abfragen - die Werte der Spalten "data_type" sowie von "last_change" bis "srs_id" werden ausgelesen und in den neuen Eintrag übernommen. Ausnahmen sind die Spalten "table_name" und "identifier", in die der Name unserer Sicht eingetragen wird, und die Spalte "description", die hier leer gelassen wird und optional mit Text gefüllt werden kann. Schaut man ein weiteres Mal in die Tabelle, sieht sie nun so aus:
Analog dazu muss das nun auch mit der Tabelle "gpkg_geometry_columns" gemacht werden, dazu lautet der SQL-Befehl:
INSERT INTO gpkg_geometry_columns
SELECT 'sicht_vogelschutz', column_name, geometry_type_name, srs_id, z, m
FROM gpkg_geometry_columns
WHERE table_name='natura2000';
Wenn ihr genau nachvollziehen wollt, was diese beiden Tabellen bewirken, lohnt sich ein Blick in den Standard des GeoPackage-Formats.
Sichtbare Veränderungen
Durch den Eintrag der räumlichen Sicht in die beiden Metadaten-Tabellen ist die Sicht nun einsatzbereit. Falls sie euch in der DB-Verwaltung noch nicht angezeigt wird, muss die GeoPackage dort aktualisiert werden (Rechtsklick auf die Datei > Neu verbinden). Dann sollte in unserem Fall die "sicht_vogelschutz" angezeigt werden und ihr könnt sie in euren QGIS-Projekten verwenden.
Wichtig!
Achtet bei der Verwendung von GeoPackage-Sichten in QGIS auf die folgenden Hinweise:
- Da es kaum ersichtlich ist, ob ein GeoPackage-Layer eine Tabelle oder eine Sicht ist, empfehle ich euch den Namen immer mit "sicht_" zu beginnen.
- Sichten sollen nicht editiert werden - QGIS bietet euch den Bearbeitungsmodus zwar an, beim Abspeichern kann das aber zu Abstürzen führen.
- Bei der Erstellung von Sichten könnt ihr mit SELECT einschränken, welche Spalten der Tabelle in diese übernommen werden - die Primärschlüssel- und Geometriespalte müssen stets dabei sein, damit die Sicht funktioniert (meist fid und geom).
- Solltet ihr eine Sicht wieder löschen wollen, müssen die Einträge aus den beiden Metadaten-Tabellen ebenfalls entfernt werden. (Die allgemeinen SQL-Befehle dafür stehen in der Textdatei, die ihr euch mit dem Beispieldatensatz herunterladen könnt.)
Was ihr nun testen könnt
Editiert den zugrundeliegenden Datensatz und schaut, wie sich beim Abspeichern auch die Sicht aktualisiert. In unserem Beispiel könnt ihr in der Attributtabelle von "natura2000" bei einem Gebiet den "SITETYPE"-Eintrag ändern, nach dem Abspeichern (und einmaligem Neuladen z.B. durch Veränderung des Kartenausschnitts) sollte auch die Sicht diese Änderung anzeigen.
Schöne Aussichten
Für diesen Blogbeitrag habe ich als Beispiel die einfachste Form einer SQL-Abfrage gewählt. Ihr könnt eure SQL-Abfragen jedoch beliebig erweitern, z.B. mit der Verknüpfung mehrerer Datensätze (JOIN) oder der Aggregation von Informationen (GROUP BY). So lassen sich für folgende layerübergreifende Fragestellung in unserem Datensatz weitere Sichten erstellen:
Natura2000-Gebiete, in denen die Fledermausart "Großes Mausohr" vorkommt:
SELECT a.*, b.ISOLATION, b.GLOBAL
FROM natura2000 a JOIN arten b ON a.SITECODE = b.SITECODE
WHERE b.SPECIESNAME = 'Myotis myotis'
Natura2000-Gebiete, die (teilweise) in der Stadt Dresden liegen:
SELECT a.*
FROM natura2000 a JOIN kreise b ON ST_Intersects(a.geom, b.geom)
WHERE b.GEN = 'Dresden'
Je nach Fragestellung muss dabei passend gewählt werden, aus welchen Daten welche Spalten übernommen werden (insbesondere für Primärschlüssel und Geometrie) und welche Tabelle die Grundlage für die Metadaten-Einträge sind.
Fazit
Zusammenfassend lässt sich sagen: mit etwas Mehraufwand lassen sich in einer GeoPackage Sichten erstellen und man muss bei der Arbeit mit diesen ein paar Dinge beachten. Gerade für einfache Abfragen lässt sich aber die allgemeine Syntax der drei dazu erforderlichen SQL-Anweisungen (siehe Textdatei) problemlos verwenden. Ist die Sicht dann korrekt erstellt, kann man sie immer wieder in QGIS-Projekte laden und hat dabei die erforderliche Teilmenge immer auf dem aktuellen Stand und keine Inkonsistenzen innerhalb der Datenbank.
Über den Autor
Steckbrief
Florian Meier wollte immer Mathematik und Geographie lehren, hat aber während seines Lehramtsstudiums die Geoinformatik kennen und lieben gelernt. Deshalb unterrichtet der UNIGIS MSc - Absolvent seit 2020 die Nutzung geographischer Informationssysteme und ist seit 2026 bei der WhereGroup als GIS-Trainer tätig.