Chapter 11. 栅格数据管理、查询和应用程序

Table of Contents
11.1. 加载和创建栅格
11.1.1. 使用raster2pgsql加载栅格
11.1.2. 使用PostGIS栅格函数创建栅格
11.1.3. 使用“out db”云栅格
11.2. 栅格目录
11.2.1. 栅格列目录
11.2.2. 栅格概视图
11.3. 使用PostGIS栅格构建自定义应用程序
11.3.1. 结合使用ST_AsPNG和其他栅格函数的PHP输出示例
11.3.2. 结合使用ST_AsPNG和其他栅格函数的ASP.NET C#输出示例
11.3.3. 将栅格查询输出为图像文件的Java控制台应用程序
11.3.4. 使用PLPython通过SQL转储图像
11.3.5. 使用PSQL输出栅格

11.1. 加载和创建栅格

对于大多数使用案例,您将通过使用打包的加载现有栅格文件来创建PostGIS栅格 raster2pgsql 栅格加载器。

11.1.1. 使用raster2pgsql加载栅格

这个 raster2pgsql 是一个栅格加载器可执行文件,用于将GDAL支持的栅格格式加载到适合加载到PostGIS栅格表的SQL中。它能够加载栅格文件的文件夹以及创建栅格概述。

由于raster2pgsql最常被编译为PostGIS的一部分(除非您编译自己的GDAL库),因此可执行文件支持的栅格类型将与GDAL依赖库中编译的栅格类型相同。要获取您的特定raster2pgsql支持的栅格类型列表,请使用 -G 换一下。这些内容应与此处记录的PostGIS安装提供的内容相同 ST_GDALDrivers 如果您对两者使用相同的GDAL库。

[Note]

该工具的较早版本是一个python脚本。该可执行文件已取代了python脚本。如果您仍然需要Python脚本示例,可以在 GDAL PostGIS栅格驱动程序使用 。请注意,raster2pgsql python脚本可能不适用于未来版本的PostGIS栅格,因此不再受支持。

[Note]

从一组已对齐的栅格创建特定因子的概视图时,概视图可能不对齐。参观 http://trac.osgeo.org/postgis/ticket/1764 例如,俯视图不对齐。

用法示例:

raster2pgsql raster_options_go_here raster_file someschema.sometable > out.sql

-?

显示帮助屏幕。如果您不传递任何参数,也会显示帮助。

-G

打印支持的栅格格式。

(C|a|d|p)以下是互斥选项:

-c

创建新表格并用栅格填充它, 这是默认模式

-a

将栅格追加到现有表中。

-d

删除表,创建新表并使用栅格填充它

-p

准备模式,只创建表格。

栅格处理:应用约束以在栅格目录中正确注册

-C

应用栅格约束--sRID、像素大小等以确保在中正确注册栅格 raster_columns 查看。

-x

禁用设置最大范围约束。仅当还使用-C标志时才适用。

-R

设置常规分块的约束(空间唯一和覆盖平铺)。仅当还使用-C标志时才适用。

栅格处理:用于操作输入栅格数据集的可选参数

-S <SRID>

为输出栅格分配指定的SRID。如果未提供或为零,则将检查栅格的元数据以确定适当的SRID。

-b频段

要从栅格中提取的波段的索引(从1开始)。对于多个波段索引,请用逗号(,)分隔。如果未指定,则将提取栅格的所有波段。

-t平铺大小

将栅格剪切成要插入的平铺,每表行一个。 TILE_SIZE 表示为WIDTHxHEIGHT或设置为值“AUTO”,以允许加载程序使用第一个栅格计算适当的平铺大小并应用于所有栅格。

-P

填充最右侧和最底部的瓷砖,以确保所有瓷砖的宽度和高度相同。

-R,--寄存器

将栅格注册为文件系统(out-db)栅格。

只有栅格的元数据和栅格的路径位置存储在数据库中(而不是像素)。

-l OVERVIEW_FACTOR

创建栅格的概览。对于多个因素,请用逗号(,)分隔。概览表名称遵循模式o_ overview factor _ table ,在哪里 overview factor 是数字总览系数的占位符,并且 table 替换为基表名称。创建的概述存储在数据库中,不受-R的影响。请注意,您生成的SQL文件将同时包含主表和概览表。

-N NODATA

要在没有NODATA值的标注栏上使用的NODATA值。

用于操作数据库对象的可选参数

-f列

指定目标栅格列的名称,默认为‘Rast’

-F

使用文件名添加一列

-n列

指定文件名列的名称。隐含-F。

-Q

将PostgreSQL标识符括在引号中。

-我

