Posted on

Arbeiten mit QGIS Virtuellen Layern und Geometriegeneratoren

Pipe Dream

In diesem Blogpost möchte ich heute die Arbeit mit Virtuellen Layern und Geometriegeneratoren in QGIS erklären. Dazu möchte ich ein Beispiel aus meiner Praxis aus dem Bereich Waldbestattungen heranziehen, nämlich die Darstellung von Urnenlagen um ein Naturdenkmal. Außerdem mit dabei: SQL, ein bisschen Mathematik und der alte Pythagoras.
Zuallererst gehe ich darauf ein, was eine Urnenlage ist und was das Problem dabei ist. Dann stelle ich die gängige Symbolik zur Darstellung vor, worauf dann die Umsetzung der Symbolik mit virtuellen Layern und Geometriegeneratoren in QGIS folgt.

Waldbestattungen und die Urnenlage

Bestattungen im Wald erfreuen sich immer größerer Beliebtheit. Dabei wird, im Gegensatz zur Bestattung auf dem örtlichen Friedhof, der oder die Verstorbene in einer Urne bei einem Naturmerkmal beigesetzt. So ein Naturmerkmal ist entweder ein Baum, ein Findling oder anderweitig bemerkenswerter Felsen. An einem Naturmerkmal werden im Normalfall 10 oder sogar 12 Personen beigesetzt. Je nach Untergrund oder sonstigen Gegebenheiten sind aber auch weniger Bestattungen möglich. Im Normalfall wird am Naturmerkmal eine Plakette angebracht, eine Kennzeichnung der eigentlichen Begräbnisstätte entfällt aber.
Währen die Lage des Naturmerkmals meistens bekannt ist, wird die Lage der Urne lediglich relativ zum Naturmerkmal erfasst. Dabei wird die Richtung und die Entfernung zum Naturmerkmal erfasst – z.B. 30° und 2m Entfernung. Die kartografische Herausforderung ist es nun, aus den relativen Lageangaben die tatsächliche Lage mit Koordinaten zu berechnen und darzustellen.

Darstellung der Urnenlage

Urnenlage
Darstellung der Urnenlage in Relation zum Naturmerkmal

Als Ausgangsdaten liegt zum einen das Naturmerkmal mit Koordinaten vor, zum anderen eine CSV-Tabelle mit den relativen Lageinformationen der Urnen. Hier liegt in diesem Fall eine 1:n Relation zwischen dem Naturmerkmal und den Urnen vor. Die Darstellung selber ist relativ einfach. Um das Naturmerkmal werden die Lagen der Urnen als Punktsymbol gezeichnet. Dabei verbindet eine Linie die Urnenlage mit dem Naturmerkmal, so dass man ein sternförmiges Symbol erhält. Die Koordinaten der Urnen werden mit Hilfe eines virtuellen Layers und ein bisschen SQL generiert, die Linien werden mittels Geometriegenerator erzeugt.
Eine Sache, der ich noch nachgehen muss: Es ist aus mir unbekannten Gründen nicht möglich, die Urnenlagen mit dem Abfragewerkzeug abzufragen (QGIS Version 2.18.15 unter Windows), obwohl die Attributtabelle alle Werte darstellt. Das ist sicherlich eine weitere Untersuchung wert, unter Umständen lässt sich dieser Mangel auch mit virtuellen Layern von GDAL beheben.

Virtuellen Layer anlegen

Die Datengrundlage für diesen Blogpost ist relativ einfach. Es gibt das Naturmerkmal mit einer – in diesem Fall – beliebigen Koordinate mit einem Rechts- und einem Hochwert und eine Tabelle im CSV-Format mit den Urnenlagen.

Name Entfernung Richtung nd_id
Urne 1 120 10 1
Urne 2 80 55 1
Urne 3 70 80 1
Urne 4 150 135 1
Urne 5 130 170 1
Urne 6 90 200 1
Urne 7 110 290 1
Urne 8 140 330 1
Tabelle der Urnen 1-8 mit Lageinformationen

Bevor es aber ans Anlegen geht, muss erst einmal die Methode zur Berechnung der Lage der Urnen festgelegt werden.

