Chapter 9. Gestión, Consulta y Aplicaciones de Datos Raster

Table of Contents

9.1. Cargando y Creando Rasters

En la mayoría de casos, crearás rasters PostGIS cargando un fichero raster utilizando el paquete de carga raster raster2pgsql.

9.1.1. Utilizar el paquete raster2pgsql para cargar rasters

The raster2pgsql is a raster loader executable that loads GDAL supported raster formats into SQL suitable for loading into a PostGIS raster table. It is capable of loading folders of raster files as well as creating overviews of rasters.

Since the raster2pgsql is compiled as part of PostGIS most often (unless you compile your own GDAL library), the raster types supported by the executable will be the same as those compiled in the GDAL dependency library. To get a list of raster types your particular raster2pgsql supports use the -G switch.

[Note]

Cuando creamos previsualizaciones de un factor específico de un conjunto de rasters que están alineados, es posible que las previsualizaciones no estén alineadas. Visita http://trac.osgeo.org/postgis/ticket/1764 para un ejemplo donde las previsualizaciones no se alinean.

9.1.1.1. Example Usage

Un ejemplo de sesión utilizando el cargador para crear un fichero de entrada y cargarlo cortado en teselas de 100x100 debería parecerse a:

# -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]

If you do not specify the schema as part of the target table name, the table will be created in the default schema of the database or user you are connecting with.

Se puede hacer una conversion y carga en un solo paso con el caracter "|" en sistemas UNIX:

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

Carga las teselas planas métricas aéreas de los Raster del estado Massachusetts en un esquema denominado aerial y crear una vista completa, y previsualizaciones de niveles 2 y 4, utiliza el modo de copia para insertar (sin archivo intermedio sólo directamente a db), y -e no fuerces todo en una transacción (bueno si quieres ver datos en tablas de inmediato sin tener que esperar). Divide los raster en teselas de 128x128 píxeles y aplica las restricciones de raster. Utiliza el modo copia en lugar de insertar en la tabla.(-F) Incluye un campo llamado nombre de archivo para contener el nombre del archivo de las teselas de donde proceden los cortes.

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

El comando -G extrae una lista similar a esta:

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

9.1.1.2. raster2pgsql options

-?

Muestra la pantalla de ayuda. También se mostrará la ayuda si no incluyes ningún argumento.

-G

Imprime los formatos raster soportados.

(c|a|d|p) Estas opciones son exclusivas entre ellas:

-c

Crea una nueva tabla y la rellena con el raster(s). Esta es la opción por defecto.

-a

Añade el/los raster/s a una tabla existente.

-d

Borra la tabla, crea una nueva y la rellena con el/los raster(s)

-p

Modo preparación, solo crea la tabla.

Procesamiento Raster: Añade condiciones para registrar de forma limpia en el catalogo raster

-C

Añade restricciones raster --srid, tamaño del pixel, etc. para asegurar que el raster es registrado de forma correcta en la vista raster_columns.

-x

Desactiva la opción de restricción de maxima extensión. Solo se aplica si la opción -C esta en uso.

-r

Establezca las restricciones (espacialmente única y tesela de cobertura) para el bloqueo regular. Sólo se aplica si la la bandera -C también está en uso.

Procesado Raster: Parámetros opcionales utilizados para manipular la entrada de datos raster

-s <SRID>

Asigna un SRID especifico al raster de salida. Si no se especifica o es igual a 0, se comprueban los metadatos del raster para determinar un SRID apropiado.

-b BAND

Indice (en base 1) de la banda para extraer del raster. Para indices de mas de una banda, separalo con comas(,). Si no se especifica, se extraerán todas las bandas del raster.

-t TILE_SIZE

Cortar el ráster en teselas para ser insertadas una por una en registros de la tabla. TILE_SIZE se expresa como ANCHOxALTO o establecer el valor "auto" para permitir que se cargue a la computadora en un tamaño de tesela apropiado utilizando el primer ráster y aplicarlo a todos los rásters.

-P

Pad right-most and bottom-most tiles to guarantee that all tiles have the same width and height.

-R, --register

Registra el raster como un fichero de sistema (out-db) raster.

Solo los metadatos del raster y el camino de acceso al raster se almacenan en la base de datos (no los pixeles).

