Chapter 5. Rasterdatenverwaltung, -abfrage und Anwendungen

Table of Contents
5.1. Laden und Erstellen von Rastertabellen
5.1.1. Verwendung von raster2pgsql zum Laden von Rastern
5.1.2. Erzeugung von Rastern mit den PostGIS Rasterfunktionen
5.2. Raster Katalog
5.2.1. Rasterspalten Katalog
5.2.2. Raster Übersicht/Raster Overviews
5.3. Eigene Anwendungen mit PostGIS Raster erstellen
5.3.1. PHP Beispiel: Ausgabe mittels ST_AsPNG in Verbindung mit anderen Rasterfunktionen
5.3.2. ASP.NET C# Beispiel: Ausgabe mittels ST_AsPNG in Verbindung mit anderen Rasterfunktionen
5.3.3. Applikation für die Java-Konsole, welche eine Rasterabfrage als Bilddatei ausgibt
5.3.4. Verwenden Sie PLPython um Bilder via SQL herauszuschreiben
5.3.5. Raster mit PSQL ausgeben

5.1. Laden und Erstellen von Rastertabellen

In den häufigsten Anwendungsfällen werden Sie einen PostGIS-Raster durch das Laden einer bestehenden Rasterdatei, mit Hilfe des Rasterladers raster2pgsql, erstellen.

5.1.1. Verwendung von raster2pgsql zum Laden von Rastern

raster2pgsql ist ein ausführbarer Rasterlader, der die von GDAL unterstützten Rasterformate in SQL umwandelt, um sie anschließend in eine PostGIS Rastertabelle zu laden. Er kann sowohl ganze Verzeichnisse mit Rasterdateien laden, als auch Rasterübersichten erzeugen.

Da "raster2pgsql" meistens als Teil von PostGIS kompiliert ist (solange Sie nicht Ihre eigene GDAL Bibliothek kompilieren), sind die von "raster2pgsql" unterstützten Rastertypen die selben wie in der GDAL Bibliothek. Um eine Liste der Rastertypen, die von Ihrem jeweiligen "raster2pgsql"unterstützt werden, zu erhalten, benutzen Sie bitte den -G Switch. Falls Sie dieselbe GDAL Bibliothek für beide verwenden, sollte diese Liste mit der Ihrer PostGIS Installation, die durch ST_GDALDrivers bereitgestellt wird, ident sein.

[Note]

Die frühere Version dieses Tools war ein Python Skript. Die lauffähige Version hat das Python Skript ersetzt. Sollten Sie weiterhin das Python Skript benötigen, können Sie unter GDAL PostGIS Raster Driver Usage Beispiele für Python finden. Beachten Sie bitte, dass zukünftige Versionen von PostGIS Raster das "raster2pgsql" Pythonskript nicht mehr unterstützen.

[Note]

Bei einem bestimmten Faktor kann es vorkommen, dass die Raster in der Übersicht/Overview nicht bündig angeordnet sind, obwohl sie die Raster selbst dies sind. Siehe http://trac.osgeo.org/postgis/ticket/1764 für ein solches Beispiel.

ANWENDUNGSBEISPIEL:

raster2pgsql raster_options_go_here raster_file someschema.sometable > out.sql

-?

Zeigt die Hilfe an, auch dann, wenn keine Argumente übergeben werden.

-G

Gibt die unterstützten Rasterformate aus.

(c|a|d|p) Dies sind sich gegenseitig ausschließende Optionen:

-c

Eine neue Tabelle anlegen und mit Raster(n) befüllen, this is the default mode

-a

Raster zu einer bestehende Tabelle hinzufügen.

-d

Tabelle löschen, eine Neu erzeugen und mit einem oder mehreren Raster befüllen

-p

Beim vorbereitenden Modus wird ledigliche eine Tabelle erstellt.

Raster-Verarbeitung: Anwendung von Constraint's zur ordnungsgemäßen Registrierung im Rasterkatalog

-C

Anwendung von Raster-Constraints, wie SRID, Zellgröße etc., um die ordnungsgemäße Registrierung des Rasters in der raster_columns View sicherzustellen.

-x

Unterbindet das Setzen der "Max-Extent" Bedingung. Wird nur angewandt, wenn auch die -C Flag gesetzt ist.

-r

Setzt die Constraints (räumlich eindeutig und die Coverage-Kachel) der regelmäßigen Blöcke. Wird nur angewandt, wenn auch die -C Flag gesetzt ist. 

Rasterdaten-Verarbeitung: Optionale Parameter zur Manipulation von Input Raster Datensätzen

-s <SRID>

