Chapter 10. Rasterdatahantering, frågor och applikationer

Table of Contents

10.1. Läs in och skapa raster

I de flesta användningsfall skapar du PostGIS-raster genom att ladda befintliga rasterfiler med hjälp av den paketerade rasterladdaren raster2pgsql.

10.1.1. Använda raster2pgsql för att läsa in raster

Raster2pgsql är en körbar rasterläsa inre som läsa inr GDAL-stödda rasterformat till SQL som lämpar sig för laddning i en PostGIS-rastertabell. Den kan läsa in mappar med rasterfiler samt skapa översikter över raster.

Eftersom raster2pgsql oftast kompileras som en del av PostGIS (om du inte kompilerar ditt eget GDAL-bibliotek), kommer de rastertyper som stöds av den körbara filen att vara desamma som de som kompileras i GDAL-beroendebiblioteket. För att få en lista över rastertyper som just din raster2pgsql stöder, använd -G-omkopplaren.

[Note]

När du skapar översikter över en viss faktor från en uppsättning raster som är anpassade är det möjligt att översikterna inte är anpassade. Besök http://trac.osgeo.org/postgis/ticket/1764 för ett exempel där översikterna inte är i linje.

10.1.1.1. Exempel på användning

Ett exempel på en session där laddaren används för att skapa en inmatningsfil och ladda upp den i 100x100 bitar kan se ut så här:

# -s use srid 4326
# -I create spatial index
# -C use standard raster constraints
# -M vacuum analyze after load
# *.tif load all these files
# -F include a filename column in the raster table
# -t tile the output 100x100
# public.demelevation load into this table
raster2pgsql -s 4326 -I -C -M -F -t 100x100 *.tif public.demelevation 
> elev.sql

# -d connect to this database
# -f read this file after connecting
psql -d gisdb -f elev.sql
[Note]

Om du inte anger schemat som en del av måltabellens namn kommer tabellen att skapas i standardschemat för den databas eller användare som du ansluter till.

En konvertering och uppladdning kan göras i ett steg med hjälp av UNIX pipes:

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

Läs in raster Massachusetts statliga planmätare flygplattor i ett schema som heter aerial och skapa en fullständig vy, 2 och 4 nivå översiktstabeller, använd kopieringsläge för att infoga (ingen mellanliggande fil bara direkt till db) och -e tvingar inte allt i en transaktion (bra om du vill se data i tabeller direkt utan att vänta). Dela upp rastren i 128x128 pixelplattor och tillämpa rasterbegränsningar. Använd kopieringsläge i stället för tabellinsättning. (-F) Inkludera ett fält som heter filename för att innehålla namnet på filen som plattorna klipptes ut från.

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
--get a list of raster types supported:
raster2pgsql -G

Kommandot -G ger en lista ungefär som

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
  ...
  Arc/Info Export E00 GRID
  ZMap Plus Grid
  NOAA NGS Geoid Height Grids

10.1.1.2. raster2pgsql-alternativ

-?

Visa hjälpskärm. Hjälp visas också om du inte skickar in några argument.

-G

Skriv ut de rasterformat som stöds.

(c|a|d|p) Dessa är ömsesidigt uteslutande alternativ:

-c

Skapa en ny tabell och fyll i den med raster, detta är standardläget

-a

Lägg till raster till en befintlig tabell.

-d

Ta bort tabell, skapa en ny och fyll den med raster(s)

-p

Förbered läge, skapa bara bordet.

Rasterbearbetning: Tillämpa begränsningar för korrekt registrering i rasterkataloger

-C

Tillämpa rasterbegränsningar - srid, pixelstorlek etc. för att säkerställa att raster är korrekt registrerat i vyn raster_columns.

-x

Inaktivera inställning av begränsning för maximal utsträckning. Tillämpas endast om flaggan -C också används.

-r

Ställ in begränsningarna (spatialt unik och täckningsplatta) för regelbunden blockering. Tillämpas endast om flaggan -C också används.