-l OVERVIEW_FACTOR

Crear una previsualización del ráster. Para más de un factor, separar con coma(,). El nombre de la tabla de la previsualización sigue el patrón o_factor de previsualización_tabla, donde factor previsualización es un marcador de posición para el factor de previsualización numérica y tabla se reemplaza con el nombre de la tabla base. La previsualización creada es almacenada en la base de datos y no se afecta por -R. Tenga en cuenta que su archivo sql generado contendrá ambas, la tabla principal y las tablas de previsualización.

-N NODATA

Valor NODATA para utilizar en bandas con valores NODATA.

Parametros opcionales para manipular objetos de la base de datos

-f COLUMN

Especifica el nombre de la columna raster de destino , por defecto es 'rast'

-F

Añade una columna con el nombre del fichero

-n COLUMN

Specify the name of the filename column. Implies -F.

-q

Wrap PostgreSQL identifiers in quotes.

-I

Crea un indice GiST de la columna raster.

-M

Ejecuta Vacuum analyze en la tabla raster.

-k

Keeps empty tiles and skips NODATA value checks for each raster band. Note you save time in checking, but could end up with far more junk rows in your database and those junk rows are not marked as empty tiles.

-T tablespace

Especifica el "tablespace" de la nueva tabla. Observa que los indices (incluyendo el de clave primaria) seguirá utilizando en "tablespace" a menos que se utilice también la opción -X.

-X tablespace

Especifica el "tablespace" para el nuevo indice de la tabla. Esto se aplica a los indices de claves primarias y indices espaciales si la opción -I se esta usando.

-Y max_rows_per_copy=50

Use copy statements instead of insert statements. Optionally specify max_rows_per_copy; default 50 when not specified.

-e

Ejecuta cada comando de forma individual, no utiliza transacciones.

-E ENDIAN

Controla el formato en el que se almacenan los datos de más de un byte (endianness) de la salida binaria generada del raster; especifica 0 para XDR y 1 para NDR(por defecto); solo las salidas NDR están soportadas actualmente.

-V version

Especifica la version del formato de salida. Por defecto es 0. Solo 0 esta soportado actualmente.

9.1.2. Crear rastrees utilizando las funciones raster de PostGIS

En muchas ocasiones, querrás crear tablas raster en la base de datos. Existen una gran cantidad de funciones para hacerlo. Los pasos generales a seguir.

  1. Crear una tabla con una columna raster para almacenar los nuevos registros raster se puede hacer de la siguiente manera:

    CREATE TABLE myrasters(rid serial primary key, rast raster);
  2. Existen muchas funciones de ayuda. Si no estas creando rasters con derivados de otro raster, entonces deberías comenzar con: ST_MakeEmptyRaster, seguido de ST_AddBand

    También puedes crear rasters a partir de geometrias. Para conseguir esto deberás utilizar ST_AsRaster quizás acompañado de otras funciones como ST_Union o ST_MapAlgebraFct o cualquier otra de la familia de funciones de álgebra de mapas.

    Incluso hay muchas más opciones para crear nuevas tablas raster a partir de las tablas existentes. Por ejemplo, puede crear una tabla raster en una proyección diferente de una existente utilizando ST_Transform

  3. Una vez que hayas terminado de llenar la tabla, tendrás que crear un índice espacial en la columna raster con algo similar a:

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

    Observa que utilizamos ST_ConvexHull ya que muchas de las operaciones raster se basan en la envolvente convexa del raster.

    [Note]

    En versiones anteriores a PostGIS 2.0 los raster se basaban en la envolvente y no en la envolvente convexa. Para que los indices espaciales funcionen correctamente necesitaras borrarlos y reemplazarlos por los indices basados en la envolvente convexa.

  4. Aplica las restricciones raster con AddRasterConstraints

9.1.3. Using "out db" cloud rasters

The raster2pgsql tool uses GDAL to access raster data, and can take advantage of a key GDAL feature: the ability to read from rasters that are stored remotely in cloud "object stores" (e.g. AWS S3, Google Cloud Storage).