Dem Output-Raster eine bestimmte SRID zuweisen. Wenn keine SRID oder Null angegeben wird, werden die Raster-Metadaten auf eine geignete SRID hin überprüft.

-b BAND

Die Kennung (1-basiert) des Bandes, das aus dem Raster entnommen werden soll. Um mehrere Bänder anzugeben, trennen Sie die Kennungen bitte durch ein Komma (,).

-t TILE_SIZE

Zerlegt den Raster in Kacheln, um eine Kachel pro Tabellenzeile einzufügen. TILE_SIZE wird entweder in BREITExHöhe ausgedrückt, oder auf den Wert "auto" gesetzt, wodurch der Raster-Lader eine passende Kachelgröße an Hand des ersten Raster's ermittelt und diese dann auf die anderen Raster anwendet.

-P

Die ganz rechts und ganz unten liegenden Kacheln aufstocken, damit für alle Kacheln gleiche Breite und Höhe sichergestellt ist.

-R, --register

Einen im Dateisystem vorliegenden Raster als (out-db) Raster registrieren.

Es werden nur die Metadaten und der Dateipfad des Rasters abgespeichert (nicht die Rasterzellen).

-l OVERVIEW_FACTOR

Erzeugt eine Übersicht/Overview des Rasters. Mehrere Faktoren sind durch einen Beistrich(,) zu trennen. Die Benennung der Übersichtstabelle erfolgt dem Muster o_overview_factor_table, wobei overview_factor ein Platzhalter für den numerischen Wert von "overview_factor" ist und table für den zugrundeliegenden Tabellennamen. Die erstellte Übersicht wird in der Datenbank gespeichert, auch wenn die Option -R gesetzt ist. Anmerkung: die erzeugte SQL-Datei enthält sowohl die Haupttabelle, als auch die Übersichtstabellen.

-N NODATA

Der NODATA-Wert, der für Bänder verwendet wird, die keinen NODATA-Wert definiert haben.

Optionale Parameter zur Manipulation von Datenbankobjekten

-f COLUMN

Gibt den Spaltennamen des Zielrasters an; standardmäßig wird er 'rast' benannt.

-F

Eine Spalte mit dem Dateinamen hinzufügen

-n COLUMN

Gibt die Bezeichnung für die Spalte mit dem Dateinamen an. Schließt -F" mit ein.

-q

Setzt die PostgreSQL-Identifikatoren unter Anführungszeichen.

-I

Einen GIST-Index auf die Rasterspalte anlegen.

-M

VACUUM ANALYZE auf die Rastertabelle.

-k

Überspringt die Überprüfung von NODATA-Werten für jedes Rasterband.

-T tablespace

Bestimmt den Tablespace für die neue Tabelle. Beachten Sie bitte, dass Indizes (einschließlich des Primärschlüssels) weiterhin den standardmäßigen Tablespace nutzen, solange nicht die -X Flag benutzt wird.

-X tablespace

Bestimmt den Tablespace für den neuen Index der Tabelle. Dieser gilt sowohl für den Primärschlüssel als auch für den räumlichen Index, falls die -I Flag gesetzt ist.

-Y

Verwendung von Kopier- anstelle von Eingabe-Anweisungen.

-e

Keine Transaktion verwenden, sondern jede Anweisung einzeln ausführen.

-E ENDIAN

Legt die Byte-Reihenfolge des binär erstellten Rasters fest; geben Sie für XDR 0 und für NDR (Standardwert) 1 an; zurzeit wird nur die Ausgabe von NDR unterstützt.

-V version

Bestimmt die Version des Ausgabeformats. Voreingestellt ist 0. Zur Zeit wird auch nur 0 unterstützt.

Eine Beispielssitzung, wo mit dem Lader eine Eingabedatei erstellt und stückchenweise als 100x100 Kacheln hochgeladen wird, könnte so aussehen:

[Note]

Sie können den Schemanamen weglassen z.B. demelevation anstatt public.demelevation , wodurch die Rastertabelle im Standardschema der Datenbank oder des Anwenders angelegt wird.

raster2pgsql -s 4326 -I -C -M *.tif -F -t 100x100 public.demelevation 
> elev.sql
psql -d gisdb -f elev.sql

Durch die Verwendung von UNIX-Pipes kann die Konvertierung und der Upload in einem Schritt vollzogen werden:

raster2pgsql -s 4326 -I -C -M *.tif -F -t 100x100 public.demelevation | psql -d gisdb