Rasterbearbetning: Valfria parametrar som används för att manipulera inmatad rasterdatauppsättning

-s <SRID>

Tilldelar utdataraster med angiven SRID. Om den inte anges eller är noll, kommer rastrets metadata att kontrolleras för att fastställa en lämplig SRID.

-b BAND

Index (1-baserat) för det band som ska extraheras från rastret. För mer än ett bandindex, separera med kommatecken (,). Om inget anges kommer alla band i rastret att extraheras.

-t TILE_SIZE

Skär rastret i brickor som ska infogas, en per tabellrad. TILE_SIZE uttrycks som WIDTHxHEIGHT eller sätts till värdet "auto" för att låta inläsaren beräkna en lämplig brickstorlek med hjälp av det första rastret och tillämpas på alla raster.

-P

Fyll på längst till höger och längst ner för att garantera att alla brickor har samma bredd och höjd.

-R, --register

Registrera rastret som ett filsystemraster (out-db).

Endast metadata för rastret och sökvägen till rastret lagras i databasen (inte pixlarna).

-l OVERVIEW_FACTOR

Skapa översikt över rastret. För mer än en faktor, separera med kommatecken(,). Tabellnamnet för översikten följer mönstret o_overview factor_table, där overview factor är en platshållare för den numeriska översiktsfaktorn och table ersätts med namnet på bastabellen. Den skapade översikten lagras i databasen och påverkas inte av -R. Observera att den genererade sql-filen kommer att innehålla både huvudtabellen och översiktstabellerna.

-N NODATA

NODATA-värde som ska användas på band utan NODATA-värde.

Valfria parametrar som används för att manipulera databasobjekt

-f COLUMN

Ange namn på målrasterkolumn, standard är 'rast'

-F

Lägg till en kolumn med namnet på filen

-n COLUMN

Ange namnet på kolumnen för filnamn. Innebär -F.

-q

Packa in PostgreSQL-identifierare i citat.

-I

Skapa ett GiST-index på rasterkolumnen.

-M

Vakuumanalysera rastertabellen.

-k

Behåller tomma plattor och hoppar över NODATA-värdeskontroller för varje rasterband. Observera att du sparar tid på att kontrollera, men kan sluta med mycket fler skräprader i din databas och dessa skräprader markeras inte som tomma rutor.

-T tablespace

Ange tablespace för den nya tabellen. Observera att index (inklusive primärnyckeln) fortfarande kommer att använda standardtabellutrymmet om inte flaggan -X också används.

-X tablespace

Ange tablespace för tabellens nya index. Detta gäller för primärnyckeln och det spatiala indexet om flaggan -I används.

-Y max_rows_per_copy=50

Använd copy-satser i stället för insert-satser. Ange valfritt max_rows_per_copy; standard 50 om inget anges.

-e

Utför varje villkor individuellt, använd inte en transaktion.

-E ENDIAN

Styr endianness för genererad binär utdata av raster; ange 0 för XDR och 1 för NDR (standard); endast NDR-utdata stöds nu

-V version

Ange version av utdataformat. Standard är 0. Endast 0 stöds för närvarande.

10.1.2. Skapa raster med hjälp av PostGIS rasterfunktioner

Vid många tillfällen vill du skapa raster och rastertabeller direkt i databasen. Det finns en uppsjö av funktioner för att göra det. De allmänna stegen att följa.

  1. Skapa en tabell med en rasterkolumn för att hålla de nya rasterposterna, vilket kan åstadkommas med:

    CREATE TABLE myrasters(rid serial primary key, rast raster);
  2. Det finns många funktioner som hjälper till med det målet. Om du skapar raster som inte är ett derivat av andra raster, bör du börja med: ST_MakeEmptyRaster, följt av ST_AddBand

    Du kan också skapa raster från geometrier. För att uppnå det vill du använda ST_AsRaster kanske tillsammans med andra funktioner som ST_Union eller ST_MapAlgebraFct eller någon av familjen av andra map algebra-funktioner.

    Det finns även många fler alternativ för att skapa nya rastertabeller från befintliga tabeller. Du kan t.ex. skapa en rastertabell i en annan projektion än en befintlig med hjälp av ST_Transform

  3. När du är klar med att fylla i din tabell initialt vill du skapa ett spatialt index på rasterkolumnen med något liknande:

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

    Observera användningen av ST_ConvexHull eftersom de flesta rasteroperatorer baseras på rastrernas konvexa skrov.

    [Note]

    Pre-2.0-versioner av PostGIS-raster baserades på kuvertet snarare än det konvexa skrovet. För att de spatiala indexen ska fungera korrekt måste du ta bort dem och ersätta dem med index baserade på konvexa skrov.

  4. Tillämpa rasterbegränsningar med hjälp av AddRasterConstraints

