PostGIS-Erweiterung

Daniel Künne

PostGIS ist eine Erweiterung für das objekt-relationale Datenbank-Managementsystem PostgreSQL um geographische Funktionen und Objekte. Somit kann der Datenbank-Server in Verbindung mit einem Geoinformationssystem (GIS) genutzt werden. Außerdem folgt PostGIS im Gegensatz zu den Implementation von MySQL oder Oracle der OpenGIS Simple Feature Specification for SQL.

Installation

Da die Installation der PostGIS-Funktionalität sich nur auf ein Datenbank-Schema auswirkt, muss bei jedem neuen Anlegen die komplette Installationsroutine durchlaufen werden.

-- Erstellung eines neuen Datenbank-Schemas
createdb -O pgsgame pgs_prod
-- Erweiterung des Befehlssatzes um die Sprache PSQL
createlang plpgsql pgs_prod
-- Import der GIS-Funktionen und -Objekte mit dem aktuellsten Update
psql -d pgs_prod -f lwpostgis.sql
psql -d pgs_prod -f lwpostgis_upgrade.sql
-- Import der Kommentare für obige Funktionen
psql -d pgs_prod -f postgis_comments.sql
-- Import der Referenzinformationen für die System
psql -d pgs_prod -f spatial_ref_sys.sql
Installation von PostGIS

In obigem Beispielcode erzeugt der Befehl createdb ein neues Datenbank-Schema mit dem Bezeichner pgs_prod für den Benutzer pgsgame. Um nun den vollen Funktionsumfang der PostGIS-Erweiterung zu aktivieren, muss zuerst die Sprache PSQL als Erweiterung für SQL aktiviert werden. Anschließend können die SQL-Skripte mit den create-Statements für die GIS-Funktionalität gegen die Datenbank abgesetzt werden. Das Importieren der Kommentare zu den Funktionen und Objekten ist nicht zwangsläufig erforderlich, liefert aber eine bessere Verständlichkeit und hat keine negativen Auswirkungen auf die Performance des Servers. Der letzte Schritt bei der Installation ist der Import der Referenzinformationen für das System. Dies ist erforderlich, da PostGIS die Geoinformationen nicht in den vom Benutzer angelegten Tabellen direkt, sondern in einer separaten Tabelle für Geodaten speichert.

Speicherung

Die Speicherung der Geometrien erfolgt innerhalb einer PostgreSQL-Datenbank, die die PostGIS-Erweiterung installiert hat, im Well-Known Binary (WKB) Format in einer speziellen Tabelle, welche nur die Geoinformationen enthält. Die Spalten aus dieser Tabelle werden durch PostGIS den eigentlichen Daten zugeordnet.

Bei WKB handelt es sich um ein binäres Datenformat, welches vom Open Geospatial Consortium extra standardisiert wurde, um Geodaten in einer Datenbank zu speichern. Neben der Repräsentation der Daten im Well-Known Binary Format besteht auch die Möglichkeit das textbasierte Well-Known Text (WKT) Format zu nutzen. Dieses dient lediglich zur Verbesserung der Lesbarkeit eines Datensatzes und nicht zur Speicherung.

-- WKT Repräsentation eines Punktes
POINT(8.0000116 52.4779105)
-- WKT Repräsentation einer Spielfläche
POLYGON((8.02003422600057 52.2860547779375, 8.02738577399943 52.2860547779375,
         8.02738577399943 52.2815632220625, 8.02003422600057 52.2815632220625,
         8.02003422600057 52.2860547779375))
WKT-Repräsentation von geographischen Daten

Indizierung

Neben den Funktionen zur einfachen Analyse bietet PostGIS Funktionen an, mit denen sich ein Zugriff auf die vorhandenen Daten optimieren lässt. Damit bei der Abarbeitung einer Anfrage nicht alle Daten nacheinander eingelesen werden müssen, sondern möglichst nur die Daten, die für eine Anfrage in Betracht kommen, bietet es sich an, einen Index auf den Daten zu erzeugen. Indizes, die den Zugriff auf vorhandene Daten optimieren, gibt es in verschiedenen Systemen, nicht nur im Geodatenbereich. Beispielsweise können bei einer normalen PostgreSQL Datenbank Indizes angelegt werden, die das Auffinden von Werten in bestimmten Spalten erheblich beschleunigen. Allerdings entsteht durch das Anlegen eines Indizes immer ein Overhead, der das System zusätzlich belastet und es sollte vom Entwickler genau abgewogen werden, ob dieser Aufwand gerechtfertigt ist.

Als Index-Typen stehen B-Trees, R-Trees und Generalized Search Trees (GiST) zur Verfügung. Einen Index für Geodaten in PostGIS sollte man mit Hilfe eines GiST erzeugen.

Da diverse Anfragen auf die Geometrien abgesetzt werden, die die Gesamtfläche des Spieles sowie die einzelnen Teilbereiche beschreiben und die Anzahl der Datensätze mit jedem neu erstellten Spiel erheblich steigt, ist hier eine Indizierung innerhalb der Serverimplementation durchaus sinnvoll.

-- GIST-Index auf die Spalte boundingBox in der Tabelle gamefields
CREATE INDEX idxBoundingbox ON pgsgame.gamefields USING gist(boundingBox GIST_GEOMETRY_OPS)
Indizierung einer Spalte

SQL-Queries

Aufgrund des Einsatzes von Hibernate als objektrelationaler Mapper und der Verwendung des Aufsatzes Hibernate Spatial müssen Im Java-Code keine SQL-Anfragen für geometrische Objekte formuliert werden. Allerdings werden im Hintergrund sehr wohl SQL-Anfragen an die Datenbank durchgereicht.

-- Liefert alle Knoten innerhalb einer gegebenen Fläche
SELECT n.coordinate FROM nodes n, areas a 
	WHERE Contains ( a.boundingBox, n.coordinate) = TRUE;
-- Liefert alle Spieler die sich in einem Umkreis von maximal 
-- 0,05 Grad um die Spielfläche befinden
SELECT p.* FROM areas a, player p 
	WHERE isempty(intersection(a.boundingBox, st_buffer(p.coordinate, 0.05))) = false;
-- Aggregatfunktion zum Zusammenfassen einzelner Areas
SELECT SUM(ST_Area(boundingBox)) AS total_area FROM areas;
Räumliche Anfragen an die Datenbank

Der obige Auszug zeigt drei Beispielanfragen, wie sie von Hibernate generiert werden. Alle drei benutzen Funktionen der PostGIS-Erweiterung und im letzten Fall wird die ST_Area-Funktion, die eine Fläche erzeugt, mit den Aggregatfunktionen von SQL verknüpft. Die SUM-Funktion ist hier aber überladen und liefert keinen Zahlenwert, sondern erzeugt im Hintergrund eine neue Geometrie.


Page last modified on March 21, 2011, at 05:10 PM