Efficient use of cloud stored rasters requires the use of a "cloud optimized" format. The most well-known and widely used is the "cloud optimized GeoTIFF" format. Using a non-cloud format, like a JPEG, or an un-tiled TIFF will result in very poor performance, as the system will have to download the entire raster each time it needs to access a subset.

First, load your raster into the cloud storage of your choice. Once it is loaded, you will have a URI to access it with, either an "http" URI, or sometimes a URI specific to the service. (e.g., "s3://bucket/object"). To access non-public buckets, you will need to supply GDAL config options to authenticate your connection. Note that this command is reading from the cloud raster and writing to the database.

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

Once the table is loaded, you need to give the database permission to read from remote rasters, by setting two permissions, postgis.enable_outdb_rasters and postgis.gdal_enabled_drivers.

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

To make the changes sticky, set them directly on your database. You will need to re-connect to experience the new settings.

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

For non-public rasters, you may have to provide access keys to read from the cloud rasters. The same keys you used to write the raster2pgsql call can be set for use inside the database, with the postgis.gdal_config_options configuration. Note that multiple options can be set by space-separating the key=value pairs.

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

Once you have the data loaded and permissions set you can interact with the raster table like any other raster table, using the same functions. The database will handle all the mechanics of connecting to the cloud data when it needs to read pixel data.

9.2. Catalogos raster

Existen dos vistas de catalogo raster que vienen en el paquete PostGIS. Ambas vistas utilizan información de las restricciones de las tablas raster. Como resultado, las vistas de catálogo tienen siempre consistencia con los datos raster de las tablas mientras que las restricciones son reforzadas.

  1. La vista raster_columns cataloga todas las columnas raster de todas las tablas de la base de datos.

  2. La vista raster_overviews cataloga todas las columnas raster de las tablas de la base de datos que sirven como previsualizaciones de tablas de grano más fino. Las tablas de este tipo se generan cuando utilizas la opción -l durante la carga.

9.2.1. Catalogo de columnas raster

El catálogo raster_columns es un catálogo de todas las columnas de la tablas raster en la base de datos que son de tipo raster. Es una vista que utiliza las restricciones de las tablas por lo que la información es siempre consistente, incluso si se restaura una tabla raster de una copia de seguridad de otra base de datos. Existen las siguientes columnas en el catálogo raster_columns.

Si has creado tus tablas sin el cargador o has olvidado especificar la variable -C del comando de carga durante la carga, puedes hacer cumplir las restricciones por defecto utilizando AddRasterConstraints, de este modo el catálogo raster_columns guardará la información mas común de tus teselas raster.

  • r_table_catalog Contienen la tabla de la base de datos. Esto siempre leerá la base de datos actual.

  • r_table_schema Esquema al que pertenece la tabla.

  • r_table_name tabla raster

  • r_raster_column Columna de la tabla r_table_name que es de tipo raster. No hay nada en PostGIS que impida tener múltiples columnas raster por tabla así que es posible tener varias veces la misma tabla raster en la lista con diferentes columnas cada vez.

  • srid El identificador del sistema de referencia espacial del raster. Debe ser una de las entradas de la tabla Section 4.5, “Spatial Reference Systems”.

  • scale_x Escala entre las coordenadas espaciales geométricas y el pixel. Esto esta disponible únicamente si todas las teselas de la columna raster tienen el mismo valor scale_x y se aplica la restricción. Para mas detalles visita ST_ScaleX .

  • scale_y Escala entre las coordenadas espaciales geométricas y el pixel. Esto esta disponible únicamente si todas las teselas de la columna raster tienen el mismo valor scale_y y se aplica la restricción scale_y. Para mas detalles visita ST_ScaleY .

  • blocksize_x Es el ancho (numero de pixeles en horizontal) de cada tesela raster.Para mas detalles visita ST_Width.

  • blocksize_y Es el ancho (numero de pixeles en vertical hacia abajo) de cada tesela raster.Para mas detalles visita ST_Height.

  • same_alignment Valor booleano que valdrá "True" si todas las teselas raster tienen el mismo alineamiento. Visita ST_SameAlignment para más información.

  • regular_blocking Si la columna del ráster tiene las limitaciones de espacio único y de cobertura de tesela, el valor es TRUE. De lo contrario, será FALSE.

  • num_bands Numero de bandas por tesela del conjunto de rasters. Es la misma información que la devuelta por ST_NumBands

  • pixel_types Un array definiendo el tipo de pixel de cada banda. Tendrás el mismo numero de elementos en este array que el numero de bandas. Los pixel_types son uno de los definidos en ST_BandPixelType.

  • nodata_values Un array de números de doble precisión que define el valor nodata_value de cada banda. En este array deberás tener el mismo numero de elementos que el numero de bandas. Este numero define el valor de los pixeles de cada banda que deben ignorarse para la mayoría de operaciones. Esta información es similar a la proporcionada por ST_BandNoDataValue.

  • out_db Una colección de banderas booleanas indican si los datos de las bandas del ráster se mantienen fuera de la base de datos. Se tendrá el mismo número de elementos en esta colección como se tiene número de bandas.

  • extent Esta es la extensión de todas las columnas raster en tu conjunto raster. Si planeas cargar mas datos que cambiarán la extensión del conjunto, deberás ejecutar la función DropRasterConstraints antes de la carga y después de la carga restablecer las restricciones con AddRasterConstraints.

  • spatial_index Un boolean es verdadero si la columna del ráster tiene un índice espacial.