10.1.3. Använda "out db"-molnraster

Verktyget raster2pgsql använder GDAL för att få åtkomst till rasterdata och kan dra nytta av en viktig GDAL-funktion: möjligheten att läsa från raster som lagras på distans i molnbaserade "objektlager" (t.ex. AWS S3, Google Cloud Storage).

Effektiv användning av molnlagrade raster kräver att man använder ett "molnoptimerat" format. Det mest välkända och använda är det"molnoptimerade GeoTIFF"-formatet. Om du använder ett format som inte är molnbaserat, t.ex. JPEG eller en TIFF som inte är kaklad, får du mycket dåliga prestanda eftersom systemet måste ladda ner hela rastret varje gång det behöver komma åt en delmängd.

Först laddar du ditt raster i den molnlagring du väljer. När den har laddats kommer du att ha en URI för att komma åt den, antingen en "http"-URI eller ibland en URI som är specifik för tjänsten. (t.ex. "s3://bucket/object"). Om du vill komma åt icke-offentliga buckets måste du ange GDAL-konfigurationsalternativ för att autentisera din anslutning. Observera att det här kommandot läser från molnrastret och skriver till databasen.

AWS_ACCESS_KEY_ID=xxxxxxxxxxxxxxxxxxxx \
AWS_SECRET_ACCESS_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \
raster2pgsql \
  -s 990000 \
  -t 256x256 \
  -I \
  -R \
  /vsis3/your.bucket.com/your_file.tif \
  your_table \
  | psql your_db

När tabellen har laddats måste du ge databasen behörighet att läsa från fjärraster genom att ange två behörigheter, postgis.enable_outdb_rasters och postgis.gdal_enabled_drivers.

SET postgis.enable_outdb_rasters = true;
SET postgis.gdal_enabled_drivers TO 'ENABLE_ALL';
    

För att ändringarna ska bli bestående kan du göra dem direkt i din databas. Du måste återansluta för att uppleva de nya inställningarna.

ALTER DATABASE your_db SET postgis.enable_outdb_rasters = true;
ALTER DATABASE your_db SET postgis.gdal_enabled_drivers TO 'ENABLE_ALL';
    

För icke-publika raster kan du behöva ange åtkomstnycklar för att läsa från molnrastern. Samma nycklar som du använde för att skriva raster2pgsql-anropet kan ställas in för användning i databasen med postgis.gdal_vsi_options -konfigurationen. Observera att flera alternativ kan ställas in genom att mellanslag separerar nyckel=värde-paren.

SET postgis.gdal_vsi_options = 'AWS_ACCESS_KEY_ID=xxxxxxxxxxxxxxxxxxxx
AWS_SECRET_ACCESS_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';

När du har laddat data och ställt in behörigheter kan du interagera med rastertabellen som med vilken annan rastertabell som helst och använda samma funktioner. Databasen hanterar all mekanik för att ansluta till molndata när den behöver läsa pixeldata.

10.2. Rasterkataloger