Winkel und Pythagoras

Das hier vorliegende Problem ist ja, dass man ausgehend von einer bekannten Lage eine neue Lage mit Hilfe von Richtung und Distanz projizieren muss. Das Verfahren ist auch bekannt als Wegpunkt-Projektion und findet unter anderem Anwendung bei Geocaching. In unserem Fall können wir aber einige Vereinfachungen heranziehen. Da die Distanzen ziemlich klein sind, fallen Faktoren wie die Erdkrümmung weg. Auch liegt das Naturmerkmal in einem kartesischen Koordinatensystem vor, in diesem Falle Gauß-Krüger. Für die Berechnung bedeutet das, das wir wie in der Schule mit einem einfachen, kartesischen Koordinatensystem rechnen können. Das erlaubt uns auch, den Satz des Pythagoras und Winkelfunktionen wie Sinus und Kosinus zu benutzen, da hier im Endeffekt ein rechtwinkliges Dreieck vorliegt. Hier interessiert uns die Länge der Ankathete und der Gegenkathete, wobei die Ankathete dem Rechtswert zugerechnet werden muss und die Länge der Gegenkathete dem Hochwert des Naturmerkmals. Die Hypotenuse ist bekannt und entspricht der Distanz von Naturmerkmal zur Urne, ebenso wie der Winkel.
Um es einmal etwas mathematischer zu formulieren: Ausgehend von dem Punkt P₁(x₁,y₁) – dem Naturmerkmal – lässt sich P₂(x₂,y₂) – die Urnenlage – mit Hilfe der Hypotenuse n – der Distanz – und dem Winkel θ wie folgt rechnen:

x₂ = x₁ + n *  cosθ
y₂ = y₁ + n * sinθ

Das folgende Diagramm erläutert die Sachlage noch einmal grafisch:

Winkeldiagramm
Schema zur Berechnung eines neuen Punktes P2 aus P1, Richtung und Distanz

Der virtuelle Layer

Nach diesem kleinen Ausflug in die Schulvergangenheit geht es nun ans Anlegen des virtuellen Layers. Wie bereits erwähnt, besteht ein 1:n Zusammenhang zwischen dem Naturmerkmal und den zugehörigen Urnenlagen. Der Dialog zum Hinzufügen eines virtuellen Layers erwartet zum einen die Quell-Layer, aus denen der virtuelle Layer erzeugt werden soll. Und zum anderen eine SQL-Abfrage, die den virtuellen Layer aus den Quell-Layern erzeugt.

Quell-Layer
Hinzufügen der Quell-Layer “ND” und “urnenlage”

Die Quell-Layer sind schnell hinzugefügt, nun geht es an den Aufbau der SQL-Abfrage. Der Layer mit dem Naturdenkmal heißt ND, die (importierte) CSV-Tabelle urnenlage. Ziel der Abfrage ist es, den Urnenlagen eine eigene Punktkoordinate und für die Visualisierung die Koordinaten des Naturmerkmals mitzugeben.
Als erstes führen wir mit einem JOIN die beiden Layer zusammen und erhalten eine Abfrage, die eine ID und einen Namen der Urne zurückgibt:

SELECT
    ul.rowid AS id,
    ul.name
FROM urnenlage AS ul
JOIN ND AS nd on nd.id = ul.nd_id

SQL-Funktionen

Um die Urnenlage zu bestimmen, sind ein paar extra Befehle notwendig, die ich im Folgenden erläutern werde. Mit den Kommandos ST_X() und ST_Y() kann man die Rechts- und Hochwerte einer Punktkoordinate extrahieren. Wir benutzen die beiden Befehle auf der Punktkoordinate des Naturdenkmals. Der SQL-Befehl sieht dann folgendermaßen aus:

SELECT
    ul.rowid AS id,
    ul.name,
    ST_X(nd.geometry) AS x,
    ST_Y(nd.geometry) AS y
FROM urnenlage AS ul
JOIN ND AS nd on nd.id = ul.nd_id

