Chapter 10. Gerência de dados raster, pesquisas e aplicações

Table of Contents

10.1. Carregando e criando dados matriciais

Para a maioria dos casos, você usará a ferramenta raster2pgsql para carregar os dados matricias para o PostGIS.

10.1.1. Usando o raster2pgsql para carregar dados matricias

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]

Na criação de overviews de um fator específico de um conjunto de rasters que estão alinhados, é possível que as overviews não se alinhem. Visite http://trac.osgeo.org/postgis/ticket/1764 para ver um exemplo onde as overviews não se alinham.

10.1.1.1. Example Usage

Uma sessão de exemplo usando o carregador para criar um arquivo de entrada fazendo upload de seus azulejos fragmentados em 100x100, pode ficar parecido com:

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

Uma conversão e u upload podem ser feitos em apenas um passo usando encadeamento UNIX:

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

Carregue as tiles em metros dos rasters do estado plano de Massachusetts no esquema chamado: aerial e crie uma view completa,tabelas panoramas de níveis 2 e 4, use o modo cópia para inserir (sem arquivos intermediários), e -e não força tudo em uma transação (é bom se você quiser ver dados em tabelas sem esperar nada por isso). Quebre os rasters em 128x128 pixel tiles e aplique restrições de rasters. Utilize o modo cópia em vez da tabela inserida. (-F) Inclui um campo chamado filename para conter o nome do arquivo de onde as tiles cortam.

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

Os comandos -G geram uma lista parecida com

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 options

-?

Tela de ajuda. A ajuda também é exibida se você não passar em nenhum argumento.

-G

Imprimir os formatos de raster suportados.

(c|a|d|p) Essas são opções mutualmente exclusivas:

-c

Criar nova table e popular ela com raster(s), esse é o modo padrão

-a

Anexar raster(s) à uma table existente.

-d

Derrubar table, criar nova e popular ela com raster(s)

-p

Preparar modo, somente criar a table.

Processo raster: Solicitando restrições para registro apropriado nos catálogos raster

-C

Solicitar restrições raster -- srid, pixelsize etc. para assegurar que o raster está registrado corretamente na view raster_columns .

-x

Desativar configuração da extensão de restrição máxima. Empregado somente se a bandeira -C também for.

-r

Configurar as restrições (espacialmente únicas e telha de cobertura) para bloqueio normal. Empregado somente se a bandeira -C também for.

Processo raster: Parâmetros opcionais usados para manipular a entrada do conjunto de dados raster

-s <SRID>

Saída raster designada com SRID específico. Se não for fornecida ou for zero, os metadados raster serão verificados para determinar um SRID apropriado.

-b BAND

Índice (1-base) da banda para extrair de raster. Para mais de um índice de banda, separe com vírgula(,). Se não especificado, todas as bandas de raster serão extraídas.

-t TILE_SIZE

Corte raster em ladrilhos para ser inserido um por fileira na tabela. O TILE_SIZE é expressado como LARGURAxALTURA ou configurado para o valor "auto" para permitir o carregador computar um tamanho usando o primeiro raster e aplicando para os outros rasters.

-P

Preenche a maioria das tiles da direita e de baixo para garantir que todas as tiles tenham a mesma largura e peso.

-R, --register

Registrar o raster como o sistema de arquivos raster (out-db).

Somente os metadados do raster e a localização do caminho para o raster estão armazenados no banco de dados (não os pixels).

-l OVERVIEW_FACTOR

Cria uma visão geral do raster. Para mais de um fator, separe com a vírgula(,). A visão geral da tabela de nomes segue o modelo o_overview factor_table, onde overview factor é um marcador de posição para um fator de visão geral numérico e table é substituído com a tabela de nome básica. A visão geral criada está armazenada no banco de dados e não é afetada por -R. Note que seu arquivo sql criado contém a tabela principal e as tabelas panoramas.

-N NODATA

NODATA valor para usar em bandas sem um valor NODATA.

Parâmetros opcionais usados para manipular objetos do banco de dados

-f COLUMN

Especificar nome de destinação da coluna raster, o padrão é 'rast'

-F

Adicionar uma coluna com o nome do arquivo

-n COLUMN

Especificar o nome da coluna filename. Sugere -F.

-q