Luftbildkacheln in "Massachusetts State Plane Meters" in das Schema aerial laden. Einen vollständigen View und Übersichtstabellen mit Faktor 2 und 4 erstellen. Verwendet den Modus "copy" für das Insert (keine dazwischengeschaltete Datei, sondern direkt in die Datenbank). Die Option -e bedingt, dass nicht alles innerhalb einer Transaktion abläuft (nützlich, wenn Sie sofort Daten sehen wollen, ohne zu warten). Die Raster werden in 128x128 Pixel große Kacheln zerlegt und Constraints auf die Raster gesetzt. Verwendet den Modus "copy" anstelle eines Tabellen-Inserts. (-F) Erzeugt das Attribut "filename", welches die Bezeichnung der Ausgangsdateien enthält, aus denen die Rasterkacheln ausgeschnitten wurden.

raster2pgsql -I -C -e -Y -F -s 26986 -t 128x128  -l 2,4 bostonaerials2008/*.jpg aerials.boston | psql -U postgres -d gisdb -h localhost -p 5432
--gibt eine Liste der unterstützten Rasterformate aus:
raster2pgsql -G

Der -G Befehl gibt eine ähnliche Liste wie die Folgende aus

Available GDAL raster formats:
  Virtual Raster
  GeoTIFF
  National Imagery Transmission Format
  Raster Product Format TOC format
  ECRG TOC format
  Erdas Imagine Images (.img)
  CEOS SAR Image
  CEOS Image
  JAXA PALSAR Product Reader (Level 1.1/1.5)
  Ground-based SAR Applications Testbed File Format (.gff)
  ELAS
  Arc/Info Binary Grid
  Arc/Info ASCII Grid
  GRASS ASCII Grid
  SDTS Raster
  DTED Elevation Raster
  Portable Network Graphics
  JPEG JFIF
  In Memory Raster
  Japanese DEM (.mem)
  Graphics Interchange Format (.gif)
  Graphics Interchange Format (.gif)
  Envisat Image Format
  Maptech BSB Nautical Charts
  X11 PixMap Format
  MS Windows Device Independent Bitmap
  SPOT DIMAP
  AirSAR Polarimetric Image
  RadarSat 2 XML Product
  PCIDSK Database File
  PCRaster Raster File
  ILWIS Raster Map
  SGI Image File Format 1.0
  SRTMHGT File Format
  Leveller heightfield
  Terragen heightfield
  USGS Astrogeology ISIS cube (Version 3)
  USGS Astrogeology ISIS cube (Version 2)
  NASA Planetary Data System
  EarthWatch .TIL
  ERMapper .ers Labelled
  NOAA Polar Orbiter Level 1b Data Set
  FIT Image
  GRIdded Binary (.grb)
  Raster Matrix Format
  EUMETSAT Archive native (.nat)
  Idrisi Raster A.1
  Intergraph Raster
  Golden Software ASCII Grid (.grd)
  Golden Software Binary Grid (.grd)
  Golden Software 7 Binary Grid (.grd)
  COSAR Annotated Binary Matrix (TerraSAR-X)
  TerraSAR-X Product
  DRDC COASP SAR Processor Raster
  R Object Data Store
  Portable Pixmap Format (netpbm)
  USGS DOQ (Old Style)
  USGS DOQ (New Style)
  ENVI .hdr Labelled
  ESRI .hdr Labelled
  Generic Binary (.hdr Labelled)
  PCI .aux Labelled
  Vexcel MFF Raster
  Vexcel MFF2 (HKV) Raster
  Fuji BAS Scanner Image
  GSC Geogrid
  EOSAT FAST Format
  VTP .bt (Binary Terrain) 1.3 Format
  Erdas .LAN/.GIS
  Convair PolGASP
  Image Data and Analysis
  NLAPS Data Format
  Erdas Imagine Raw
  DIPEx
  FARSITE v.4 Landscape File (.lcp)
  NOAA Vertical Datum .GTX
  NADCON .los/.las Datum Grid Shift
  NTv2 Datum Grid Shift
  ACE2
  Snow Data Assimilation System
  Swedish Grid RIK (.rik)
  USGS Optional ASCII DEM (and CDED)
  GeoSoft Grid Exchange Format
  Northwood Numeric Grid Format .grd/.tab
  Northwood Classified Grid Format .grc/.tab
  ARC Digitized Raster Graphics
  Standard Raster Product (ASRP/USRP)
  Magellan topo (.blx)
  SAGA GIS Binary Grid (.sdat)
  Kml Super Overlay
  ASCII Gridded XYZ
  HF2/HFZ heightfield raster
  OziExplorer Image File
  USGS LULC Composite Theme Grid
  Arc/Info Export E00 GRID
  ZMap Plus Grid
  NOAA NGS Geoid Height Grids

5.1.2. Erzeugung von Rastern mit den PostGIS Rasterfunktionen

Oftmals werden Sie die Raster und die Rastertabellen direkt in der Datenbank erzeugen wollen. Dafür existieren eine Unmenge an Funktionen. Dies verlangt im Allgemeinen die folgende Schritte.

  1. Erstellung einer Tabelle mit einer Rasterspalte für die neuen Rasterdatensätze:

    CREATE TABLE myrasters(rid serial primary key, rast raster);
  2. Es existieren viele Funktionen die Ihnen helfen dieses Ziel zu erreichen. Wenn Sie einen Raster nicht von anderen Rastern ableiten, sondern selbst erzeugen, können Sie mit ST_MakeEmptyRaster beginnen, gefolgt von ST_AddBand

    Sie können Raster auch aus Geometrien erzeugen. Hierzu können Sie ST_AsRaster verwenden, möglicherweise in Verbindung mit anderen Funktionen, wie ST_Union, ST_MapAlgebraFct oder irgendeiner anderen Map Algebra Funktion.

    Es gibt sogar noch viele andere Möglichkeiten, um eine neue Rastertabelle aus bestehenden Tabellen zu erzeugen. Sie können zum Beispiel mit ST_Transform einen Raster in eine andere Projektion transformieren und so eine neue Rastertabelle erstellen.

  3. Wenn Sie mit der Erstbefüllung der Tabelle fertig sind, werden Sie einen räumlichen Index auf die Rasterspalte setzen wollen:

    CREATE INDEX myrasters_rast_st_convexhull_idx ON myrasters USING gist( ST_ConvexHull(rast) );

    Beachten Sie bitte die Verwendung von ST_ConvexHull; der Grund dafür ist, dass die meisten Rasteroperatoren auf der konvexen Hülle des Rasters beruhen.

    [Note]

    Vor der Version 2.0 von PostGIS, basierten die Raster auf der Einhüllenden, anstatt auf der konvexen Hülle. Damit die räumlichen Indizes korrekt funktionieren, müssen Sie diese löschen und mit einem auf der konvexen Hülle basierenden Index ersetzen.

  4. Mittels AddRasterConstraints Bedingungen auf den Raster legen.

5.2. Raster Katalog

Mit PostGIS kommen zwei Views des Rasterkatalogs. Beide Views nützen die Information, welche in den Bedingungen/Constraints der Rastertabellen festgelegt ist. Da die Bedingungen zwingend sind, sind die Views des Rasterkatalogs immer konsistent mit den Daten in den Rastertabellen.

  1. raster_columns diese View/gespeicherte Abfrage katalogisiert alle Rastertabellenspalten Ihrer Datenbank.

  2. raster_overviews Dieser View katalogisiert all jene Spalten einer Rastertabelle in Ihrer Datenbank, die als Übersicht für Rastertabellen mit höherer Auflösung dienen. Tabellen dieses Typs werden mit der -l Option beim Laden erstellt.

5.2.1. Rasterspalten Katalog

raster_columns ist ein Katalog mit allen Rasterspalten Ihrer Datenbanktabellen. Es handelt sich dabei um einen View, der die Constraints auf die Tabellen ausnutzt, um so immer konsistent mit dem aktuellen Stand der Datenbank zu bleiben; sogar dann, wenn Sie den Raster aus einem Backup oder einer anderen Datenbank wiederherstellen. Der raster_columns Katalog beinhaltet die folgenden Spalten.

Falls Sie Ihre Tabellen nicht mit dem Loader erstellt haben, oder vergessen haben, die -C Option während des Ladens anzugeben, können Sie die Constraints auch anschließend erzwingen, indem Sie AddRasterConstraints verwenden, wodurch der raster_columns Katalog die Information über Ihre Rasterkacheln, wie üblich abspeichert.

  • r_table_catalog Die Datenbank, in der sich die Tabelle befindet. Greift immer auf die aktuelle Datenbank zu.

  • r_table_schema Das Datenbankschema in dem sich die Rastertabelle befindet.

  • r_table_name Rastertabelle

  • r_raster_column Die Spalte, in der Tabelle r_table_name, die den Datentyp Raster aufweist. In PostGIS gibt es nichts, was Sie daran hindert, mehrere Rasterspalten in einer Tabelle zu haben. Somit ist es möglich auf unterschiedliche Raster(spalten) in einer einzigen Rastertabelle zuzugreifen.

  • srid Der Identifikator für das Koordinatensystem in dem der Raster vorliegt. Sollte in Section 4.3.1, “Die SPATIAL_REF_SYS Tabelle und Koordinatenreferenzsysteme” eingetragen sein.

  • scale_x Der Skalierungsfaktor zwischen den Koordinaten der Vektoren und den Pixeln. Dieser steht nur dann zur Verfügung, wenn alle Kacheln der Rasterspalte denselben scale_x aufweisen und dieser Constraint auch gesetzt ist. Siehe ST_ScaleX für genauere Angaben.

  • scale_y Der Skalierungsfaktor zwischen den Koordinaten der Vektoren und den Pixeln. Dieser steht nur dann zur Verfügung, wenn alle Kacheln der Rasterspalte denselben scale_y aufweisen und der Constraint scale_y auch gesetzt ist. Siehe ST_ScaleY für genauere Angaben.

  • blocksize_x Die Breite (Anzahl der waagrechten Zellen) einer Rasterkachel. Siehe ST_Width für weitere Details.

  • blocksize_y Die Höhe (Anzahl der senkrechten Zellen) einer Rasterkachel. Siehe ST_Height für weitere Details.

  • same_alignment Eine boolesche Variable, die TRUE ist, wenn alle Rasterkacheln dieselbe Ausrichtung haben. Siehe ST_SameAlignment für genauere Angaben.

  • regular_blocking Wenn auf die Rasterspalte die Constraints für die räumliche Eindeutigkeit und für die Coveragekachel gesetzt sind, ist der Wert TRUE, ansonsten FALSE..

  • num_bands Die Anzahl der Bänder, die jede Kachel des Rasters aufweist. ST_NumBands gibt die gleiche Information aus. ST_NumBands

  • pixel_types Ein Feld das den Pixeltyp für die Bänder festlegt. Die Anzahl der Elemente in diesem Feld entspricht der Anzahl der Rasterbänder. Die "pixel_types" sind unter ST_BandPixelType definiert.

  • nodata_values Ein Feld mit Double Precision Zahlen, welche den nodata_value für jedes Band festlegen. Die Anzahl der Elemente in diesem Feld entspricht der Anzahl der Rasterbänder. Diese Zahlen legen den Pixelwert für jedes Rasterband fest, der bei den meisten Operationen ignoriert wir. Eine ähnliche Information erhalten Sie durch ST_BandNoDataValue.

  • out_db Ein Feld mit booleschen Flags, das anzeigt, ob die Rasterbanddaten außerhalb der Datenbank gehalten werden. Die Anzahl der Elemente in diesem Feld entspricht der Anzahl der Rasterbänder.

  • extent Die Ausdehnung aller Rasterspalten in Ihrem Rasterdatensatz. Falls Sie vor haben Daten zu laden, welche die Ausdehnung des Datensatzes ändern, sollten Sie die Funktion DropRasterConstraints ausführen, bevor Sie die Daten laden und nach dem Laden die Constraints mit der Funktion AddRasterConstraints erneut setzen.

  • spatial_index Eine Boolesche Variable, die TRUE anzeigt, wenn ein räumlicher Index auf das Rasterattribut gelegt ist.

5.2.2. Raster Übersicht/Raster Overviews

raster_overviews Katalogisiert Information über die Rastertabellenspalten die für die Übersichten/Overviews herangezogen wurden, sowie weitere zusätzliche Information bezüglich Overviews. Die Übersichtstabellen werden sowohl in raster_columns als auch in raster_overviews registriert, da sie sowohl eigene Raster darstellen, als auch, als niedriger aufgelöstes Zerrbild einer höher aufgelösten Tabelle, einem bestimmten Zweck dienen. Wenn Sie den -l Switch beim Laden des Rasters angeben, werden diese gemeinsam mit der Rasterhaupttabelle erstellt; sie können aber auch händisch über AddOverviewConstraints erstellt werden.

Übersichtstabellen enthalten dieselben Constraints wie andere Rastertabellen und zusätzliche informative Constraints, spezifisch für die Übersichten.

[Note]

Die Information in raster_overviews befindet sich nicht in raster_columns. Falls Sie die Information der Übersichtstabelle und der raster_columns zusammen benötigen, können Sie einen Join auf raster_overviews und raster_columns ausführen, um die gesamte Information zu erhalten.

Die zwei Hauptgründe für Übersichtsraster sind:

  1. Eine niedrig aufgelöste Darstellung der Basistabellen; wird im Allgemeinen zum schnellen Hinauszoomen verwendet.

  2. Die Berechnungen laufen grundsätzlich schneller ab, als bei den Stammdaten mit höherer Auflösung, da weniger Datensätze vorhanden sind und die Pixel eine größere Fläche abdecken. Obwohl diese Berechnungen nicht so exakt sind, wie jene auf die hochauflösenden Stammtabellen, sind sie doch für viele Überschlagsrechnunen ausreichend.

Der raster_overviews Katalog enthält folgende Attribute an Information.

  • o_table_catalog Die Datenbank, in der sich die Übersichtstabelle befindet. Liest immer die aktuelle Datenbank.

  • o_table_schema Das Datenbankschema dem die Rasterübersichtstabelle angehört.

  • o_table_name Der Tabellenname der Rasterübersicht

  • o_raster_column das Rasterattribut in der Übersichtstabelle.

  • r_table_catalog Die Datenbank, in der sich die Rastertabelle befindet, für die diese Übersicht gilt. Greift immer auf die aktuelle Datenbank zu.

  • r_table_schema Das Datenbankschema, in dem sich die Rastertabelle befindet, zu der der Übersichtsdienst gehört.

  • r_table_name Die Rastertabelle, welche von dieser Übersicht bedient wird.

  • r_raster_column Die Rasterspalte, die diese Overviewspalte bedient.

  • overview_factor - der Pyramidenlevel der Übersichtstabelle. Umso größer die Zahl ist, desto geringer ist die Auflösung. Wenn ein Ordner für die Bilder angegeben ist, rechnet raster2pgsql eine Übersicht für jede Bilddatei und ladet diese einzeln. Es wird Level 1 und die Ursprungsdatei angenommen. Beim Level 2 repräsentiert jede Kachel 4 Originalkacheln. Angenommen Sie haben einen Ordner mit Bilddateien in einer Auflösung von 5000x5000 Pixel, die Sie auf 125x125 große Kacheln zerlegen wollen. Für jede Bilddattei enthält die Basistabelle (5000*5000)/(125*125) Datensätze = 1600, Ihre (l=2) o_2 Tabelle hat dann eine Obergrenze von (1600/Power(2,2)) = 400 Zeilen, Ihre (l=3) o_3 (1600/Power(2,3) ) = 200 Zeilen. Wenn sich die Pixel nicht durch die Größe Ihrer Kacheln teilen lassen, erhalten Sie einige Ausschusskacheln (Kacheln die nicht zur Gänze gefüllt sind). Beachten Sie bitte, dass jede durch raster2pgsql erzeugte Übersichtskachel dieselbe Pixelanzahl hat wie die ursprüngliche Kachel, aber eine geringere Auflösung, wo ein Pixel (Power(2,overview_factor) Pixel der Ursprungsdatei) repräsentiert.

5.3. Eigene Anwendungen mit PostGIS Raster erstellen

Da PostGIS-Raster SQL-Funktionen für die bekannten Bildformate zur Verfügung stellt, haben Sie bei der Ausgabe von Rastern eine Reihe von Möglichkeiten. Zum Beispiel können Sie OpenOffice/LibreOffice für die Darstellung nutzen, so wie unter Rendering PostGIS Raster graphics with LibreOffice Base Reports dargestellt. Zusätzlich steht Ihnen eine Vielzahl an Sprachen zur Verfügung, wie in diesem Abschnitt gezeigt wird.

5.3.1. PHP Beispiel: Ausgabe mittels ST_AsPNG in Verbindung mit anderen Rasterfunktionen

In diesem Abschnitt zeigen wir die Anwendung des PHP PostgreSQL Treibers und der Funktion ST_AsGDALRaster, um die Bänder 1,2,3 eines Rasters an einen PHP Request-Stream zu übergeben. Dieser kann dann in einen "img src" HTML Tag eingebunden werden.

Dieses Beispiel zeigt, wie Sie ein ganzes Bündel von Rasterfunktionen kombinieren können, um jene Kacheln zu erhalten, die ein bestimmtes WGS84 Umgebungsrechteck schneiden. Anschließend werden alle Bänder dieser Kacheln mit ST_Union vereinigt, mit ST_Transform in die vom Benutzer vorgegebene Projektion transformiert und das Ergebnis mit ST_AsPNG als PNG ausgegeben.

Sie können das unten angeführte Programm über

http://mywebserver/test_raster.php?srid=2249

aufrufen, um den Raster in "Massachusetts State Plane Feet" zu erhalten.

<?php
/** Inahlt von test_raster.php **/
$conn_str ='dbname=mydb host=localhost port=5432 user=myuser password=mypwd';
$dbconn = pg_connect($conn_str);
header('Content-Type: image/png');
/**Wenn eine bestimmte Projektion angefragt ist, wird diese verwendet, ansonsten wird "Mass State Plane Meters" verwendet **/
if (!empty( $_REQUEST['srid'] ) && is_numeric( $_REQUEST['srid']) ){
                $input_srid = intval($_REQUEST['srid']);
}
else { $input_srid = 26986; }
/**  "set bytea_output" für PostgreSQL 9.0+, wird für 8.4 nicht benötigt**/
$sql = "set bytea_output='escape';
SELECT ST_AsPNG(ST_Transform(
                        ST_AddBand(ST_Union(rast,1), ARRAY[ST_Union(rast,2),ST_Union(rast,3)])
                                ,$input_srid) ) As new_rast
 FROM aerials.boston
        WHERE
         ST_Intersects(rast, ST_Transform(ST_MakeEnvelope(-71.1217, 42.227, -71.1210, 42.218,4326),26986) )";