在栅格列上创建一个Gist索引。

-M

对栅格表进行真空分析。

-k

跳过每个栅格标注栏的NODATA值检查。

-T tablespace

指定新表的表空间。请注意,索引(包括主键)仍将使用默认表空间,除非还使用-X标志。

-X tablespace

指定表的新索引的表空间。如果使用-i标志,这适用于主键和空间索引。

-Y

使用COPY语句而不是INSERT语句。

-e

单独执行每条语句,不要使用事务。

-E Endian

控制栅格生成的二进制输出的字节顺序;为XDR指定0,为NDR指定1(默认);现在仅支持NDR输出

-五 version

指定输出格式的版本。默认值为0。目前仅支持0。

一个使用加载器创建输入文件并将其分块上传到100x100块的示例会话可能如下所示:

[Note]

您可以省略架构名称,例如 demelevation 而不是 public.demelevation 将在数据库或用户的默认方案中创建栅格表

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

转换和上载可以使用UNIX管道在一个步骤中完成:

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

将栅格马萨诸塞州平面米航拍切片加载到名为 aerial 并创建一个完整的视图,2级和4级概览表,使用复制模式进行插入(没有直接到数据库的中间文件),以及-e不强制事务中的所有内容(如果您希望在不等待的情况下立即看到表中的数据,这是很好的)。将栅格分解为128x128像素的平铺并应用栅格约束。使用复制模式而不是表插入。(-F)包括一个名为FileName的字段,用于保存从中剪切分片的文件的名称。

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

G命令输出如下所示的列表

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

11.1.2. 使用PostGIS栅格函数创建栅格

在许多情况下,您会希望在数据库中直接创建栅格和栅格表。有太多的函数可以做到这一点。要遵循的一般步骤。

  1. 创建包含栅格列的表以保存新的栅格记录,这可以通过以下方式完成:

    CREATE TABLE myrasters(rid serial primary key, rast raster);
  2. 有许多功能可以帮助实现这一目标。如果您要创建的栅格不是其他栅格的派生栅格,则需要从以下内容开始: ST_MakeEmptyRaster ,然后是 ST_AddBand

    也可以从几何图形创建栅格。要实现这一点,您需要使用 ST_AsRaster 或许还伴随着其他功能,如 ST_UnionST_MapAlgebraFct 或其他地图代数函数族中的任何一个。

    甚至还有更多选项可用于从现有表创建新的栅格表。例如,您可以使用在不同于现有投影的投影中创建栅格表 ST_Transform

  3. 最初填充表后,您需要在栅格列上创建一个空间索引,如下所示:

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

    请注意 ST_ConvexHull 因为大多数栅格运算符都是基于栅格的凸壳的。

    [Note]

    2.0之前版本的PostGIS栅格是基于封套而不是凸壳的。为了使空间索引正常工作,您需要删除这些索引,并替换为基于凸壳的索引。

  4. 使用以下内容应用栅格约束 AddRasterConstraints

11.1.3. 使用“out db”云栅格

这个 raster2pgsql 该工具使用GDAL来访问栅格数据,并且可以利用GDAL的一项关键功能:能够读取符合以下条件的栅格 远程存储 在云“对象存储”中(例如,AWS S3、谷歌云存储)。

要有效使用云存储的栅格,需要使用“云优化”格式。最广为人知和使用最广泛的是“ 云优化GeoTIFF 使用非云格式,如JPEG或非平铺的TIFF将导致非常差的性能,因为系统每次需要访问子集时都必须下载整个栅格。