Identificadores wrap PostgreSQL em citações.

-I

Cria um índice GiST na coluna raster.

-M

Vácuo analise a tabela 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

Especificar o espaço da tabela para a nova tabela. Note que os índices (incluindo a chave primária) continuarão sendo usados o espaço de tabela padrão, a menos que a bandeira -X também esteja sendo usada.

-X tablespace

Especificar o espaço da tabela para a nova tabela. Isto se aplica à chave primária e ao índice espacial se a bandeira -I estiver sendo usada.

-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

Execute cada declaração individualmente, não use uma transação.

-E ENDIAN

Controla endianidade da saída binária gerada do raster; especificamos 0 para XDR e 1 para NDR (padrão); somente a saída NDR é suportada agora

-V version

Especificamos uma versão de formato de saída. O padrão é 0. Somente o 0 é suportado neste momento.

10.1.2. Criando rasters utilizando as funções rasters do PostGIS

Em várias ocasiões, você vai querer criar rasters e tabelas rasters no banco de dados. Existe uma superabundância de funções que fazem isto. Os passos gerais para seguir.

  1. Cria uma tabela com uma coluna raster para segurar os novos relatos rasters que são efetuados com:

    CREATE TABLE myrasters(rid serial primary key, rast raster);
  2. Existem várias funções para auxiliar com este objetivo. Se você não estiver criando rasters como derivados de outros rasters, você precisará de começar com: ST_MakeEmptyRaster, seguido por ST_AddBand

    Você também pode criar rasters de geometrias. Para alcançar seu objetivo, você irá querer usar ST_AsRaster talvez acompanhado com outras funções como: ST_Union ou ST_MapAlgebraFct ou qualquer um da família de outras funções álgebra de mapa.

    Existem ainda mais opções para a criação de novas tabelas rasters a partir das tabelas existentes. Você pode criar uma tabela raster em uma projeção diferente de uma existente, por exemplo, utilizando: ST_Transform

  3. Uma vez que você houver terminado de popular sua tabela inicialmente, você vai querer criar um índice espacial na coluna raster com algo parecido com:

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

    Note o uso do ST_ConvexHull já que a maioria dos operados raster são baseados no casco convexo dos rasters.

    [Note]

    Versões pre-2.0 do raster PostGIS eram baseadas no envelope em vez do casco convexo, Para os índices espaciais funcionar propriamente, você precisará derrubar estes e substituí-los com índice de casco convexo.

  4. Aplique restrições rasters usando

10.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_vsi_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.

10.2. Catálogos Raster

Existem duas view raster catalogadas que vêm compactadas com o PostGIS. Ambas views utilizam informações embutidas em restrições das tabelas rasters. Como resultado as views catalogadas são sempre consistentes com os dados raster nas tabelas já que as restrições são impostas.

  1. raster_columns esta view cataloga todas os tabelas de colunas rasters no seu banco de dados.

  2. raster_overviews esta view cataloga todos as tabelas de colunas raster no seu banco de dados que servem como um panorama para uma tabela granulada melhor. Tabelas deste tipo são geradas quando você utiliza o interruptor -l durante o carregamento.

10.2.1. Catálogo de Colunas Raster

O raster_columns é um catálogo de todas as colunas de tabela raster no seu banco de dados que são do tipo raster. É uma view utilizando as restrições nas tabelas para que a informação seja sempre consistente, mesmo se você tiver restaurado uma tabela raster de um backup de outro banco de dados. As seguintes colunas existem no catálogo raster_columns.