$result = pg_query($sql);
$row = pg_fetch_row($result);
pg_free_result($result);
if ($row === false) return;
echo pg_unescape_bytea($row[0]);
?>

5.3.2. ASP.NET C# Beispiel: Ausgabe mittels ST_AsPNG in Verbindung mit anderen Rasterfunktionen

In diesem Abschnitt zeigen wir die Anwendung des Npgsql PostgreSQL .NET Treibers und der Funktion ST_AsGDALRaster, um die Bänder 1,2,3 eines Rasters an einen PHP Request-Stream zu übergeben. Dieser kann dann in einen "img src" HTML Tag eingebunden werden.

Für dieses Beispiel benötigen Sie den npgsql .NET PostgreSQL Treiber. Um loslegen zu können, reicht es aus, dass Sie die neueste Version von http://npgsql.projects.postgresql.org/ in Ihren ASP.NET Ordner laden.

Dieses Beispiel zeigt, wie Sie ein ganzes Bündel von Rasterfunktionen kombinieren können, um jene Kacheln zu erhalten, die ein bestimmtes WGS84 Umgebungsrechteck schneiden. Anschließend werden alle Bänder dieser Kacheln mit ST_Union vereinigt, mit ST_Transform in die vom Benutzer vorgegebene Projektion transformiert und das Ergebnis mit ST_AsPNG als PNG ausgegeben.