Det finns två rasterkatalogvyer som levereras med PostGIS. Båda vyerna använder information som är inbäddad i begränsningarna i rastertabellerna. Som ett resultat är katalogvyerna alltid konsekventa med rasterdata i tabellerna eftersom begränsningarna verkställs.

  1. raster_columns Denna vy katalogiserar alla rastertabellkolumner i databasen.

  2. raster_overviews Denna vy katalogiserar alla rastertabellkolumner i din databas som fungerar som översikter för en mer finkornig tabell. Tabeller av den här typen genereras när du använder växeln -l under inläsning.

10.2.1. Rasterkolumner Katalog

Raster_columns är en katalog över alla kolumner i rastertabeller i databasen som är av typen raster. Det är en vy som utnyttjar begränsningarna i tabellerna så att informationen alltid är konsekvent även om du återställer en rastertabell från en säkerhetskopia av en annan databas. Följande kolumner finns i katalogen raster_columns.

Om du inte skapade dina tabeller med inläsningsprogrammet eller glömde att ange flaggan -C under inläsningen kan du genomdriva begränsningarna i efterhand med hjälp av AddRasterConstraints så att raster_columns-katalogen registrerar den gemensamma informationen om dina rasterplattor.

  • r_table_catalog Den databas som tabellen finns i. Detta kommer alltid att läsa den aktuella databasen.

  • r_table_schema Det databasschema som rastertabellen tillhör.

  • r_table_namn rastertabell

  • r_raster_column den kolumn i tabellen r_table_name som är av typen raster. Det finns inget i PostGIS som hindrar dig från att ha flera rasterkolumner per tabell, så det är möjligt att ha en rastertabell listad flera gånger med en annan rasterkolumn för varje.

  • srid Den spatiala referensidentifieraren för rastret. Bör vara en post i Section 4.5, “Spatiala referenssystem”.

  • scale_x Skalningen mellan geometriska rumskoordinater och pixel. Detta är endast tillgängligt om alla tiles i rasterkolumnen har samma scale_x och denna begränsning tillämpas. Se ST_ScaleX för mer information.

  • scale_y Skalningen mellan geometriska rumskoordinater och pixel. Detta är endast tillgängligt om alla tiles i rasterkolumnen har samma scale_y och scale_y-begränsningen tillämpas. Se ST_ScaleY för mer information.

  • blocksize_x Bredden (antal pixlar tvärs över) för varje rasterplatta. Se ST_Width för mer information.

  • blocksize_y Bredden (antal pixlar nedåt) för varje rasterplatta. Se ST_Height för mer information.

  • same_alignment En boolean som är sann om alla rasterplattor har samma inriktning . Se ST_SameAlignment för mer information.

  • regular_blocking Om rasterkolumnen har begränsningarna spatially unique och coverage tile är värdet TRUE. Annars kommer det att vara FALSE.

  • num_bands Antalet band i varje platta i rasteruppsättningen. Detta är samma information som den som tillhandahålls av ST_NumBands

  • pixel_types En array som definierar pixeltypen för varje band. Du kommer att ha samma antal element i denna array som du har antal band. Pixel_types är en av följande definierade i ST_BandPixelType.

  • nodata_values En matris med tal med dubbel precision som anger nodata_värdet för varje band. Du kommer att ha samma antal element i den här matrisen som du har antal band. Dessa siffror definierar pixelvärdet för varje band som bör ignoreras för de flesta operationer. Detta är liknande information som tillhandahålls av ST_BandNoDataValue.

  • out_db En array med booleska flaggor som anger om rasterbanddata sparas utanför databasen. Du kommer att ha samma antal element i denna array som du har antal band.

  • extent Detta är omfattningen av alla rasterrader i din rasteruppsättning. Om du planerar att läsa in mer data som kommer att ändra uppsättningens utsträckning, bör du köra funktionen DropRasterConstraints före laddningen och sedan tillämpa begränsningar på nytt med AddRasterConstraints efter laddningen.

  • spatial_index En boolean som är sann om rasterkolumnen har ett spatialt index.

10.2.2. Raster-översikter