Se você criou suas tabelas sem o carregador ou esqueceu de especificar a bandeira -C durante o carregamento, você pode forçar as restrições depois de usá-las de fato AddRasterConstraints para que o catálogo raster_columns registre as informações comuns sobre as tiles raster.

  • r_table_catalog O banco de dados que a tabela está. Isto irá sempre ler o banco de dados atual.

  • r_table_schema O esquema do banco de dados que o raster pertence.

  • r_table_name raster table

  • r_raster_column a coluna é a r_table_name tabela que é do tipo raster. Não há nada no PostGIS que previna múltiplas colunas raster por tabela, assim, é possível haver uma tabela raster listada várias vezes com uma coluna raster diferente pra cada uma.

  • srid O identificador de referência espacial do raster. Deve ser uma entrada no Section 4.5, “The SPATIAL_REF_SYS Table and Spatial Reference Systems”.

  • scale_x A escala entre coordenadas geométricas espaciais e pixel. Isto só está disponível se todas as tiles na coluna raster tiverem a mesma scale_x e esta restrição for aplicada. Recorra a ST_ScaleX para mais detalhes.

  • scale_y A escala entre coordenadas geométricas espaciais e pixel. Isto só está disponível se todas as tiles na coluna raster tiverem a mesma scale_y e a restrição scale_y for aplicada. Recorra a ST_ScaleY para mais detalhes.

  • blocksize_x A largura (número de pixels obliquamente) de cada raster tile. Recorrer aST_Width para mais detalhes.

  • blocksize_y A largura (número de pixels para baixo) de cada raster tile. Recorrer a ST_Height para mais detalhes.

  • same_alignment Uma booleana que é verdade se todos os rasters tiles têm o mesmo alinhamento. Recorrer a ST_SameAlignment para mais detalhes.

  • regular_blocking Se a coluna raster possui a espacialidade única e cobre restrições tiles, o valor com ela se torna VERDADE. Senão, será FALSO.

  • num_bands O número de bandas em cada tile do seu conjunto de raster. É a mesma informação da que é fornecida por ST_NumBands

  • pixel_types Um arranjo definindo o tipo de pixel para cada banda. Você terá o mesmo número de elementos e bandas nesse arranjo. Os pixel_types são uns dos definidos em ST_BandPixelType.

  • nodata_values Um arranjo de números preciso dobrados indicando o nodata_value para cada banda. Você terá o mesmo número de elementos e de bandas neste arranjo. Esses números definem o valor do pixel para cada banda que deveria ser ignorada para a maioria das operações. Uma informação parecida é fornecida por: ST_BandNoDataValue.

  • out_db Um arranjo de bandeiras booleanas indicando se os dados das bandas rasters são mantidos de fora do banco de dados. Você terá o mesmo número de elementos e bandas neste arranjo.

  • extent Isto é uma extensão de todas as filas raster no sua configuração raster. Se você planeja carregar mais dados que irão modificar a extensão de configuração, precisará executar a função DropRasterConstraints antes de carregar e então reaplicar as restrições com AddRasterConstraints depois carregar.

  • spatial_index Uma booleana que é verdade se uma coluna raster possui um índice espacial.

10.2.2. Panoramas Raster

raster_overviews cataloga informação sobre as colunas de tabelas raster usadas para panoramas e informações adicionais sobre elas, que são úteis para saber quando usar os panoramas. As tabelas de panoramas são catalogadas em raster_columns e raster_overviews, porque elas são raster, mas também têm um propósito especial de serem uma caricatura de baixa resolução de uma tabela de alta resolução. Elas são geradas ao longo do lado da tabela raster principal quando você usa a troca -l no carregamento raster ou podem ser geradas manualmente, utilizando: AddOverviewConstraints.

Tabelas resumidas contêm as mesmas restrições que as outras tabelas raster bem como informações adicionais somente restrições específicas para panoramas.

[Note]

A informação em raster_overviews não duplica a informação em raster_columns. Se você precisa da informação sobre uma tabela panorama presente em raster_columns, você pode unir as raster_overviews e raster_columns para obter o conjunto completo de informações que precisa.

Duas razões principais para panoramas são:

  1. Baixa resolução das tabelas de núcleo comumente usadas para um mapeamento de aproximação mais rápido.

  2. Os cálculos são, geralmente, mais rápidos de serem feitos em si mesmos que a resolução mais alta de seus parentes, porque são relatos menores e cada pixel cobre mais território. Embora os cálculos não são tão atuais quanto as tabelas high-res que eles suportam, eles pode ser suficientes em vários cálculos da regra do polegar.