Dasselbe Beispiel wie Section 5.3.1, “PHP Beispiel: Ausgabe mittels ST_AsPNG in Verbindung mit anderen Rasterfunktionen” nur in C# implementiert.

Sie können das unten angeführte Programm über

http://mywebserver/TestRaster.ashx?srid=2249

aufrufen, um den Raster in "Massachusetts State Plane Feet" zu bekommen.

-- web.config Verbindungsaufbau --
<connectionStrings>
    <add name="DSN"
        connectionString="server=localhost;database=mydb;Port=5432;User Id=myuser;password=mypwd"/>
</connectionStrings
>
// Code für TestRaster.ashx
<%@ WebHandler Language="C#" Class="TestRaster" %>
using System;
using System.Data;
using System.Web;
using Npgsql;

public class TestRaster : IHttpHandler
{
        public void ProcessRequest(HttpContext context)
        {

                context.Response.ContentType = "image/png";
                context.Response.BinaryWrite(GetResults(context));

        }

        public bool IsReusable {
                get { return false; }
        }

        public byte[] GetResults(HttpContext context)
        {
                byte[] result = null;
                NpgsqlCommand command;
                string sql = null;
                int input_srid = 26986;
        try {
                    using (NpgsqlConnection conn = new NpgsqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["DSN"].ConnectionString)) {
                            conn.Open();

                if (context.Request["srid"] != null)
                {
                    input_srid = Convert.ToInt32(context.Request["srid"]);
                }
                sql = @"SELECT ST_AsPNG(
                            ST_Transform(
                                        ST_AddBand(
                                ST_Union(rast,1), ARRAY[ST_Union(rast,2),ST_Union(rast,3)])
                                                    ,:input_srid) ) As new_rast
                        FROM aerials.boston
                                WHERE
                                    ST_Intersects(rast,
                                    ST_Transform(ST_MakeEnvelope(-71.1217, 42.227, -71.1210, 42.218,4326),26986) )";
                            command = new NpgsqlCommand(sql, conn);
                command.Parameters.Add(new NpgsqlParameter("input_srid", input_srid));


                            result = (byte[]) command.ExecuteScalar();
                conn.Close();
                        }

                }
        catch (Exception ex)
        {
            result = null;
            context.Response.Write(ex.Message.Trim());
        }
                return result;
        }
}