Als nächstes setzen wir die oben genannten Formeln zur Berechnung der Urnenlage ein. Dazu benötigen wir die Funktionen COS() und SIN(), RADIANS() und MakePoint() zur Erzeugung einer Punktgeometrie. Wir müssen, bevor wir sin und cos anwenden können, die Richtungsangaben nach Radiant konvertieren. Denn die Winkelfunktionen in QGIS erwarten Radiant-Werte und nicht die klassischen, auf 360° basierenden Werte. Zu beachten ist weiterhin, dass die Entfernung in cm angegeben ist und in die Einheiten des Koordinatensystems, hier Meter, konvertiert werden müssen. Den neuen Rechtswert ermitteln wir also mit

ST_X(nd.geometry) + (COS(RADIANS(ul.richtung)) * (ul.entfernung / 100.0))

der neue Hochwert ergibt sich dann wie folgt

ST_Y(nd.geometry) + (SIN(RADIANS(ul.richtung)) * (ul.entfernung / 100.0))

Die komplette SQL-Anweisung sieht dann wie folgt aus:

SELECT
    ul.rowid AS id,
    ul.name,
    ST_X(nd.geometry) AS x,
    ST_Y(nd.geometry) AS y,
    MakePoint(
        ST_X(nd.geometry) + (COS(RADIANS(ul.richtung)) * (ul.entfernung / 100.0)),
        ST_Y(nd.geometry) + (SIN(RADIANS(ul.richtung)) * (ul.entfernung / 100.0))
    ) AS geometry
FROM urnenlage AS ul
JOIN ND AS nd on nd.id = ul.nd_id
Alle Einstellungen des virtuellen Layers
Alle Einstellungen des virtuellen Layers

Letzte Einstellungen

In den Einstellungen des virtuellen Layers legt man nun noch die ID-Spalte fest und für ein bisschen Performanceoptimierung setzt man die Geometrie auf manuell. Die Spalte ist geometry, der Typ ist Punkt und man kann noch ein Koordinatensystem festlegen. Ein Klick auf OK und man erhält einen neuen Layer in QGIS mit den Lagen der Urnen als Punktlayer. Im nächsten Schritt zeichnen wir noch die Linien, die die Urnenlagen mit den Naturmerkmal verbinden. Dazu verwenden wir die Geometriegeneratoren im Style-Menü.

Urnenlage
Die Lage der Urnen um das Naturdenkmal

Geometriegeneratoren

Mit Hilfe von Geometriegeneratoren können wir mit Hilfe von Befehlen eine andere Art von Geometrie als die des Layers erzeugen. Hier in diesem Fall können wir aus dem Punktlayer Linien erzeugen und zur Darstellung nutzen. Dazu fügen wir eine neue Symbolebene hinzu. Die untere der Symbolebenen ändern wir nun zum Symboltyp “Geometriegenerator”. Wichtig ist hier, dass wir als Geometrieart Linie/Multilinie auswählen. Der Ausdruck

make_line( 
    make_point(  "x" ,  "y" ),
     $geometry
)

erzeugt die Linie. Der Befehl make_line erzeugt eine Linie und erwartet zwei Punkte als Parameter. make_point erzeugt einen Punkt aus den Spalten “x” und “y”, die wie oben im SQL gezeigt, die Koordinaten des Naturmerkmals sind. $geometry referenziert die Geometrie des aktuellen Datensatzes, hier einer Urnenlage mit Koordinaten. Einmal mit OK bestätigen und man erhält das gewünschte Ausgangsbild.

Einstellungen für den Geometriegenerator
Einstellungen für den Geometriegenerator

Automatische Updates inklusive

Es gibt einen Vorteil, CSV als Datengrundlage zu verwenden. Denn QGIS überwacht die Textdatei ständig. Jede Änderung, die an der Datei vorgenommen wird, erscheint – mehr oder weniger – sofort in QGIS. Ein ähnliches Verhalten zeigt auch der virtuelle Layer. Jede Änderung an den Quelldateien wird automatisch an den virtuellen Layer weitergegeben und das Erscheinungsbild passt sich entsprechend an. So kann man neue Naturmerkmale hinzufügen, neue Urnenlagen hinzufügen oder bestehende Daten ändern, ohne erneut Hand anlegen zu müssen.

Layer überwachen
Layer auf Änderungen überwachen