O catálogo raster_overviews contém as seguintes colunas de informação.

  • o_table_catalog O banco de dados que o panorama está localizado. Isto sempre irá ler o banco de dados atual.

  • o_table_schema O esquema do banco de dados que a tabela do panorama raster pertence.

  • o_table_name nome da tabela de panorama raster

  • o_raster_column a coluna raster na tabela panorama

  • r_table_catalog O banco de dados que a tabela raster que este panorama está. Isto sempre lerá o banco de dados atual.

  • r_table_schema O esquema do banco de dados da tabela raster que os serviços do panorama pertence.

  • r_table_name tabela raster que este panorama fornece.

  • r_raster_column a coluna raster que esta coluna panorama fornece.

  • overview_factor - este é o nível da pirâmide da tabela panorama. Quanto maior o número menor a resolução da tabela. raster2pgsql se dada uma pasta de imagens, irá calcular panorama de cada arquivo de imagem e carregar separadamente. O nível 1 é assumido e sempre o arquivo original. Nível 2 terá que cada tile representa 4 do original. Então, por exemplo, se você tem uma pasta com arquivos de imagens de 5000x5000 pixel e você escolhe ordenar 125x125, para cada arquivo de imagem sua tabela base terá (5000*5000)/(125*125) records = 1600, your (l=2) o_2 will have ceiling(1600/Power(2,2)) = 400 rows, your (l=3) o_3 will have ceiling(1600/Power(2,3) ) = 200 rows. Se seus pixels não são visíveis pelo tamanho das suas tiles, você pegará algumas tiles sobras (que não estão completamente cheias). Note que cada tile panorama gerada pelo raster2pgsql tem o meso número de pixels de seus pais, mas é de uma resolução menor onde cada pixel dele representa (Power(2,overview_factor) pixels do original).

10.3. Construindo Aplicações Personalizadas com o 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.

10.3.1. PHP Exemplo Outputting usando ST_AsPNG em consenso co outras funções raster

Nesta seção, demonstraremos como usar o driver PHP PostgreSQL e a família ST_AsGDALRaster de funções para gerar banda 1,2,3 de um raster para um fluxo de solicitação PHP que pode ser inserido em uma img src html tag.

A consulta exemplo demonstra como combinar um conjunto de funções raster para apanhar todas as tiles que intersectam uma caixa delimitadora wgs 84 e então une com ST_Union as tiles intersectando retornando todas as bandas, transforma para projeção de usuário específico usando ST_Transform, e gera os resultados como um png usando ST_AsPNG.

Você poderia chamar o abaixo usando

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

para obter a imagem raster no 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# Exemplo gerado usando ST_AsPNG em consenso com outras funções raster

Nesta seção, demonstraremos como usar o driver PHP PostgreSQL .NET driver e a família ST_AsGDALRaster de funções para gerar banda 1,2,3 de um raster para um fluxo de solicitação PHP que pode ser inserido em uma img src html tag.

Você precisará do driver npgsql .NET PostgreSQL para este exercício que pode ser obtido em: http://npgsql.projects.postgresql.org/. Apenas faça o download e coloque na sua pasta ASP.NET bin e você estará pronto.

A consulta exemplo demonstra como combinar um conjunto de funções raster para apanhar todas as tiles que intersectam uma caixa delimitadora wgs 84 e então une com ST_Union as tiles intersectando retornando todas as bandas, transforma para projeção de usuário específico usando ST_Transform, e gera os resultados como um png usando ST_AsPNG.

Este é o mesmo exemplo de Section 10.3.1, “PHP Exemplo Outputting usando ST_AsPNG em consenso co outras funções raster” exceto implementado em C#.

Você poderia chamar o abaixo usando

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

para obter a imagem raster no 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. O app console Java que gera a consulta raster como arquivo de imagem

Este é um exemplo de aplicativo console java que utiliza uma consulta que retorna uma imagem e gera um arquivo específico.

Você pode baixar os últimos drivers PostgreSQL JDBC de http://jdbc.postgresql.org/download.html

Você pode compilar o código seguinte usando um comando como:

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

E chama da linha de comando com algo tipo

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. Use PLPython para excluir imagens via SQL

Esta é uma função plpython armazenada que cria um arquivo no diretório do servidor para cada relato. Requer que tenha instalado plpython. Deve funcionar bem com plpythonu e 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. Rasters de saída com PSQL

Infelizmente o PSQL não tem facilidade em usar funcionalidade embutida para binários gerados. Isto é um pequeno hack no legado PostgreSQL de suporte de objetos grandes. Para usar, primeiro lance sua linha de comando psql conectada no seu banco de dados.

Diferente da aproximação python, esta cria o arquivo no seu computador 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);