5.3.3. Applikation für die Java-Konsole, welche eine Rasterabfrage als Bilddatei ausgibt

Eine einfache Java Applikation, die eine Abfrage entgegennimmt, ein Bild erzeugt und in eine bestimmte Datei ausgibt.

Sie können die neuesten PostgreSQL JDBC Treiber unter http://jdbc.postgresql.org/download.html herunterladen.

Sie können den unten angegebenen Code mit einem Befehl wie folgt kompilieren:

set env CLASSPATH .:..\postgresql-9.0-801.jdbc4.jar
javac SaveQueryImage.java
jar cfm SaveQueryImage.jar Manifest.txt *.class

Und ihn von der Befehlszeile wie folgt aufrufen:

java -jar SaveQueryImage.jar "SELECT ST_AsPNG(ST_AsRaster(ST_Buffer(ST_Point(1,5),10, 'quad_segs=2'),150, 150, '8BUI',100));" "test.png" 
-- Manifest.txt --
Class-Path: postgresql-9.0-801.jdbc4.jar
Main-Class: SaveQueryImage
// Code für SaveQueryImage.java
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.io.*;

public class SaveQueryImage {
  public static void main(String[] argv) {
      System.out.println("Checking if Driver is registered with DriverManager.");

      try {
        //java.sql.DriverManager.registerDriver (new org.postgresql.Driver());
        Class.forName("org.postgresql.Driver");
      }
      catch (ClassNotFoundException cnfe) {
        System.out.println("Couldn't find the driver!");
        cnfe.printStackTrace();
        System.exit(1);
      }

      Connection conn = null;

      try {
        conn = DriverManager.getConnection("jdbc:postgresql://localhost:5432/mydb","myuser", "mypwd");
        conn.setAutoCommit(false);

        PreparedStatement sGetImg = conn.prepareStatement(argv[0]);

        ResultSet rs = sGetImg.executeQuery();

                FileOutputStream fout;
                try
                {
                        rs.next();
                        /** Output to file name requested by user **/
                        fout = new FileOutputStream(new File(argv[1]) );
                        fout.write(rs.getBytes(1));
                        fout.close();
                }
                catch(Exception e)
                {
                        System.out.println("Can't create file");
                        e.printStackTrace();
                }

        rs.close();
                sGetImg.close();
        conn.close();
      }
      catch (SQLException se) {
        System.out.println("Couldn't connect: print out a stack trace and exit.");
        se.printStackTrace();
        System.exit(1);
      }
  }
}