9.2.2. Previsualizaciones raster

raster_overviews Los catálogos de información acerca de las columnas de tablas ráster utilizadas para las previsualizaciones e información adicional de ellos que son útiles para conocer cuando utilizar vistas generales. Las tablas de previsualización Overview tables están catalogados tanto en raster_columns y raster_overviews porque son rásters en su propio derecho pero también sirven a un propósito especial adicional de ser una caricatura de resolución baja o de una tabla de resolución alta. Estos se generan a lo largo de la tabla ráster principal cuando se utiliza el -l interuptor en la carga del ráster o se puede generar manualmente utilizando AddOverviewConstraints.

Las tablas de previsualización contienen las mismas restricciones que cualquier tabla raster además de restricciones adicionales especificas a las previsualizaciones.

[Note]

La información de la tabla raster_overviews no duplica la información de raster_columns. Si necesitas información sobre una tabla de previsualizaciones pobremente en raster_columns puedes unir la tabla raster_overviews a raster_columns para obtener toda la información que necesitas.

Las dos principales razones de crear previsualizaciones son:

  1. Tener una representación de baja resolución de las tablas principales para tener una respuesta rápida en operaciones de zoom-out.

  2. Los cálculos son generalmente más rápidos en las previsualizaciones que en las imágenes de mayor resolución porque hay menos registros y cada pixel cubre más territorio. Aunque los cálculos no son tan precisos como en las tablas de alta resolución de las que provienen, pueden ser suficientes en muchos cálculos empíricos.

El catálogo raster_overviews contiene las siguientes columnas de información.

  • o_table_catalog La base de datos a la cual pertenece la tabla de previsualizaciones. Esto siempre leerá la base de datos actual.

  • o_table_schema El esquema de la base de datos al cual pertenece la tabla de previsualizaciones.

  • o_table_name El nombre de la tala de previsualizaciones.

  • o_raster_column La columna raster de la tabla de previsualizaciones.

  • r_table_catalog La base de datos de la tabla raster para la cual esta previsualización sirve. Esto siempre va a leer la base de datos actual.

  • r_table_schema El esquema de la base de datos de la tabla ráster al cual pertenecen estas previsualizaciones.

  • r_table_name tabla raster para la cual sirven las previsualizaciones.

  • r_raster_column la columna raster para la cual sirven estas previsualizaciones.

  • overview_factor - este es el nivel de pirámide de la tabla de previsualizaciones . Cuanto más alto sea el número, más baja es la resolución de la tabla. Si se le da una carpeta de imágenes al comando raster2pgsql, se calcularán previsualizaciones de cada archivo de imagen y se cargarán por separado. El Nivel 1 supone siempre el archivo original. Nivel 2 tendrá cada tesela representada por 4 de la original. Por ejemplo, si tienes una carpeta de archivos de imagen de 5000x5000 pixeles que decidiste dividir en imágenes de 125x125 , para presentar cada imagen tu tabla base tendrá (5000*5000)/(125*125)=1.600 registros , tu tabla (l=2) o_2 tendrá un tope de (1600/Potencia (2,2))=400 filas , tu (l=3) o_3 tendrá un tope de (1600/Potencia (2,3)) = 200 filas. Si los píxeles no son divisibles por el tamaño de tus teselas , obtendrás algunas de relleno (teselas no completamente llenas ) . Ten en cuenta que cada tesela de previsualización generada por el comando raster2pgsql tiene el mismo número de pixeles que la tesela de origen , pero es de menor resolución que cada pixel de la que representa (Potencia(2,factor_de_previsualizacion) pixeles del original) .