raster_overviews katalogiserar information om rastertabellkolumner som används för översikter och ytterligare information om dem som är bra att känna till när man använder översikter. Översiktstabeller katalogiseras i både raster_columns och raster_overviews eftersom de är rastertabeller i sig själva men också har ett särskilt syfte, nämligen att vara en karikatyr med lägre upplösning av en tabell med högre upplösning. Dessa genereras tillsammans med huvudrastertabellen när du använder -l-omkopplaren i rasterladdningen eller kan genereras manuellt med AddOverviewConstraints.

Översiktstabeller innehåller samma begränsningar som andra rastertabeller samt ytterligare begränsningar som endast gäller information och som är specifika för översikter.

[Note]

Informationen i raster_overviews duplicerar inte informationen i raster_columns. Om du behöver information om en översiktstabell som finns i raster_columns kan du koppla ihop raster_overviews och raster_columns för att få den fullständiga information du behöver.

Två huvudskäl till översikter är:

  1. Lågupplöst representation av kärntabellerna som ofta används för snabb utzoomning av kartor.

  2. Det går i allmänhet snabbare att göra beräkningar på dem än på deras högupplösta förlagor eftersom det finns färre poster och varje pixel täcker ett större område. Även om beräkningarna inte är lika exakta som de högupplösta tabeller de stöder, kan de vara tillräckliga i många tumregelberäkningar.

Katalogen raster_overviews innehåller följande kolumner med information.

  • o_table_catalog Den databas som översiktstabellen finns i. Detta kommer alltid att läsa den aktuella databasen.

  • o_table_schema Det databasschema som översiktsrastertabellen tillhör.

  • o_table_name namn på tabell för rasteröversikt

  • o_raster_column rasterkolumnen i översiktstabellen.

  • r_table_catalog Databasen där rastertabellen för denna översiktstjänst finns. Detta kommer alltid att läsa den aktuella databasen.

  • r_table_schema Databasschemat för den rastertabell som denna översiktstjänst tillhör.

  • r_table_name rastertabell som denna översikt hanterar.

  • r_raster_column den rasterkolumn som denna översiktskolumn hanterar.

  • overview_factor - detta är pyramidnivån för översiktstabellen. Ju högre siffra desto lägre upplösning på tabellen. raster2pgsql kommer, om den får en mapp med bilder, att beräkna översikten för varje bildfil och läsa in den separat. Nivå 1 antas alltid vara originalfilen. Nivå 2 är att varje platta representerar 4 av originalet. Så om du till exempel har en mapp med bildfiler på 5000x5000 pixlar som du valt att dela upp i 125x125, kommer din bastabell för varje bildfil att ha (5000*5000)/(125*125) poster = 1600, din (l=2) o_2-tabell kommer att ha tak(1600/Power(2,2)) = 400 rader, din (l=3) o_3 kommer att ha tak(1600/Power(2,3)) = 200 rader. Om dina pixlar inte är delbara med storleken på dina brickor kommer du att få några skrotbrickor (brickor som inte är helt fyllda). Observera att varje översiktsplatta som genereras av raster2pgsql har samma antal pixlar som sin förälder, men har en lägre upplösning där varje pixel i den representerar (Power(2,overview_factor) pixlar av originalet).

10.3. Bygga anpassade applikationer med PostGIS Raster

Det faktum att PostGIS raster ger dig SQL-funktioner för att rendera raster i kända bildformat ger dig många alternativ för att rendera dem. Du kan till exempel använda OpenOffice / LibreOffice för rendering, vilket visas i Rendering av PostGIS Raster-grafik med LibreOffice Base Reports. Dessutom kan du använda en mängd olika språk som visas i det här avsnittet.

10.3.1. PHP-exempel Utdata med ST_AsPNG i kombination med andra rasterfunktioner

I det här avsnittet kommer vi att visa hur man använder PHP PostgreSQL-drivrutinen och ST_AsGDALRaster -familjen av funktioner för att mata ut band 1,2,3 av en raster till en PHP-förfrågningsström som sedan kan bäddas in i en img src html-tagg.