5.3.4. Verwenden Sie PLPython um Bilder via SQL herauszuschreiben

Diese als plpython gespeicherte Prozedur erzeugt eine Datei pro Datensatz im Serververzeichnis. Benötigt die Installation von plpython. Funktioniert sowohl mit plpythonu als auch mit plpython3u.

CREATE OR REPLACE FUNCTION write_file (param_bytes bytea, param_filepath text)
RETURNS text
AS $$
f = open(param_filepath, 'wb+')
f.write(param_bytes)
return param_filepath
$$ LANGUAGE plpythonu;
-- 5 Bilder in verschiedenen Größen nach PostgreSQL schreiben
-- der Account des PostgreSQL Daemons benötigt Schreibrechte auf den Ordner
-- die Namen der erzeugten Dateien werden ausgegeben;
 SELECT write_file(ST_AsPNG(
        ST_AsRaster(ST_Buffer(ST_Point(1,5),j*5, 'quad_segs=2'),150*j, 150*j, '8BUI',100)),
         'C:/temp/slices'|| j || '.png')
         FROM generate_series(1,5) As j;

     write_file
---------------------
 C:/temp/slices1.png
 C:/temp/slices2.png
 C:/temp/slices3.png
 C:/temp/slices4.png
 C:/temp/slices5.png

5.3.5. Raster mit PSQL ausgeben

Leider hat PSQL keine einfach zu benützende Funktion für die Ausgabe von Binärdateien eingebaut. Dieser Hack baut auf der etwas veralteten "Large Object" Unterstützung von PostgreSQL auf. Um ihn anzuwenden verbinden Sie sich bitte zuerst über die Befehlszeile "psql" mit Ihrer Datenbank.

Anders als beim Ansatz mit Python, wird die Datei bei diesem Ansatz auf Ihrem lokalen Rechner erzeugt.

SELECT oid, lowrite(lo_open(oid, 131072), png) As num_bytes
 FROM
 ( VALUES (lo_create(0),
   ST_AsPNG( (SELECT rast FROM aerials.boston WHERE rid=1) )
  ) ) As v(oid,png);
-- die Ausgabe sieht ungefähr so aus --
   oid   | num_bytes
---------+-----------
 2630819 |     74860

-- beachten Sie die OID und ersetzen Sie c:/test.png mit dem tatsächlichen Pfad
-- auf Ihrem Rechner
 \lo_export 2630819 'C:/temp/aerial_samp.png'

-- löscht die Datei aus dem "large object" Speicher der Datenbank
SELECT lo_unlink(2630819);