首先,将您的栅格加载到您选择的云存储中。加载后,您将有一个URI来访问它,可以是“http”URI,有时也可以是特定于服务的URI。(例如,“s3://存储桶/对象”)。要访问非公共存储桶,您需要提供GDAL配置选项来验证您的连接。请注意,此命令是 阅读 从云栅格和 写作 添加到数据库中。

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

一旦加载表,您需要授予数据库从远程栅格读取的权限,方法是设置两个权限, postgis.enable_outdb_rasterspostgis.gdal_enabled_drivers

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

要使更改具有粘性,请直接在数据库中设置它们。您需要重新连接才能体验新设置。

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

对于非公共栅格,您可能需要提供访问密钥才能从云栅格中读取。您用来编写 raster2pgsql 调用可以设置为在数据库内部使用,使用 postgis.gdal_config_options 配置。注意,可以通过空格分隔设置多个选项 key=value 成对的。

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

一旦加载了数据并设置了权限,您就可以使用相同的函数与栅格表进行交互,就像任何其他栅格表一样。当数据库需要读取像素数据时,它将处理连接到云数据的所有机制。

11.2. 栅格目录

有两个随PostGIS一起提供的栅格目录视图。这两个视图都利用嵌入在栅格表的约束中的信息。因此,由于强制实施了约束,因此目录视图始终与表中的栅格数据一致。

  1. raster_columns 此视图对数据库中的所有栅格表列进行编录。

  2. raster_overviews 此视图编目数据库中的所有栅格表列,这些列用作更细粒度的表的总览。此类型的表是在使用 -l 在加载过程中切换。

11.2.1. 栅格列目录

这个 raster_columns 是数据库中所有栅格类型的栅格表列的目录。它是一个利用对表的约束的视图,因此即使从另一个数据库的备份中恢复一个栅格表,信息也始终是一致的。以下列存在于 raster_columns 目录。

如果您没有使用加载器创建表或忘记指定 -C 标志的情况下,您可以在加载后使用 AddRasterConstraints 这样就可以 raster_columns CATALOG注册有关您的栅格平铺的常见信息。

  • r_table_catalog 表所在的数据库。这将始终读取当前数据库。

  • r_table_schema 栅格表所属的数据库模式。

  • r_table_name 栅格表

  • r_raster_column 中的列 r_table_name 栅格类型的表。在PostGIS中,没有什么可以阻止您在每个表中拥有多个栅格列,因此可以多次列出一个栅格表,每个栅格表都有一个不同的栅格列。

  • srid 栅格的空间参考标识符。中的条目。 Section 4.5, “空间参考系”

  • scale_x 几何空间坐标和像素之间的缩放。仅当栅格列中的所有切片都具有相同的 scale_x 并且应用了该约束。参考 ST_ScaleX 了解更多详细信息。

  • scale_y 几何空间坐标和像素之间的缩放。仅当栅格列中的所有切片都具有相同的 scale_y 以及 scale_y 已应用约束。参考 ST_ScaleY 了解更多详细信息。

  • blocksize_x 每个栅格平铺的宽度(像素数)。参考 ST_Width 了解更多详细信息。

  • blocksize_y 每个栅格平铺的宽度(向下的像素数)。参考 ST_Height 了解更多详细信息。

  • same_alignment 一个布尔值,如果所有栅格平铺都具有相同的对齐方式,则为真。参考 ST_SameAlignment 了解更多详细信息。

  • regular_blocking 如果栅格列具有空间唯一和覆盖范围平铺约束,则值为TRUE。否则,它将是错误的。

  • num_bands 栅格集的每个平铺中的波段数。这与由提供的信息相同 ST_NumBands

  • pixel_types 定义每个波段的像素类型的数组。此数组中的元素数量与波段数量相同。Pixel_Types是中定义的以下类型之一 ST_BandPixelType

  • nodata_values 一个双精度数字数组,表示 nodata_value 每个乐队都有。此数组中的元素数量与波段数量相同。这些数字定义了在大多数操作中应忽略的每个波段的像素值。这是由提供的类似信息 ST_BandNoDataValue

  • out_db 指示是否在数据库外部维护栅格标注栏数据的布尔标志数组。此数组中的元素数量与波段数量相同。

  • extent 这是栅格集中所有栅格行的范围。如果您计划加载更多将更改集合范围的数据,则需要运行 DropRasterConstraints 函数,然后使用 AddRasterConstraints 装货后。

  • spatial_index 一个布尔值,如果栅格列具有空间索引,则为真。

11.2.2. 栅格概视图

raster_overviews 编录有关用于概视图的栅格表列的信息,以及有关它们的其他信息,这些信息在利用概视图时非常有用。概览表在两个目录中都有编目 raster_columnsraster_overviews 因为它们本身就是栅格,但也有一个额外的特殊目的,那就是成为较高分辨率表格的较低分辨率漫画。使用时,将在主栅格表的旁边生成 -l 切换到栅格加载或可使用手动生成 AddOverviewConstraints

概览表包含与其他栅格表相同的约束,以及特定于概视图的其他仅信息性约束。

[Note]

中的信息 raster_overviews 不会复制中的信息 raster_columns 。如果您需要有关在 raster_columns 你可以加入 raster_overviewsraster_columns 共同获取您所需的全套信息。

综述的两个主要原因是:

  1. 核心表的低分辨率表示,通常用于快速映射缩小。

  2. 在它们上进行计算通常比它们更高分辨率的父代更快,因为它们的记录更少,每个像素覆盖的区域更大。虽然计算不像它们支持的高分辨率表那样准确,但它们在许多经验法则计算中是足够的。

这个 raster_overviews 目录包含以下信息列。

  • o_table_catalog 概览表所在的数据库。这将始终读取当前数据库。

  • o_table_schema 概述栅格表所属的数据库模式。

  • o_table_name 栅格概览表名称

  • o_raster_column 概览表中的栅格列。

  • r_table_catalog 此概述服务所在的栅格表的数据库。这将始终读取当前数据库。

  • r_table_schema 此概述服务所属的栅格表的数据库模式。

  • r_table_name 此概述服务的栅格表。

  • r_raster_column 此概述专栏所服务的栅格列。

  • overview_factor -这是概览表的金字塔级别。数字越大,表格的分辨率就越低。如果给raster2pgsql一个图像文件夹,它将计算每个图像文件的概览并单独加载。假定为级别1,并且始终为原始文件。级别2 IS将使每个瓷砖代表原始瓷砖的4个。例如,如果您有一个包含5000x5000像素图像文件的文件夹,并且您选择将其分块为125x125,那么对于每个图像文件,您的基表将有(5000*5000)/(125*125)条记录=1600,您的(l=2) o_2 表将有上限(1600/Power(2,2))=400行,您的(l=3) o_3 将有上限(1600/Power(2,3))=200行。如果您的像素不能除以您的瓷砖的大小,你会得到一些废瓷砖(瓷砖没有完全填满)。请注意,由raster2pgsql生成的每个概述平铺的像素数与其父平铺的像素数相同,但分辨率较低,其中它的每个像素表示(Power(2,view_factor)像素的原始)。

11.3. 使用PostGIS栅格构建自定义应用程序

PostGIS栅格为您提供了以已知图像格式渲染栅格的SQL函数,这一事实为您提供了许多渲染选项。例如,您可以使用OpenOffice/LibreOffice进行渲染,如中所示 使用LibreOffice基本报表渲染PostGIS栅格图形 。此外,您还可以使用本节中演示的多种语言。

11.3.1. 结合使用ST_AsPNG和其他栅格函数的PHP输出示例

在本节中,我们将演示如何使用PHP PostgreSQL驱动程序和 ST_AsGDALRaster 将栅格的波段1、2、3输出到PHP请求流的函数系列,然后可以嵌入到img src html标记中。

示例查询演示了如何将一整组栅格函数组合在一起,以获取与特定WGS 84边界框相交的所有切片,然后与 ST_Union 相交的切片一起返回所有波段,使用转换为用户指定的投影 ST_Transform ,然后使用PNG将结果输出为PNG ST_AsPNG

您可以使用以下命令调用以下代码

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

以获得马萨诸塞州平面英尺的栅格图像。

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

11.3.2. 结合使用ST_AsPNG和其他栅格函数的ASP.NET C#输出示例

在本部分中,我们将演示如何使用Npgsql PostgreSQL.NET驱动程序和 ST_AsGDALRaster 将栅格的波段1、2、3输出到PHP请求流的函数系列,然后可以嵌入到img src html标记中。

本练习需要npgsql.NET PostgreSQL驱动程序,您可以从获取最新的 http://npgsql.projects.postgresql.org/ 。只需下载最新版本并放入您的ASP.NETbin文件夹,就可以了。

示例查询演示了如何将一整组栅格函数组合在一起,以获取与特定WGS 84边界框相交的所有切片,然后与 ST_Union 相交的切片一起返回所有波段,使用转换为用户指定的投影 ST_Transform ,然后使用PNG将结果输出为PNG ST_AsPNG

这与下面的示例相同 Section 11.3.1, “结合使用ST_AsPNG和其他栅格函数的PHP输出示例” 除了用C#实现之外。

您可以使用以下命令调用以下代码

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

以获得马萨诸塞州平面英尺的栅格图像。

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

11.3.3. 将栅格查询输出为图像文件的Java控制台应用程序

这是一个简单的Java控制台应用程序,它接受一个查询,返回一个图像并输出到指定的文件。

您可以从下载最新的PostgreSQL JDBC驱动程序 http://jdbc.postgresql.org/download.html

您可以使用类似以下命令的命令编译以下代码:

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

并在命令行中使用类似于

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

11.3.4. 使用PLPython通过SQL转储图像

这是一个plpython存储函数,它在服务器目录中为每个记录创建一个文件。要求您安装了plpython。对于plpythonu和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

11.3.5. 使用PSQL输出栅格

遗憾的是,PSQL没有用于输出二进制文件的易于使用的内置功能。这有点像是利用了PostgreSQL对遗留大对象的支持。要使用它,首先启动连接到数据库的psql命令行。

与python方法不同,此方法在您的本地计算机上创建文件。

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