Exempelfrågan visar hur man kombinerar ett helt gäng rasterfunktioner tillsammans för att ta tag i alla plattor som skär en viss wgs 84 avgränsningsbox och sedan förenar med ST_Union de korsande plattorna tillsammans och returnerar alla band, transformerar till användarens angivna projektion med ST_Transform och sedan matar ut resultaten som en png med ST_AsPNG.

Du skulle ringa nedanstående med

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

för att få rasterbilden i Massachusetts state plane feet.


<?php
/** contents of 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');
/**If a particular projection was requested use it otherwise use mass state plane meters **/
if (!empty( $_REQUEST['srid'] ) &amp;&amp; is_numeric( $_REQUEST['srid']) ){
                $input_srid = intval($_REQUEST['srid']);
}
else { $input_srid = 26986; }
/** The set bytea_output may be needed for PostgreSQL 9.0+, but not for 8.4 **/
$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]);
?>

10.3.2. ASP.NET C# Exempel Utdata med hjälp av ST_AsPNG tillsammans med andra rasterfunktioner

I det här avsnittet visar vi hur man använder Npgsql PostgreSQL .NET-drivrutinen och ST_AsGDALRaster -familjen av funktioner för att mata ut band 1,2,3 av en raster till en PHP-förfrågningsström som sedan kan bäddas in i en img src html-tagg.

Du behöver npgsql .NET PostgreSQL-drivrutinen för den här övningen som du kan få det senaste från http://npgsql.projects.postgresql.org/. Ladda bara ner det senaste och släpp in i din ASP.NET bin-mapp så är du redo att gå.

Exempelfrågan visar hur man kombinerar ett helt gäng rasterfunktioner tillsammans för att ta tag i alla plattor som skär en viss wgs 84 avgränsningsbox och sedan förenar med ST_Union de korsande plattorna tillsammans och returnerar alla band, transformerar till användarens angivna projektion med ST_Transform och sedan matar ut resultaten som en png med ST_AsPNG.

Detta är samma exempel som Section 10.3.1, “PHP-exempel Utdata med ST_AsPNG i kombination med andra rasterfunktioner” men implementerat i C#.

Du skulle ringa nedanstående med

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

för att få rasterbilden i Massachusetts state plane feet.

 -- web.config connection string section --
<connectionStrings>
    <add name="DSN"
        connectionString="server=localhost;database=mydb;Port=5432;User Id=myuser;password=mypwd"/>
</connectionStrings>
// Code for 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;
        }
}

10.3.3. Java-konsolapp som matar ut rasterfråga som bildfil

Detta är en enkel java-konsolapp som tar en fråga som returnerar en bild och matar ut till den angivna filen.

Du kan ladda ner de senaste PostgreSQL JDBC-drivrutinerna från http://jdbc.postgresql.org/download.html

Du kan kompilera följande kod med hjälp av ett kommando ungefär som:

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

Och anropa den från kommandoraden med något i stil med

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 for 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);
      }
  }
}

10.3.4. Använd PLPython för att dumpa bilder via SQL

Detta är en plpython-lagrad funktion som skapar en fil i serverkatalogen för varje post. Kräver att du har plpython installerat. Bör fungera bra med både plpythonu och 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;
--write out 5 images to the PostgreSQL server in varying sizes
-- note the postgresql daemon account needs to have write access to folder
-- this echos back the file names created;
 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

10.3.5. Utdata av raster med PSQL

Tyvärr har PSQL inte lättanvänd inbyggd funktionalitet för att mata ut binärer. Det här är lite av ett hack som piggy backar på PostgreSQL något äldre stort objektstöd. För att använda först starta din psql-kommandorad ansluten till din databas.

Till skillnad från pythonmetoden skapas filen här på din lokala dator.

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);
-- you'll get an output something like --
   oid   | num_bytes
---------+-----------
 2630819 |     74860

-- next note the oid and do this replacing the c:/test.png to file path location
-- on your local computer
 \lo_export 2630819 'C:/temp/aerial_samp.png'

-- this deletes the file from large object storage on db
SELECT lo_unlink(2630819);