9.3. Contruyendo aplicaciones personalizadas con PostGIS Raster

The fact that PostGIS raster provides you with SQL functions to render rasters in known image formats gives you a lot of options for rendering them. For example you can use OpenOffice / LibreOffice for rendering as demonstrated in Rendering PostGIS Raster graphics with LibreOffice Base Reports. In addition you can use a wide variety of languages as demonstrated in this section.

9.3.1. Ejemplo de salida utilizando ST_AsPNG junto con otras opciones raster en PHP

En esta sección, mostraremos como utilizar el driver PHP PostgreSQL y la familia de funciones ST_AsGDALRaster para extraer las nadas 1,2,3 de un raster a una consulta PHP que puede incluirse como una marca html img src.

La consulta de ejemplo muestra cómo combinar un montón de funciones de mapa de bits juntos para obtener todas las teselas que se cruzan con un cuadro delimitador en wgs84 en particular y luego unimos las teselas que intersectan con ST_Union devolviendo todas las bandas, transformadas al sistema de proyección especifico del usuario con ST_Transform, y luego enviamos el resultado como un png con ST_AsPNG.

Se podría llamar a la continuación utilizando

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

para obtener la imagen raster en pies del estado de Massachusetts.


<?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]);
?>

9.3.2. Ejemplo de salida utilizando ST_AsPNG junto con otras opciones raster en ASP.NET C#

En esta sección, mostraremos como utilizar el driver Npgsql PostgreSQL .NET y la familia de funciones ST_AsGDALRaster para extraer las nadas 1,2,3 de un raster a una consulta PHP que puede incluirse como una marca html imv src.

Necesitarás el driver npgsql .NET PostgreSQL para este ejercicio que puedes obtener en http://npgsql.projects.postgresql.org/ en su ultima versión. Simplemente descarga la última versión y copialo en tu carpeta bin de ASP.NET y ya estarás listo para seguir.

La consulta de ejemplo muestra cómo combinar un montón de funciones de mapa de bits juntos para obtener todas las teselas que se cruzan con un cuadro delimitador en wgs84 en particular y luego unimos las teselas que intersectan con ST_Union devolviendo todas las bandas, transformadas al sistema de proyección especifico del usuario con ST_Transform, y luego enviamos el resultado como un png con ST_AsPNG.

Este ejemplo es el mismo que el ejemplo Section 9.3.1, “Ejemplo de salida utilizando ST_AsPNG junto con otras opciones raster en PHP” salvo que este esta implementado en C#.

Puedes llamar a este método utilizando

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

para obtener la imagen raster en coordenadas planas en pies del estado de Massachusetts.

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

9.3.3. Aplicación de consola Java que extrae un raster como un fichero de imagen

Esta es una aplicación simple de la consola java que toma una consulta y devuelve una imagen y la extrae a un fichero especificado.

Puedes descargar el último driver PostgreSQL JDBC desde http://jdbc.postgresql.org/download.html

Puedes compilar el siguiente código utilizando un comando similar a este:

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

Y llamarlo desde la linea de comandos de forma similar a:

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

9.3.4. Utilizar PLPython para extraer imágenes vía SQL

Este es una función de almacenamiento plpython que crea un archivo en el directorio del servidor por cada registro. Requiere que tenga instalado plpython. Deberá trabajar bien con ambos plpythonu y 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

9.3.5. Extraer un raster con PSQL

Sadly PSQL doesn't have easy to use built-in functionality for outputting binaries. This is a bit of a hack that piggy backs on PostgreSQL somewhat legacy large object support. To use first launch your psql commandline connected to your database.

A diferencia del enfoque de python, este, crea el fichero en tu equipo local.

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