<!-- Converted by db4-upgrade version 1.1 -->
<chapter xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="RT_reference">
  <title>Raster Reference</title>

  <para><varname>raster</varname> is a PostGIS type for storing and analyzing raster data. </para>
  <para>For loading rasters from raster files please refer to <xref linkend="RT_Loading_Rasters"/></para>

    <para>Some examples in this reference use a raster table of dummy data,
    created with the following code:</para>
<programlisting language="sql">CREATE TABLE dummy_rast(rid integer, rast raster);
INSERT INTO dummy_rast(rid, rast)
VALUES (1,
('01' -- little endian (uint8 ndr)
||
'0000' -- version (uint16 0)
||
'0000' -- nBands (uint16 0)
||
'0000000000000040' -- scaleX (float64 2)
||
'0000000000000840' -- scaleY (float64 3)
||
'000000000000E03F' -- ipX (float64 0.5)
||
'000000000000E03F' -- ipY (float64 0.5)
||
'0000000000000000' -- skewX (float64 0)
||
'0000000000000000' -- skewY (float64 0)
||
'00000000' -- SRID (int32 0)
||
'0A00' -- width (uint16 10)
||
'1400' -- height (uint16 20)
)::raster
),
-- Raster: 5 x 5 pixels, 3 bands, PT_8BUI pixel type, NODATA = 0
(2, ('01000003009A9999999999A93F9A9999999999A9BF000000E02B274A' ||
'41000000007719564100000000000000000000000000000000FFFFFFFF050005000400FDFEFDFEFEFDFEFEFDF9FAFEF' ||
'EFCF9FBFDFEFEFDFCFAFEFEFE04004E627AADD16076B4F9FE6370A9F5FE59637AB0E54F58617087040046566487A1506CA2E3FA5A6CAFFBFE4D566DA4CB3E454C5665')::raster);</programlisting>

  <para>The functions below are ones which a user of PostGIS Raster is likely to need.
  There are other raster support functions which are not of interest to a general
  user.</para>

  <section xml:id="Raster_Types">
    <title>Raster Support Data types</title><info>
            <abstract>
                <para>This section lists the PostgreSQL data types specifically created to support raster functionality.</para>
            </abstract>
    </info>


        <refentry xml:id="geomval">
            <refnamediv>
                <refname>geomval</refname>
                <refpurpose>A spatial datatype with two fields - geom (holding a geometry object)
                    and val (holding a double precision pixel value from a raster band).</refpurpose>
            </refnamediv>

            <refsection>
            <title>Description</title>
            <para>geomval is a compound data type consisting of a geometry object referenced by the .geom field
                and val, a double precision value that represents the pixel value at a particular geometric location in a raster band.
                It is used by the ST_DumpAsPolygon and Raster intersection family of functions as an output type to explode a raster band into
                geometry polygons.</para>
            </refsection>
            <refsection>
                <title>See Also</title>
                <para><xref linkend="PostGIS_Geometry_DumpFunctions"/> </para>
            </refsection>
        </refentry>

        <refentry xml:id="addbandarg">
            <refnamediv>
                <refname>addbandarg</refname>
                <refpurpose>A composite type used as input into the ST_AddBand function defining the attributes and initial value of the new band.</refpurpose>
            </refnamediv>

            <refsection>
                <title>Description</title>
                <para>A composite type used as input into the ST_AddBand function defining the attributes and initial value of the new band.</para>
                <informaltable tabstyle="styledtable">
                    <tgroup cols="3">
                        <thead>
                            <row>
                                <entry>Field</entry>
                                <entry>Type</entry>
                                <entry>Description</entry>
                            </row>
                        </thead>
                        <tbody>
                            <row>
                                <entry><varname>index</varname></entry>
                                <entry><type>integer</type></entry>
                                <entry>1-based value indicating the position where the new band will be added amongst the raster's bands. If NULL, the new band will be added at the end of the raster's bands.</entry>
                            </row>
                            <row>
                                <entry><varname>pixeltype</varname></entry>
                                <entry><type>text</type></entry>
                                <entry>Pixel type of the new band. One of the pixel types described in <xref linkend="RT_ST_BandPixelType"/>.</entry>
                            </row>
                            <row>
                                <entry><varname>initialvalue</varname></entry>
                                <entry><type>double precision</type></entry>
                                <entry>Initial value that all pixels of the new band will be set to.</entry>
                            </row>
                            <row>
                                <entry><varname>nodataval</varname></entry>
                                <entry><type>double precision</type></entry>
                                <entry>NODATA value of the new band. If NULL, the new band will not have a NODATA value assigned.</entry>
                            </row>
                        </tbody>
                    </tgroup>
                </informaltable>
            </refsection>

            <refsection>
                <title>See Also</title>
                <para>
                    <xref linkend="RT_ST_AddBand"/>
                </para>
            </refsection>
        </refentry>

        <refentry xml:id="rastbandarg">
            <refnamediv>
                <refname>rastbandarg</refname>
                <refpurpose>A composite type for use when needing to express a raster and a band index of that raster.</refpurpose>
            </refnamediv>

            <refsection>
                <title>Description</title>
                <para>A composite type for use when needing to express a raster and a band index of that raster.</para>
                <informaltable tabstyle="styledtable">
                    <tgroup cols="3">
                        <thead>
                            <row>
                                <entry>Field</entry>
                                <entry>Type</entry>
                                <entry>Description</entry>
                            </row>
                        </thead>
                        <tbody>
                            <row>
                                <entry><varname>rast</varname></entry>
                                <entry><type>raster</type></entry>
                                <entry>The raster in question.</entry>
                            </row>
                            <row>
                                <entry><varname>nband</varname></entry>
                                <entry><type>integer</type></entry>
                                <entry>1-based value indicating the raster band.</entry>
                            </row>
                        </tbody>
                    </tgroup>
                </informaltable>
            </refsection>

            <refsection>
                <title>See Also</title>
                <para>
                    <xref linkend="RT_ST_MapAlgebra"/>
                </para>
            </refsection>
        </refentry>

        <refentry xml:id="raster">
            <refnamediv>
                <refname>raster</refname>
                <refpurpose>raster spatial data type.</refpurpose>
            </refnamediv>

            <refsection>
            <title>Description</title>
            <para>raster is a spatial data type used to represent raster data such as those imported from JPEGs, TIFFs, PNGs, digital elevation models.
                Each raster has 1 or more bands each having a set of pixel values. Rasters can be georeferenced.</para>
            <note>
              <para>Requires PostGIS be compiled with GDAL support. Currently rasters can be implicitly converted to geometry type, but the conversion returns the
                <xref linkend="RT_ST_ConvexHull"/> of the raster.  This auto casting may be removed in the near future so don't rely on it.</para>
            </note>
            </refsection>

            <refsection>
            <title>Casting Behavior</title>
            <para>This section lists the automatic as well as explicit casts allowed for this data type</para>
            <informaltable rowsep="1" frame="all" tabstyle="postgis-cast-table">
            <tgroup cols="2">
                <thead>
                  <row>
                    <entry>Cast To</entry>
                    <entry>Behavior</entry>
                  </row>
                </thead>
                <tbody>
                  <row>
                    <entry>geometry</entry>
                    <entry>automatic</entry>
                  </row>
                </tbody>
            </tgroup>
            </informaltable>
            </refsection>

            <refsection>
                <title>See Also</title>
                <para><xref linkend="RT_reference"/></para>
            </refsection>
        </refentry>

        <refentry xml:id="reclassarg">
          <refnamediv>
            <refname>reclassarg</refname>
            <refpurpose>A composite type used as input into the ST_Reclass function defining the behavior of reclassification.</refpurpose>
          </refnamediv>
          <refsection>
            <title>Description</title>
            <para>A composite type used as input into the <xref linkend="RT_ST_Reclass"/> function defining the behavior of reclassification.</para>
            <informaltable tabstyle="styledtable">
                <tgroup cols="3">
                    <thead>
                        <row>
                            <entry>Field</entry>
                            <entry>Type</entry>
                            <entry>Description</entry>
                        </row>
                    </thead>
                    <tbody>
                        <row>
                            <entry><varname>nband</varname></entry>
                            <entry><type>integer</type></entry>
                            <entry>The band number of band to reclassify.</entry>
                        </row>
                        <row>
                            <entry><varname>reclassexpr</varname></entry>
                            <entry><type>text</type></entry>
                            <entry>Comma-delimited <literal>range:map_range</literal> mappings that define how old band values map to new band values.</entry>
                        </row>
                        <row>
                            <entry><varname>pixeltype</varname></entry>
                            <entry><type>text</type></entry>
                            <entry>One of defined pixel types as described in <xref linkend="RT_ST_BandPixelType"/>.</entry>
                        </row>
                        <row>
                            <entry><varname>nodataval</varname></entry>
                            <entry><type>double precision</type></entry>
                            <entry>Value to treat as no data. For image outputs that support transparency, these will be blank.</entry>
                        </row>
                    </tbody>
                </tgroup>
            </informaltable>
            <para>The <varname>reclassexpr</varname> range delimiters mean: <literal>(</literal> greater than, <literal>)</literal> less than, <literal>]</literal> less than or equal, and <literal>[</literal> greater than or equal.</para>
            <itemizedlist>
                <listitem><para><literal>[a-b]</literal> means <literal>a &lt;= x &lt;= b</literal>.</para></listitem>
                <listitem><para><literal>(a-b]</literal> means <literal>a &lt; x &lt;= b</literal>.</para></listitem>
                <listitem><para><literal>[a-b)</literal> means <literal>a &lt;= x &lt; b</literal>.</para></listitem>
                <listitem><para><literal>(a-b)</literal> means <literal>a &lt; x &lt; b</literal>.</para></listitem>
            </itemizedlist>
            <para>Opening-parenthesis notation is optional, so <literal>a-b</literal> means the same as <literal>(a-b)</literal>.</para>
          </refsection>
          <refsection>
              <title>Examples</title>
              <para>Reclassify band 2 as an 8BUI where 255 is nodata value.</para>
              <programlisting language="sql">SELECT ROW(2, '0-100:1-10, 101-500:11-150,501 - 10000: 151-254', '8BUI', 255)::reclassarg;</programlisting>

              <para>Reclassify band 1 as an 1BB and no nodata value defined.</para>
              <programlisting language="sql">SELECT ROW(1, '0-100]:0, (100-255:1', '1BB', NULL)::reclassarg;</programlisting>
          </refsection>
           <refsection>
                <title>See Also</title>
                <para><xref linkend="RT_ST_Reclass"/></para>
           </refsection>
        </refentry>

        <refentry xml:id="summarystats">
            <refnamediv>
                <refname>summarystats</refname>
                <refpurpose>A composite type returned by the ST_SummaryStats and ST_SummaryStatsAgg functions.</refpurpose>
            </refnamediv>

            <refsection>
                <title>Description</title>
                <para>
                    A composite type returned by the <xref linkend="RT_ST_SummaryStats"/> and <xref linkend="RT_ST_SummaryStatsAgg"/> functions.

                    <variablelist>
                        <varlistentry>
                            <term>
                                count
                                integer
                            </term>
                            <listitem>
                                <para>
                                    Number of pixels counted for the summary statistics.
                                </para>
                            </listitem>
                        </varlistentry>

                        <varlistentry>
                            <term>
                                sum
                                double precision
                            </term>
                            <listitem>
                                <para>
                                    Sum of all counted pixel values.
                                </para>
                            </listitem>
                        </varlistentry>

                        <varlistentry>
                            <term>
                                mean
                                double precision
                            </term>
                            <listitem>
                                <para>
                                    Arithmetic mean of all counted pixel values.
                                </para>
                            </listitem>
                        </varlistentry>

                        <varlistentry>
                            <term>
                                stddev
                                double precision
                            </term>
                            <listitem>
                                <para>
                                    Standard deviation of all counted pixel values.
                                </para>
                            </listitem>
                        </varlistentry>

                        <varlistentry>
                            <term>
                                min
                                double precision
                            </term>
                            <listitem>
                                <para>
                                    Minimum value of counted pixel values.
                                </para>
                            </listitem>
                        </varlistentry>

                        <varlistentry>
                            <term>
                                max
                                double precision
                            </term>
                            <listitem>
                                <para>
                                    Maximum value of counted pixel values.
                                </para>
                            </listitem>
                        </varlistentry>

                    </variablelist>

                </para>
            </refsection>

            <refsection>
                <title>See Also</title>
                <para>
                    <xref linkend="RT_ST_SummaryStats"/>,
                    <xref linkend="RT_ST_SummaryStatsAgg"/>
                </para>
            </refsection>
        </refentry>
        <refentry xml:id="unionarg">
            <refnamediv>
                <refname>unionarg</refname>
                <refpurpose>A composite type used as input into the ST_Union function defining the bands to be processed and behavior of the UNION operation.</refpurpose>
            </refnamediv>

            <refsection>
                <title>Description</title>
                <para>A composite type used as input into the ST_Union function defining the bands to be processed and behavior of the UNION operation.</para>
                <informaltable tabstyle="styledtable">
                    <tgroup cols="3">
                        <thead>
                            <row>
                                <entry>Field</entry>
                                <entry>Type</entry>
                                <entry>Description</entry>
                            </row>
                        </thead>
                        <tbody>
                            <row>
                                <entry><varname>nband</varname></entry>
                                <entry><type>integer</type></entry>
                                <entry>1-based value indicating the band of each input raster to be processed.</entry>
                            </row>
                            <row>
                                <entry><varname>uniontype</varname></entry>
                                <entry><type>text</type></entry>
                                <entry>Type of union operation. One of the types described in <xref linkend="RT_ST_Union"/>.</entry>
                            </row>
                        </tbody>
                    </tgroup>
                </informaltable>
            </refsection>

            <refsection>
                <title>See Also</title>
                <para>
                    <xref linkend="RT_ST_Union"/>
                </para>
            </refsection>
        </refentry>

  </section>

  <section xml:id="Raster_Management_Functions">
    <title>Raster Management</title>
    <refentry xml:id="RT_AddRasterConstraints">
      <refnamediv>
        <refname>AddRasterConstraints</refname>

        <refpurpose>Adds raster constraints to a loaded raster table for a specific column that constrains spatial ref, scaling, blocksize, alignment, bands, band type and a flag to denote if raster column is regularly blocked. The table must be loaded with data for the constraints to be inferred. Returns true if the constraint setting was accomplished and issues a notice otherwise.</refpurpose>
      </refnamediv>

      <refsynopsisdiv>
        <funcsynopsis>
          <funcprototype>
            <funcdef>boolean <function>AddRasterConstraints</function></funcdef>

            <paramdef><type>name </type>
            <parameter>rasttable</parameter></paramdef>

            <paramdef><type>name </type>
            <parameter>rastcolumn</parameter></paramdef>

            <paramdef choice="opt"><type>boolean </type>
            <parameter>srid=true</parameter></paramdef>

            <paramdef choice="opt"><type>boolean </type>
            <parameter>scale_x=true</parameter></paramdef>

            <paramdef choice="opt"><type>boolean </type>
            <parameter>scale_y=true</parameter></paramdef>

            <paramdef choice="opt"><type>boolean </type>
            <parameter>blocksize_x=true</parameter></paramdef>

            <paramdef choice="opt"><type>boolean </type>
            <parameter>blocksize_y=true</parameter></paramdef>

            <paramdef choice="opt"><type>boolean </type>
            <parameter>same_alignment=true</parameter></paramdef>

            <paramdef choice="opt"><type>boolean </type>
            <parameter>regular_blocking=false</parameter></paramdef>

            <paramdef choice="opt"><type>boolean </type>
                <parameter>num_bands=true</parameter>
            </paramdef>
            <paramdef choice="opt"><type>boolean </type>
                <parameter>pixel_types=true</parameter>
            </paramdef>
            <paramdef choice="opt"><type>boolean </type>
                <parameter>nodata_values=true</parameter>
            </paramdef>
            <paramdef choice="opt"><type>boolean </type>
                <parameter>out_db=true</parameter>
            </paramdef>
            <paramdef choice="opt"><type>boolean </type>
                <parameter>extent=true</parameter>
            </paramdef>
          </funcprototype>
          <funcprototype>
            <funcdef>boolean <function>AddRasterConstraints</function></funcdef>
            <paramdef><type>name </type>
            <parameter>rasttable</parameter></paramdef>

            <paramdef><type>name </type>
            <parameter>rastcolumn</parameter></paramdef>

            <paramdef><type>text[] </type>
            <parameter>VARIADIC constraints</parameter></paramdef>
          </funcprototype>

          <funcprototype>
            <funcdef>boolean <function>AddRasterConstraints</function></funcdef>

            <paramdef><type>name </type>
            <parameter>rastschema</parameter></paramdef>

            <paramdef><type>name </type>
            <parameter>rasttable</parameter></paramdef>

            <paramdef><type>name </type>
            <parameter>rastcolumn</parameter></paramdef>

            <paramdef><type>text[] </type>
            <parameter>VARIADIC constraints</parameter></paramdef>
          </funcprototype>

          <funcprototype>
            <funcdef>boolean <function>AddRasterConstraints</function></funcdef>

            <paramdef><type>name </type>
            <parameter>rastschema</parameter></paramdef>

            <paramdef><type>name </type>
            <parameter>rasttable</parameter></paramdef>

            <paramdef><type>name </type>
            <parameter>rastcolumn</parameter></paramdef>

            <paramdef choice="opt"><type>boolean </type>
            <parameter>srid=true</parameter></paramdef>

            <paramdef choice="opt"><type>boolean </type>
            <parameter>scale_x=true</parameter></paramdef>

            <paramdef choice="opt"><type>boolean </type>
            <parameter>scale_y=true</parameter></paramdef>

            <paramdef choice="opt"><type>boolean </type>
            <parameter>blocksize_x=true</parameter></paramdef>

            <paramdef choice="opt"><type>boolean </type>
            <parameter>blocksize_y=true</parameter></paramdef>

            <paramdef choice="opt"><type>boolean </type>
            <parameter>same_alignment=true</parameter></paramdef>

            <paramdef choice="opt"><type>boolean </type>
            <parameter>regular_blocking=false</parameter></paramdef>

            <paramdef choice="opt"><type>boolean </type>
            <parameter>num_bands=true</parameter></paramdef>
            <paramdef choice="opt"><type>boolean </type>
            <parameter>pixel_types=true</parameter></paramdef>

            <paramdef choice="opt"><type>boolean </type>
                <parameter>nodata_values=true</parameter>
            </paramdef>
            <paramdef choice="opt"><type>boolean </type>
                <parameter>out_db=true</parameter>
            </paramdef>
            <paramdef choice="opt"><type>boolean </type>
                <parameter>extent=true</parameter>
            </paramdef>
          </funcprototype>
        </funcsynopsis>
      </refsynopsisdiv>

      <refsection>
        <title>Description</title>

        <para>Generates constraints on a raster column that are used to display information in the <varname>raster_columns</varname> raster catalog.
        The <varname>rastschema</varname> is the name of the table schema the table resides in. The <varname>srid</varname>
        must be an integer value reference to an entry in the SPATIAL_REF_SYS
        table.</para>

        <para><varname>raster2pgsql</varname> loader uses this function to register raster tables</para>
        <para>Valid constraint names to pass in: refer to <xref linkend="RT_Raster_Columns"/> for more details.</para>
        <itemizedlist>
            <listitem><para><varname>blocksize</varname> sets both X and Y blocksize</para></listitem>
            <listitem><para><varname>blocksize_x</varname> sets X tile (width in pixels of each tile)</para></listitem>
            <listitem><para><varname>blocksize_y</varname> sets Y tile (height in pixels of each tile)</para></listitem>
            <listitem><para><varname>extent</varname> computes extent of whole table and applies constraint all rasters must be within that extent</para></listitem>

            <listitem><para><varname>num_bands</varname> number of bands</para></listitem>
            <listitem><para><varname>pixel_types</varname> reads array of pixel types for each band ensure all band n have same pixel type</para></listitem>
            <listitem><para><varname>regular_blocking</varname> sets spatially unique (no two rasters can be spatially the same) and coverage tile (raster is aligned to a coverage) constraints</para></listitem>
            <listitem><para><varname>same_alignment</varname> ensures they all have same alignment meaning any two tiles you compare will return true for. Refer to <xref linkend="RT_ST_SameAlignment"/>.</para></listitem>
            <listitem><para><varname>srid</varname> ensures all have same srid</para></listitem>
            <listitem><para>More -- any listed as inputs into the above functions</para></listitem>
        </itemizedlist>
        <note>
            <para>This function infers the constraints from the data already present in the table.  As such for it to work, you must create the raster column first
            and then load it with data.
            </para>
        </note>
        <note>
            <para>If you need to load more data in your tables after you have already applied constraints, you may want to run the DropRasterConstraints
                if the extent of your data has changed.
            </para>
        </note>
        <para role="availability" conformance="2.0.0">Availability: 2.0.0</para>
      </refsection>

        <refsection>
        <title>Examples</title>
        <para>Apply all possible constraints on column based on data.</para>
        <para>Verify the raster table is registered correctly in the raster_columns view.</para>

        <programlisting language="sql">CREATE TABLE myrasters(rid SERIAL primary key, rast raster);
INSERT INTO myrasters(rast)
SELECT ST_AddBand(ST_MakeEmptyRaster(1000, 1000, 0.3, -0.3, 2, 2, 0, 0, 4326), 1, '8BSI'::text, -129, NULL);

SELECT AddRasterConstraints('myrasters'::name, 'rast'::name);
SELECT srid, scale_x, scale_y, blocksize_x, blocksize_y, num_bands, pixel_types, nodata_values
    FROM raster_columns
    WHERE r_table_name = 'myrasters';</programlisting>
<screen role="text-primary"> srid | scale_x | scale_y | blocksize_x | blocksize_y | num_bands | pixel_types| nodata_values
------+---------+---------+-------------+-------------+-----------+-------------+---------------
 4326 |       2 |       2 |        1000 |        1000 |         1 | {8BSI}      | {0}</screen>

        <para>Apply single constraint.</para>

        <programlisting language="sql">CREATE TABLE public.myrasters2(rid SERIAL primary key, rast raster);
INSERT INTO myrasters2(rast)
SELECT ST_AddBand(ST_MakeEmptyRaster(1000, 1000, 0.3, -0.3, 2, 2, 0, 0, 4326), 1, '8BSI'::text, -129, NULL);

SELECT AddRasterConstraints('public'::name, 'myrasters2'::name, 'rast'::name, 'regular_blocking', 'blocksize');</programlisting>
<screen role="text-primary">NOTICE:  Adding regular blocking constraint
NOTICE:  Adding blocksize-X constraint
NOTICE:  Adding blocksize-Y constraint</screen>
      </refsection>

      <refsection>
        <title>See Also</title>

        <para><xref linkend="RT_Raster_Columns"/>, <xref linkend="RT_ST_AddBand"/>, <xref linkend="RT_ST_MakeEmptyRaster"/>, <xref linkend="RT_DropRasterConstraints"/>, <xref linkend="RT_ST_BandPixelType"/>, <xref linkend="RT_ST_SRID"/></para>
      </refsection>
    </refentry>

    <refentry xml:id="RT_DropRasterConstraints">
      <refnamediv>
        <refname>DropRasterConstraints</refname>

        <refpurpose>Drops PostGIS raster constraints that refer to a raster table column. Useful if you need to reload data or update your raster column data.</refpurpose>
      </refnamediv>

      <refsynopsisdiv>
        <funcsynopsis>
          <funcprototype>
            <funcdef>boolean <function>DropRasterConstraints</function></funcdef>
            <paramdef><type>name </type>
            <parameter>rasttable</parameter></paramdef>

            <paramdef><type>name </type>
            <parameter>rastcolumn</parameter></paramdef>

            <paramdef><type>boolean </type>
            <parameter>srid</parameter></paramdef>

            <paramdef><type>boolean </type>
            <parameter>scale_x</parameter></paramdef>

            <paramdef><type>boolean </type>
            <parameter>scale_y</parameter></paramdef>

            <paramdef><type>boolean </type>
            <parameter>blocksize_x</parameter></paramdef>

            <paramdef><type>boolean </type>
            <parameter>blocksize_y</parameter></paramdef>

            <paramdef><type>boolean </type>
            <parameter>same_alignment</parameter></paramdef>

            <paramdef><type>boolean </type>
            <parameter>regular_blocking</parameter></paramdef>

            <paramdef choice="opt"><type>boolean </type>
            <parameter>num_bands=true</parameter></paramdef>
            <paramdef choice="opt"><type>boolean </type>
            <parameter>pixel_types=true</parameter></paramdef>

            <paramdef choice="opt"><type>boolean </type>
            <parameter>nodata_values=true</parameter></paramdef>

            <paramdef choice="opt"><type>boolean </type>
                <parameter>out_db=true</parameter>
            </paramdef>
            <paramdef choice="opt"><type>boolean </type>
            <parameter>extent=true</parameter></paramdef>
          </funcprototype>

          <funcprototype>
            <funcdef>boolean <function>DropRasterConstraints</function></funcdef>
            <paramdef><type>name </type>
            <parameter>rastschema</parameter></paramdef>

            <paramdef><type>name </type>
            <parameter>rasttable</parameter></paramdef>

            <paramdef><type>name </type>
            <parameter>rastcolumn</parameter></paramdef>

            <paramdef choice="opt"><type>boolean </type>
            <parameter>srid=true</parameter></paramdef>

            <paramdef><type>boolean </type>
            <parameter>scale_x=true</parameter></paramdef>

            <paramdef choice="opt"><type>boolean </type>
            <parameter>scale_y=true</parameter></paramdef>

            <paramdef choice="opt"><type>boolean </type>
            <parameter>blocksize_x=true</parameter></paramdef>

            <paramdef choice="opt"><type>boolean </type>
            <parameter>blocksize_y=true</parameter></paramdef>

            <paramdef choice="opt"><type>boolean </type>
            <parameter>same_alignment=true</parameter></paramdef>

            <paramdef choice="opt"><type>boolean </type>
            <parameter>regular_blocking=false</parameter></paramdef>

            <paramdef choice="opt"><type>boolean </type>
            <parameter>num_bands=true</parameter></paramdef>
            <paramdef choice="opt"><type>boolean </type>
            <parameter>pixel_types=true</parameter></paramdef>

            <paramdef choice="opt"><type>boolean </type>
            <parameter>nodata_values=true</parameter></paramdef>

            <paramdef choice="opt"><type>boolean </type>
                <parameter>out_db=true</parameter>
            </paramdef>

            <paramdef choice="opt"><type>boolean </type>
            <parameter>extent=true</parameter></paramdef>
          </funcprototype>

          <funcprototype>
            <funcdef>boolean <function>DropRasterConstraints</function></funcdef>
            <paramdef><type>name </type>
            <parameter>rastschema</parameter></paramdef>

            <paramdef><type>name </type>
            <parameter>rasttable</parameter></paramdef>

            <paramdef><type>name </type>
            <parameter>rastcolumn</parameter></paramdef>
            <paramdef><type>text[] </type>
            <parameter>constraints</parameter></paramdef>

          </funcprototype>

        </funcsynopsis>
      </refsynopsisdiv>

      <refsection>
        <title>Description</title>
        <para>Drops PostGIS raster constraints that refer to a raster table column that were added by <xref linkend="RT_AddRasterConstraints"/>. Useful if you need to load more data or update your raster column data.
        You do not need to do this if you want to get rid of a raster table or a raster column. </para>
        <para>To drop a raster table use standard SQL: <code>DROP TABLE mytable</code>.</para>
        <para>To drop just a raster column and leave the rest of the table, use standard SQL: <code>ALTER TABLE mytable DROP COLUMN rast</code>.</para>
        <para>the table will disappear from the <varname>raster_columns</varname> catalog if the column or table is dropped.  However if only the constraints are dropped, the
        raster column will still be listed in the <varname>raster_columns</varname> catalog, but there will be no other information about it aside from the column name and table.</para>
        <para role="availability" conformance="2.0.0">Availability: 2.0.0</para>
      </refsection>
      <refsection>
        <title>Examples</title>

        <programlisting language="sql">
SELECT DropRasterConstraints ('myrasters', 'rast');</programlisting>
<screen role="text-primary"> droprasterconstraints
-----------------------
 t
(1 row)</screen>

                <para>Verify change in raster_columns.</para>
                <programlisting language="sql">
SELECT srid, scale_x, scale_y, blocksize_x, blocksize_y, num_bands, pixel_types, nodata_values
    FROM raster_columns
    WHERE r_table_name = 'myrasters';</programlisting>
<screen role="text-primary"> srid | scale_x | scale_y | blocksize_x | blocksize_y | num_bands | pixel_types| nodata_values
------+---------+---------+-------------+-------------+-----------+-------------+---------------
    0 |         |         |             |             |           |             |</screen>
      </refsection>
      <refsection>
        <title>See Also</title>

        <para><xref linkend="RT_AddRasterConstraints"/></para>
      </refsection>
    </refentry>

  <refentry xml:id="RT_AddOverviewConstraints">
      <refnamediv>
        <refname>AddOverviewConstraints</refname>

        <refpurpose>Tag a raster column as being an overview of another.</refpurpose>
      </refnamediv>

      <refsynopsisdiv>
        <funcsynopsis>

          <funcprototype>
        <funcdef>boolean <function>AddOverviewConstraints</function></funcdef>
        <paramdef><type>name </type>
        <parameter>ovschema</parameter></paramdef>
        <paramdef><type>name </type>
        <parameter>ovtable</parameter></paramdef>
        <paramdef><type>name </type>
        <parameter>ovcolumn</parameter></paramdef>
        <paramdef><type>name </type>
        <parameter>refschema</parameter></paramdef>
        <paramdef><type>name </type>
        <parameter>reftable</parameter></paramdef>
        <paramdef><type>name </type>
        <parameter>refcolumn</parameter></paramdef>
        <paramdef><type>int </type>
        <parameter>ovfactor</parameter></paramdef>
          </funcprototype>

          <funcprototype>
        <funcdef>boolean <function>AddOverviewConstraints</function></funcdef>
        <paramdef><type>name </type>
        <parameter>ovtable</parameter></paramdef>
        <paramdef><type>name </type>
        <parameter>ovcolumn</parameter></paramdef>
        <paramdef><type>name </type>
        <parameter>reftable</parameter></paramdef>
        <paramdef><type>name </type>
        <parameter>refcolumn</parameter></paramdef>
        <paramdef><type>int </type>
        <parameter>ovfactor</parameter></paramdef>
          </funcprototype>

        </funcsynopsis>
      </refsynopsisdiv>

      <refsection>
        <title>Description</title>

        <para>
Adds constraints on a raster column that are used to display information
in the <varname>raster_overviews</varname> raster catalog.
        </para>
        <para>
The <varname>ovfactor</varname> parameter represents the scale multiplier
in the overview column: higher overview factors have lower resolution.
        </para>
        <para>
When the <varname>ovschema</varname> and <varname>refschema</varname>
parameters are omitted, the first table found scanning the
<varname>search_path</varname> will be used.
        </para>

        <para role="availability" conformance="2.0.0">Availability: 2.0.0</para>
      </refsection>

      <refsection>
        <title>Examples</title>

        <para>Verify the raster table is registered correctly in the raster_overviews view.</para>
        <programlisting language="sql">
CREATE TABLE res1 AS SELECT
ST_AddBand(ST_MakeEmptyRaster(1000, 1000, 0, 0, 2),
  1, '8BSI'::text, -129, NULL
) r1;

CREATE TABLE res2 AS SELECT
ST_AddBand(ST_MakeEmptyRaster(500, 500, 0, 0, 4),
  1, '8BSI'::text, -129, NULL
) r2;

SELECT AddOverviewConstraints('res2', 'r2', 'res1', 'r1', 2);
SELECT o_table_name ot, o_raster_column oc,
       r_table_name rt, r_raster_column rc,
       overview_factor f
FROM raster_overviews WHERE o_table_name = 'res2';</programlisting>
<screen role="text-primary">  ot  | oc |  rt  | rc | f
------+----+------+----+---
 res2 | r2 | res1 | r1 | 2
(1 row)</screen>
      </refsection>

      <refsection>
        <title>See Also</title>

      <para>
 <xref linkend="RT_Raster_Overviews"/>,
 <xref linkend="RT_DropOverviewConstraints"/>,
 <xref linkend="RT_CreateOverview"/>,
 <xref linkend="RT_AddRasterConstraints"/>
      </para>
      </refsection>
    </refentry>

  <refentry xml:id="RT_DropOverviewConstraints">
      <refnamediv>
        <refname>DropOverviewConstraints</refname>

        <refpurpose>Untag a raster column from being an overview of another.</refpurpose>
      </refnamediv>

      <refsynopsisdiv>
        <funcsynopsis>

          <funcprototype>
        <funcdef>boolean <function>DropOverviewConstraints</function></funcdef>
        <paramdef><type>name </type>
        <parameter>ovschema</parameter></paramdef>
        <paramdef><type>name </type>
        <parameter>ovtable</parameter></paramdef>
        <paramdef><type>name </type>
        <parameter>ovcolumn</parameter></paramdef>
          </funcprototype>

          <funcprototype>
        <funcdef>boolean <function>DropOverviewConstraints</function></funcdef>
        <paramdef><type>name </type>
        <parameter>ovtable</parameter></paramdef>
        <paramdef><type>name </type>
        <parameter>ovcolumn</parameter></paramdef>
          </funcprototype>

        </funcsynopsis>
      </refsynopsisdiv>

      <refsection>
        <title>Description</title>

        <para>
Remove from a raster column the constraints used to show it as
being an overview of another in the <varname>raster_overviews</varname>
raster catalog.
        </para>
        <para>
When the <varname>ovschema</varname> parameter is omitted,
the first table found scanning the <varname>search_path</varname>
will be used.
        </para>

        <para role="availability" conformance="2.0.0">Availability: 2.0.0</para>
      </refsection>

      <refsection>
        <title>See Also</title>

      <para>
 <xref linkend="RT_Raster_Overviews"/>,
 <xref linkend="RT_AddOverviewConstraints"/>,
 <xref linkend="RT_DropRasterConstraints"/>
      </para>
      </refsection>
    </refentry>

        <refentry xml:id="RT_PostGIS_GDAL_Version">
            <refnamediv>
                <refname>PostGIS_GDAL_Version</refname>
                <refpurpose>Reports the version of the GDAL library in use by PostGIS.</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                    <funcprototype>
                        <funcdef>text <function>PostGIS_GDAL_Version</function></funcdef>
                        <paramdef></paramdef>
                    </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>
                <para>Reports the version of the GDAL library in use by PostGIS. Will also check and report if GDAL can find its data files.</para>
            </refsection>

            <refsection>
                <title>Examples</title>
                <programlisting language="sql">SELECT PostGIS_GDAL_Version();</programlisting>
<screen role="text-primary">GDAL 1.11dev, released 2013/04/13</screen>
            </refsection>

            <refsection>
                <title>See Also</title>
                <para>
                    <xref linkend="postgis_gdal_datapath"/>
                </para>
            </refsection>
        </refentry>

    <refentry xml:id="RT_PostGIS_Raster_Lib_Build_Date">
      <refnamediv>
        <refname>PostGIS_Raster_Lib_Build_Date</refname>

        <refpurpose>Reports full raster library build date.</refpurpose>
      </refnamediv>

      <refsynopsisdiv>
        <funcsynopsis>
          <funcprototype>
            <funcdef>text <function>PostGIS_Raster_Lib_Build_Date</function></funcdef>

            <paramdef></paramdef>
          </funcprototype>
        </funcsynopsis>
      </refsynopsisdiv>

      <refsection>
        <title>Description</title>

        <para>Reports raster build date</para>
      </refsection>

      <refsection>
        <title>Examples</title>

        <programlisting language="sql">SELECT PostGIS_Raster_Lib_Build_Date();</programlisting>
<screen role="text-primary">2010-04-28 21:15:10</screen>
      </refsection>

      <refsection>
        <title>See Also</title>

        <para> <xref linkend="RT_PostGIS_Raster_Lib_Version"/></para>
      </refsection>
    </refentry>

    <refentry xml:id="RT_PostGIS_Raster_Lib_Version">
      <refnamediv>
        <refname>PostGIS_Raster_Lib_Version</refname>

        <refpurpose>Reports full raster version and build configuration
        infos.</refpurpose>
      </refnamediv>

      <refsynopsisdiv>
        <funcsynopsis>
          <funcprototype>
            <funcdef>text <function>PostGIS_Raster_Lib_Version</function></funcdef>

            <paramdef></paramdef>
          </funcprototype>
        </funcsynopsis>
      </refsynopsisdiv>

      <refsection>
        <title>Description</title>

        <para>Reports full raster version and build configuration
        infos.</para>
      </refsection>

      <refsection>
        <title>Examples</title>

        <programlisting language="sql">SELECT PostGIS_Raster_Lib_Version();</programlisting>
<screen role="text-primary">2.0.0</screen>
      </refsection>

      <refsection>
        <title>See Also</title>

        <para> <xref linkend="PostGIS_Lib_Version"/></para>
      </refsection>

    </refentry>

    <refentry xml:id="RT_ST_GDALDrivers">
      <refnamediv>
        <refname>ST_GDALDrivers</refname>

        <refpurpose>Returns a list of raster formats supported by PostGIS through GDAL.  Only those formats with can_write=True can be used by ST_AsGDALRaster</refpurpose>
      </refnamediv>

      <refsynopsisdiv>
        <funcsynopsis>
          <funcprototype>
            <funcdef>setof record <function>ST_GDALDrivers</function></funcdef>
            <paramdef><type>integer </type> <parameter>OUT idx</parameter></paramdef>
            <paramdef><type>text </type> <parameter>OUT short_name</parameter></paramdef>
            <paramdef><type>text </type> <parameter>OUT long_name</parameter></paramdef>
            <paramdef><type>text </type> <parameter>OUT can_read</parameter></paramdef>
            <paramdef><type>text </type> <parameter>OUT can_write</parameter></paramdef>
            <paramdef><type>text </type> <parameter>OUT create_options</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>
      </refsynopsisdiv>

      <refsection>
        <title>Description</title>

        <para>
            Returns a list of raster formats short_name,long_name and creator options of each format supported by GDAL.  Use the short_name as input in the <varname>format</varname> parameter of <xref linkend="RT_ST_AsGDALRaster"/>.
            Options vary depending on what drivers your libgdal was compiled with. <varname>create_options</varname> returns an xml formatted set of CreationOptionList/Option consisting of name and optional <varname>type</varname>, <varname>description</varname> and set of <varname>VALUE</varname> for each creator option for the specific driver.
        </para>

         <para role="changed" conformance="2.5.0">Changed: 2.5.0 - add can_read and can_write columns.</para>
         <para role="changed" conformance="2.0.6">Changed: 2.0.6, 2.1.3 - by default no drivers are enabled, unless GUC or Environment variable gdal_enabled_drivers is set.</para>
         <para role="availability" conformance="2.0.0">Availability: 2.0.0 - requires GDAL &gt;= 1.6.0. </para>

      </refsection>

      <refsection>
        <title>Examples</title>
        <para>List of Drivers.</para>

        <programlisting language="sql">SET postgis.gdal_enabled_drivers = 'ENABLE_ALL';
SELECT short_name, long_name, can_write
FROM ST_GDALDrivers()
ORDER BY short_name;</programlisting>
<screen role="text-primary">   short_name    |                          long_name                          | can_write
-----------------+-------------------------------------------------------------+-----------
 AAIGrid         | Arc/Info ASCII Grid                                         | t
 ACE2            | ACE2                                                        | f
 ADRG            | ARC Digitized Raster Graphics                               | f
 AIG             | Arc/Info Binary Grid                                        | f
 AirSAR          | AirSAR Polarimetric Image                                   | f
 ARG             | Azavea Raster Grid format                                   | t
 BAG             | Bathymetry Attributed Grid                                  | f
 BIGGIF          | Graphics Interchange Format (.gif)                          | f
 BLX             | Magellan topo (.blx)                                        | t
 BMP             | MS Windows Device Independent Bitmap                        | f
 BSB             | Maptech BSB Nautical Charts                                 | f
 PAux            | PCI .aux Labelled                                           | f
 PCIDSK          | PCIDSK Database File                                        | f
 PCRaster        | PCRaster Raster File                                        | f
 PDF             | Geospatial PDF                                              | f
 PDS             | NASA Planetary Data System                                  | f
 PDS4            | NASA Planetary Data System 4                                | t
 PLMOSAIC        | Planet Labs Mosaics API                                     | f
 PLSCENES        | Planet Labs Scenes API                                      | f
 PNG             | Portable Network Graphics                                   | t
 PNM             | Portable Pixmap Format (netpbm)                             | f
 PRF             | Racurs PHOTOMOD PRF                                         | f
 R               | R Object Data Store                                         | t
 Rasterlite      | Rasterlite                                                  | t
 RDA             | DigitalGlobe Raster Data Access driver                      | f
 RIK             | Swedish Grid RIK (.rik)                                     | f
 RMF             | Raster Matrix Format                                        | f
 ROI_PAC         | ROI_PAC raster                                              | f
 RPFTOC          | Raster Product Format TOC format                            | f
 RRASTER         | R Raster                                                    | f
 RS2             | RadarSat 2 XML Product                                      | f
 RST             | Idrisi Raster A.1                                           | t
 SAFE            | Sentinel-1 SAR SAFE Product                                 | f
 SAGA            | SAGA GIS Binary Grid (.sdat, .sg-grd-z)                     | t
 SAR_CEOS        | CEOS SAR Image                                              | f
 SDTS            | SDTS Raster                                                 | f
 SENTINEL2       | Sentinel 2                                                  | f
 SGI             | SGI Image File Format 1.0                                   | f
 SNODAS          | Snow Data Assimilation System                               | f
 SRP             | Standard Raster Product (ASRP/USRP)                         | f
 SRTMHGT         | SRTMHGT File Format                                         | t
 Terragen        | Terragen heightfield                                        | f
 TIL             | EarthWatch .TIL                                             | f
 TSX             | TerraSAR-X Product                                          | f
 USGSDEM         | USGS Optional ASCII DEM (and CDED)                          | t
 VICAR           | MIPL VICAR file                                             | f
 VRT             | Virtual Raster                                              | t
 WCS             | OGC Web Coverage Service                                    | f
 WMS             | OGC Web Map Service                                         | t
 WMTS            | OGC Web Map Tile Service                                    | t
 XPM             | X11 PixMap Format                                           | t
 XYZ             | ASCII Gridded XYZ                                           | t
 ZMap            | ZMap Plus Grid                                              | t</screen>

<para>List of options for each driver.</para>
<para>Output the create options XML column of JPEG as a table. These creator options can be used in the ST_AsGDALRaster options argument.</para>
<programlisting language="sql">
SELECT (xpath('@name', g.opt))[1]::text As oname,
       (xpath('@type', g.opt))[1]::text As otype,
       (xpath('@description', g.opt))[1]::text As descrip
FROM (SELECT unnest(xpath('/CreationOptionList/Option', create_options::xml)) As opt
FROM  ST_GDALDrivers()
WHERE short_name = 'JPEG') As g;</programlisting>
<screen role="text-primary">       oname        |  otype  |      descrip
--------------------+---------+-------------------------------------------------
 PROGRESSIVE        | boolean | whether to generate a progressive JPEG
 QUALITY            | int     | good=100, bad=0, default=75
 WORLDFILE          | boolean | whether to generate a worldfile
 INTERNAL_MASK      | boolean | whether to generate a validity mask
 COMMENT            | string  | Comment
 SOURCE_ICC_PROFILE | string  | ICC profile encoded in Base64
 EXIF_THUMBNAIL     | boolean | whether to generate an EXIF thumbnail(overview).
                                By default its max dimension will be 128
 THUMBNAIL_WIDTH    | int     | Forced thumbnail width
 THUMBNAIL_HEIGHT   | int     | Forced thumbnail height
(9 rows)</screen>

<para>This example turns a few common GeoTIFF creator options into a compact table.</para>
<programlisting language="sql">WITH gtiff_options AS (
    SELECT
        option_name,
        option_type,
        default_value
    FROM ST_GDALDrivers() AS driver
    CROSS JOIN LATERAL XMLTABLE(
        '/CreationOptionList/Option'
        PASSING (driver.create_options::xml)
        COLUMNS
            option_name text PATH '@name',
            option_type text PATH '@type',
            default_value text PATH '@default'
    ) AS options
    WHERE driver.short_name = 'GTiff'
)
SELECT option_name AS name, option_type AS type, coalesce(default_value, '') AS default_value
FROM gtiff_options
WHERE option_name = ANY (ARRAY[
    'COMPRESS',
    'INTERLEAVE',
    'TILED',
    'BLOCKXSIZE',
    'BLOCKYSIZE',
    'JPEG_QUALITY'
])
ORDER BY 1;</programlisting>
<screen role="text-primary">     name      |     type      | default_value
---------------+---------------+---------------
 BLOCKXSIZE    | int           |
 BLOCKYSIZE    | int           |
 COMPRESS      | string-select |
 INTERLEAVE    | string-select | PIXEL
 JPEG_QUALITY  | int           | 75
 TILED         | boolean       |
(6 rows)</screen>

<para>Use <function>XMLTABLE</function> to expose selected GTiff creation
options as rows. The same pattern can be used without the name filter to inspect
the full XML document.</para>
<programlisting language="sql">SET postgis.gdal_enabled_drivers = 'ENABLE_ALL';

SELECT option_name, option_type
FROM ST_GDALDrivers() AS driver
CROSS JOIN LATERAL XMLTABLE(
    '/CreationOptionList/Option'
    PASSING (driver.create_options::xml)
    COLUMNS
        option_name text PATH '@name',
        option_type text PATH '@type'
) AS options
WHERE driver.short_name = 'GTiff'
  AND option_name IN ('COMPRESS', 'TILED', 'BIGTIFF')
ORDER BY option_name;</programlisting>
<screen role="text-primary"> option_name |  option_type
-------------+---------------
 BIGTIFF     | string-select
 COMPRESS    | string-select
 TILED       | boolean
(3 rows)</screen>
      </refsection>

      <refsection>
        <title>See Also</title>

        <para><xref linkend="RT_ST_AsGDALRaster"/>, <xref linkend="ST_SRID"/>, <xref linkend="postgis_gdal_enabled_drivers"/> </para>
      </refsection>
    </refentry>

        <refentry xml:id="RT_UpdateRasterSRID">
            <refnamediv>
                <refname>UpdateRasterSRID</refname>
                <refpurpose>
                    Change the SRID of all rasters in the user-specified column and table.
                </refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>

                    <funcprototype>
                        <funcdef>raster <function>UpdateRasterSRID</function></funcdef>
                        <paramdef><type>name </type> <parameter>schema_name</parameter></paramdef>
                        <paramdef><type>name </type> <parameter>table_name</parameter></paramdef>
                        <paramdef><type>name </type> <parameter>column_name</parameter></paramdef>
                        <paramdef><type>integer </type> <parameter>new_srid</parameter></paramdef>
                    </funcprototype>

                    <funcprototype>
                        <funcdef>raster <function>UpdateRasterSRID</function></funcdef>
                        <paramdef><type>name </type> <parameter>table_name</parameter></paramdef>
                        <paramdef><type>name </type> <parameter>column_name</parameter></paramdef>
                        <paramdef><type>integer </type> <parameter>new_srid</parameter></paramdef>
                    </funcprototype>

                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>
                    Change the SRID of all rasters in the user-specified column and table. The function will drop all appropriate column constraints (extent, alignment and SRID) before changing the SRID of the specified column's rasters.
                </para>

                <note>
                    <para>
                        The data (band pixel values) of the rasters are not touched by this function.  Only the raster's metadata is changed.
                    </para>
                </note>

                <para role="availability" conformance="2.1.0">Availability: 2.1.0</para>
            </refsection>
      <refsection>
        <title>See Also</title>
        <para>
          <xref linkend="UpdateGeometrySRID"/>
        </para>
      </refsection>
        </refentry>

        <refentry xml:id="RT_CreateOverview">
            <refnamediv>
                <refname>ST_CreateOverview</refname>
                <refpurpose>
Create an reduced resolution version of a given raster coverage.
                </refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>

                    <funcprototype>
                        <funcdef>regclass <function>ST_CreateOverview</function></funcdef>
                        <paramdef><type>regclass </type> <parameter>tab</parameter></paramdef>
                        <paramdef><type>name </type> <parameter>col</parameter></paramdef>
                        <paramdef><type>int </type> <parameter>factor</parameter></paramdef>
                      <paramdef choice="opt"><type>text </type> <parameter>algo='NearestNeighbor'</parameter></paramdef>
                    </funcprototype>

                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>
Create an overview table with resampled tiles from the source table.
Output tiles will have the same size of input tiles and cover the same
spatial extent with a lower resolution (pixel size will be
1/<varname>factor</varname> of the original in both directions).
                </para>

        <para>
The overview table will be made available in the
<varname>raster_overviews</varname> catalog and will have raster
constraints enforced.
                </para>

                <para>Algorithm options are: 'NearestNeighbor', 'Bilinear', 'Cubic', 'CubicSpline', and 'Lanczos'.  Refer to: <link xlink:href="http://www.gdal.org/gdalwarp.html">GDAL Warp resampling methods</link> for more details.</para>

                <para role="availability" conformance="2.2.0">Availability: 2.2.0</para>
            </refsection>

            <refsection><title>Example</title>
                <para>Output to generally better quality but slower to product format</para>
                <programlisting language="sql">SELECT ST_CreateOverview('mydata.mytable'::regclass, 'rast', 2, 'Lanczos');</programlisting>

                <para>Output to faster to process default nearest neighbor</para>
                <programlisting language="sql">SELECT ST_CreateOverview('mydata.mytable'::regclass, 'rast', 2);</programlisting>
            </refsection>

            <refsection>
            <title>See Also</title>
            <para>
        <xref linkend="RT_Retile"/>,
        <xref linkend="RT_AddOverviewConstraints"/>,
        <xref linkend="RT_AddRasterConstraints"/>,
        <xref linkend="RT_Raster_Overviews"/>
            </para>
            </refsection>
        </refentry>
  </section>

    <section xml:id="Raster_Constructors">
        <title>Raster Constructors</title>

        <refentry xml:id="RT_ST_AddBand">
            <refnamediv>
                <refname>ST_AddBand</refname>
                <refpurpose>
                    Returns a raster with the new band(s) of given type added with given initial value in the given index location. If no index is specified, the band is added to the end.
                </refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>

                    <funcprototype>
                        <funcdef>(1) raster <function>ST_AddBand</function></funcdef>
                        <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                        <paramdef><type>addbandarg[] </type> <parameter>addbandargset</parameter></paramdef>
                    </funcprototype>

                    <funcprototype>
                        <funcdef>(2) raster <function>ST_AddBand</function></funcdef>
                        <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                        <paramdef><type>integer </type> <parameter>index</parameter></paramdef>
                        <paramdef><type>text </type> <parameter>pixeltype</parameter></paramdef>
                        <paramdef choice="opt"><type>double precision </type> <parameter>initialvalue=0</parameter></paramdef>
                        <paramdef choice="opt"><type>double precision </type> <parameter>nodataval=NULL</parameter></paramdef>
                    </funcprototype>

                    <funcprototype>
                        <funcdef>(3) raster <function>ST_AddBand</function></funcdef>
                        <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                        <paramdef><type>text </type> <parameter>pixeltype</parameter></paramdef>
                        <paramdef choice="opt"><type>double precision </type> <parameter>initialvalue=0</parameter></paramdef>
                        <paramdef choice="opt"><type>double precision </type> <parameter>nodataval=NULL</parameter></paramdef>
                    </funcprototype>

                    <funcprototype>
                        <funcdef>(4) raster <function>ST_AddBand</function></funcdef>
                        <paramdef><type>raster </type> <parameter>torast</parameter></paramdef>
                        <paramdef><type>raster </type> <parameter>fromrast</parameter></paramdef>
                        <paramdef choice="opt"><type>integer </type> <parameter>fromband=1</parameter></paramdef>
                        <paramdef choice="opt"><type>integer </type> <parameter>torastindex=at_end</parameter></paramdef>
                    </funcprototype>

                    <funcprototype>
                        <funcdef>(5) raster <function>ST_AddBand</function></funcdef>
                        <paramdef><type>raster </type> <parameter>torast</parameter></paramdef>
                        <paramdef><type>raster[] </type> <parameter>fromrasts</parameter></paramdef>
                        <paramdef choice="opt"><type>integer </type> <parameter>fromband=1</parameter></paramdef>
                        <paramdef choice="opt"><type>integer </type> <parameter>torastindex=at_end</parameter></paramdef>
                    </funcprototype>

                    <funcprototype>
                        <funcdef>(6) raster <function>ST_AddBand</function></funcdef>
                        <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                        <paramdef><type>integer </type> <parameter>index</parameter></paramdef>
                        <paramdef><type>text </type> <parameter>outdbfile</parameter></paramdef>
                        <paramdef><type>integer[] </type> <parameter>outdbindex</parameter></paramdef>
                        <paramdef choice="opt"><type>double precision </type> <parameter>nodataval=NULL</parameter></paramdef>
                    </funcprototype>

                    <funcprototype>
                        <funcdef>(7) raster <function>ST_AddBand</function></funcdef>
                        <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                        <paramdef><type>text </type> <parameter>outdbfile</parameter></paramdef>
                        <paramdef><type>integer[] </type> <parameter>outdbindex</parameter></paramdef>
                        <paramdef choice="opt"><type>integer </type> <parameter>index=at_end</parameter></paramdef>
                        <paramdef choice="opt"><type>double precision </type> <parameter>nodataval=NULL</parameter></paramdef>
                    </funcprototype>

                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>
                    Returns a raster with a new band added in given position (index), of given type, of given initial value, and of given nodata value.  If no index is specified, the band is added to the end. If no <varname>fromband</varname> is specified, band 1 is assumed. Pixel type is a string representation of one of the pixel types specified in <xref linkend="RT_ST_BandPixelType"/>.  If an existing index is specified all subsequent bands &gt;= that index are incremented by 1. If an initial value greater than the max of the pixel type is specified, then the initial value is set to the highest value allowed by the pixel type.
                </para>

                <para>
                    For the variant that takes an array of <xref linkend="addbandarg"/> (Variant 1), a specific addbandarg's index value is relative to the raster at the time when the band described by that addbandarg is being added to the raster.  See the Multiple New Bands example below.
                </para>

                <para>
                    For the variant that takes an array of rasters (Variant 5),  if <varname>torast</varname> is NULL then the <varname>fromband</varname> band of each raster in the array is accumulated into a new raster.
                </para>

                <para>
                    For the variants that take <varname>outdbfile</varname> (Variants 6 and 7), the value must include the full path to the raster file. The file must also be accessible to the postgres server process.
                </para>

                <para role="enhanced" conformance="2.1.0">Enhanced: 2.1.0 support for addbandarg added.</para>
                <para role="enhanced" conformance="2.1.0">Enhanced: 2.1.0 support for new out-db bands added.</para>
            </refsection>

            <refsection>
                <title>Examples</title>
                <para>Single New Band.</para>

                <para>This example adds another 8-bit unsigned integer band with pixels initialized to 200.</para>
                <programlisting language="sql">
UPDATE dummy_rast
    SET rast = ST_AddBand(rast, '8BUI'::text, 200)
WHERE rid = 1;
                </programlisting>

                <para>Create an empty raster 100x100 units, with upper left right at 0, add 2 bands (band 1 is 0/1 boolean bit switch, band2 allows values 0-15) Uses addbandargs.</para>
                <para>Output metadata for the raster bands to verify they are correct.</para>
                <programlisting language="sql">
INSERT INTO dummy_rast(rid, rast)
    VALUES(10, ST_AddBand(ST_MakeEmptyRaster(100, 100, 0, 0, 1, -1, 0, 0, 0),
    ARRAY[
        ROW(1, '1BB'::text, 0, NULL),
        ROW(2, '4BUI'::text, 0, NULL)
            ]::addbandarg[]
     )
    );

SELECT  (bmd).*
FROM (SELECT ST_BandMetaData(rast, generate_series(1, 2)) As bmd
    FROM dummy_rast WHERE rid = 10) AS foo;</programlisting>
<screen role="text-primary"> pixeltype | nodatavalue | isoutdb | path
-----------+----------------+-------------+---------+------
 1BB       |             | f       |
 4BUI      |             | f       |</screen>
<para>This example outputs metadata for the raster.</para>
<programlisting language="sql">
SELECT  (rmd).width, (rmd).height, (rmd).numbands
FROM (SELECT ST_MetaData(rast) As rmd
    FROM dummy_rast WHERE rid = 10) AS foo;</programlisting>
<screen role="text-primary"> width | height | numbands
-------+--------+----------
   100 |    100 |        2</screen>

                <para>Multiple New Bands.</para>

                <programlisting language="sql">
SELECT
    *
FROM ST_BandMetaData(ST_AddBand(ST_MakeEmptyRaster(10, 10, 0, 0, 1, -1, 0, 0, 0),
        ARRAY[
            ROW(NULL, '8BUI', 255, 0),
            ROW(NULL, '16BUI', 1, 2),
            ROW(2, '32BUI', 100, 12),
            ROW(2, '32BF', 3.14, -1)
        ]::addbandarg[]
    ),
    ARRAY[]::integer[]
);</programlisting>
<screen role="text-primary"> bandnum | pixeltype | nodatavalue | isoutdb | path | outdbbandnum | filesize | filetimestamp
---------+-----------+-------------+---------+------+--------------+----------+---------------
       1 | 8BUI      |           0 | f       | null |         null |     null |          null
       2 | 32BF      |          -1 | f       | null |         null |     null |          null
       3 | 32BUI     |          12 | f       | null |         null |     null |          null
       4 | 16BUI     |           2 | f       | null |         null |     null |          null</screen>

                <para>Aggregate the 1st band of a table of like rasters into a single raster. With as many bands as there are test_types and as many rows (new rasters) as there are mice. Note that The ORDER BY test_type clause relies on aggregate ORDER BY support. The resulting raster will have a band for each test_type alphabetical by test_type. For mouse lovers: No mice were harmed in this exercise.</para>
                <programlisting language="sql">
SELECT
    mouse,
    ST_AddBand(NULL, array_agg(rast ORDER BY test_type), 1) As rast
FROM mice_studies
GROUP BY mouse;
                </programlisting>

                <para>New Out-db band.</para>
                <programlisting language="sql">
SELECT
    *
FROM ST_BandMetaData(ST_AddBand(ST_MakeEmptyRaster(10, 10, 0, 0, 1, -1, 0, 0, 0),
        '/home/raster/mytestraster.tif'::text, NULL::int[]
    ),
    ARRAY[]::integer[]
);</programlisting>
<screen role="text-primary"> bandnum | pixeltype | nodatavalue | isoutdb | path
---------+-----------+-------------+---------+------
       1 | 8BUI      |             | t       | /home/raster/mytestraster.tif
       2 | 8BUI      |             | t       | /home/raster/mytestraster.tif
       3 | 8BUI      |             | t       | /home/raster/mytestraster.tif</screen>
            </refsection>

            <refsection>
                <title>See Also</title>
                <para>
                    <xref linkend="RT_ST_BandMetaData"/>,
                    <xref linkend="RT_ST_BandPixelType"/>,
                    <xref linkend="RT_ST_MakeEmptyRaster"/>,
                    <xref linkend="RT_ST_MetaData"/>,
                    <xref linkend="RT_ST_NumBands"/>,
                    <xref linkend="RT_ST_Reclass"/>
                </para>
            </refsection>
        </refentry>

            <refentry xml:id="RT_ST_AsRaster">
            <refnamediv>
                <refname>ST_AsRaster</refname>
                <refpurpose>Converts a PostGIS geometry to a PostGIS raster.</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                  <funcprototype>
                    <funcdef>raster <function>ST_AsRaster</function></funcdef>
                    <paramdef><type>geometry </type> <parameter>geom</parameter></paramdef>
                    <paramdef><type>raster </type> <parameter>ref</parameter></paramdef>
                    <paramdef><type>text </type> <parameter>pixeltype</parameter></paramdef>
                    <paramdef choice="opt"><type>double precision </type> <parameter>value=1</parameter></paramdef>
                    <paramdef choice="opt"><type>double precision </type> <parameter>nodataval=0</parameter></paramdef>
                    <paramdef choice="opt"><type>boolean </type> <parameter>touched=false</parameter></paramdef>
                  </funcprototype>

                  <funcprototype>
                    <funcdef>raster <function>ST_AsRaster</function></funcdef>
                    <paramdef><type>geometry </type> <parameter>geom</parameter></paramdef>
                    <paramdef><type>raster </type> <parameter>ref</parameter></paramdef>
                    <paramdef choice="opt"><type>text[] </type> <parameter>pixeltype=ARRAY['8BUI']</parameter></paramdef>
                    <paramdef choice="opt"><type>double precision[] </type> <parameter>value=ARRAY[1]</parameter></paramdef>
                    <paramdef choice="opt"><type>double precision[] </type> <parameter>nodataval=ARRAY[0]</parameter></paramdef>
                    <paramdef choice="opt"><type>boolean </type> <parameter>touched=false</parameter></paramdef>
                  </funcprototype>

                  <funcprototype>
                    <funcdef>raster <function>ST_AsRaster</function></funcdef>
                    <paramdef><type>geometry </type> <parameter>geom</parameter></paramdef>
                    <paramdef><type>double precision </type> <parameter>scalex</parameter></paramdef>
                    <paramdef><type>double precision </type> <parameter>scaley</parameter></paramdef>
                    <paramdef><type>double precision </type> <parameter>gridx</parameter></paramdef>
                    <paramdef><type>double precision </type> <parameter>gridy</parameter></paramdef>
                    <paramdef><type>text </type> <parameter>pixeltype</parameter></paramdef>
                    <paramdef choice="opt"><type>double precision </type> <parameter>value=1</parameter></paramdef>
                    <paramdef choice="opt"><type>double precision </type> <parameter>nodataval=0</parameter></paramdef>
                    <paramdef choice="opt"><type>double precision </type> <parameter>skewx=0</parameter></paramdef>
                    <paramdef choice="opt"><type>double precision </type> <parameter>skewy=0</parameter></paramdef>
                    <paramdef choice="opt"><type>boolean </type> <parameter>touched=false</parameter></paramdef>
                  </funcprototype>

                  <funcprototype>
                    <funcdef>raster <function>ST_AsRaster</function></funcdef>
                    <paramdef><type>geometry </type> <parameter>geom</parameter></paramdef>
                    <paramdef><type>double precision </type> <parameter>scalex</parameter></paramdef>
                    <paramdef><type>double precision </type> <parameter>scaley</parameter></paramdef>
                    <paramdef choice="opt"><type>double precision </type> <parameter>gridx=NULL</parameter></paramdef>
                    <paramdef choice="opt"><type>double precision </type> <parameter>gridy=NULL</parameter></paramdef>
                    <paramdef choice="opt"><type>text[] </type> <parameter>pixeltype=ARRAY['8BUI']</parameter></paramdef>
                    <paramdef choice="opt"><type>double precision[] </type> <parameter>value=ARRAY[1]</parameter></paramdef>
                    <paramdef choice="opt"><type>double precision[] </type> <parameter>nodataval=ARRAY[0]</parameter></paramdef>
                    <paramdef choice="opt"><type>double precision </type> <parameter>skewx=0</parameter></paramdef>
                    <paramdef choice="opt"><type>double precision </type> <parameter>skewy=0</parameter></paramdef>
                    <paramdef choice="opt"><type>boolean </type> <parameter>touched=false</parameter></paramdef>
                  </funcprototype>

                  <funcprototype>
                    <funcdef>raster <function>ST_AsRaster</function></funcdef>
                    <paramdef><type>geometry </type> <parameter>geom</parameter></paramdef>
                    <paramdef><type>double precision </type> <parameter>scalex</parameter></paramdef>
                    <paramdef><type>double precision </type> <parameter>scaley</parameter></paramdef>
                    <paramdef><type>text </type> <parameter>pixeltype</parameter></paramdef>
                    <paramdef choice="opt"><type>double precision </type> <parameter>value=1</parameter></paramdef>
                    <paramdef choice="opt"><type>double precision </type> <parameter>nodataval=0</parameter></paramdef>
                    <paramdef choice="opt"><type>double precision </type> <parameter>upperleftx=NULL</parameter></paramdef>
                    <paramdef choice="opt"><type>double precision </type> <parameter>upperlefty=NULL</parameter></paramdef>
                    <paramdef choice="opt"><type>double precision </type> <parameter>skewx=0</parameter></paramdef>
                    <paramdef choice="opt"><type>double precision </type> <parameter>skewy=0</parameter></paramdef>
                    <paramdef choice="opt"><type>boolean </type> <parameter>touched=false</parameter></paramdef>
                  </funcprototype>

                  <funcprototype>
                    <funcdef>raster <function>ST_AsRaster</function></funcdef>
                    <paramdef><type>geometry </type> <parameter>geom</parameter></paramdef>
                    <paramdef><type>double precision </type> <parameter>scalex</parameter></paramdef>
                    <paramdef><type>double precision </type> <parameter>scaley</parameter></paramdef>
                    <paramdef><type>text[] </type> <parameter>pixeltype</parameter></paramdef>
                    <paramdef choice="opt"><type>double precision[] </type> <parameter>value=ARRAY[1]</parameter></paramdef>
                    <paramdef choice="opt"><type>double precision[] </type> <parameter>nodataval=ARRAY[0]</parameter></paramdef>
                    <paramdef choice="opt"><type>double precision </type> <parameter>upperleftx=NULL</parameter></paramdef>
                    <paramdef choice="opt"><type>double precision </type> <parameter>upperlefty=NULL</parameter></paramdef>
                    <paramdef choice="opt"><type>double precision </type> <parameter>skewx=0</parameter></paramdef>
                    <paramdef choice="opt"><type>double precision </type> <parameter>skewy=0</parameter></paramdef>
                    <paramdef choice="opt"><type>boolean </type> <parameter>touched=false</parameter></paramdef>
                  </funcprototype>

                  <funcprototype>
                    <funcdef>raster <function>ST_AsRaster</function></funcdef>
                    <paramdef><type>geometry </type> <parameter>geom</parameter></paramdef>
                    <paramdef><type>integer </type> <parameter>width</parameter></paramdef>
                    <paramdef><type>integer </type> <parameter>height</parameter></paramdef>
                    <paramdef><type>double precision </type> <parameter>gridx</parameter></paramdef>
                    <paramdef><type>double precision </type> <parameter>gridy</parameter></paramdef>
                    <paramdef><type>text </type> <parameter>pixeltype</parameter></paramdef>
                    <paramdef choice="opt"><type>double precision </type> <parameter>value=1</parameter></paramdef>
                    <paramdef choice="opt"><type>double precision </type> <parameter>nodataval=0</parameter></paramdef>
                    <paramdef choice="opt"><type>double precision </type> <parameter>skewx=0</parameter></paramdef>
                    <paramdef choice="opt"><type>double precision </type> <parameter>skewy=0</parameter></paramdef>
                    <paramdef choice="opt"><type>boolean </type> <parameter>touched=false</parameter></paramdef>
                  </funcprototype>

                  <funcprototype>
                    <funcdef>raster <function>ST_AsRaster</function></funcdef>
                    <paramdef><type>geometry </type> <parameter>geom</parameter></paramdef>
                    <paramdef><type>integer </type> <parameter>width</parameter></paramdef>
                    <paramdef><type>integer </type> <parameter>height</parameter></paramdef>
                    <paramdef choice="opt"><type>double precision </type> <parameter>gridx=NULL</parameter></paramdef>
                    <paramdef choice="opt"><type>double precision </type> <parameter>gridy=NULL</parameter></paramdef>
                    <paramdef><type>text[] </type> <parameter>pixeltype=ARRAY['8BUI']</parameter></paramdef>
                    <paramdef choice="opt"><type>double precision[] </type> <parameter>value=ARRAY[1]</parameter></paramdef>
                    <paramdef choice="opt"><type>double precision[] </type> <parameter>nodataval=ARRAY[0]</parameter></paramdef>
                    <paramdef choice="opt"><type>double precision </type> <parameter>skewx=0</parameter></paramdef>
                    <paramdef choice="opt"><type>double precision </type> <parameter>skewy=0</parameter></paramdef>
                    <paramdef choice="opt"><type>boolean </type> <parameter>touched=false</parameter></paramdef>
                  </funcprototype>

                  <funcprototype>
                    <funcdef>raster <function>ST_AsRaster</function></funcdef>
                    <paramdef><type>geometry </type> <parameter>geom</parameter></paramdef>
                    <paramdef><type>integer </type> <parameter>width</parameter></paramdef>
                    <paramdef><type>integer </type> <parameter>height</parameter></paramdef>
                    <paramdef><type>text </type> <parameter>pixeltype</parameter></paramdef>
                    <paramdef choice="opt"><type>double precision </type> <parameter>value=1</parameter></paramdef>
                    <paramdef choice="opt"><type>double precision </type> <parameter>nodataval=0</parameter></paramdef>
                    <paramdef choice="opt"><type>double precision </type> <parameter>upperleftx=NULL</parameter></paramdef>
                    <paramdef choice="opt"><type>double precision </type> <parameter>upperlefty=NULL</parameter></paramdef>
                    <paramdef choice="opt"><type>double precision </type> <parameter>skewx=0</parameter></paramdef>
                    <paramdef choice="opt"><type>double precision </type> <parameter>skewy=0</parameter></paramdef>
                    <paramdef choice="opt"><type>boolean </type> <parameter>touched=false</parameter></paramdef>
                  </funcprototype>

                  <funcprototype>
                    <funcdef>raster <function>ST_AsRaster</function></funcdef>
                    <paramdef><type>geometry </type> <parameter>geom</parameter></paramdef>
                    <paramdef><type>integer </type> <parameter>width</parameter></paramdef>
                    <paramdef><type>integer </type> <parameter>height</parameter></paramdef>
                    <paramdef><type>text[] </type> <parameter>pixeltype</parameter></paramdef>
                    <paramdef><type>double precision[] </type> <parameter>value=ARRAY[1]</parameter></paramdef>
                    <paramdef><type>double precision[] </type> <parameter>nodataval=ARRAY[0]</parameter></paramdef>
                    <paramdef choice="opt"><type>double precision </type> <parameter>upperleftx=NULL</parameter></paramdef>
                    <paramdef choice="opt"><type>double precision </type> <parameter>upperlefty=NULL</parameter></paramdef>
                    <paramdef choice="opt"><type>double precision </type> <parameter>skewx=0</parameter></paramdef>
                    <paramdef choice="opt"><type>double precision </type> <parameter>skewy=0</parameter></paramdef>
                    <paramdef choice="opt"><type>boolean </type> <parameter>touched=false</parameter></paramdef>
                  </funcprototype>

                </funcsynopsis>

            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>Converts a PostGIS geometry to a PostGIS raster. The many variants offers three groups of  possibilities for setting the alignment and pixelsize of the resulting raster.</para>

                 <para>The first group, composed of the two first variants, produce a raster having the same alignment (<varname>scalex</varname>, <varname>scaley</varname>, <varname>gridx</varname> and <varname>gridy</varname>), pixel type and nodata value as the provided reference raster. You generally pass this reference raster by joining the table containing the geometry with the table containing the reference raster.</para>

                 <para>The second group, composed of four variants, let you set the dimensions of the raster by providing the parameters of a pixel size (<varname>scalex</varname> &amp; <varname>scaley</varname> and <varname>skewx</varname> &amp; <varname>skewy</varname>). The <varname>width</varname> &amp; <varname>height</varname> of the resulting raster will be adjusted to fit the extent of the geometry. In most cases, you must cast integer <varname>scalex</varname> &amp; <varname>scaley</varname> arguments to double precision so that PostgreSQL choose the right variant.</para>

                 <para>The third group, composed of four variants, let you fix the dimensions of the raster by providing the dimensions of the raster (<varname>width</varname> &amp; <varname>height</varname>). The parameters of the pixel size (<varname>scalex</varname> &amp; <varname>scaley</varname> and <varname>skewx</varname> &amp; <varname>skewy</varname>) of the resulting raster will be adjusted to fit the extent of the geometry.</para>

                 <para>The two first variants of each of those two last groups let you specify the alignment with an arbitrary corner of the alignment grid (<varname>gridx</varname> &amp; <varname>gridy</varname>) and the two last variants takes the upper left corner (<varname>upperleftx</varname> &amp; <varname>upperlefty</varname>).</para>

                 <para>Each group of variant allows producing a one band raster or a multiple bands raster. To produce a multiple bands raster, you must provide an array of pixel types (<varname>pixeltype[]</varname>), an array of initial values (<varname>value</varname>) and an array of nodata values (<varname>nodataval</varname>). If not provided pixeltyped defaults to 8BUI, values to 1 and nodataval to 0.</para>

                 <para>The output raster will be in the same spatial reference as the source geometry. The only exception is for variants with a reference raster. In this case the resulting raster will get the same SRID as the reference raster.</para>

                 <para>The optional <varname>touched</varname> parameter defaults to false and maps to the GDAL ALL_TOUCHED rasterization option, which determines if pixels touched by lines or polygons will be burned. Not just those on the line render path, or whose center point is within the polygon.</para>

                 <para>This is particularly useful for rendering jpegs and pngs of geometries directly from the database when using in combination
                    with <xref linkend="RT_ST_AsPNG"/> and other <xref linkend="RT_ST_AsGDALRaster"/> family of functions.</para>
                 <para role="availability" conformance="2.0.0">Availability: 2.0.0 - requires GDAL &gt;= 1.6.0. </para>

                 <para>Curved geometry inputs are linearized before rasterization, including NURBSCurve inputs handled by PostGIS. TIN and PolyhedralSurface inputs are not supported.</para>
            </refsection>

            <refsection>
                <title>Examples: Output geometries as PNG files</title>
                <para>This example outputs a black circle on a white background, occupying 150 by 150 pixels.</para>
                <programlisting language="sql">SELECT ST_AsPNG(
    ST_AsRaster(
        ST_Buffer(ST_Point(1, 5), 10),
        150, 150,
        ARRAY['8BUI', '8BUI', '8BUI'],
        ARRAY[0, 0, 0],
        ARRAY[255, 255, 255]
    )
) AS image;</programlisting>
                <screen role="visual-primary"> image
-------------------------------
 PNG image, 150 x 150 pixels
                </screen>

                <para>This example maps bands to RGB channels, producing the teal value (118,154,118).</para>
                <programlisting language="sql">
SELECT ST_AsPNG(
    ST_AsRaster(
        ST_Buffer('LINESTRING(50 50,150 150,150 50)'::geometry, 10, 'join=bevel'),
        200, 200,
        ARRAY['8BUI', '8BUI', '8BUI'],
        ARRAY[118, 154, 118],
        ARRAY[255, 255, 255]
    )
) AS image;</programlisting>
                <screen role="visual-primary"> image
-------------------------------
 PNG image, 200 x 200 pixels
                </screen>

            </refsection>
            <!-- Optionally add a "See Also" section -->
            <refsection>
                <title>See Also</title>
                <para><xref linkend="RT_ST_BandPixelType"/>, <xref linkend="ST_Buffer"/>, <xref linkend="RT_ST_GDALDrivers"/>, <xref linkend="RT_ST_AsGDALRaster"/>, <xref linkend="RT_ST_AsPNG"/>, <xref linkend="RT_ST_AsJPEG"/>, <xref linkend="RT_ST_SRID"/></para>
            </refsection>
        </refentry>

<!-- { ST_AsRasterAgg -->

      <refentry xml:id="RT_ST_AsRasterAgg">
            <refnamediv>
                <refname>ST_AsRasterAgg</refname>
                <refpurpose>
                    Aggregate. Renders PostGIS geometries into a new raster.
                </refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                    <funcprototype>
                        <funcdef>raster <function>ST_AsRasterAgg</function></funcdef>
                        <paramdef><type>geometry </type> <parameter>geom</parameter></paramdef>
                        <paramdef><type>double precision </type> <parameter>val</parameter></paramdef>
                        <paramdef><type>raster </type> <parameter>ref</parameter></paramdef>
                        <paramdef><type>text </type> <parameter>pixeltype</parameter></paramdef>
                        <paramdef><type>double precision </type> <parameter>nodataval</parameter></paramdef>
                        <paramdef><type>text </type> <parameter>uniontype</parameter></paramdef>
                        <paramdef><type>boolean </type> <parameter>touched</parameter></paramdef>
                    </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>
Returns a single-band raster containing the rendered version of all incoming
geometries, each with its associated value.
                </para>

                <para role="availability" conformance="3.6.0">Availability: 3.6.0 </para>
            </refsection>

            <refsection>
                <title>Examples</title>
                <programlisting language="sql">
WITH inp(g, v) AS (
    VALUES
        ( ST_Buffer(ST_MakePoint(10, 0), 10), 1 ),
        ( ST_Buffer(ST_MakePoint(20, 0), 10), 2 )
),
agg AS (
    SELECT ST_AsRasterAgg(
        g,
        v,
        ST_MakeEmptyRaster(0, 0, 0, 0, 1.0),
        '8BUI',
        99,
        'SUM',
        true
    ) r
    FROM inp
)
SELECT
    ST_Width(r) w,
    ST_Height(r) h,
    ST_Value(r, 'POINT(5 0)') v5_0,
    ST_Value(r, 'POINT(15 0)') v15_0,
    ST_Value(r, 'POINT(25 0)') v25_0
FROM agg;</programlisting>
<screen role="text-primary"> w  | h  | v5_0 | v15_0 | v25_0
----+----+------+-------+-------
 30 | 20 |    1 |     3 |     2
(1 row)</screen>
            </refsection>

            <refsection>
                <title>See Also</title>
                <para>
                    <xref linkend="RT_ST_AsRaster"/>,
                    <xref linkend="RT_ST_DumpAsPolygons"/>,
                    <xref linkend="RT_ST_Union"/>
                </para>
            </refsection>
        </refentry>

<!-- ST_AsRasterAgg }-->

            <refentry xml:id="RT_ST_Band">
            <refnamediv>
                <refname>ST_Band</refname>
                <refpurpose>Returns one or more bands of an existing raster as a new raster.  Useful for building new rasters from existing rasters.</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                   <funcprototype>
                    <funcdef>raster <function>ST_Band</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    <paramdef choice="opt"><type>integer[] </type> <parameter>nbands = ARRAY[1]</parameter></paramdef>
                  </funcprototype>

                  <funcprototype>
                    <funcdef>raster <function>ST_Band</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    <paramdef><type>integer </type> <parameter>nband</parameter></paramdef>
                  </funcprototype>

                <funcprototype>
                    <funcdef>raster <function>ST_Band</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    <paramdef><type>text </type> <parameter>nbands</parameter></paramdef>
                    <paramdef choice="opt"><type>character </type> <parameter>delimiter=,</parameter></paramdef>
                  </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>Returns one or more bands of an existing raster as a new raster.  Useful for building new rasters from existing rasters or export of only selected
                bands of a raster or rearranging the order of bands in a raster. If no band is specified or any of specified bands does not exist in the raster, then all bands are returned. Used as a helper function in various functions such as for deleting a band. </para>
                <warning><para>For the <code>nbands</code> as text variant of function, the default delimiter is <code>,</code> which means you can ask for <code>'1,2,3'</code> and if you wanted to use a different delimiter you would do <code>ST_Band(rast, '1@2@3', '@')</code>.  For asking for multiple bands, we strongly suggest you use the array form of this function e.g. <code>ST_Band(rast, '{1,2,3}'::int[]);</code> since the <code>text</code> list of bands form may be removed in future versions of PostGIS.</para></warning>

                 <para role="availability" conformance="2.0.0">Availability: 2.0.0</para>
            </refsection>

                <refsection>
                    <title>Examples</title>

                    <para>This example creates two rasters: one containing band 1 of dummy_rast, and one containing band 2 reclassified as 2BUI.</para>
                    <programlisting language="sql">
SELECT ST_NumBands(rast1) As numb1, ST_BandPixelType(rast1) As pix1,
 ST_NumBands(rast2) As numb2, ST_BandPixelType(rast2) As pix2
FROM (
    SELECT ST_Band(rast) As rast1, ST_Reclass(ST_Band(rast, 3), '100-200):1, [200-254:2', '2BUI') As rast2
        FROM dummy_rast
        WHERE rid = 2) As foo;</programlisting>
<screen role="text-primary"> numb1 | pix1 | numb2 | pix2
-------+------+-------+------
     1 | 8BUI |     1 | 2BUI</screen>

                    <para>Return bands 2 and 3 using array cast syntax.</para>
                    <programlisting language="sql">SELECT ST_NumBands(ST_Band(rast, '{2,3}'::int[])) As num_bands
FROM dummy_rast WHERE rid=2;
</programlisting>
<screen role="text-primary">2</screen>
                    <para>Return bands 2 and 3 using array syntax.</para>
                    <programlisting language="sql">SELECT ST_NumBands(ST_Band(rast, ARRAY[2, 3])) As num_bands
    FROM dummy_rast
WHERE rid=2;
                    </programlisting>
<screen role="text-primary">2</screen>
        <para>This example uses three distinct shapes as the red, green, and blue bands of a synthetic raster. It compares the original RGB raster with band 2 followed by band 1 twice, and with band 3 alone.</para>
        <programlisting language="sql">WITH canvas AS (
    SELECT ST_AddBand(
        ST_AddBand(
            ST_AddBand(
                ST_MakeEmptyRaster(128, 128, 0, 128, 1, -1, 0, 0, 0),
                '8BUI'::text, 0::double precision, 0::double precision
            ),
            '8BUI'::text, 0::double precision, 0::double precision
        ),
        '8BUI'::text, 0::double precision, 0::double precision
    ) AS rast
), bands AS (
    SELECT ST_SetValue(
        ST_SetValue(
            ST_SetValue(rast, 1, ST_Buffer('POINT(32 96)'::geometry, 22), 220),
            2, ST_Buffer('LINESTRING(18 20,110 110)'::geometry, 6,
                         'endcap=flat join=bevel'), 210
        ),
        3, ST_Buffer('LINESTRING(10 48,118 48)'::geometry, 7,
                     'endcap=flat'), 180
    ) AS rast
    FROM canvas
)
SELECT ST_AsPNG(rast) AS "original RGB",
    ST_AsPNG(ST_Band(rast, ARRAY[2, 1, 1])) AS "bands 2,1,1",
    ST_AsPNG(ST_Band(rast, 3)) AS "band 3"
FROM bands;
                    </programlisting>
<screen role="visual-primary"> original RGB                | bands 2,1,1                | band 3
-----------------------------+----------------------------+----------------------------
 PNG image, 128 x 128 pixels | PNG image, 128 x 128 pixels | PNG image, 128 x 128 pixels
</screen>
<para>Band selection from a multi-band raster.</para>
<informaltable>
  <tgroup cols="2">
    <tbody>
      <row>
        <entry><para><informalfigure>
            <mediaobject>
              <imageobject><imagedata fileref="images/st_band01.png"/></imageobject>
              <caption><para>original (column rast)</para></caption>
            </mediaobject>
          </informalfigure></para></entry>
        <entry><para><informalfigure>
            <mediaobject>
              <imageobject><imagedata fileref="images/st_band02.png"/></imageobject>
              <caption><para>dupe_band</para></caption>
            </mediaobject>
          </informalfigure></para></entry>
      </row>
      <row>
        <entry><para><informalfigure>
            <mediaobject>
              <imageobject><imagedata fileref="images/st_band03.png"/></imageobject>
              <caption><para>sing_band</para></caption>
            </mediaobject>
          </informalfigure></para></entry>
        <entry><para/></entry>
      </row>
    </tbody>
  </tgroup>
</informaltable>

            </refsection>

            <refsection>
                <title>See Also</title>
                <para><xref linkend="RT_ST_AddBand"/>, <xref linkend="RT_ST_NumBands"/>, <xref linkend="RT_ST_Reclass"/>, <xref linkend="RT_reference"/></para>
            </refsection>
        </refentry>

        <refentry xml:id="RT_ST_MakeEmptyCoverage">
                  <refnamediv>
                    <refname>ST_MakeEmptyCoverage</refname>
                    <refpurpose>Cover georeferenced area with a grid of empty raster tiles.</refpurpose>
                  </refnamediv>

                  <refsynopsisdiv>
                    <funcsynopsis>
                      <funcprototype>
                        <funcdef>raster <function>ST_MakeEmptyCoverage</function></funcdef>
                        <paramdef><type>integer </type> <parameter>tilewidth</parameter></paramdef>
                        <paramdef><type>integer </type> <parameter>tileheight</parameter></paramdef>
                        <paramdef><type>integer </type> <parameter>width</parameter></paramdef>
                        <paramdef><type>integer </type> <parameter>height</parameter></paramdef>
                        <paramdef><type>double precision </type> <parameter>upperleftx</parameter></paramdef>
                        <paramdef><type>double precision </type> <parameter>upperlefty</parameter></paramdef>
                        <paramdef><type>double precision </type> <parameter>scalex</parameter></paramdef>
                        <paramdef><type>double precision </type> <parameter>scaley</parameter></paramdef>
                        <paramdef><type>double precision </type> <parameter>skewx</parameter></paramdef>
                        <paramdef><type>double precision </type> <parameter>skewy</parameter></paramdef>
                        <paramdef choice="opt"><type>integer </type> <parameter>srid=unknown</parameter></paramdef>
                      </funcprototype>
                    </funcsynopsis>
                  </refsynopsisdiv>

                  <refsection>
                    <title>Description</title>

                    <para>Create a set of raster tiles with <xref linkend="RT_ST_MakeEmptyRaster"/>. Grid dimension is <varname>width</varname> &amp; <varname>height</varname>. Tile dimension is <varname>tilewidth</varname> &amp; <varname>tileheight</varname>. The covered georeferenced area is from upper left corner (<varname>upperleftx</varname>, <varname>upperlefty</varname>) to lower right corner (<varname>upperleftx</varname> + <varname>width</varname> * <varname>scalex</varname>, <varname>upperlefty</varname> + <varname>height</varname> * <varname>scaley</varname>).</para>
                    <note><para>Note that scaley is generally negative for rasters and scalex is generally positive. So lower right corner will have a lower y value and higher x value than the upper left corner.</para></note>
                    <para role="availability" conformance="2.4.0">Availability: 2.4.0 </para>
                  </refsection>

                  <refsection>
                    <title>Examples Basic</title>
                    <para>Create 16 tiles in a 4x4 grid to cover the WGS84 area from upper left corner (22, 77) to lower right corner (55, 33).</para>
                    <programlisting language="sql">SELECT (ST_MetaData(tile)).* FROM ST_MakeEmptyCoverage(1, 1, 4, 4, 22, 33, (55 - 22)/(4)::float, (33 - 77)/(4)::float, 0., 0., 4326) tile;</programlisting>
<screen role="text-primary"> upperleftx | upperlefty | width | height | scalex | scaley | skewx | skewy | srid | numbands
-------------------------------------------------------------------------------------
         22 |         33 |     1 |      1 |   8.25 |    -11 |     0 |     0 | 4326 |        0
      30.25 |         33 |     1 |      1 |   8.25 |    -11 |     0 |     0 | 4326 |        0
       38.5 |         33 |     1 |      1 |   8.25 |    -11 |     0 |     0 | 4326 |        0
      46.75 |         33 |     1 |      1 |   8.25 |    -11 |     0 |     0 | 4326 |        0
         22 |         22 |     1 |      1 |   8.25 |    -11 |     0 |     0 | 4326 |        0
      30.25 |         22 |     1 |      1 |   8.25 |    -11 |     0 |     0 | 4326 |        0
       38.5 |         22 |     1 |      1 |   8.25 |    -11 |     0 |     0 | 4326 |        0
      46.75 |         22 |     1 |      1 |   8.25 |    -11 |     0 |     0 | 4326 |        0
         22 |         11 |     1 |      1 |   8.25 |    -11 |     0 |     0 | 4326 |        0
      30.25 |         11 |     1 |      1 |   8.25 |    -11 |     0 |     0 | 4326 |        0
       38.5 |         11 |     1 |      1 |   8.25 |    -11 |     0 |     0 | 4326 |        0
      46.75 |         11 |     1 |      1 |   8.25 |    -11 |     0 |     0 | 4326 |        0
         22 |          0 |     1 |      1 |   8.25 |    -11 |     0 |     0 | 4326 |        0
      30.25 |          0 |     1 |      1 |   8.25 |    -11 |     0 |     0 | 4326 |        0
       38.5 |          0 |     1 |      1 |   8.25 |    -11 |     0 |     0 | 4326 |        0
      46.75 |          0 |     1 |      1 |   8.25 |    -11 |     0 |     0 | 4326 |        0</screen>
                  </refsection>

                  <refsection>
                    <title>See Also</title>
                    <para>
                      <xref linkend="RT_ST_MakeEmptyRaster"/>
                    </para>
                  </refsection>
        </refentry>

        <refentry xml:id="RT_ST_MakeEmptyRaster">
            <refnamediv>
                <refname>ST_MakeEmptyRaster</refname>
                <refpurpose>Returns an empty raster (having no bands) of given dimensions (width &amp; height), upperleft X and Y, pixel size and rotation (scalex, scaley, skewx &amp; skewy) and reference system (srid).
                If a raster is passed in, returns a new raster with the same size, alignment and SRID.  If srid is left out, the spatial ref is set to unknown (0).</refpurpose>
            </refnamediv>
            <refsynopsisdiv>
                <funcsynopsis>
                  <funcprototype>
                    <funcdef>raster <function>ST_MakeEmptyRaster</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                  </funcprototype>
                  <funcprototype>
                    <funcdef>raster <function>ST_MakeEmptyRaster</function></funcdef>
                    <paramdef><type>integer </type> <parameter>width</parameter></paramdef>
                    <paramdef><type>integer </type> <parameter>height</parameter></paramdef>
                    <paramdef><type>float8 </type> <parameter>upperleftx</parameter></paramdef>
                    <paramdef><type>float8 </type> <parameter>upperlefty</parameter></paramdef>
                    <paramdef><type>float8 </type> <parameter>scalex</parameter></paramdef>
                    <paramdef><type>float8 </type> <parameter>scaley</parameter></paramdef>
                    <paramdef><type>float8 </type> <parameter>skewx</parameter></paramdef>
                    <paramdef><type>float8 </type> <parameter>skewy</parameter></paramdef>
                    <paramdef choice="opt"><type>integer </type> <parameter>srid=unknown</parameter></paramdef>
                  </funcprototype>

                  <funcprototype>
                    <funcdef>raster <function>ST_MakeEmptyRaster</function></funcdef>
                    <paramdef><type>integer </type> <parameter>width</parameter></paramdef>
                    <paramdef><type>integer </type> <parameter>height</parameter></paramdef>
                    <paramdef><type>float8  </type> <parameter>upperleftx</parameter></paramdef>
                    <paramdef><type>float8  </type> <parameter>upperlefty</parameter></paramdef>
                    <paramdef><type>float8  </type> <parameter>pixelsize</parameter></paramdef>
                  </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>
            <refsection>
                <title>Description</title>
                <para>Returns an empty raster (having no band) of given dimensions (width &amp; height) and georeferenced in spatial (or world) coordinates with upper left X (upperleftx), upper left Y (upperlefty),
                pixel size and rotation (scalex, scaley, skewx &amp; skewy) and reference system (srid).</para>

                <para>The last version use a single parameter to specify the pixel size (pixelsize). scalex is set to this argument and scaley is set to the negative value of this argument. skewx and skewy are set to 0. </para>

                <para>If an existing raster is passed in, it returns a new raster with the same meta data settings (without the bands). </para>

                <para>If no srid is specified it defaults to 0. After you create an empty raster you probably want to add bands to it and maybe edit it. Refer to <xref linkend="RT_ST_AddBand"/> to define bands and <xref linkend="RT_ST_SetValue"/> to set initial pixel values.</para>

                </refsection>

                <refsection>
                    <title>Examples</title>
                    <para>Use an existing raster as a template and output metadata of the rasters we added.</para>

                    <programlisting language="sql">
INSERT INTO dummy_rast(rid, rast)
VALUES(3, ST_MakeEmptyRaster(100, 100, 0.0005, 0.0005, 1, 1, 0, 0, 4326) );
INSERT INTO dummy_rast(rid, rast)
SELECT 4, ST_MakeEmptyRaster(rast)
FROM dummy_rast WHERE rid = 3;
SELECT
    rid,
    (md).width,
    (md).height,
    (md).scalex,
    (md).scaley,
    (md).srid
FROM (
    SELECT rid, ST_MetaData(rast) AS md
    FROM dummy_rast
    WHERE rid IN (3, 4)
) AS foo
ORDER BY rid;
</programlisting>
<screen role="text-primary"> rid | width | height | scalex | scaley | srid
-----+-------+--------+--------+--------+------
   3 |   100 |    100 |      1 |      1 | 4326
   4 |   100 |    100 |      1 |      1 | 4326</screen>

            </refsection>

            <refsection>
                <title>See Also</title>
                <para><xref linkend="RT_ST_AddBand"/>, <xref linkend="RT_ST_MetaData"/>, <xref linkend="RT_ST_ScaleX"/>, <xref linkend="RT_ST_ScaleY"/>, <xref linkend="RT_ST_SetValue"/>, <xref linkend="RT_ST_SkewX"/>, , <xref linkend="RT_ST_SkewY"/></para>
            </refsection>
        </refentry>

        <refentry xml:id="RT_ST_Tile">

            <refnamediv>
                <refname>ST_Tile</refname>
                <refpurpose>Returns a set of rasters resulting from the split of the input raster based upon the desired dimensions of the output rasters.</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                    <funcprototype>
                        <funcdef>setof raster <function>ST_Tile</function></funcdef>
                        <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                        <paramdef><type>int[] </type> <parameter>nband</parameter></paramdef>
                        <paramdef><type>integer </type> <parameter>width</parameter></paramdef>
                        <paramdef><type>integer </type> <parameter>height</parameter></paramdef>
                        <paramdef choice="opt"><type>boolean </type> <parameter>padwithnodata=FALSE</parameter></paramdef>
                        <paramdef choice="opt"><type>double precision </type> <parameter>nodataval=NULL</parameter></paramdef>
                    </funcprototype>

                    <funcprototype>
                        <funcdef>setof raster <function>ST_Tile</function></funcdef>
                        <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                        <paramdef><type>integer </type> <parameter>nband</parameter></paramdef>
                        <paramdef><type>integer </type> <parameter>width</parameter></paramdef>
                        <paramdef><type>integer </type> <parameter>height</parameter></paramdef>
                        <paramdef choice="opt"><type>boolean </type> <parameter>padwithnodata=FALSE</parameter></paramdef>
                        <paramdef choice="opt"><type>double precision </type> <parameter>nodataval=NULL</parameter></paramdef>
                    </funcprototype>

                    <funcprototype>
                        <funcdef>setof raster <function>ST_Tile</function></funcdef>
                        <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                        <paramdef><type>integer </type> <parameter>width</parameter></paramdef>
                        <paramdef><type>integer </type> <parameter>height</parameter></paramdef>
                        <paramdef choice="opt"><type>boolean </type> <parameter>padwithnodata=FALSE</parameter></paramdef>
                        <paramdef choice="opt"><type>double precision </type> <parameter>nodataval=NULL</parameter></paramdef>
                    </funcprototype>

                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>
                    Returns a set of rasters resulting from the split of the input raster based upon the desired dimensions of the output rasters.
                </para>

                <para>
                    If <varname>padwithnodata</varname> = FALSE, edge tiles on the right and bottom sides of the raster may have different dimensions than the rest of the tiles. If <varname>padwithnodata</varname> = TRUE, all tiles will have the same dimensions with the possibility that edge tiles being padded with NODATA values.  If raster band(s) do not have NODATA value(s) specified, one can be specified by setting <varname>nodataval</varname>.
                </para>

                <note>
                    <para>
                        If a specified band of the input raster is out-of-db, the corresponding band in the output rasters will also be out-of-db.
                    </para>
                </note>

                <para role="availability" conformance="2.1.0">Availability: 2.1.0</para>
            </refsection>

            <refsection>
                <title>Examples</title>

                <programlisting language="sql">
WITH foo AS (
    SELECT ST_AddBand(ST_AddBand(ST_MakeEmptyRaster(3, 3, 0, 0, 1, -1, 0, 0, 0), 1, '8BUI', 1, 0), 2, '8BUI', 10, 0) AS rast UNION ALL
    SELECT ST_AddBand(ST_AddBand(ST_MakeEmptyRaster(3, 3, 3, 0, 1, -1, 0, 0, 0), 1, '8BUI', 2, 0), 2, '8BUI', 20, 0) AS rast UNION ALL
    SELECT ST_AddBand(ST_AddBand(ST_MakeEmptyRaster(3, 3, 6, 0, 1, -1, 0, 0, 0), 1, '8BUI', 3, 0), 2, '8BUI', 30, 0) AS rast UNION ALL

    SELECT ST_AddBand(ST_AddBand(ST_MakeEmptyRaster(3, 3, 0, -3, 1, -1, 0, 0, 0), 1, '8BUI', 4, 0), 2, '8BUI', 40, 0) AS rast UNION ALL
    SELECT ST_AddBand(ST_AddBand(ST_MakeEmptyRaster(3, 3, 3, -3, 1, -1, 0, 0, 0), 1, '8BUI', 5, 0), 2, '8BUI', 50, 0) AS rast UNION ALL
    SELECT ST_AddBand(ST_AddBand(ST_MakeEmptyRaster(3, 3, 6, -3, 1, -1, 0, 0, 0), 1, '8BUI', 6, 0), 2, '8BUI', 60, 0) AS rast UNION ALL

    SELECT ST_AddBand(ST_AddBand(ST_MakeEmptyRaster(3, 3, 0, -6, 1, -1, 0, 0, 0), 1, '8BUI', 7, 0), 2, '8BUI', 70, 0) AS rast UNION ALL
    SELECT ST_AddBand(ST_AddBand(ST_MakeEmptyRaster(3, 3, 3, -6, 1, -1, 0, 0, 0), 1, '8BUI', 8, 0), 2, '8BUI', 80, 0) AS rast UNION ALL
    SELECT ST_AddBand(ST_AddBand(ST_MakeEmptyRaster(3, 3, 6, -6, 1, -1, 0, 0, 0), 1, '8BUI', 9, 0), 2, '8BUI', 90, 0) AS rast
), bar AS (
    SELECT ST_Union(rast) AS rast FROM foo
), baz AS (
    SELECT
        row_number() OVER (
            ORDER BY ST_UpperLeftY(rast) DESC, ST_UpperLeftX(rast)
        ) AS tile_id,
        rast
    FROM (
        SELECT ST_Tile(rast, 3, 3, TRUE) AS rast
        FROM bar
    ) AS tiled
)
SELECT
    tile_id,
    ST_UpperLeftX(rast) AS ulx,
    ST_UpperLeftY(rast) AS uly,
    ST_Value(rast, 1, 1, 1) AS band1,
    ST_Value(rast, 2, 1, 1) AS band2
FROM baz;</programlisting>
<screen role="text-primary"> tile_id | ulx | uly | band1 | band2
---------+-----+-----+-------+-------
       1 |   0 |   0 |     1 |    10
       2 |   3 |   0 |     2 |    20
       3 |   6 |   0 |     3 |    30
       4 |   0 |  -3 |     4 |    40
       5 |   3 |  -3 |     5 |    50
       6 |   6 |  -3 |     6 |    60
       7 |   0 |  -6 |     7 |    70
       8 |   3 |  -6 |     8 |    80
       9 |   6 |  -6 |     9 |    90
(9 rows)</screen>

                <programlisting language="sql">
WITH foo AS (
    SELECT ST_AddBand(ST_AddBand(ST_MakeEmptyRaster(3, 3, 0, 0, 1, -1, 0, 0, 0), 1, '8BUI', 1, 0), 2, '8BUI', 10, 0) AS rast UNION ALL
    SELECT ST_AddBand(ST_AddBand(ST_MakeEmptyRaster(3, 3, 3, 0, 1, -1, 0, 0, 0), 1, '8BUI', 2, 0), 2, '8BUI', 20, 0) AS rast UNION ALL
    SELECT ST_AddBand(ST_AddBand(ST_MakeEmptyRaster(3, 3, 6, 0, 1, -1, 0, 0, 0), 1, '8BUI', 3, 0), 2, '8BUI', 30, 0) AS rast UNION ALL

    SELECT ST_AddBand(ST_AddBand(ST_MakeEmptyRaster(3, 3, 0, -3, 1, -1, 0, 0, 0), 1, '8BUI', 4, 0), 2, '8BUI', 40, 0) AS rast UNION ALL
    SELECT ST_AddBand(ST_AddBand(ST_MakeEmptyRaster(3, 3, 3, -3, 1, -1, 0, 0, 0), 1, '8BUI', 5, 0), 2, '8BUI', 50, 0) AS rast UNION ALL
    SELECT ST_AddBand(ST_AddBand(ST_MakeEmptyRaster(3, 3, 6, -3, 1, -1, 0, 0, 0), 1, '8BUI', 6, 0), 2, '8BUI', 60, 0) AS rast UNION ALL

    SELECT ST_AddBand(ST_AddBand(ST_MakeEmptyRaster(3, 3, 0, -6, 1, -1, 0, 0, 0), 1, '8BUI', 7, 0), 2, '8BUI', 70, 0) AS rast UNION ALL
    SELECT ST_AddBand(ST_AddBand(ST_MakeEmptyRaster(3, 3, 3, -6, 1, -1, 0, 0, 0), 1, '8BUI', 8, 0), 2, '8BUI', 80, 0) AS rast UNION ALL
    SELECT ST_AddBand(ST_AddBand(ST_MakeEmptyRaster(3, 3, 6, -6, 1, -1, 0, 0, 0), 1, '8BUI', 9, 0), 2, '8BUI', 90, 0) AS rast
), bar AS (
    SELECT ST_Union(rast) AS rast FROM foo
), baz AS (
    SELECT
        row_number() OVER (
            ORDER BY ST_UpperLeftY(rast) DESC, ST_UpperLeftX(rast)
        ) AS tile_id,
        rast
    FROM (
        SELECT ST_Tile(rast, ARRAY[2], 3, 3) AS rast
        FROM bar
    ) AS tiled
)
SELECT
    tile_id,
    ST_UpperLeftX(rast) AS ulx,
    ST_UpperLeftY(rast) AS uly,
    ST_Value(rast, 1, 1, 1) AS band_value
FROM baz;</programlisting>
<screen role="text-primary"> tile_id | ulx | uly | band_value
---------+-----+-----+------------
       1 |   0 |   0 |         10
       2 |   3 |   0 |         20
       3 |   6 |   0 |         30
       4 |   0 |  -3 |         40
       5 |   3 |  -3 |         50
       6 |   6 |  -3 |         60
       7 |   0 |  -6 |         70
       8 |   3 |  -6 |         80
       9 |   6 |  -6 |         90
(9 rows)</screen>

            </refsection>

            <refsection>
                <title>See Also</title>
                <para>
                    <xref linkend="RT_ST_Union"/>,
                    <xref linkend="RT_Retile"/>
                </para>
            </refsection>

        </refentry>

        <refentry xml:id="RT_Retile">
            <refnamediv>
                <refname>ST_Retile</refname>
                <refpurpose>
                    Return a set of configured tiles from an arbitrarily tiled raster coverage.
                </refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>

                    <funcprototype>
                        <funcdef>SETOF raster <function>ST_Retile</function></funcdef>
                        <paramdef><type>regclass </type> <parameter>tab</parameter></paramdef>
                        <paramdef><type>name </type> <parameter>col</parameter></paramdef>
                        <paramdef><type>geometry </type> <parameter>ext</parameter></paramdef>
                        <paramdef><type>float8 </type> <parameter>sfx</parameter></paramdef>
                        <paramdef><type>float8 </type> <parameter>sfy</parameter></paramdef>
                        <paramdef><type>int </type> <parameter>tw</parameter></paramdef>
                        <paramdef><type>int </type> <parameter>th</parameter></paramdef>
                      <paramdef choice="opt"><type>text </type> <parameter>algo='NearestNeighbor'</parameter></paramdef>
                    </funcprototype>

                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>
Return a set of tiles having the specified scale (<varname>sfx</varname>,
<varname>sfy</varname>) and max size (<varname>tw</varname>,
<varname>th</varname>) and covering the specified extent
(<varname>ext</varname>) with data coming from the specified
raster coverage (<varname>tab</varname>, <varname>col</varname>).
                </para>

                <para>Algorithm options are: 'NearestNeighbor', 'Bilinear', 'Cubic', 'CubicSpline', and 'Lanczos'.  Refer to: <link xlink:href="http://www.gdal.org/gdalwarp.html">GDAL Warp resampling methods</link> for more details.</para>

                <para role="availability" conformance="2.2.0">Availability: 2.2.0</para>
            </refsection>
      <refsection>
        <title>See Also</title>
        <para>
          <xref linkend="RT_CreateOverview"/>
        </para>
      </refsection>
        </refentry>


        <refentry xml:id="RT_ST_FromGDALRaster">

            <refnamediv>
                <refname>ST_FromGDALRaster</refname>
                <refpurpose>Returns a raster from a supported GDAL raster file.</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                    <funcprototype>
                        <funcdef>raster <function>ST_FromGDALRaster</function></funcdef>
                        <paramdef><type>bytea </type> <parameter>gdaldata</parameter></paramdef>
                        <paramdef choice="opt"><type>integer </type> <parameter>srid=NULL</parameter></paramdef>
                    </funcprototype>

                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>
                    Returns a raster from a supported GDAL raster file. <varname>gdaldata</varname> is of type bytea and should be the contents of the GDAL raster file.
                </para>

                <para>
                    If <varname>srid</varname> is NULL, the function will try to automatically assign the SRID from the GDAL raster. If <varname>srid</varname> is provided, the value provided will override any automatically assigned SRID.
                </para>

                <para role="availability" conformance="2.1.0">Availability: 2.1.0</para>
            </refsection>

            <refsection>
                <title>Examples</title>

                <programlisting language="sql">
WITH foo AS (
    SELECT ST_AsPNG(ST_AddBand(ST_AddBand(ST_AddBand(ST_MakeEmptyRaster(2, 2, 0, 0, 0.1, -0.1, 0, 0, 4326), 1, '8BUI', 1, 0), 2, '8BUI', 2, 0), 3, '8BUI', 3, 0)) AS png
),
bar AS (
    SELECT 1 AS rid, ST_FromGDALRaster(png) AS rast FROM foo
    UNION ALL
    SELECT 2 AS rid, ST_FromGDALRaster(png, 3310) AS rast FROM foo
)
SELECT
    rid,
    ST_MetaData(rast) AS metadata,
    ST_SummaryStats(rast, 1) AS stats1,
    ST_SummaryStats(rast, 2) AS stats2,
    ST_SummaryStats(rast, 3) AS stats3
FROM bar
ORDER BY rid;</programlisting>
<screen role="text-primary"> rid |         metadata          |    stats1     |    stats2     |     stats3
-----+---------------------------+---------------+---------------+----------------
   1 | (0,0,2,2,1,-1,0,0,0,3)    | (4,4,1,0,1,1) | (4,8,2,0,2,2) | (4,12,3,0,3,3)
   2 | (0,0,2,2,1,-1,0,0,3310,3) | (4,4,1,0,1,1) | (4,8,2,0,2,2) | (4,12,3,0,3,3)
(2 rows)</screen>

            </refsection>

            <refsection>
                <title>See Also</title>
                <para>
                    <xref linkend="RT_ST_AsGDALRaster"/>
                </para>
            </refsection>

        </refentry>

    </section>
    <section xml:id="Raster_Accessors">
        <title>Raster Accessors</title>

        <refentry xml:id="RT_ST_GeoReference">
            <refnamediv>
                <refname>ST_GeoReference</refname>
                <refpurpose>Returns the georeference meta data in GDAL or ESRI format as commonly seen in a world file. Default is GDAL.</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                  <funcprototype>
                    <funcdef>text <function>ST_GeoReference</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    <paramdef choice="opt"><type>text </type> <parameter>format=GDAL</parameter></paramdef>
                  </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>Returns the georeference meta data including carriage return in GDAL or ESRI format as commonly seen in a <link xlink:href="http://en.wikipedia.org/wiki/World_file">world file</link>. Default is GDAL if no type specified.  type is string 'GDAL' or 'ESRI'.
                     </para>
                <para>Difference between format representations is as follows:</para>
                <para><varname>GDAL</varname>:
<screen role="text-primary">scalex
skewy
skewx
scaley
upperleftx
upperlefty</screen></para>
                <para><varname>ESRI</varname>:
<screen role="text-primary">scalex
skewy
skewx
scaley
upperleftx + scalex*0.5
upperlefty + scaley*0.5</screen></para>
            </refsection>

            <refsection>
                <title>Examples</title>

                <programlisting language="sql">SELECT
    format,
    replace(ST_GeoReference(rast, format), E'\n', ' | ') AS georef
FROM dummy_rast
CROSS JOIN (VALUES ('ESRI'), ('GDAL')) AS formats(format)
WHERE rid = 1;</programlisting>
<screen role="text-primary"> format | georef
--------+---------------------------------------------------------------------------
 ESRI   | 2.0000000000 | 0.0000000000 | 0.0000000000 | 3.0000000000 | 1.5000000000 | 2.0000000000
 GDAL   | 2.0000000000 | 0.0000000000 | 0.0000000000 | 3.0000000000 | 0.5000000000 | 0.5000000000
(2 rows)</screen>
            </refsection>

            <refsection>
                <title>See Also</title>
                <para><xref linkend="RT_ST_SetGeoReference"/>, <xref linkend="RT_ST_ScaleX"/>, <xref linkend="RT_ST_ScaleY"/></para>
            </refsection>
        </refentry>

        <refentry xml:id="RT_ST_Height">
            <refnamediv>
                <refname>ST_Height</refname>
                <refpurpose>Returns the height of the raster in pixels.</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                  <funcprototype>
                    <funcdef>integer <function>ST_Height</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                  </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>Returns the height of the raster.</para>
                </refsection>

                <refsection>
                    <title>Examples</title>

                    <programlisting language="sql">SELECT rid, ST_Height(rast) As rastheight
FROM dummy_rast;</programlisting>
<screen role="text-primary"> rid | rastheight
-----+------------
   1 |         20
   2 |          5</screen>

            </refsection>

            <refsection>
                <title>See Also</title>
                <para><xref linkend="RT_ST_Width"/></para>
            </refsection>
        </refentry>

        <refentry xml:id="RT_ST_IsEmpty">
            <refnamediv>
                <refname>ST_IsEmpty</refname>
                <refpurpose>Returns true if the raster is empty (width = 0 and height = 0). Otherwise, returns false.</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                  <funcprototype>
                    <funcdef>boolean <function>ST_IsEmpty</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                  </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>Returns true if the raster is empty (width = 0 and height = 0). Otherwise, returns false.</para>

                <para role="availability" conformance="2.0.0">Availability: 2.0.0</para>
            </refsection>

            <refsection>
                <title>Examples</title>

                <programlisting language="sql">SELECT ST_IsEmpty(ST_MakeEmptyRaster(100, 100, 0, 0, 0, 0, 0, 0))</programlisting>
<screen role="text-primary">f</screen>
<programlisting language="sql">SELECT ST_IsEmpty(ST_MakeEmptyRaster(0, 0, 0, 0, 0, 0, 0, 0))</programlisting>
<screen role="text-primary">t</screen>
            </refsection>

            <!-- Optionally add a "See Also" section -->
            <refsection>
                <title>See Also</title>
                <para><xref linkend="RT_ST_HasNoBand"/></para>
            </refsection>
        </refentry>

     <refentry xml:id="RT_ST_MemSize">
      <refnamediv>
        <refname>ST_MemSize</refname>

        <refpurpose>Returns the amount of space (in bytes) the raster takes.</refpurpose>
      </refnamediv>

      <refsynopsisdiv>
        <funcsynopsis>
          <funcprototype>
            <funcdef>integer <function>ST_MemSize</function></funcdef>
            <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>
      </refsynopsisdiv>

      <refsection>
        <title>Description</title>

        <para>Returns the amount of space (in bytes) the raster takes. </para>
        <para>This is a nice compliment to PostgreSQL built in functions pg_column_size, pg_size_pretty, pg_relation_size, pg_total_relation_size.</para>
        <note><para>pg_relation_size which gives the byte size of a table may return byte size lower than ST_MemSize. This is because
        pg_relation_size does not add toasted table contribution and large geometries are stored in TOAST tables. pg_column_size might return lower because it returns the compressed size.</para>
        <para>pg_total_relation_size - includes, the table, the toasted tables, and the indexes.</para>
        </note>

        <para role="availability" conformance="2.2.0">Availability: 2.2.0</para>
      </refsection>


      <refsection>
        <title>Examples</title>

        <programlisting language="sql">SELECT ST_MemSize(ST_AsRaster(ST_Buffer(ST_Point(1, 5), 10, 1000), 150, 150, '8BUI')) AS rast_mem;</programlisting>
<screen role="text-primary">22568</screen>
      </refsection>

      <!-- Optionally add a "See Also" section -->
      <refsection>
        <title>See Also</title>

        <para/>
      </refsection>
    </refentry>

        <refentry xml:id="RT_ST_MetaData">
            <refnamediv>
                <refname>ST_MetaData</refname>
                <refpurpose>Returns basic meta data about a raster object such as pixel size, rotation (skew), upper, lower left, etc.</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                  <funcprototype>
                    <funcdef>record <function>ST_MetaData</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                  </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>Returns basic meta data about a raster object such as pixel size, rotation (skew), upper, lower left, etc. Columns returned:
                    upperleftx | upperlefty | width | height | scalex | scaley | skewx | skewy | srid | numbands</para>
            </refsection>

            <refsection>
                <title>Examples</title>

                <programlisting language="sql">SELECT
    rid,
    format('(%s, %s)', (md).upperleftx, (md).upperlefty) AS upper_left,
    format('%sx%s', (md).width, (md).height) AS size,
    format('(%s, %s)', (md).scalex, (md).scaley) AS scale,
    format('(%s, %s)', (md).skewx, (md).skewy) AS skew,
    (md).srid AS srid,
    (md).numbands AS numbands
FROM (
    SELECT rid, ST_MetaData(rast) AS md
    FROM dummy_rast
) AS foo
ORDER BY rid;</programlisting>
<screen role="text-primary"> rid |        upper_left        | size  |      scale      |  skew  | srid | numbands
-----+--------------------------+-------+-----------------+--------+------+----------
   1 | (0.5, 0.5)               | 10x20 | (2, 3)          | (0, 0) |    0 |        0
   2 | (3427927.75, 5793244)    | 5x5   | (0.05, -0.05)   | (0, 0) |    0 |        3
(2 rows)</screen>
            </refsection>

            <!-- Optionally add a "See Also" section -->
            <refsection>
                <title>See Also</title>
                <para><xref linkend="RT_ST_BandMetaData"/>, <xref linkend="RT_ST_NumBands"/></para>
            </refsection>
        </refentry>

        <refentry xml:id="RT_ST_NumBands">
            <refnamediv>
                <refname>ST_NumBands</refname>
                <refpurpose>Returns the number of bands in the raster object.</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                  <funcprototype>
                    <funcdef>integer <function>ST_NumBands</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                  </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>Returns the number of bands in the raster object.</para>
            </refsection>

            <refsection>
                <title>Examples</title>

                <programlisting language="sql">SELECT rid, ST_NumBands(rast) As numbands
FROM dummy_rast;</programlisting>
<screen role="text-primary">rid | numbands
----+----------
  1 |        0
  2 |        3</screen>
            </refsection>

            <!-- Optionally add a "See Also" section -->
            <refsection>
                <title>See Also</title>
                <para><xref linkend="RT_ST_Value"/></para>
            </refsection>
        </refentry>

        <refentry xml:id="RT_ST_PixelHeight">
            <refnamediv>
                <refname>ST_PixelHeight</refname>
                <refpurpose>Returns the pixel height in geometric units of the spatial reference system.</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                  <funcprototype>
                    <funcdef>double precision <function>ST_PixelHeight</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                  </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>Returns the height of a pixel in geometric units of the spatial reference system. In the common case where
                there is no skew, the pixel height is just the scale ratio between geometric coordinates and raster pixels.</para>
                <para>Refer to <xref linkend="RT_ST_PixelWidth"/> for a diagrammatic visualization of the relationship. </para>
            </refsection>

            <refsection>
                <title>Examples</title>
                <para>Rasters with no skew.</para>

                <programlisting language="sql">SELECT ST_Height(rast) As rastheight, ST_PixelHeight(rast) As pixheight,
 ST_ScaleX(rast) As scalex, ST_ScaleY(rast) As scaley, ST_SkewX(rast) As skewx,
        ST_SkewY(rast) As skewy
FROM dummy_rast;</programlisting>
<screen role="text-primary"> rastheight | pixheight | scalex | scaley | skewx | skewy
------------+-----------+--------+--------+-------+----------
         20 |         3 |      2 |      3 |     0 |        0
          5 |      0.05 |   0.05 |  -0.05 |     0 |        0</screen>


                <para>Rasters with skew different than 0.</para>

                <programlisting language="sql">SELECT ST_Height(rast) As rastheight, ST_PixelHeight(rast) As pixheight,
 ST_ScaleX(rast) As scalex, ST_ScaleY(rast) As scaley, ST_SkewX(rast) As skewx,
        ST_SkewY(rast) As skewy
FROM (SELECT ST_SetSkew(rast, 0.5, 0.5) As rast
        FROM dummy_rast) As skewed;</programlisting>
<screen role="text-primary">rastheight |     pixheight     | scalex | scaley | skewx | skewy
-----------+-------------------+--------+--------+-------+----------
        20 |  3.04138126514911 |      2 |      3 |   0.5 |      0.5
         5 | 0.502493781056044 |   0.05 |  -0.05 |   0.5 |      0.5</screen>

        </refsection>

        <!-- Optionally add a "See Also" section -->
        <refsection>
            <title>See Also</title>
            <para>
                <xref linkend="RT_ST_PixelWidth"/>,
                <xref linkend="RT_ST_ScaleX"/>,
                <xref linkend="RT_ST_ScaleY"/>,
                <xref linkend="RT_ST_SkewX"/>,
                <xref linkend="RT_ST_SkewY"/>
            </para>
        </refsection>
    </refentry>

    <refentry xml:id="RT_ST_PixelWidth">
        <refnamediv>
            <refname>ST_PixelWidth</refname>
            <refpurpose>Returns the pixel width in geometric units of the spatial reference system.</refpurpose>
        </refnamediv>

        <refsynopsisdiv>
            <funcsynopsis>
              <funcprototype>
                <funcdef>double precision <function>ST_PixelWidth</function></funcdef>
                <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
              </funcprototype>
            </funcsynopsis>
        </refsynopsisdiv>

        <refsection>
            <title>Description</title>

            <para>Returns the width of a pixel in geometric units of the spatial reference system. In the common case where
            there is no skew, the pixel width is just the scale ratio between geometric coordinates and raster pixels.</para>
            <para>The following executable example draws the two pixel basis
            vectors on the same coordinate frame as a skewed raster footprint.
            The <literal>i direction</literal> vector is
            <literal>(scaleX, skewY)</literal>; the <literal>j direction</literal>
            vector is <literal>(skewX, scaleY)</literal>.</para>
        </refsection>

        <refsection>
            <title>Examples</title>
            <para>Pixel basis vectors and footprint for a raster with non-zero skew.</para>
            <programlisting language="sql">WITH raster AS (
    SELECT ST_MakeEmptyRaster(
        3, 3, 0, 0,
        2, -3, 1, 0.5,
        0
    ) AS rast
)
SELECT
    ST_ConvexHull(rast) AS footprint,
    ST_MakeLine(
        ST_Point(0, 0),
        ST_Point(ST_ScaleX(rast), ST_SkewY(rast))
    ) AS "i direction (scaleX, skewY)",
    ST_MakeLine(
        ST_Point(0, 0),
        ST_Point(ST_SkewX(rast), ST_ScaleY(rast))
    ) AS "j direction (skewX, scaleY)"
FROM raster;</programlisting>
            <screen role="visual-primary visual-overlay text-primary">POLYGON((0 0,6 1.5,9 -7.5,3 -9,0 0)) | LINESTRING(0 0,2 0.5) | LINESTRING(0 0,1 -3)</screen>
            <para>Rasters with no skew.</para>

            <programlisting language="sql">SELECT ST_Width(rast) As rastwidth, ST_PixelWidth(rast) As pixwidth,
ST_ScaleX(rast) As scalex, ST_ScaleY(rast) As scaley, ST_SkewX(rast) As skewx,
ST_SkewY(rast) As skewy
FROM dummy_rast;</programlisting>
<screen role="text-primary">    rastwidth | pixwidth | scalex | scaley | skewx | skewy
-----------+----------+--------+--------+-------+----------
10 |        2 |      2 |      3 |     0 |        0
 5 |     0.05 |   0.05 |  -0.05 |     0 |        0</screen>


            <para>Rasters with skew different than 0.</para>

            <programlisting language="sql">SELECT ST_Width(rast) As rastwidth, ST_PixelWidth(rast) As pixwidth,
ST_ScaleX(rast) As scalex, ST_ScaleY(rast) As scaley, ST_SkewX(rast) As skewx,
ST_SkewY(rast) As skewy
FROM (SELECT ST_SetSkew(rast, 0.5, 0.5) As rast
FROM dummy_rast) As skewed;</programlisting>
<screen role="text-primary">    rastwidth |     pixwidth      | scalex | scaley | skewx | skewy
-----------+-------------------+--------+--------+-------+----------
10 |  2.06155281280883 |      2 |      3 |   0.5 |      0.5
 5 | 0.502493781056044 |   0.05 |  -0.05 |   0.5 |      0.5</screen>

    </refsection>

    <!-- Optionally add a "See Also" section -->
    <refsection>
        <title>See Also</title>
        <para><xref linkend="RT_ST_PixelHeight"/>, <xref linkend="RT_ST_ScaleX"/>, <xref linkend="RT_ST_ScaleY"/>, <xref linkend="RT_ST_SkewX"/>, <xref linkend="RT_ST_SkewY"/></para>
    </refsection>
    </refentry>

        <refentry xml:id="RT_ST_ScaleX">
            <refnamediv>
                <refname>ST_ScaleX</refname>
                <refpurpose>Returns the X component of the pixel width in units of coordinate reference system.</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                  <funcprototype>
                    <funcdef>float8 <function>ST_ScaleX</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                  </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>Returns the X component of the pixel width in units of coordinate reference system. Refer to <link xlink:href="http://en.wikipedia.org/wiki/World_file">World File</link>
                for more details.</para>
                <para role="changed" conformance="2.0.0.">Changed: 2.0.0. In WKTRaster versions this was called ST_PixelSizeX.</para>
                </refsection>

                <refsection>
                    <title>Examples</title>

                    <programlisting language="sql">SELECT rid, ST_ScaleX(rast) As rastpixwidth
FROM dummy_rast;</programlisting>
<screen role="text-primary"> rid | rastpixwidth
-----+--------------
   1 |            2
   2 |         0.05</screen>

            </refsection>

            <!-- Optionally add a "See Also" section -->
            <refsection>
                <title>See Also</title>
                <para><xref linkend="RT_ST_Width"/></para>
            </refsection>
        </refentry>

        <refentry xml:id="RT_ST_ScaleY">
            <refnamediv>
                <refname>ST_ScaleY</refname>
                <refpurpose>Returns the Y component of the pixel height in units of coordinate reference system.</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                  <funcprototype>
                    <funcdef>float8 <function>ST_ScaleY</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                  </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>Returns the Y component of the pixel height in units of coordinate reference system.  May be negative.  Refer to <link xlink:href="http://en.wikipedia.org/wiki/World_file">World File</link>
                for more details.</para>

                <para role="changed" conformance="2.0.0.">Changed: 2.0.0. In WKTRaster versions this was called ST_PixelSizeY.</para>
                </refsection>

                <refsection>
                    <title>Examples</title>

                    <programlisting language="sql">SELECT rid, ST_ScaleY(rast) As rastpixheight
FROM dummy_rast;</programlisting>
<screen role="text-primary"> rid | rastpixheight
-----+---------------
   1 |             3
   2 |         -0.05</screen>

            </refsection>

            <!-- Optionally add a "See Also" section -->
            <refsection>
                <title>See Also</title>
                <para><xref linkend="RT_ST_Height"/></para>
            </refsection>
        </refentry>

        <refentry xml:id="RT_ST_RasterToWorldCoord">
            <refnamediv>
                <refname>ST_RasterToWorldCoord</refname>
                <refpurpose>Returns the raster's upper left corner as geometric X and Y (longitude and latitude) given a column and row. Column and row starts at 1.</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                  <funcprototype>
                    <funcdef>record <function>ST_RasterToWorldCoord</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    <paramdef><type>integer </type> <parameter>xcolumn</parameter></paramdef>
                    <paramdef><type>integer </type> <parameter>yrow</parameter></paramdef>
                  </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>
                    Returns the upper left corner as geometric X and Y (longitude and latitude) given a column and row.  Returned X and Y are in geometric units of the georeferenced raster.
                    Numbering of column and row starts at 1 but if either parameter is passed a zero, a negative number or a number greater than the respective dimension of the raster, it will return coordinates outside of the raster assuming the raster's grid is applicable outside the raster's bounds.
                </para>

                <para role="availability" conformance="2.1.0">Availability: 2.1.0</para>

            </refsection>

            <refsection>
                <title>Examples</title>

                    <para>This example uses a non-skewed raster.</para>
                    <programlisting language="sql">
SELECT
    rid,
    (ST_RasterToWorldCoord(rast, 1, 1)).*,
    (ST_RasterToWorldCoord(rast, 2, 2)).*
FROM dummy_rast</programlisting>
<screen role="text-primary"> rid | longitude  | latitude | longitude |  latitude
-----+------------+----------+-----------+------------
   1 |        0.5 |      0.5 |       2.5 |        3.5
   2 | 3427927.75 |  5793244 | 3427927.8 | 5793243.95</screen>

                    <para>This example uses a skewed raster.</para>
                    <programlisting language="sql">
SELECT
    rid,
    (ST_RasterToWorldCoord(rast, 1, 1)).*,
    (ST_RasterToWorldCoord(rast, 2, 3)).*
FROM (
    SELECT
        rid,
        ST_SetSkew(rast, 100.5, 0) As rast
    FROM dummy_rast
) As foo</programlisting>
<screen role="text-primary"> rid | longitude  | latitude | longitude | latitude
-----+------------+----------+-----------+-----------
   1 |        0.5 |      0.5 |     203.5 |       6.5
   2 | 3427927.75 |  5793244 | 3428128.8 | 5793243.9</screen>

            </refsection>

            <!-- Optionally add a "See Also" section -->
            <refsection>
                <title>See Also</title>
                <para>
                    <xref linkend="RT_ST_RasterToWorldCoordX"/>,
                    <xref linkend="RT_ST_RasterToWorldCoordY"/>,
                    <xref linkend="RT_ST_SetSkew"/>
                </para>
            </refsection>
        </refentry>

        <refentry xml:id="RT_ST_RasterToWorldCoordX">
            <refnamediv>
                <refname>ST_RasterToWorldCoordX</refname>
                <refpurpose>Returns the geometric X coordinate upper left of a raster, column and row. Numbering of columns
                    and rows starts at 1.</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                  <funcprototype>
                    <funcdef>float8 <function>ST_RasterToWorldCoordX</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    <paramdef><type>integer </type> <parameter>xcolumn</parameter></paramdef>
                  </funcprototype>
                  <funcprototype>
                    <funcdef>float8 <function>ST_RasterToWorldCoordX</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    <paramdef><type>integer </type> <parameter>xcolumn</parameter></paramdef>
                    <paramdef><type>integer </type> <parameter>yrow</parameter></paramdef>
                  </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>Returns the upper left X coordinate of a raster column row in geometric units of the georeferenced raster.
                    Numbering of columns and rows starts at 1 but if you pass in a negative number or number higher than number of
                        columns in raster, it will give you
                    coordinates outside of the raster file to left or right with the assumption that the
                    skew and pixel sizes are same as selected raster. </para>
                <note><para>For non-skewed rasters, providing the X column is sufficient.  For skewed rasters,
                        the georeferenced coordinate is a function of the ST_ScaleX and ST_SkewX and row and column.
                        An error will be raised if you give just the X column for a skewed raster.</para></note>

                <para role="changed" conformance="2.1.0">Changed: 2.1.0 In prior versions, this was called ST_Raster2WorldCoordX</para>

                </refsection>

                <refsection>
                    <title>Examples</title>

                    <para>This example shows that providing a column is sufficient for a non-skewed raster.</para>
                    <programlisting language="sql">
SELECT rid, ST_RasterToWorldCoordX(rast, 1) As x1coord,
    ST_RasterToWorldCoordX(rast, 2) As x2coord,
    ST_ScaleX(rast) As pixelx
FROM dummy_rast;</programlisting>
<screen role="text-primary"> rid |  x1coord   |  x2coord  | pixelx
-----+------------+-----------+--------
   1 |        0.5 |       2.5 |      2
   2 | 3427927.75 | 3427927.8 |   0.05</screen>

                    <para>For fun let's skew it.</para>
                    <programlisting language="sql">
SELECT rid, ST_RasterToWorldCoordX(rast, 1, 1) As x1coord,
    ST_RasterToWorldCoordX(rast, 2, 3) As x2coord,
    ST_ScaleX(rast) As pixelx
FROM (SELECT rid, ST_SetSkew(rast, 100.5, 0) As rast FROM dummy_rast) As foo;</programlisting>
<screen role="text-primary"> rid |  x1coord   |  x2coord  | pixelx
-----+------------+-----------+--------
   1 |        0.5 |     203.5 |      2
   2 | 3427927.75 | 3428128.8 |   0.05</screen>

            </refsection>

            <!-- Optionally add a "See Also" section -->
            <refsection>
                <title>See Also</title>
                <para><xref linkend="RT_ST_ScaleX"/>, <xref linkend="RT_ST_RasterToWorldCoordY"/>, <xref linkend="RT_ST_SetSkew"/>, <xref linkend="RT_ST_SkewX"/></para>
            </refsection>
        </refentry>

        <refentry xml:id="RT_ST_RasterToWorldCoordY">
            <refnamediv>
                <refname>ST_RasterToWorldCoordY</refname>
                <refpurpose>Returns the geometric Y coordinate upper left corner of a raster, column and row. Numbering of columns
                    and rows starts at 1. </refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                  <funcprototype>
                    <funcdef>float8 <function>ST_RasterToWorldCoordY</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    <paramdef><type>integer </type> <parameter>yrow</parameter></paramdef>
                  </funcprototype>
                  <funcprototype>
                    <funcdef>float8 <function>ST_RasterToWorldCoordY</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    <paramdef><type>integer </type> <parameter>xcolumn</parameter></paramdef>
                    <paramdef><type>integer </type> <parameter>yrow</parameter></paramdef>
                  </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>Returns the upper left Y coordinate of a raster column row in geometric units of the georeferenced raster.
                    Numbering of columns and rows starts at 1 but if you pass in a negative number or number higher than number of
                        columns/rows in raster, it will give you
                    coordinates outside of the raster file to left or right with the assumption that the
                    skew and pixel sizes are same as selected raster tile. </para>
                <note><para>For non-skewed rasters, providing the Y column is sufficient. For skewed rasters,
                        the georeferenced coordinate is a function of the ST_ScaleY and ST_SkewY and row and column.
                        An error will be raised if you give just the Y row for a skewed raster.</para></note>

                <para role="changed" conformance="2.1.0">Changed: 2.1.0 In prior versions, this was called ST_Raster2WorldCoordY</para>
                </refsection>

                <refsection>
                    <title>Examples</title>

                    <para>Non-skewed raster providing row is sufficient.</para>
                    <programlisting language="sql">
SELECT rid, ST_RasterToWorldCoordY(rast, 1) As y1coord,
    ST_RasterToWorldCoordY(rast, 3) As y2coord,
    ST_ScaleY(rast) As pixely
FROM dummy_rast;</programlisting>
<screen role="text-primary"> rid | y1coord |  y2coord  | pixely
-----+---------+-----------+--------
   1 |     0.5 |       6.5 |      3
   2 | 5793244 | 5793243.9 |  -0.05</screen>

                    <para>For fun let's skew it.</para>
                    <programlisting language="sql">
SELECT rid, ST_RasterToWorldCoordY(rast, 1, 1) As y1coord,
    ST_RasterToWorldCoordY(rast, 2, 3) As y2coord,
    ST_ScaleY(rast) As pixely
FROM (SELECT rid, ST_SetSkew(rast, 0, 100.5) As rast FROM dummy_rast) As foo;</programlisting>
<screen role="text-primary"> rid | y1coord |  y2coord  | pixely
-----+---------+-----------+--------
   1 |     0.5 |       107 |      3
   2 | 5793244 | 5793344.4 |  -0.05</screen>

            </refsection>

            <!-- Optionally add a "See Also" section -->
            <refsection>
                <title>See Also</title>
                <para><xref linkend="RT_ST_ScaleY"/>, <xref linkend="RT_ST_RasterToWorldCoordX"/>, <xref linkend="RT_ST_SetSkew"/>, <xref linkend="RT_ST_SkewY"/></para>
            </refsection>
        </refentry>

        <refentry xml:id="RT_ST_Rotation">
            <refnamediv>
                <refname>ST_Rotation</refname>
                <refpurpose>Returns the rotation of the raster in radian.</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                    <funcprototype>
                        <funcdef>float8 <function>ST_Rotation</function></funcdef>
                        <paramdef><type>raster</type> <parameter>rast</parameter></paramdef>
                    </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>Returns the uniform rotation of the raster in radian. If a raster does not have uniform rotation, NaN is returned.
                Refer to <link xlink:href="http://en.wikipedia.org/wiki/World_file">World File</link> for more details.</para>
            </refsection>

            <refsection>
                <title>Examples</title>

                <programlisting language="sql">SELECT rid, ST_Rotation(ST_SetScale(ST_SetSkew(rast, sqrt(2)), sqrt(2))) AS rot FROM dummy_rast;</programlisting>
<screen role="text-primary"> rid |        rot
-----+-------------------
   1 | 0.785398163397448
   2 | 0.785398163397448</screen>
            </refsection>

            <!-- Optionally add a "See Also" section -->
            <refsection>
                <title>See Also</title>
                <para><xref linkend="RT_ST_SetRotation"/>, <xref linkend="RT_ST_SetScale"/>, <xref linkend="RT_ST_SetSkew"/></para>
            </refsection>
        </refentry>

        <refentry xml:id="RT_ST_SkewX">
            <refnamediv>
                <refname>ST_SkewX</refname>
                <refpurpose>Returns the georeference X skew (or rotation parameter).</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                  <funcprototype>
                    <funcdef>float8 <function>ST_SkewX</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                  </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>Returns the georeference X skew (or rotation parameter).  Refer to <link xlink:href="http://en.wikipedia.org/wiki/World_file">World File</link>
                for more details.</para>
                </refsection>

                <refsection>
                    <title>Examples</title>

                    <programlisting language="sql">WITH refs AS (
    SELECT
        rid,
        format('(%s, %s)', ST_SkewX(rast), ST_SkewY(rast)) AS skew,
        string_to_array(ST_GeoReference(rast), E'\n') AS georef
    FROM dummy_rast
)
SELECT
    rid,
    skew,
    term,
    georef[idx] AS value
FROM refs
CROSS JOIN (VALUES
    (1, 'scaleX'),
    (2, 'skewY'),
    (3, 'skewX'),
    (4, 'scaleY'),
    (5, 'originX'),
    (6, 'originY')
) AS parts(idx, term)
ORDER BY rid, idx;</programlisting>
<screen role="text-primary"> rid |  skew  |  term   |       value
-----+--------+---------+--------------------
   1 | (0, 0) | scaleX  | 2.0000000000
   1 | (0, 0) | skewY   | 0.0000000000
   1 | (0, 0) | skewX   | 0.0000000000
   1 | (0, 0) | scaleY  | 3.0000000000
   1 | (0, 0) | originX | 0.5000000000
   1 | (0, 0) | originY | 0.5000000000
   2 | (0, 0) | scaleX  | 0.0500000000
   2 | (0, 0) | skewY   | 0.0000000000
   2 | (0, 0) | skewX   | 0.0000000000
   2 | (0, 0) | scaleY  | -0.0500000000
   2 | (0, 0) | originX | 3427927.7500000000
   2 | (0, 0) | originY | 5793244.0000000000
(12 rows)</screen>

            </refsection>

            <!-- Optionally add a "See Also" section -->
            <refsection>
                <title>See Also</title>
                <para><xref linkend="RT_ST_GeoReference"/>, <xref linkend="RT_ST_SkewY"/>, <xref linkend="RT_ST_SetSkew"/></para>
            </refsection>
        </refentry>

        <refentry xml:id="RT_ST_SkewY">
            <refnamediv>
                <refname>ST_SkewY</refname>
                <refpurpose>Returns the georeference Y skew (or rotation parameter).</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                  <funcprototype>
                    <funcdef>float8 <function>ST_SkewY</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                  </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>Returns the georeference Y skew (or rotation parameter).  Refer to <link xlink:href="http://en.wikipedia.org/wiki/World_file">World File</link>
                for more details.</para>
                </refsection>

                <refsection>
                    <title>Examples</title>

                    <programlisting language="sql">WITH refs AS (
    SELECT
        rid,
        format('(%s, %s)', ST_SkewX(rast), ST_SkewY(rast)) AS skew,
        string_to_array(ST_GeoReference(rast), E'\n') AS georef
    FROM dummy_rast
)
SELECT
    rid,
    skew,
    term,
    georef[idx] AS value
FROM refs
CROSS JOIN (VALUES
    (1, 'scaleX'),
    (2, 'skewY'),
    (3, 'skewX'),
    (4, 'scaleY'),
    (5, 'originX'),
    (6, 'originY')
) AS parts(idx, term)
ORDER BY rid, idx;</programlisting>
<screen role="text-primary"> rid |  skew  |  term   |       value
-----+--------+---------+--------------------
   1 | (0, 0) | scaleX  | 2.0000000000
   1 | (0, 0) | skewY   | 0.0000000000
   1 | (0, 0) | skewX   | 0.0000000000
   1 | (0, 0) | scaleY  | 3.0000000000
   1 | (0, 0) | originX | 0.5000000000
   1 | (0, 0) | originY | 0.5000000000
   2 | (0, 0) | scaleX  | 0.0500000000
   2 | (0, 0) | skewY   | 0.0000000000
   2 | (0, 0) | skewX   | 0.0000000000
   2 | (0, 0) | scaleY  | -0.0500000000
   2 | (0, 0) | originX | 3427927.7500000000
   2 | (0, 0) | originY | 5793244.0000000000
(12 rows)</screen>

            </refsection>

            <!-- Optionally add a "See Also" section -->
            <refsection>
                <title>See Also</title>
                <para><xref linkend="RT_ST_GeoReference"/>, <xref linkend="RT_ST_SkewX"/>, <xref linkend="RT_ST_SetSkew"/></para>
            </refsection>
        </refentry>

        <refentry xml:id="RT_ST_SRID">
            <refnamediv>
                <refname>ST_SRID</refname>
                <refpurpose>Returns the spatial reference identifier of the raster as defined in spatial_ref_sys table.</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                  <funcprototype>
                    <funcdef>integer <function>ST_SRID</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                  </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>Returns the spatial reference identifier of the raster object as defined in the spatial_ref_sys table.</para>
                <note><para>Non-georeferenced rasters and geometries use SRID 0.</para></note>
            </refsection>

            <refsection>
                <title>Examples</title>

                <programlisting language="sql">SELECT ST_SRID(rast) As srid
FROM dummy_rast WHERE rid=1;</programlisting>
<screen role="text-primary">0</screen>
            </refsection>

            <!-- Optionally add a "See Also" section -->
            <refsection>
                <title>See Also</title>
                <para><xref linkend="spatial_ref_sys"/>, <xref linkend="ST_SRID"/></para>
            </refsection>
        </refentry>

        <refentry xml:id="RT_ST_Summary">
            <refnamediv>
                <refname>ST_Summary</refname>
                <refpurpose>Returns a text summary of the contents of the raster.</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                  <funcprototype>
                    <funcdef>text <function>ST_Summary</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                  </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>Returns a text summary of the contents of the raster.</para>

                <para role="availability" conformance="2.1.0">Availability: 2.1.0</para>
            </refsection>

            <refsection>
                <title>Examples</title>
                <programlisting language="sql">
SELECT ST_Summary(ST_AddBand(ST_AddBand(ST_AddBand(ST_MakeEmptyRaster(10, 10, 0, 0, 1, -1, 0, 0, 0),
                1, '8BUI', 1, 0
            ),
            2, '32BF', 0, -9999
        ),
        3, '16BSI', 0, NULL
    )
);</programlisting>
<screen role="text-primary"> Raster of 10x10 pixels has 3 bands and extent of BOX(0 -10,10 0)+
     band 1 of pixtype 8BUI is in-db with NODATA value of 0      +
     band 2 of pixtype 32BF is in-db with NODATA value of -9999  +
     band 3 of pixtype 16BSI is in-db with no NODATA value
(1 row)</screen>
            </refsection>

            <refsection>
                <title>See Also</title>
                <para>
                    <xref linkend="RT_ST_MetaData"/>,
                    <xref linkend="RT_ST_BandMetaData"/>,
                    <xref linkend="ST_Summary"/>
                    <xref linkend="ST_Extent"/>
                </para>
            </refsection>
        </refentry>

        <refentry xml:id="RT_ST_UpperLeftX">
            <refnamediv>
                <refname>ST_UpperLeftX</refname>
                <refpurpose>Returns the upper left X coordinate of raster in projected spatial ref.</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                  <funcprototype>
                    <funcdef>float8 <function>ST_UpperLeftX</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                  </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>Returns the upper left X coordinate of raster in projected spatial ref.</para>
                </refsection>

                <refsection>
                    <title>Examples</title>

                    <programlisting language="sql">
SELECt rid, ST_UpperLeftX(rast) As ulx
FROM dummy_rast;</programlisting>
<screen role="text-primary"> rid |    ulx
-----+------------
   1 |        0.5
   2 | 3427927.75</screen>

            </refsection>

            <refsection>
                <title>See Also</title>
                <para><xref linkend="RT_ST_UpperLeftY"/>, <xref linkend="RT_ST_GeoReference"/>, <xref linkend="RT_Box3D"/></para>
            </refsection>
        </refentry>

        <refentry xml:id="RT_ST_UpperLeftY">
            <refnamediv>
                <refname>ST_UpperLeftY</refname>
                <refpurpose>Returns the upper left Y coordinate of raster in projected spatial ref.</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                  <funcprototype>
                    <funcdef>float8 <function>ST_UpperLeftY</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                  </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>Returns the upper left Y coordinate of raster in projected spatial ref.</para>
                </refsection>

                <refsection>
                    <title>Examples</title>

                    <programlisting language="sql">
SELECT rid, ST_UpperLeftY(rast) As uly
FROM dummy_rast;</programlisting>
<screen role="text-primary"> rid |   uly
-----+---------
   1 |     0.5
   2 | 5793244</screen>

            </refsection>

            <refsection>
                <title>See Also</title>
                <para><xref linkend="RT_ST_UpperLeftX"/>, <xref linkend="RT_ST_GeoReference"/>, <xref linkend="RT_Box3D"/></para>
            </refsection>
        </refentry>

        <refentry xml:id="RT_ST_Width">
            <refnamediv>
                <refname>ST_Width</refname>
                <refpurpose>Returns the width of the raster in pixels.</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                  <funcprototype>
                    <funcdef>integer <function>ST_Width</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                  </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>Returns the width of the raster in pixels.</para>
                </refsection>

                <refsection>
                    <title>Examples</title>

                    <programlisting language="sql">SELECT ST_Width(rast) As rastwidth
FROM dummy_rast WHERE rid=1;</programlisting>
<screen role="text-primary">10</screen>

            </refsection>

            <!-- Optionally add a "See Also" section -->
            <refsection>
                <title>See Also</title>
                <para><xref linkend="RT_ST_Height"/></para>
            </refsection>
        </refentry>


        <refentry xml:id="RT_ST_WorldToRasterCoord">
            <refnamediv>
                <refname>ST_WorldToRasterCoord</refname>
                <refpurpose>    Returns the upper left corner as column and row given geometric X and Y (longitude and latitude) or a point geometry expressed in the spatial reference coordinate system of the raster.</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                  <funcprototype>
                    <funcdef>record <function>ST_WorldToRasterCoord</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    <paramdef><type>geometry </type> <parameter>pt</parameter></paramdef>
                  </funcprototype>

                   <funcprototype>
                    <funcdef>record <function>ST_WorldToRasterCoord</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    <paramdef><type>double precision </type> <parameter>longitude</parameter></paramdef>
                    <paramdef><type>double precision </type> <parameter>latitude</parameter></paramdef>
                  </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>
                    Returns the upper left corner as column and row given geometric X and Y (longitude and latitude) or a point geometry.
                    This function works regardless of whether or not the geometric X and Y or point geometry is outside the extent of the raster.
                    Geometric X and Y must be expressed in the spatial reference coordinate system of the raster.
                </para>

                <para role="availability" conformance="2.1.0">Availability: 2.1.0</para>

            </refsection>

            <refsection>
                <title>Examples</title>

                <programlisting language="sql">
SELECT
    rid,
    (ST_WorldToRasterCoord(rast, 3427927.8, 20.5)).*,
    (ST_WorldToRasterCoord(rast, ST_GeomFromText('POINT(3427927.8 20.5)', ST_SRID(rast)))).*
FROM dummy_rast;</programlisting>
<screen role="text-primary"> rid | columnx |   rowy    | columnx |   rowy
-----+---------+-----------+---------+-----------
   1 | 1713964 |         7 | 1713964 |         7
   2 |       2 | 115864471 |       2 | 115864471</screen>
            </refsection>

            <!-- Optionally add a "See Also" section -->
            <refsection>
                <title>See Also</title>
                <para>
                    <xref linkend="RT_ST_WorldToRasterCoordX"/>,
                    <xref linkend="RT_ST_WorldToRasterCoordY"/>,
                    <xref linkend="RT_ST_RasterToWorldCoordX"/>,
                    <xref linkend="RT_ST_RasterToWorldCoordY"/>,
                    <xref linkend="RT_ST_SRID"/>
                </para>
            </refsection>
        </refentry>

        <refentry xml:id="RT_ST_WorldToRasterCoordX">
            <refnamediv>
                <refname>ST_WorldToRasterCoordX</refname>
                <refpurpose>Returns the column in the raster of the point geometry (pt) or a X and Y world coordinate (xw, yw) represented
                in world spatial reference system of raster.</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                  <funcprototype>
                    <funcdef>integer <function>ST_WorldToRasterCoordX</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    <paramdef><type>geometry </type> <parameter>pt</parameter></paramdef>
                  </funcprototype>

                  <funcprototype>
                    <funcdef>integer <function>ST_WorldToRasterCoordX</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    <paramdef><type>double precision </type> <parameter>xw</parameter></paramdef>
                  </funcprototype>

                   <funcprototype>
                    <funcdef>integer <function>ST_WorldToRasterCoordX</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    <paramdef><type>double precision </type> <parameter>xw</parameter></paramdef>
                    <paramdef><type>double precision </type> <parameter>yw</parameter></paramdef>
                  </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>Returns the column in the raster of the point geometry (pt) or a X and Y world coordinate (xw, yw).  A point, or (both xw and yw world coordinates are required if a raster is skewed).  If a raster
                    is not skewed then xw is sufficient. World coordinates are in the spatial reference coordinate system of the raster.</para>
                <para role="changed" conformance="2.1.0">Changed: 2.1.0 In prior versions, this was called ST_World2RasterCoordX</para>
            </refsection>

            <refsection>
                <title>Examples</title>

                <programlisting language="sql">SELECT rid, ST_WorldToRasterCoordX(rast, 3427927.8) As xcoord,
        ST_WorldToRasterCoordX(rast, 3427927.8, 20.5) As xcoord_xwyw,
        ST_WorldToRasterCoordX(rast, ST_GeomFromText('POINT(3427927.8 20.5)', ST_SRID(rast))) As ptxcoord
FROM dummy_rast;</programlisting>
<screen role="text-primary"> rid | xcoord  |  xcoord_xwyw   | ptxcoord
-----+---------+---------+----------
   1 | 1713964 | 1713964 |  1713964
   2 |       1 |       1 |        1</screen>
            </refsection>

            <!-- Optionally add a "See Also" section -->
            <refsection>
                <title>See Also</title>
                <para>
                    <xref linkend="RT_ST_RasterToWorldCoordX"/>,
                    <xref linkend="RT_ST_RasterToWorldCoordY"/>,
                    <xref linkend="RT_ST_SRID"/>
                </para>
            </refsection>
        </refentry>

        <refentry xml:id="RT_ST_WorldToRasterCoordY">
            <refnamediv>
                <refname>ST_WorldToRasterCoordY</refname>
                <refpurpose>Returns the row in the raster of the point geometry (pt) or a X and Y world coordinate (xw, yw) represented
                in world spatial reference system of raster.</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                  <funcprototype>
                    <funcdef>integer <function>ST_WorldToRasterCoordY</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    <paramdef><type>geometry </type> <parameter>pt</parameter></paramdef>
                  </funcprototype>

                  <funcprototype>
                    <funcdef>integer <function>ST_WorldToRasterCoordY</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    <paramdef><type>double precision </type> <parameter>xw</parameter></paramdef>
                  </funcprototype>

                   <funcprototype>
                    <funcdef>integer <function>ST_WorldToRasterCoordY</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    <paramdef><type>double precision </type> <parameter>xw</parameter></paramdef>
                    <paramdef><type>double precision </type> <parameter>yw</parameter></paramdef>
                  </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>Returns the row in the raster of the point geometry (pt) or a X and Y world coordinate (xw, yw).  A point, or (both xw and yw world coordinates are required if a raster is skewed).  If a raster
                    is not skewed then xw is sufficient. World coordinates are in the spatial reference coordinate system of the raster.</para>
                <para role="changed" conformance="2.1.0">Changed: 2.1.0 In prior versions, this was called ST_World2RasterCoordY</para>
            </refsection>

            <refsection>
                <title>Examples</title>

                <programlisting language="sql">SELECT rid, ST_WorldToRasterCoordY(rast, 20.5) As ycoord,
        ST_WorldToRasterCoordY(rast, 3427927.8, 20.5) As ycoord_xwyw,
        ST_WorldToRasterCoordY(rast, ST_GeomFromText('POINT(3427927.8 20.5)', ST_SRID(rast))) As ptycoord
FROM dummy_rast;</programlisting>
<screen role="text-primary"> rid |  ycoord   | ycoord_xwyw | ptycoord
-----+-----------+-------------+-----------
   1 |         7 |           7 |         7
   2 | 115864471 |   115864471 | 115864471</screen>
            </refsection>

            <!-- Optionally add a "See Also" section -->
            <refsection>
                <title>See Also</title>
                <para><xref linkend="RT_ST_RasterToWorldCoordX"/>, <xref linkend="RT_ST_RasterToWorldCoordY"/>, <xref linkend="RT_ST_SRID"/></para>
            </refsection>
        </refentry>

    </section>

    <section xml:id="RasterBand_Accessors">
        <title>Raster Band Accessors</title>
        <refentry xml:id="RT_ST_BandMetaData">
            <refnamediv>
                <refname>ST_BandMetaData</refname>
                <refpurpose>Returns basic meta data for a specific raster band. band num 1 is assumed if none-specified.</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                  <funcprototype>
                        <funcdef>(1) record <function>ST_BandMetaData</function></funcdef>
                        <paramdef><type>raster </type><parameter>rast</parameter></paramdef>
                        <paramdef choice="opt"><type>integer </type><parameter>band=1</parameter></paramdef>
                  </funcprototype>
                  <funcprototype>
                        <funcdef>(2) record <function>ST_BandMetaData</function></funcdef>
                        <paramdef><type>raster </type><parameter>rast</parameter></paramdef>
                        <paramdef choice="opt"><type>integer[] </type><parameter>band</parameter></paramdef>
                  </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>Returns basic meta data about a raster band. Columns returned: pixeltype, nodatavalue, isoutdb, path, outdbbandnum, filesize, filetimestamp.
                </para>
                <note>
                    <para>
                        If raster contains no bands then an error is thrown.
                    </para>
                </note>

                <note>
                    <para>
                        If band has no NODATA value, nodatavalue are NULL.
                    </para>
                </note>
                <note>
                    <para>
                        If isoutdb is False, path, outdbbandnum, filesize and filetimestamp are NULL. If outdb access is disabled, filesize and filetimestamp will also be NULL.
                    </para>
                </note>

                <para role="enhanced" conformance="2.5.0">Enhanced: 2.5.0 to include <emphasis>outdbbandnum</emphasis>, <emphasis>filesize</emphasis> and <emphasis>filetimestamp</emphasis> for outdb rasters.</para>
            </refsection>

            <refsection>
                <title>Examples</title>
                <para>Variant 1.</para>

                <programlisting language="sql">
SELECT
    rid,
    (foo.md).*
FROM (
    SELECT
        rid,
        ST_BandMetaData(rast, 1) AS md
    FROM dummy_rast
    WHERE rid=2
) As foo;</programlisting>
<screen role="text-primary">
 rid | pixeltype | nodatavalue | isoutdb | path | outdbbandnum
-----+-----------+-------------+---------+------+--------------
   2 | 8BUI      |           0 | f       |      |
(1 row)
                </screen>


                <para>Variant 2.</para>

                <programlisting language="sql">
WITH foo AS (
    SELECT
        ST_AddBand(NULL::raster, '/home/pele/devel/geo/postgis-git/raster/test/regress/loader/Projected.tif', NULL::int[]) AS rast
)
SELECT
    bandnum,
    pixeltype,
    isoutdb,
    regexp_replace(path, '^.*/', '') AS file,
    outdbbandnum
FROM ST_BandMetaData((SELECT rast FROM foo),
    ARRAY[1, 3, 2]::int[]
);</programlisting>
<screen role="text-primary"> bandnum | pixeltype | isoutdb |     file      | outdbbandnum
---------+-----------+---------+---------------+--------------
       1 | 8BUI      | t       | Projected.tif |            1
       3 | 8BUI      | t       | Projected.tif |            3
       2 | 8BUI      | t       | Projected.tif |            2</screen>

            </refsection>

            <!-- Optionally add a "See Also" section -->
            <refsection>
                <title>See Also</title>
                <para><xref linkend="RT_ST_MetaData"/>, <xref linkend="RT_ST_BandPixelType"/></para>
            </refsection>
        </refentry>

        <refentry xml:id="RT_ST_BandNoDataValue">
            <refnamediv>
                <refname>ST_BandNoDataValue</refname>
                <refpurpose>Returns the value in a given band that represents no data. If no band num 1 is assumed.</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                  <funcprototype>
                    <funcdef>double precision <function>ST_BandNoDataValue</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    <paramdef choice="opt"><type>integer </type> <parameter>bandnum=1</parameter></paramdef>
                  </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>Returns the value that represents no data for the band</para>
                </refsection>

                <refsection>
                    <title>Examples</title>

                    <programlisting language="sql">SELECT ST_BandNoDataValue(rast, 1) As bnval1,
    ST_BandNoDataValue(rast, 2) As bnval2, ST_BandNoDataValue(rast, 3) As bnval3
FROM dummy_rast
WHERE rid = 2;</programlisting>
<screen role="text-primary"> bnval1 | bnval2 | bnval3
--------+--------+--------
      0 |      0 |      0</screen>

            </refsection>

            <refsection>
                <title>See Also</title>
                <para><xref linkend="RT_ST_NumBands"/></para>
            </refsection>
        </refentry>


        <refentry xml:id="RT_ST_BandIsNoData">
            <refnamediv>
                <refname>ST_BandIsNoData</refname>
                <refpurpose>Returns true if the band is filled with only nodata values.</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                  <funcprototype>
                    <funcdef>boolean <function>ST_BandIsNoData</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    <paramdef><type>integer </type> <parameter>band</parameter></paramdef>
                    <paramdef choice="opt"><type>boolean </type> <parameter>forceChecking=false</parameter></paramdef>
                  </funcprototype>
                 <funcprototype>
                    <funcdef>boolean <function>ST_BandIsNoData</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    <paramdef choice="opt"><type>boolean </type> <parameter>forceChecking=false</parameter></paramdef>
                  </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>
                <para>Returns true if the band is filled with only nodata
                values. Band 1 is assumed if not specified. If the last argument
                is TRUE, the entire band is checked pixel by pixel. Otherwise,
                the function simply returns the value of the isnodata flag for
                the band. The default value for this parameter is FALSE, if not
                specified.</para>

                <para role="availability" conformance="2.0.0">Availability: 2.0.0</para>

                <note>
                    <para>If the flag is dirty (this is, the result is different
                    using TRUE as last parameter and not using it) you should
                    update the raster to set this flag to true, by using ST_SetBandIsNoData(),
                    or ST_SetBandNoDataValue() with TRUE as last argument. See <xref linkend="RT_ST_SetBandIsNoData"/>.</para>
                </note>
            </refsection>

                <refsection>
                    <title>Examples</title>

                    <para>This example creates a dummy table with one raster
                    column. The raster has two bands and one pixel per band. In
                    the first band, the NODATA value and pixel value are both 3.
                    In the second band, the NODATA value is 13 and the pixel
                    value is 4.</para>
                    <programlisting language="sql">
create table dummy_rast (rid integer, rast raster);

insert into dummy_rast values(
1,
(
'01' -- little endian (uint8 ndr)
||
'0000' -- version (uint16 0)
||
'0200' -- nBands (uint16 0)
||
'17263529ED684A3F' -- scaleX (float64 0.000805965234044584)
||
'F9253529ED684ABF' -- scaleY (float64 -0.00080596523404458)
||
'1C9F33CE69E352C0' -- ipX (float64 -75.5533328537098)
||
'718F0E9A27A44840' -- ipY (float64 49.2824585505576)
||
'ED50EB853EC32B3F' -- skewX (float64 0.000211812383858707)
||
'7550EB853EC32B3F' -- skewY (float64 0.000211812383858704)
||
'E6100000' -- SRID (int32 4326)
||
'0100' -- width (uint16 1)
||
'0100' -- height (uint16 1)
||
'6' -- hasnodatavalue and isnodata value set to true.
||
'2' -- first band type (4BUI)
||
'03' -- novalue==3
||
'03' -- pixel(0,0)==3 (same that nodata)
||
'0' -- hasnodatavalue set to false
||
'5' -- second band type (16BSI)
||
'0D00' -- novalue==13
||
'0400' -- pixel(0,0)==4
)::raster
);

select ST_BandIsNoData(rast, 1) from dummy_rast where rid = 1; -- Expected true
select ST_BandIsNoData(rast, 2) from dummy_rast where rid = 1; -- Expected false
            </programlisting>

            </refsection>

            <refsection>
                <title>See Also</title>
                <para><xref linkend="RT_ST_BandNoDataValue"/>, <xref linkend="RT_ST_NumBands"/>, <xref linkend="RT_ST_SetBandNoDataValue"/>, <xref linkend="RT_ST_SetBandIsNoData"/></para>
            </refsection>
        </refentry>

        <refentry xml:id="RT_ST_BandPath">
            <refnamediv>
                <refname>ST_BandPath</refname>
                <refpurpose>Returns system file path to a band stored in file system. If no bandnum specified, 1 is assumed.</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                  <funcprototype>
                    <funcdef>text <function>ST_BandPath</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    <paramdef choice="opt"><type>integer </type> <parameter>bandnum=1</parameter></paramdef>
                  </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>Returns system file path to a band.  Throws an error if called with an in db band.</para>
                </refsection>

                <refsection>
                    <title>Examples</title>

                    <programlisting language="sql">WITH foo AS (
    SELECT ST_AddBand(
        NULL::raster,
        '/home/pele/devel/geo/postgis-git/raster/test/regress/loader/Projected.tif',
        NULL::int[]
    ) AS rast
)
SELECT bandnum, ST_BandPath(rast, bandnum) AS path
FROM foo
CROSS JOIN generate_series(1, 3) AS bandnum;</programlisting>
                    <screen role="text-primary"> bandnum |                                    path
---------+----------------------------------------------------------------------------
       1 | /home/pele/devel/geo/postgis-git/raster/test/regress/loader/Projected.tif
       2 | /home/pele/devel/geo/postgis-git/raster/test/regress/loader/Projected.tif
       3 | /home/pele/devel/geo/postgis-git/raster/test/regress/loader/Projected.tif</screen>

            </refsection>

            <refsection>
                <title>See Also</title>
                <para>
                    <xref linkend="RT_ST_BandMetaData"/>,
                    <xref linkend="RT_ST_SetBandPath"/>,
                    <xref linkend="RT_ST_SetBandIndex"/>
                </para>
            </refsection>
        </refentry>

        <refentry xml:id="RT_ST_BandFileSize">
            <refnamediv>
                <refname>ST_BandFileSize</refname>
                <refpurpose>Returns the file size of a band stored in file system. If no bandnum specified, 1 is assumed.</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                  <funcprototype>
                    <funcdef>bigint <function>ST_BandFileSize</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    <paramdef choice="opt"><type>integer </type> <parameter>bandnum=1</parameter></paramdef>
                  </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>Returns the file size of a band stored in file system.  Throws an error if called with an in db band, or if outdb access is not enabled.</para>

                                <para>This function is typically used in conjunction with ST_BandPath() and ST_BandFileTimestamp() so a client can determine if the filename of a outdb raster as seen by it is the same as the one seen by the server.</para>

                <para role="availability" conformance="2.5.0">Availability: 2.5.0</para>

            </refsection>

                        <refsection>
                                <title>Examples</title>

                                <programlisting language="sql">SELECT ST_BandFileSize(rast, 1) FROM dummy_rast WHERE rid = 1;</programlisting>
<screen role="text-primary">240574</screen>

            </refsection>

        </refentry>

        <refentry xml:id="RT_ST_BandFileTimestamp">
            <refnamediv>
                <refname>ST_BandFileTimestamp</refname>
                <refpurpose>Returns the file timestamp of a band stored in file system. If no bandnum specified, 1 is assumed.</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                  <funcprototype>
                    <funcdef>bigint <function>ST_BandFileTimestamp</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    <paramdef choice="opt"><type>integer </type> <parameter>bandnum=1</parameter></paramdef>
                  </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>Returns the file timestamp (number of seconds since Jan 1st 1970 00:00:00 UTC) of a band stored in file system.  Throws an error if called with an in db band, or if outdb access is not enabled.</para>

                                <para>This function is typically used in conjunction with ST_BandPath() and ST_BandFileSize() so a client can determine if the filename of a outdb raster as seen by it is the same as the one seen by the server.</para>

                <para role="availability" conformance="2.5.0">Availability: 2.5.0</para>
            </refsection>

                        <refsection>
                                <title>Examples</title>

                                <programlisting language="sql">SELECT ST_BandFileTimestamp(rast, 1) FROM dummy_rast WHERE rid = 1;</programlisting>
<screen role="text-primary">1521807257</screen>

            </refsection>
        </refentry>

        <refentry xml:id="RT_ST_BandPixelType">
            <refnamediv>
                <refname>ST_BandPixelType</refname>
                <refpurpose>Returns the type of pixel for given band. If no bandnum specified, 1 is assumed.</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                  <funcprototype>
                    <funcdef>text <function>ST_BandPixelType</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    <paramdef choice="opt"><type>integer </type> <parameter>bandnum=1</parameter></paramdef>
                  </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>Returns name describing data type and size of values stored in each cell of given band.</para>
                <para>There are 11 pixel types.  Pixel Types supported are as follows:
                    <itemizedlist>
                        <listitem>
                          <para>1BB -  1-bit boolean</para>
                        </listitem>

                        <listitem>
                          <para>2BUI - 2-bit unsigned integer</para>
                        </listitem>

                        <listitem>
                          <para>4BUI - 4-bit unsigned integer </para>
                        </listitem>

                        <listitem>
                          <para>8BSI - 8-bit signed integer </para>
                        </listitem>
                        <listitem>
                          <para>8BUI - 8-bit unsigned integer</para>
                        </listitem>
                        <listitem>
                          <para>16BSI - 16-bit signed integer</para>
                        </listitem>
                        <listitem>
                          <para>16BUI - 16-bit unsigned integer</para>
                        </listitem>
                        <listitem>
                          <para>32BSI - 32-bit signed integer</para>
                        </listitem>
                        <listitem>
                          <para>32BUI - 32-bit unsigned integer</para>
                        </listitem>
                        <listitem>
                          <para>32BF - 32-bit float</para>
                        </listitem>
                        <listitem>
                          <para>64BF - 64-bit float</para>
                        </listitem>
                    </itemizedlist>
                </para>
            </refsection>

            <refsection>
                <title>Examples</title>

                    <programlisting language="sql">SELECT ST_BandPixelType(rast, 1) As btype1,
    ST_BandPixelType(rast, 2) As btype2, ST_BandPixelType(rast, 3) As btype3
FROM dummy_rast
WHERE rid = 2;</programlisting>
<screen role="text-primary"> btype1 | btype2 | btype3
--------+--------+--------
 8BUI   | 8BUI   | 8BUI</screen>

            </refsection>

            <refsection>
                <title>See Also</title>
                <para><xref linkend="RT_ST_NumBands"/></para>
            </refsection>
        </refentry>

        <refentry xml:id="ST_MinPossibleValue">
            <refnamediv>
                <refname>ST_MinPossibleValue</refname>
                <refpurpose>Returns the minimum value this pixeltype can store.</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                  <funcprototype>
                    <funcdef>integer <function>ST_MinPossibleValue</function></funcdef>
                    <paramdef><type>text </type> <parameter>pixeltype</parameter></paramdef>
                  </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>
                <para>Returns the minimum value this pixeltype can store.</para>
            </refsection>

            <refsection>
                <title>Examples</title>

                    <programlisting language="sql">SELECT ST_MinPossibleValue('16BSI');</programlisting>
<screen role="text-primary">-32768</screen>
<programlisting language="sql">SELECT ST_MinPossibleValue('8BUI');</programlisting>
<screen role="text-primary">0</screen>

            </refsection>

            <refsection>
                <title>See Also</title>
                <para><xref linkend="RT_ST_BandPixelType"/></para>
            </refsection>
        </refentry>

        <refentry xml:id="RT_ST_HasNoBand">
            <refnamediv>
                <refname>ST_HasNoBand</refname>
                <refpurpose>Returns true if there is no band with given band number.  If no band number is specified, then band number 1 is assumed.</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                  <funcprototype>
                        <funcdef>boolean <function>ST_HasNoBand</function></funcdef>
                        <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                        <paramdef><type>integer </type> <parameter>bandnum=1</parameter></paramdef>
                  </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>Returns true if there is no band with given band number.  If no band number is specified, then band number 1 is assumed.</para>

                <para role="availability" conformance="2.0.0">Availability: 2.0.0</para>
            </refsection>

            <refsection>
                <title>Examples</title>

                <programlisting language="sql">SELECT rid, ST_HasNoBand(rast) As hb1, ST_HasNoBand(rast, 2) as hb2,
ST_HasNoBand(rast, 4) as hb4, ST_NumBands(rast) As numbands
FROM dummy_rast;</programlisting>
<screen role="text-primary">rid | hb1 | hb2 | hb4 | numbands
-----+-----+-----+-----+----------
1 | t   | t   | t   |        0
2 | f   | f   | t   |        3</screen>

            </refsection>

            <refsection>
                <title>See Also</title>
                <para><xref linkend="RT_ST_NumBands"/></para>
            </refsection>
        </refentry>

    </section>

    <section xml:id="Raster_Pixel_Accessors">
        <title>Raster Pixel Accessors and Setters</title>

        <refentry xml:id="RT_ST_PixelAsPolygon">
            <refnamediv>
                <refname>ST_PixelAsPolygon</refname>
                <refpurpose>Returns the polygon geometry that bounds the pixel for a particular row and column.</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                  <funcprototype>
                    <funcdef>geometry <function>ST_PixelAsPolygon</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    <paramdef><type>integer </type> <parameter>columnx</parameter></paramdef>
                    <paramdef><type>integer </type> <parameter>rowy</parameter></paramdef>
                  </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>Returns the polygon geometry that bounds the pixel for a particular row and column.</para>

                <para role="availability" conformance="2.0.0">Availability: 2.0.0</para>

            </refsection>

            <refsection>
                    <title>Examples</title>
                    <para>This example returns a raster pixel polygon.</para>
                    <programlisting language="sql">
SELECT i, j, ST_PixelAsPolygon(foo.rast, i, j) As b1pgeom
FROM dummy_rast As foo
    CROSS JOIN generate_series(1, 2) As i
    CROSS JOIN generate_series(1, 1) As j
WHERE rid=2;</programlisting>
<screen role="text-primary"> i | j |                                                    b1pgeom
---+---+-----------------------------------------------------------------------------
 1 | 1 | POLYGON((3427927.75 5793244,3427927.8 5793244,3427927.8 5793243.95,...
 2 | 1 | POLYGON((3427927.8 5793244,3427927.85 5793244,3427927.85 5793243.95, ..</screen>
            </refsection>

            <refsection>
                <title>See Also</title>
                <para>
                    <xref linkend="RT_ST_DumpAsPolygons"/>,
                    <xref linkend="RT_ST_PixelAsPolygons"/>,
                    <xref linkend="RT_ST_PixelAsPoint"/>,
                    <xref linkend="RT_ST_PixelAsPoints"/>,
                    <xref linkend="RT_ST_PixelAsCentroid"/>,
                    <xref linkend="RT_ST_PixelAsCentroids"/>,
                    <xref linkend="RT_ST_Intersection"/>,
                    <xref linkend="ST_AsText"/>
                </para>
            </refsection>
        </refentry>

        <refentry xml:id="RT_ST_PixelAsPolygons">
            <refnamediv>
                <refname>ST_PixelAsPolygons</refname>
                <refpurpose>Returns the polygon geometry that bounds every pixel of a raster band along with the value, the X and the Y raster coordinates of each pixel.</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                  <funcprototype>
                    <funcdef>setof record <function>ST_PixelAsPolygons</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    <paramdef choice="opt"><type>integer </type> <parameter>band=1</parameter></paramdef>
                    <paramdef choice="opt"><type>boolean </type> <parameter>exclude_nodata_value=TRUE</parameter></paramdef>
                  </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>Returns the polygon geometry that bounds every pixel of a raster band along with the value (double precision), the X and the Y raster coordinates (integers) of each pixel.</para>

                <para>
                    Return record format: <parameter>geom</parameter> <xref linkend="geometry"/>, <parameter>val</parameter> double precision, <parameter>x</parameter> integer, <parameter>y</parameter> integers.
                </para>
                <note>
                    <para>When <parameter>exclude_nodata_value</parameter> is
                    <literal>TRUE</literal>, only pixels whose values are not
                    NODATA are returned. Unlike <xref
                    linkend="RT_ST_DumpAsPolygons"/>, this function returns one
                    polygon per pixel rather than merging adjacent pixels with
                    the same value.</para>
                </note>

                <para role="availability" conformance="2.0.0">Availability: 2.0.0</para>
                <para role="enhanced" conformance="2.1.0">Enhanced: 2.1.0 exclude_nodata_value optional argument was added.</para>
                <para role="changed" conformance="2.1.1">Changed: 2.1.1 Changed behavior of exclude_nodata_value.</para>
            </refsection>

            <refsection>
                    <title>Examples</title>
                    <para>This example returns a raster pixel polygon.</para>
                    <programlisting language="sql">WITH raster AS (
    SELECT ST_SetValue(
        ST_SetValue(
            ST_AddBand(
                ST_MakeEmptyRaster(
                    2, 2, 0, 0, 0.001, -0.001, 0.001, 0.001, 4269
                ),
                1, '8BUI', 1, 0
            ),
            2, 2, 10
        ),
        1, 1, NULL
    ) AS rast
), pixels AS (
    SELECT (ST_PixelAsPolygons(rast)).*
    FROM raster
)
SELECT x, y, val, geom AS geom
FROM pixels
ORDER BY x, y;</programlisting>
<screen role="visual"> x | y | val |                geom
---+---+-----------------------------------------------------------------------------
 1 | 2 |   1 | POLYGON((0.001 -0.001,0.002 0,0.003 -0.001,0.002 -0.002,0.001 -0.001))
 2 | 1 |   1 | POLYGON((0.001 0.001,0.002 0.002,0.003 0.001,0.002 0,0.001 0.001))
 2 | 2 |  10 | POLYGON((0.002 0,0.003 0.001,0.004 0,0.003 -0.001,0.002 0))</screen>
            </refsection>

            <refsection>
                <title>See Also</title>
                <para>
                    <xref linkend="RT_ST_DumpAsPolygons"/>,
                    <xref linkend="RT_ST_PixelAsPolygon"/>,
                    <xref linkend="RT_ST_PixelAsPoint"/>,
                    <xref linkend="RT_ST_PixelAsPoints"/>,
                    <xref linkend="RT_ST_PixelAsCentroid"/>,
                    <xref linkend="RT_ST_PixelAsCentroids"/>,
                    <xref linkend="ST_AsText"/>
                </para>
            </refsection>
        </refentry>

        <refentry xml:id="RT_ST_PixelAsPoint">
            <refnamediv>
                <refname>ST_PixelAsPoint</refname>
                <refpurpose>
                    Returns a point geometry of the pixel's upper-left corner.
                </refpurpose>
            </refnamediv>
            <refsynopsisdiv>
                <funcsynopsis>
                    <funcprototype>
                        <funcdef>geometry <function>ST_PixelAsPoint</function></funcdef>
                        <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                        <paramdef><type>integer </type> <parameter>columnx</parameter></paramdef>
                        <paramdef><type>integer </type> <parameter>rowy</parameter></paramdef>
                    </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>
                <para>Returns a point geometry of the pixel's upper-left corner.</para>
                <para role="availability" conformance="2.1.0">Availability: 2.1.0</para>
            </refsection>

            <refsection>
                <title>Examples</title>
                <programlisting language="sql">SELECT ST_PixelAsPoint(rast, 1, 1) FROM dummy_rast WHERE rid = 1;</programlisting>
<screen role="visual-primary text-primary">POINT(0.5 0.5)</screen>
            </refsection>

            <refsection>
                <title>See Also</title>
                <para>
                    <xref linkend="RT_ST_DumpAsPolygons"/>,
                    <xref linkend="RT_ST_PixelAsPolygon"/>,
                    <xref linkend="RT_ST_PixelAsPolygons"/>,
                    <xref linkend="RT_ST_PixelAsPoints"/>,
                    <xref linkend="RT_ST_PixelAsCentroid"/>,
                    <xref linkend="RT_ST_PixelAsCentroids"/>
                </para>
            </refsection>

        </refentry>

        <refentry xml:id="RT_ST_PixelAsPoints">
            <refnamediv>
                <refname>ST_PixelAsPoints</refname>
                <refpurpose>
                    Returns a point geometry for each pixel of a raster band along with the value, the X and the Y raster coordinates of each pixel.  The coordinates of the point geometry are of the pixel's upper-left corner.
                </refpurpose>
            </refnamediv>
            <refsynopsisdiv>
                <funcsynopsis>
                    <funcprototype>
                        <funcdef>setof record <function>ST_PixelAsPoints</function></funcdef>
                        <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                        <paramdef choice="opt"><type>integer </type> <parameter>band=1</parameter></paramdef>
                        <paramdef choice="opt"><type>boolean </type> <parameter>exclude_nodata_value=TRUE</parameter></paramdef>
                    </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>
                <para>
                    Returns a point geometry for each pixel of a raster band along with the value, the X and the Y raster coordinates of each pixel.  The coordinates of the point geometry are of the pixel's upper-left corner.
                </para>

                <para>
                    Return record format: <parameter>geom</parameter> <xref linkend="geometry"/>, <parameter>val</parameter> double precision, <parameter>x</parameter> integer, <parameter>y</parameter> integers.
                </para>
                <note>
                    <para>
                        When <parameter>exclude_nodata_value</parameter> = TRUE, only those pixels whose values are not NODATA are returned as points.
                    </para>
                </note>
                <para role="availability" conformance="2.1.0">Availability: 2.1.0</para>
                <para role="changed" conformance="2.1.1">Changed: 2.1.1 Changed behavior of exclude_nodata_value.</para>
            </refsection>

            <refsection>
                <title>Examples</title>
                <para>This example returns point features together with a derived marker size that a client can use for value-scaled point rendering.</para>
                <programlisting language="sql">SELECT
    x,
    y,
    val,
    round((val / 32.0)::numeric, 2) AS marker_scale,geom AS geom
FROM (
    SELECT (ST_PixelAsPoints(rast, 1)).*
    FROM dummy_rast
    WHERE rid = 2
) AS foo
ORDER BY y, x;</programlisting>
<screen role="visual-primary text-primary"> x | y | val | marker_scale |          geom
---+---+-----+--------------+------------------------------
 1 | 1 | 253 |         7.91 | POINT(3427927.75 5793244)
 2 | 1 | 254 |         7.94 | POINT(3427927.8 5793244)
 3 | 1 | 253 |         7.91 | POINT(3427927.85 5793244)
 4 | 1 | 254 |         7.94 | POINT(3427927.9 5793244)
 5 | 1 | 254 |         7.94 | POINT(3427927.95 5793244)
 1 | 2 | 253 |         7.91 | POINT(3427927.75 5793243.95)
 2 | 2 | 254 |         7.94 | POINT(3427927.8 5793243.95)
 3 | 2 | 254 |         7.94 | POINT(3427927.85 5793243.95)
 4 | 2 | 253 |         7.91 | POINT(3427927.9 5793243.95)
 5 | 2 | 249 |         7.78 | POINT(3427927.95 5793243.95)
 1 | 3 | 250 |         7.81 | POINT(3427927.75 5793243.9)
 2 | 3 | 254 |         7.94 | POINT(3427927.8 5793243.9)
 3 | 3 | 254 |         7.94 | POINT(3427927.85 5793243.9)
 4 | 3 | 252 |         7.88 | POINT(3427927.9 5793243.9)
 5 | 3 | 249 |         7.78 | POINT(3427927.95 5793243.9)
 1 | 4 | 251 |         7.84 | POINT(3427927.75 5793243.85)
 2 | 4 | 253 |         7.91 | POINT(3427927.8 5793243.85)
 3 | 4 | 254 |         7.94 | POINT(3427927.85 5793243.85)
 4 | 4 | 254 |         7.94 | POINT(3427927.9 5793243.85)
 5 | 4 | 253 |         7.91 | POINT(3427927.95 5793243.85)
 1 | 5 | 252 |         7.88 | POINT(3427927.75 5793243.8)
 2 | 5 | 250 |         7.81 | POINT(3427927.8 5793243.8)
 3 | 5 | 254 |         7.94 | POINT(3427927.85 5793243.8)
 4 | 5 | 254 |         7.94 | POINT(3427927.9 5793243.8)
 5 | 5 | 254 |         7.94 | POINT(3427927.95 5793243.8)</screen>
            </refsection>

            <refsection>
                <title>See Also</title>
                <para>
                    <xref linkend="RT_ST_DumpAsPolygons"/>,
                    <xref linkend="RT_ST_PixelAsPolygon"/>,
                    <xref linkend="RT_ST_PixelAsPolygons"/>,
                    <xref linkend="RT_ST_PixelAsPoint"/>,
                    <xref linkend="RT_ST_PixelAsCentroid"/>,
                    <xref linkend="RT_ST_PixelAsCentroids"/>
                </para>
            </refsection>

        </refentry>

        <refentry xml:id="RT_ST_PixelAsCentroid">
            <refnamediv>
                <refname>ST_PixelAsCentroid</refname>
                <refpurpose>
                    Returns the centroid (point geometry) of the area represented by a pixel.
                </refpurpose>
            </refnamediv>
            <refsynopsisdiv>
                <funcsynopsis>
                    <funcprototype>
                        <funcdef>geometry <function>ST_PixelAsCentroid</function></funcdef>
                        <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                        <paramdef><type>integer </type> <parameter>x</parameter></paramdef>
                        <paramdef><type>integer </type> <parameter>y</parameter></paramdef>
                    </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>
                <para>Returns the centroid (point geometry) of the area represented by a pixel.</para>
                <para role="enhanced" conformance="3.2.0">Enhanced: 3.2.0 Faster now implemented in C.</para>
                <para role="availability" conformance="2.1.0">Availability: 2.1.0</para>
            </refsection>

            <refsection>
                <title>Examples</title>
                <programlisting language="sql">SELECT ST_PixelAsCentroid(rast, 1, 1) FROM dummy_rast WHERE rid = 1;</programlisting>
<screen role="text-primary visual-primary">POINT(1.5 2)</screen>
            </refsection>

            <refsection>
                <title>See Also</title>
                <para>
                    <xref linkend="RT_ST_DumpAsPolygons"/>,
                    <xref linkend="RT_ST_PixelAsPolygon"/>,
                    <xref linkend="RT_ST_PixelAsPolygons"/>,
                    <xref linkend="RT_ST_PixelAsPoint"/>,
                    <xref linkend="RT_ST_PixelAsPoints"/>,
                    <xref linkend="RT_ST_PixelAsCentroids"/>
                </para>
            </refsection>

        </refentry>

        <refentry xml:id="RT_ST_PixelAsCentroids">
            <refnamediv>
                <refname>ST_PixelAsCentroids</refname>
                <refpurpose>
                    Returns the centroid (point geometry) for each pixel of a raster band along with the value, the X and the Y raster coordinates of each pixel.  The point geometry is the centroid of the area represented by a pixel.
                </refpurpose>
            </refnamediv>
            <refsynopsisdiv>
                <funcsynopsis>
                    <funcprototype>
                        <funcdef>setof record <function>ST_PixelAsCentroids</function></funcdef>
                        <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                        <paramdef choice="opt"><type>integer </type> <parameter>band=1</parameter></paramdef>
                        <paramdef choice="opt"><type>boolean </type> <parameter>exclude_nodata_value=TRUE</parameter></paramdef>
                    </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>
                <para>
                    Returns the centroid (point geometry) for each pixel of a raster band along with the value, the X and the Y raster coordinates of each pixel.  The point geometry is the centroid of the area represented by a pixel.
                </para>
                <para>
                    Return record format: <parameter>geom</parameter> <xref linkend="geometry"/>, <parameter>val</parameter> double precision, <parameter>x</parameter> integer, <parameter>y</parameter> integers.
                </para>
                <note>
                    <para>
                        When <parameter>exclude_nodata_value</parameter> = TRUE, only those pixels whose values are not NODATA are returned as points.
                    </para>
                </note>

                <para role="enhanced" conformance="3.2.0">Enhanced: 3.2.0 Faster now implemented in C.</para>
                <para role="changed" conformance="2.1.1">Changed: 2.1.1 Changed behavior of exclude_nodata_value.</para>
                <para role="availability" conformance="2.1.0">Availability: 2.1.0</para>
            </refsection>

            <refsection>
                <title>Examples</title>
                <para>This example uses LATERAL syntax.</para>
                <programlisting language="sql">
SELECT x, y, val,geom
    FROM (SELECT dp.* FROM dummy_rast, LATERAL ST_PixelAsCentroids(rast, 1) AS dp WHERE rid = 2) foo;</programlisting>
<screen role="visual-primary text-primary"> x | y | val |           st_astext
---+---+-----+--------------------------------
 1 | 1 | 253 | POINT(3427927.775 5793243.975)
 2 | 1 | 254 | POINT(3427927.825 5793243.975)
 3 | 1 | 253 | POINT(3427927.875 5793243.975)
 4 | 1 | 254 | POINT(3427927.925 5793243.975)
 5 | 1 | 254 | POINT(3427927.975 5793243.975)
 1 | 2 | 253 | POINT(3427927.775 5793243.925)
 2 | 2 | 254 | POINT(3427927.825 5793243.925)
 3 | 2 | 254 | POINT(3427927.875 5793243.925)
 4 | 2 | 253 | POINT(3427927.925 5793243.925)
 5 | 2 | 249 | POINT(3427927.975 5793243.925)
 1 | 3 | 250 | POINT(3427927.775 5793243.875)
 2 | 3 | 254 | POINT(3427927.825 5793243.875)
 3 | 3 | 254 | POINT(3427927.875 5793243.875)
 4 | 3 | 252 | POINT(3427927.925 5793243.875)
 5 | 3 | 249 | POINT(3427927.975 5793243.875)
 1 | 4 | 251 | POINT(3427927.775 5793243.825)
 2 | 4 | 253 | POINT(3427927.825 5793243.825)
 3 | 4 | 254 | POINT(3427927.875 5793243.825)
 4 | 4 | 254 | POINT(3427927.925 5793243.825)
 5 | 4 | 253 | POINT(3427927.975 5793243.825)
 1 | 5 | 252 | POINT(3427927.775 5793243.775)
 2 | 5 | 250 | POINT(3427927.825 5793243.775)
 3 | 5 | 254 | POINT(3427927.875 5793243.775)
 4 | 5 | 254 | POINT(3427927.925 5793243.775)
 5 | 5 | 254 | POINT(3427927.975 5793243.775)</screen>
            </refsection>

            <refsection>
                <title>See Also</title>
                <para>
                    <xref linkend="RT_ST_DumpAsPolygons"/>,
                    <xref linkend="RT_ST_PixelAsPolygon"/>,
                    <xref linkend="RT_ST_PixelAsPolygons"/>,
                    <xref linkend="RT_ST_PixelAsPoint"/>,
                    <xref linkend="RT_ST_PixelAsPoints"/>,
                    <xref linkend="RT_ST_PixelAsCentroid"/>
                </para>
            </refsection>

        </refentry>

        <refentry xml:id="RT_ST_Value">
            <refnamediv>
                <refname>ST_Value</refname>
                <refpurpose>Returns the value of a given band in a given columnx, rowy pixel or at a particular geometric point. Band numbers start at 1 and assumed to be 1 if not specified. If <varname>exclude_nodata_value</varname> is set to false, then all pixels include <varname>nodata</varname> pixels are considered to intersect and return value. If <varname>exclude_nodata_value</varname> is not passed in then reads it from metadata of raster.</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                   <funcprototype>
                    <funcdef>double precision <function>ST_Value</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    <paramdef><type>geometry </type> <parameter>pt</parameter></paramdef>
                    <paramdef choice="opt"><type>boolean </type> <parameter>exclude_nodata_value=true</parameter></paramdef>
                  </funcprototype>
                 <funcprototype>
                    <funcdef>double precision <function>ST_Value</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    <paramdef><type>integer </type> <parameter>band</parameter></paramdef>
                    <paramdef><type>geometry </type> <parameter>pt</parameter></paramdef>
                    <paramdef choice="opt"><type>boolean </type> <parameter>exclude_nodata_value=true</parameter></paramdef>
                    <paramdef choice="opt"><type>text </type> <parameter>resample='nearest'</parameter></paramdef>
                  </funcprototype>
                  <funcprototype>
                    <funcdef>double precision <function>ST_Value</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    <paramdef><type>integer </type> <parameter>x</parameter></paramdef>
                    <paramdef><type>integer </type> <parameter>y</parameter></paramdef>
                    <paramdef choice="opt"><type>boolean </type> <parameter>exclude_nodata_value=true</parameter></paramdef>
                  </funcprototype>
                  <funcprototype>
                    <funcdef>double precision <function>ST_Value</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    <paramdef><type>integer </type> <parameter>band</parameter></paramdef>
                    <paramdef><type>integer </type> <parameter>x</parameter></paramdef>
                    <paramdef><type>integer </type> <parameter>y</parameter></paramdef>
                    <paramdef choice="opt"><type>boolean </type> <parameter>exclude_nodata_value=true</parameter></paramdef>
                  </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>Returns the value of a given band in a given columnx, rowy pixel or at a given geometry point. Band numbers start at 1 and band is assumed to be 1 if not specified.</para>
                <para>If <varname>exclude_nodata_value</varname> is set to true, then only non <varname>nodata</varname> pixels are considered.  If <varname>exclude_nodata_value</varname> is set to false, then all pixels are considered.</para>
                <para>The allowed values of the <varname>resample</varname> parameter are "nearest" which performs the default nearest-neighbor resampling, "bilinear" which performs a <link xlink:href="https://en.wikipedia.org/wiki/Bilinear_interpolation">bilinear interpolation</link> to estimate the value between pixel centers, and the nearest-neighbor boundary options "nearest-UL", "nearest-UR", "nearest-LL", and "nearest-LR". Boundary options choose which pixel is returned when the point lies on a horizontal or vertical pixel boundary, including corner intersections.</para>

                <para role="enhanced" conformance="3.7.0">Enhanced: 3.7.0 resample accepts nearest-neighbor boundary options "nearest-UL", "nearest-UR", "nearest-LL", and "nearest-LR".</para>
                <para role="enhanced" conformance="3.2.0">Enhanced: 3.2.0 resample optional argument was added.</para>
                <para role="enhanced" conformance="2.0.0">Enhanced: 2.0.0 exclude_nodata_value optional argument was added.</para>
                </refsection>

                <refsection>
                    <title>Examples</title>
                    <para>Get raster values at particular postgis geometry points. The srid of your geometry should be same as for your raster.</para>
                    <programlisting language="sql">
SELECT rid, ST_Value(rast, foo.pt_geom) As b1pval, ST_Value(rast, 2, foo.pt_geom) As b2pval
FROM dummy_rast CROSS JOIN (SELECT ST_SetSRID(ST_Point(3427927.77, 5793243.76), 0) As pt_geom) As foo
WHERE rid=2;</programlisting>
<screen role="text-primary"> rid | b1pval | b2pval
-----+--------+--------
   2 |    252 |     79</screen>

                    <para>General fictitious example using a real table.</para>
                    <programlisting language="sql">
SELECT rid, ST_Value(rast, 3, sometable.geom) As b3pval
FROM sometable
WHERE ST_Intersects(rast, sometable.geom);</programlisting>
                    <programlisting language="sql">
SELECT rid, ST_Value(rast, 1, 1, 1) As b1pval,
    ST_Value(rast, 2, 1, 1) As b2pval, ST_Value(rast, 3, 1, 1) As b3pval
FROM dummy_rast
WHERE rid=2;</programlisting>
<screen role="text-primary"> rid | b1pval | b2pval | b3pval
-----+--------+--------+--------
   2 |    253 |     78 |     70</screen>

                <para>Get all values in bands 1,2,3 of each pixel.</para>
                <programlisting language="sql">
<![CDATA[

SELECT x, y, ST_Value(rast, 1, x, y) As b1val,
    ST_Value(rast, 2, x, y) As b2val, ST_Value(rast, 3, x, y) As b3val
FROM dummy_rast CROSS JOIN
generate_series(1, 1000) As x CROSS JOIN generate_series(1, 1000) As y
WHERE rid =  2 AND x <= ST_Width(rast) AND y <= ST_Height(rast);]]></programlisting>
<screen role="text-primary"><![CDATA[ x | y | b1val | b2val | b3val
---+---+-------+-------+-------
 1 | 1 |   253 |    78 |    70
 1 | 2 |   253 |    96 |    80
 1 | 3 |   250 |    99 |    90
 1 | 4 |   251 |    89 |    77
 1 | 5 |   252 |    79 |    62
 2 | 1 |   254 |    98 |    86
 2 | 2 |   254 |   118 |   108
 :
 :]]></screen>

                <para>Get all values in bands 1,2,3 of each pixel same as above but returning the upper left point point of each pixel.</para>
                <programlisting language="sql">
<![CDATA[

SELECT ST_SetSRID(ST_Point(ST_UpperLeftX(rast) + ST_ScaleX(rast)*x,
        ST_UpperLeftY(rast) + ST_ScaleY(rast)*y),
        ST_SRID(rast)) As uplpt,
    ST_Value(rast, 1, x, y) As b1val,
    ST_Value(rast, 2, x, y) As b2val, ST_Value(rast, 3, x, y) As b3val
FROM dummy_rast CROSS JOIN
generate_series(1,1000) As x CROSS JOIN generate_series(1,1000) As y
WHERE rid =  2 AND x <= ST_Width(rast) AND y <= ST_Height(rast);]]></programlisting>
<screen role="text-primary"><![CDATA[            uplpt            | b1val | b2val | b3val
-----------------------------+-------+-------+-------
 POINT(3427929.25 5793245.5) |   253 |    78 |    70
 POINT(3427929.25 5793247)   |   253 |    96 |    80
 POINT(3427929.25 5793248.5) |   250 |    99 |    90
:]]></screen>
<para>Get a polygon formed by union of all pixels that fall in a particular value range and intersect a particular polygon.</para>
<programlisting language="sql"><![CDATA[

SELECT ST_Union(pixpolyg) As shadow
FROM (SELECT ST_Translate(ST_MakeEnvelope(ST_UpperLeftX(rast), ST_UpperLeftY(rast),
            ST_UpperLeftX(rast) + ST_ScaleX(rast),
            ST_UpperLeftY(rast) + ST_ScaleY(rast), 0
            ), ST_ScaleX(rast)*x, ST_ScaleY(rast)*y
        ) As pixpolyg, ST_Value(rast, 2, x, y) As b2val
    FROM dummy_rast CROSS JOIN
generate_series(1,1000) As x CROSS JOIN generate_series(1,1000) As y
WHERE rid =  2
    AND x <= ST_Width(rast) AND y <= ST_Height(rast)) As foo
WHERE
    ST_Intersects(
        pixpolyg,
        ST_GeomFromText('POLYGON((3427928 5793244,3427927.75 5793243.75,3427928 5793243.75,3427928 5793244))',0)
        ) AND b2val != 254;]]></programlisting>
<screen role="visual"><![CDATA[
        shadow
------------------------------------------------------------------------------------
 MULTIPOLYGON(((3427928 5793243.9,3427928 5793243.85,3427927.95 5793243.85,3427927.95 5793243.9,
 3427927.95 5793243.95,3427928 5793243.95,3427928.05 5793243.95,3427928.05 5793243.9,3427928 5793243.9)),((3427927.95 5793243.9,3427927.95 579324
3.85,3427927.9 5793243.85,3427927.85 5793243.85,3427927.85 5793243.9,3427927.9 5793243.9,3427927.9 5793243.95,
3427927.95 5793243.95,3427927.95 5793243.9)),((3427927.85 5793243.75,3427927.85 5793243.7,3427927.8 5793243.7,3427927.8 5793243.75,
3427927.8 5793243.8,3427927.8 5793243.85,3427927.85 5793243.85,3427927.85 5793243.8,3427927.85 5793243.75)),
((3427928.05 5793243.75,3427928.05 5793243.7,3427928 5793243.7,3427927.95 5793243.7,3427927.95 5793243.75,3427927.95 5793243.8,3427
927.95 5793243.85,3427928 5793243.85,3427928 5793243.8,3427928.05 5793243.8,
3427928.05 5793243.75)),((3427927.95 5793243.75,3427927.95 5793243.7,3427927.9 5793243.7,3427927.85 5793243.7,
3427927.85 5793243.75,3427927.85 5793243.8,3427927.85 5793243.85,3427927.9 5793243.85,
3427927.95 5793243.85,3427927.95 5793243.8,3427927.95 5793243.75)))

]]></screen>

                <para>Checking all the pixels of a large raster tile can take a long time. You can dramatically improve speed at some lose of precision by orders of magnitude. By sampling pixels using the step optional parameter of generate_series. This next example does the same as previous but by checking 1 for every 4 (2x2) pixels and putting in the last checked. Putting in the checked pixel as the value for subsequent 4.</para>
                <programlisting language="sql">
<![CDATA[


SELECT ST_Union(pixpolyg) As shadow
FROM (SELECT ST_Translate(ST_MakeEnvelope(ST_UpperLeftX(rast), ST_UpperLeftY(rast),
            ST_UpperLeftX(rast) + ST_ScaleX(rast)*2,
            ST_UpperLeftY(rast) + ST_ScaleY(rast)*2, 0
            ), ST_ScaleX(rast)*x, ST_ScaleY(rast)*y
        ) As pixpolyg, ST_Value(rast, 2, x, y) As b2val
    FROM dummy_rast CROSS JOIN
generate_series(1,1000,2) As x CROSS JOIN generate_series(1,1000,2) As y
WHERE rid =  2
    AND x <= ST_Width(rast)  AND y <= ST_Height(rast)  ) As foo
WHERE
    ST_Intersects(
        pixpolyg,
        ST_GeomFromText('POLYGON((3427928 5793244,3427927.75 5793243.75,3427928 5793243.75,3427928 5793244))',0)
        ) AND b2val != 254;]]></programlisting>
<screen role="visual"><![CDATA[
        shadow
------------------------------------------------------------------------------------
 MULTIPOLYGON(((3427927.9 5793243.85,3427927.8 5793243.85,3427927.8 5793243.95,
 3427927.9 5793243.95,3427928 5793243.95,3427928.1 5793243.95,3427928.1 5793243.85,3427928 5793243.85,3427927.9 5793243.85)),
 ((3427927.9 5793243.65,3427927.8 5793243.65,3427927.8 5793243.75,3427927.8 5793243.85,3427927.9 5793243.85,
 3427928 5793243.85,3427928 5793243.75,3427928.1 5793243.75,3427928.1 5793243.65,3427928 5793243.65,3427927.9 5793243.65)))

]]></screen>
            </refsection>

            <refsection>
                <title>See Also</title>
                <para>
                    <xref linkend="RT_ST_DumpValues"/>,
                    <xref linkend="RT_ST_SetValue"/>,
                    <xref linkend="RT_ST_DumpAsPolygons"/>,
                    <xref linkend="RT_ST_NumBands"/>,
                    <xref linkend="RT_ST_PixelAsPolygon"/>,
                    <xref linkend="RT_ST_ScaleX"/>,
                    <xref linkend="RT_ST_ScaleY"/>,
                    <xref linkend="RT_ST_UpperLeftX"/>,
                    <xref linkend="RT_ST_UpperLeftY"/>,
                    <xref linkend="RT_ST_SRID"/>,
                    <xref linkend="ST_AsText"/>,
                    <xref linkend="ST_Point"/>,
                    <xref linkend="ST_MakeEnvelope"/>,
                    <xref linkend="ST_Intersects"/>,
                    <xref linkend="ST_Intersection"/>
                </para>
            </refsection>
        </refentry>

        <refentry xml:id="RT_ST_NearestValue">
            <refnamediv>
                <refname>ST_NearestValue</refname>
                <refpurpose>
                    Returns the nearest non-<varname>NODATA</varname> value of a given band's pixel specified by a columnx and rowy or a geometric point expressed in the same spatial reference coordinate system as the raster.
                </refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                    <funcprototype>
                        <funcdef>double precision <function>ST_NearestValue</function></funcdef>
                        <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                        <paramdef><type>integer </type> <parameter>bandnum</parameter></paramdef>
                        <paramdef><type>geometry </type> <parameter>pt</parameter></paramdef>
                        <paramdef choice="opt"><type>boolean </type> <parameter>exclude_nodata_value=true</parameter></paramdef>
                    </funcprototype>

                    <funcprototype>
                        <funcdef>double precision <function>ST_NearestValue</function></funcdef>
                        <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                        <paramdef><type>geometry </type> <parameter>pt</parameter></paramdef>
                        <paramdef choice="opt"><type>boolean </type> <parameter>exclude_nodata_value=true</parameter></paramdef>
                    </funcprototype>

                  <funcprototype>
                        <funcdef>double precision <function>ST_NearestValue</function></funcdef>
                        <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                        <paramdef><type>integer </type> <parameter>bandnum</parameter></paramdef>
                        <paramdef><type>integer </type> <parameter>columnx</parameter></paramdef>
                        <paramdef><type>integer </type> <parameter>rowy</parameter></paramdef>
                        <paramdef choice="opt"><type>boolean </type> <parameter>exclude_nodata_value=true</parameter></paramdef>
                    </funcprototype>

                    <funcprototype>
                        <funcdef>double precision <function>ST_NearestValue</function></funcdef>
                        <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                        <paramdef><type>integer </type> <parameter>columnx</parameter></paramdef>
                        <paramdef><type>integer </type> <parameter>rowy</parameter></paramdef>
                        <paramdef choice="opt"><type>boolean </type> <parameter>exclude_nodata_value=true</parameter></paramdef>
                    </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>
                <para>
                    Returns the nearest non-<varname>NODATA</varname> value of a given band in a given columnx, rowy pixel or at a specific geometric point.  If the columnx, rowy pixel or the pixel at the specified geometric point is <varname>NODATA</varname>, the function will find the nearest pixel to the columnx, rowy pixel or geometric point whose value is not <varname>NODATA</varname>.
                </para>
                <para>
                    Band numbers start at 1 and <varname>bandnum</varname> is assumed to be 1 if not specified. If <varname>exclude_nodata_value</varname> is set to false, then all pixels include <varname>nodata</varname> pixels are considered to intersect and return value. If <varname>exclude_nodata_value</varname> is not passed in then reads it from metadata of raster.
                </para>
                <para role="availability" conformance="2.1.0">Availability: 2.1.0</para>
                <note>
                    <para>
                        ST_NearestValue is a drop-in replacement for ST_Value.
                    </para>
                </note>
            </refsection>

            <refsection>
                <title>Examples</title>

                <para>This example reads a value from pixel 2x2.</para>
                <programlisting language="sql">
WITH source AS (
    SELECT ST_SetValues(
        ST_AddBand(
            ST_MakeEmptyRaster(5, 5, -2, 2, 1, -1, 0, 0, 0),
            1, '8BUI', 1, 0
        ),
        1, 1, 1,
        ARRAY[
            [0, 1, 1, 1, 1],
            [1, 1, 1, 0, 1],
            [1, 0, 1, 1, 1],
            [1, 1, 1, 1, 0],
            [1, 1, 0, 1, 1]
        ]::double precision[][]
    ) AS rast
)
SELECT
    ST_Value(rast, 2, 2) AS value,
    ST_NearestValue(rast, 2, 2) AS nearestvalue
FROM source</programlisting>
<screen role="text-primary"> value | nearestvalue
-------+--------------
     1 |            1</screen>

                <para>This example reads a NODATA value from pixel 2x3.</para>
                <programlisting language="sql">
WITH source AS (
    SELECT ST_SetValues(
        ST_AddBand(
            ST_MakeEmptyRaster(5, 5, -2, 2, 1, -1, 0, 0, 0),
            1, '8BUI', 1, 0
        ),
        1, 1, 1,
        ARRAY[
            [0, 1, 1, 1, 1],
            [1, 1, 1, 0, 1],
            [1, 0, 1, 1, 1],
            [1, 1, 1, 1, 0],
            [1, 1, 0, 1, 1]
        ]::double precision[][]
    ) AS rast
)
SELECT
    ST_Value(rast, 2, 3) AS value,
    ST_NearestValue(rast, 2, 3) AS nearestvalue
FROM source</programlisting>
<screen role="text-primary"> value | nearestvalue
-------+--------------
       |            1</screen>

            </refsection>

            <refsection>
                <title>See Also</title>
                <para>
                    <xref linkend="RT_ST_Neighborhood"/>,
                    <xref linkend="RT_ST_Value"/>
                </para>
            </refsection>

        </refentry>

        <refentry xml:id="RT_ST_SetZ">
            <refnamediv>
                <refname>ST_SetZ</refname>
                <refpurpose>Returns a geometry with the same X/Y coordinates as the input geometry, and values from the raster copied into the Z dimension using the requested resample algorithm.</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                   <funcprototype>
                    <funcdef>geometry <function>ST_SetZ</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    <paramdef><type>geometry </type> <parameter>geom</parameter></paramdef>
                    <paramdef choice="opt"><type>text </type> <parameter>resample=nearest</parameter></paramdef>
                    <paramdef choice="opt"><type>integer </type> <parameter>band=1</parameter></paramdef>
                  </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>Returns a geometry with the same X/Y coordinates as the input geometry, and values from the raster copied into the Z dimensions using the requested resample algorithm.</para>
                <para>The <varname>resample</varname> parameter can be set to "nearest" to copy the values from the cell each vertex falls within, or "bilinear" to use <link xlink:href="https://en.wikipedia.org/wiki/Bilinear_interpolation">bilinear interpolation</link> to calculate a value that takes neighboring cells into account also.</para>

                <para role="availability" conformance="3.2.0">Availability: 3.2.0</para>
            </refsection>

                <refsection>
                    <title>Examples</title>
                    <para>2x2 test raster with values. 10 50. 40 20.</para>
                    <programlisting language="sql">
WITH test_raster AS (
SELECT
ST_SetValues(
ST_AddBand(
ST_MakeEmptyRaster(
      width =&gt; 2,
      height =&gt; 2,
      upperleftx =&gt; 0,
      upperlefty =&gt; 2,
      scalex =&gt; 1.0,
      scaley =&gt; -1.0,
      skewx =&gt; 0,
      skewy =&gt; 0,
      srid =&gt; 4326),
    index =&gt; 1,
    pixeltype =&gt; '16BSI',
    initialvalue =&gt; 0,
    nodataval =&gt; -999
),
  1,
  1,
  1,
  newvalueset =&gt; ARRAY[ARRAY[10.0::float8, 50.0::float8], ARRAY[40.0::float8, 20.0::float8]]) AS rast
)
SELECT
ST_SetZ(
    rast,
    band =&gt; 1,
    geom =&gt; 'SRID=4326;LINESTRING(1.0 1.9,1.0 0.2)'::geometry,
    resample =&gt; 'bilinear'
)
FROM test_raster</programlisting>
<screen role="visual-primary text-primary">LINESTRING Z (1 1.9 38,1 0.2 27)</screen>

            </refsection>

            <refsection>
                <title>See Also</title>
                <para>
                    <xref linkend="RT_ST_Value"/>,
                    <xref linkend="RT_ST_SetM"/>
                </para>
            </refsection>
        </refentry>


        <refentry xml:id="RT_ST_SetM">
            <refnamediv>
                <refname>ST_SetM</refname>
                <refpurpose>Returns a geometry with the same X/Y coordinates as the input geometry, and values from the raster copied into the M dimension using the requested resample algorithm.</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                   <funcprototype>
                    <funcdef>geometry <function>ST_SetM</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    <paramdef><type>geometry </type> <parameter>geom</parameter></paramdef>
                    <paramdef choice="opt"><type>text </type> <parameter>resample=nearest</parameter></paramdef>
                    <paramdef choice="opt"><type>integer </type> <parameter>band=1</parameter></paramdef>
                  </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>Returns a geometry with the same X/Y coordinates as the input geometry, and values from the raster copied into the M dimensions using the requested resample algorithm.</para>
                <para>The <varname>resample</varname> parameter can be set to "nearest" to copy the values from the cell each vertex falls within, or "bilinear" to use <link xlink:href="https://en.wikipedia.org/wiki/Bilinear_interpolation">bilinear interpolation</link> to calculate a value that takes neighboring cells into account also.</para>

                <para role="availability" conformance="3.2.0">Availability: 3.2.0</para>
            </refsection>

                <refsection>
                    <title>Examples</title>
                    <para>2x2 test raster with values. 10 50. 40 20.</para>
                    <programlisting language="sql">
WITH test_raster AS (
SELECT
ST_SetValues(
ST_AddBand(
ST_MakeEmptyRaster(
      width =&gt; 2,
      height =&gt; 2,
      upperleftx =&gt; 0,
      upperlefty =&gt; 2,
      scalex =&gt; 1.0,
      scaley =&gt; -1.0,
      skewx =&gt; 0,
      skewy =&gt; 0,
      srid =&gt; 4326),
    index =&gt; 1,
    pixeltype =&gt; '16BSI',
    initialvalue =&gt; 0,
    nodataval =&gt; -999
),
  1,
  1,
  1,
  newvalueset =&gt; ARRAY[ARRAY[10.0::float8, 50.0::float8], ARRAY[40.0::float8, 20.0::float8]]) AS rast
)
SELECT
ST_SetM(
    rast,
    band =&gt; 1,
    geom =&gt; 'SRID=4326;LINESTRING(1.0 1.9,1.0 0.2)'::geometry,
    resample =&gt; 'bilinear'
)
FROM test_raster</programlisting>
<screen role="visual-primary text-primary">LINESTRING M (1 1.9 38,1 0.2 27)</screen>

            </refsection>

            <refsection>
                <title>See Also</title>
                <para>
                    <xref linkend="RT_ST_Value"/>,
                    <xref linkend="RT_ST_SetZ"/>
                </para>
            </refsection>
        </refentry>

        <refentry xml:id="RT_ST_Neighborhood">
            <refnamediv>
                <refname>ST_Neighborhood</refname>
                <refpurpose>
                    Returns a 2-D double precision array of the non-<varname>NODATA</varname> values around a given band's pixel specified by either a columnX and rowY or a geometric point expressed in the same spatial reference coordinate system as the raster.
                </refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                  <funcprototype>
                        <funcdef>double precision[][] <function>ST_Neighborhood</function></funcdef>
                        <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                        <paramdef><type>integer </type> <parameter>bandnum</parameter></paramdef>
                        <paramdef><type>integer </type> <parameter>columnX</parameter></paramdef>
                        <paramdef><type>integer </type> <parameter>rowY</parameter></paramdef>
                        <paramdef><type>integer </type> <parameter>distanceX</parameter></paramdef>
                        <paramdef><type>integer </type> <parameter>distanceY</parameter></paramdef>
                        <paramdef choice="opt"><type>boolean </type> <parameter>exclude_nodata_value=true</parameter></paramdef>
                    </funcprototype>

                    <funcprototype>
                        <funcdef>double precision[][] <function>ST_Neighborhood</function></funcdef>
                        <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                        <paramdef><type>integer </type> <parameter>columnX</parameter></paramdef>
                        <paramdef><type>integer </type> <parameter>rowY</parameter></paramdef>
                        <paramdef><type>integer </type> <parameter>distanceX</parameter></paramdef>
                        <paramdef><type>integer </type> <parameter>distanceY</parameter></paramdef>
                        <paramdef choice="opt"><type>boolean </type> <parameter>exclude_nodata_value=true</parameter></paramdef>
                    </funcprototype>

                    <funcprototype>
                        <funcdef>double precision[][] <function>ST_Neighborhood</function></funcdef>
                        <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                        <paramdef><type>integer </type> <parameter>bandnum</parameter></paramdef>
                        <paramdef><type>geometry </type> <parameter>pt</parameter></paramdef>
                        <paramdef><type>integer </type> <parameter>distanceX</parameter></paramdef>
                        <paramdef><type>integer </type> <parameter>distanceY</parameter></paramdef>
                        <paramdef choice="opt"><type>boolean </type> <parameter>exclude_nodata_value=true</parameter></paramdef>
                    </funcprototype>

                    <funcprototype>
                        <funcdef>double precision[][] <function>ST_Neighborhood</function></funcdef>
                        <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                        <paramdef><type>geometry </type> <parameter>pt</parameter></paramdef>
                        <paramdef><type>integer </type> <parameter>distanceX</parameter></paramdef>
                        <paramdef><type>integer </type> <parameter>distanceY</parameter></paramdef>
                        <paramdef choice="opt"><type>boolean </type> <parameter>exclude_nodata_value=true</parameter></paramdef>
                    </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>
                <para>
                    Returns a 2-D double precision array of the non-<varname>NODATA</varname> values around a given band's pixel specified by either a columnX and rowY or a geometric point expressed in the same spatial reference coordinate system as the raster.  The <varname>distanceX</varname> and <varname>distanceY</varname> parameters define the number of pixels around the specified pixel in the X and Y axes, e.g. I want all values within 3 pixel distance along the X axis and 2 pixel distance along the Y axis around my pixel of interest.  The center value of the 2-D array will be the value at the pixel specified by the columnX and rowY or the geometric point.
                </para>
                <para>
                    Band numbers start at 1 and <varname>bandnum</varname> is assumed to be 1 if not specified. If <varname>exclude_nodata_value</varname> is set to false, then all pixels include <varname>nodata</varname> pixels are considered to intersect and return value. If <varname>exclude_nodata_value</varname> is not passed in then reads it from metadata of raster.
                </para>
                <note>
                    <para>
                        The number of elements along each axis of the returning 2-D array is 2 * (<varname>distanceX</varname>|<varname>distanceY</varname>) + 1.  So for a <varname>distanceX</varname> and <varname>distanceY</varname> of 1, the returning array will be 3x3.
                    </para>
                </note>
                <note>
                    <para>
                        The 2-D array output can be passed to any of the raster processing builtin functions, e.g. ST_Min4ma, ST_Sum4ma, ST_Mean4ma.
                    </para>
                </note>
                <para role="availability" conformance="2.1.0">Availability: 2.1.0</para>
            </refsection>

            <refsection>
                <title>Examples</title>

                <para>This example reads a value from pixel 2x2.</para>
                <programlisting language="sql">
SELECT
    ST_Neighborhood(rast, 2, 2, 1, 1)
FROM (
    SELECT
        ST_SetValues(ST_AddBand(ST_MakeEmptyRaster(5, 5, -2, 2, 1, -1, 0, 0, 0),
                '8BUI'::text, 1, 0
            ),
            1, 1, 1, ARRAY[
                [0, 1, 1, 1, 1],
                [1, 1, 1, 0, 1],
                [1, 0, 1, 1, 1],
                [1, 1, 1, 1, 0],
                [1, 1, 0, 1, 1]
            ]::double precision[],
            1
        ) AS rast
) AS foo</programlisting>
<screen role="text-primary">{{NULL,1,1},{1,1,1},{1,NULL,1}}</screen>

                <para>This example reads a NODATA value from pixel 2x3.</para>
                <programlisting language="sql">
SELECT
    ST_Neighborhood(rast, 2, 3, 1, 1)
FROM (
    SELECT
        ST_SetValues(ST_AddBand(ST_MakeEmptyRaster(5, 5, -2, 2, 1, -1, 0, 0, 0),
                '8BUI'::text, 1, 0
            ),
            1, 1, 1, ARRAY[
                [0, 1, 1, 1, 1],
                [1, 1, 1, 0, 1],
                [1, 0, 1, 1, 1],
                [1, 1, 1, 1, 0],
                [1, 1, 0, 1, 1]
            ]::double precision[],
            1
        ) AS rast
) AS foo</programlisting>
<screen role="text-primary">{{1,1,1},{1,NULL,1},{1,1,1}}</screen>

                <para>Pixel 3x3 has value. Exclude_nodata_value = FALSE.</para>
                <programlisting language="sql">
SELECT
    ST_Neighborhood(rast, 3, 3, 1, 1, false)
FROM ST_SetValues(ST_AddBand(ST_MakeEmptyRaster(5, 5, -2, 2, 1, -1, 0, 0, 0),
                '8BUI'::text, 1, 0
            ),
            1, 1, 1, ARRAY[
                [0, 1, 1, 1, 1],
                [1, 1, 1, 0, 1],
                [1, 0, 1, 1, 1],
                [1, 1, 1, 1, 0],
                [1, 1, 0, 1, 1]
            ]::double precision[],
            1
        ) AS rast</programlisting>
<screen role="text-primary">{{1,1,0},{0,1,1},{1,1,1}}</screen>

            </refsection>

            <refsection>
                <title>See Also</title>
                <para>
                    <xref linkend="RT_ST_NearestValue"/>,
                    <xref linkend="RT_ST_Min4ma"/>,
                    <xref linkend="RT_ST_Max4ma"/>,
                    <xref linkend="RT_ST_Sum4ma"/>,
                    <xref linkend="RT_ST_Mean4ma"/>,
                    <xref linkend="RT_ST_Range4ma"/>,
                    <xref linkend="RT_ST_Distinct4ma"/>,
                    <xref linkend="RT_ST_StdDev4ma"/>
                </para>
            </refsection>

        </refentry>


           <refentry xml:id="RT_ST_SetValue">
            <refnamediv>
                <refname>ST_SetValue</refname>
                <refpurpose>Returns modified raster resulting from setting the value of a given band in a given columnx, rowy pixel or the pixels that intersect a particular geometry. Band numbers start at 1 and assumed to be 1 if not specified.</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                    <funcprototype>
                        <funcdef>raster <function>ST_SetValue</function></funcdef>
                        <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                        <paramdef><type>integer </type> <parameter>bandnum</parameter></paramdef>
                        <paramdef><type>geometry </type> <parameter>geom</parameter></paramdef>
                        <paramdef><type>double precision </type> <parameter>newvalue</parameter></paramdef>
                    </funcprototype>
                    <funcprototype>
                        <funcdef>raster <function>ST_SetValue</function></funcdef>
                        <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                        <paramdef><type>geometry </type> <parameter>geom</parameter></paramdef>
                        <paramdef><type>double precision </type> <parameter>newvalue</parameter></paramdef>
                    </funcprototype>
                  <funcprototype>
                        <funcdef>raster <function>ST_SetValue</function></funcdef>
                        <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                        <paramdef><type>integer </type> <parameter>bandnum</parameter></paramdef>
                        <paramdef><type>integer </type> <parameter>columnx</parameter></paramdef>
                        <paramdef><type>integer </type> <parameter>rowy</parameter></paramdef>
                        <paramdef><type>double precision </type> <parameter>newvalue</parameter></paramdef>
                  </funcprototype>
                    <funcprototype>
                        <funcdef>raster <function>ST_SetValue</function></funcdef>
                        <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                        <paramdef><type>integer </type> <parameter>columnx</parameter></paramdef>
                        <paramdef><type>integer </type> <parameter>rowy</parameter></paramdef>
                        <paramdef><type>double precision </type> <parameter>newvalue</parameter></paramdef>
                  </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>
                <para>Returns modified raster resulting from setting the specified pixels' values to new value for the designated band given the raster's row and column or a geometry. If no band is specified, then band 1 is assumed.
                </para>

                <para role="enhanced" conformance="2.1.0">Enhanced: 2.1.0 Geometry variant of ST_SetValue() now supports any geometry type, not just point. The geometry variant is a wrapper around the geomval[] variant of ST_SetValues()</para>
            </refsection>

            <refsection>
                <title>Examples</title>

                <para>This example uses geometry input.</para>
                <programlisting language="sql">
<![CDATA[

                SELECT (foo.geomval).val, ST_Union((foo.geomval).geom)
FROM (SELECT ST_DumpAsPolygons(ST_SetValue(
            rast,
            1,
            ST_Point(3427927.75, 5793243.95),
            50)
            ) As geomval
FROM dummy_rast
where rid = 2) As foo
WHERE (foo.geomval).val < 250
GROUP BY (foo.geomval).val;]]></programlisting>
<screen role="text-primary"><![CDATA[ val |                                                     st_astext
-----+-------------------------------------------------------------------
  50 | POLYGON((3427927.75 5793244,3427927.75 5793243.95,3427927.8 579324 ...
 249 | POLYGON((3427927.95 5793243.95,3427927.95 5793243.85,3427928 57932 ...]]></screen>

                <para>This example stores the changed raster.</para>
                <programlisting language="sql">
UPDATE dummy_rast SET rast = ST_SetValue(rast, 1, ST_Point(3427927.75, 5793243.95), 100)
    WHERE rid = 2   ;

                </programlisting>
            </refsection>
            <refsection>
                <title>See Also</title>
                <para><xref linkend="RT_ST_Value"/>, <xref linkend="RT_ST_DumpAsPolygons"/></para>
            </refsection>
        </refentry>

        <refentry xml:id="RT_ST_SetValues">
            <refnamediv>
                <refname>ST_SetValues</refname>
                <refpurpose>Returns modified raster resulting from setting the values of a given band.</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                    <funcprototype>
                        <funcdef>raster <function>ST_SetValues</function></funcdef>
                        <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                        <paramdef><type>integer </type> <parameter>nband</parameter></paramdef>
                        <paramdef><type>integer </type> <parameter>columnx</parameter></paramdef>
                        <paramdef><type>integer </type> <parameter>rowy</parameter></paramdef>
                        <paramdef><type>double precision[][] </type> <parameter>newvalueset</parameter></paramdef>
                        <paramdef><type>boolean[][] </type> <parameter>noset=NULL</parameter></paramdef>
                        <paramdef><type>boolean </type> <parameter>keepnodata=FALSE</parameter></paramdef>
                    </funcprototype>

                    <funcprototype>
                        <funcdef>raster <function>ST_SetValues</function></funcdef>
                        <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                        <paramdef><type>integer </type> <parameter>nband</parameter></paramdef>
                        <paramdef><type>integer </type> <parameter>columnx</parameter></paramdef>
                        <paramdef><type>integer </type> <parameter>rowy</parameter></paramdef>
                        <paramdef><type>double precision[][] </type> <parameter>newvalueset</parameter></paramdef>
                        <paramdef><type>double precision </type> <parameter>nosetvalue</parameter></paramdef>
                        <paramdef><type>boolean </type> <parameter>keepnodata=FALSE</parameter></paramdef>
                    </funcprototype>

                  <funcprototype>
                        <funcdef>raster <function>ST_SetValues</function></funcdef>
                        <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                        <paramdef><type>integer </type> <parameter>nband</parameter></paramdef>
                        <paramdef><type>integer </type> <parameter>columnx</parameter></paramdef>
                        <paramdef><type>integer </type> <parameter>rowy</parameter></paramdef>
                        <paramdef><type>integer </type> <parameter>width</parameter></paramdef>
                        <paramdef><type>integer </type> <parameter>height</parameter></paramdef>
                        <paramdef><type>double precision </type> <parameter>newvalue</parameter></paramdef>
                        <paramdef><type>boolean </type> <parameter>keepnodata=FALSE</parameter></paramdef>
                    </funcprototype>

                  <funcprototype>
                        <funcdef>raster <function>ST_SetValues</function></funcdef>
                        <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                        <paramdef><type>integer </type> <parameter>columnx</parameter></paramdef>
                        <paramdef><type>integer </type> <parameter>rowy</parameter></paramdef>
                        <paramdef><type>integer </type> <parameter>width</parameter></paramdef>
                        <paramdef><type>integer </type> <parameter>height</parameter></paramdef>
                        <paramdef><type>double precision </type> <parameter>newvalue</parameter></paramdef>
                        <paramdef><type>boolean </type> <parameter>keepnodata=FALSE</parameter></paramdef>
                    </funcprototype>

                  <funcprototype>
                        <funcdef>raster <function>ST_SetValues</function></funcdef>
                        <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                        <paramdef><type>integer </type> <parameter>nband</parameter></paramdef>
                        <paramdef><type>geomval[] </type> <parameter>geomvalset</parameter></paramdef>
                        <paramdef><type>boolean </type> <parameter>keepnodata=FALSE</parameter></paramdef>
                    </funcprototype>

                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>
                <para>
                    Returns modified raster resulting from setting specified pixels to new value(s) for the designated band. <varname>columnx</varname> and <varname>rowy</varname> are 1-indexed.
                </para>

                <para>
                    If <varname>keepnodata</varname> is TRUE, those pixels whose values are NODATA will not be set with the corresponding value in <varname>newvalueset</varname>.
                </para>

                <para>
                    For Variant 1, the specific pixels to be set are determined by the <varname>columnx</varname>, <varname>rowy</varname> pixel coordinates and the dimensions of the <varname>newvalueset</varname> array. <varname>noset</varname> can be used to prevent pixels with values present in <varname>newvalueset</varname> from being set (due to PostgreSQL not permitting ragged/jagged arrays). See example Variant 1.
                </para>

                <para>
                    Variant 2 is like Variant 1 but with a simple double precision <varname>nosetvalue</varname> instead of a boolean <varname>noset</varname> array. Elements in <varname>newvalueset</varname> with the <varname>nosetvalue</varname> value with be skipped.  See example Variant 2.
                </para>

                <para>
                    For Variant 3, the specific pixels to be set are determined by the <varname>columnx</varname>, <varname>rowy</varname> pixel coordinates, <varname>width</varname> and <varname>height</varname>. See example Variant 3.
                </para>

                <para>
                    Variant 4 is the same as Variant 3 with the exception that it assumes that the first band's pixels of <varname>rast</varname> will be set.
                </para>

                <para>
                    For Variant 5, an array of <xref linkend="geomval"/> is used to determine the specific pixels to be set.  If all the geometries in the array are of type POINT or MULTIPOINT, the function uses a shortcut where the longitude and latitude of each point is used to set a pixel directly.  Otherwise, the geometries are converted to rasters and then iterated through in one pass. See example Variant 5.
                </para>

                <para role="availability" conformance="2.1.0">Availability: 2.1.0</para>

            </refsection>

            <refsection>
                <title>Examples</title>
                <para>Variant 1.</para>

                <para>These examples pass <literal>FALSE</literal> for
                <parameter>exclude_nodata_value</parameter> so that every
                raster cell remains visible. NODATA cells display the band's
                NODATA value, which is <literal>0</literal> here.</para>

                <para>Set the lower-right 2 by 2 block of a 3 by 3 raster to
                <literal>9</literal>.</para>
                <programlisting language="sql"><![CDATA[SELECT
    (poly).x,
    (poly).y,
    (poly).val
FROM (
SELECT
    ST_PixelAsPolygons(ST_SetValues(ST_AddBand(ST_MakeEmptyRaster(3, 3, 0, 0, 1, -1, 0, 0, 0),
                1, '8BUI', 1, 0
            ),
            1, 2, 2, ARRAY[[9, 9], [9, 9]]::double precision[][]
        ),
        1, FALSE
    ) AS poly
) foo
ORDER BY 1, 2;]]></programlisting>
<screen role="text-primary"><![CDATA[ x | y | val
---+---+-----
 1 | 1 |   1
 1 | 2 |   1
 1 | 3 |   1
 2 | 1 |   1
 2 | 2 |   9
 2 | 3 |   9
 3 | 1 |   1
 3 | 2 |   9
 3 | 3 |   9]]></screen>

                <para>Replace the complete raster from an array; the central
                <literal>NULL</literal> becomes NODATA.</para>
                <programlisting language="sql"><![CDATA[SELECT
    (poly).x,
    (poly).y,
    (poly).val
FROM (
SELECT
    ST_PixelAsPolygons(ST_SetValues(ST_AddBand(ST_MakeEmptyRaster(3, 3, 0, 0, 1, -1, 0, 0, 0),
                1, '8BUI', 1, 0
            ),
            1, 1, 1, ARRAY[[9, 9, 9], [9, NULL, 9], [9, 9, 9]]::double precision[][]
        ),
        1, FALSE
    ) AS poly
) foo
ORDER BY 1, 2;]]></programlisting>
<screen role="text-primary"><![CDATA[ x | y | val
---+---+-----
 1 | 1 |   9
 1 | 2 |   9
 1 | 3 |   9
 2 | 1 |   9
 2 | 2 |   0
 2 | 3 |   9
 3 | 1 |   9
 3 | 2 |   9
 3 | 3 |   9]]></screen>

                <para>Use the <parameter>noset</parameter> mask to retain the
                left-middle source pixel while replacing the other cells.</para>
                <programlisting language="sql">SELECT
    (poly).x,
    (poly).y,
    (poly).val
FROM (
SELECT
    ST_PixelAsPolygons(ST_SetValues(ST_AddBand(ST_MakeEmptyRaster(3, 3, 0, 0, 1, -1, 0, 0, 0),
                1, '8BUI', 1, 0
            ),
            1, 1, 1,
                ARRAY[[9, 9, 9], [9, NULL, 9], [9, 9, 9]]::double precision[][],
                ARRAY[[false], [true]]::boolean[][]
        ),
        1, FALSE
    ) AS poly
) foo
ORDER BY 1, 2;</programlisting>
<screen role="text-primary"> x | y | val
---+---+-----
 1 | 1 |   9
 1 | 2 |   1
 1 | 3 |   9
 2 | 1 |   9
 2 | 2 |   0
 2 | 3 |   9
 3 | 1 |   9
 3 | 2 |   9
 3 | 3 |   9</screen>

                <para>With <parameter>keepnodata</parameter> enabled, an
                existing NODATA pixel is not overwritten.</para>
                <programlisting language="sql">SELECT
    (poly).x,
    (poly).y,
    (poly).val
FROM (
SELECT
    ST_PixelAsPolygons(ST_SetValues(ST_SetValue(ST_AddBand(ST_MakeEmptyRaster(3, 3, 0, 0, 1, -1, 0, 0, 0),
                    1, '8BUI', 1, 0
                ),
                1, 1, 1, NULL
            ),
            1, 1, 1,
                ARRAY[[9, 9, 9], [9, NULL, 9], [9, 9, 9]]::double precision[][],
                ARRAY[[false], [true]]::boolean[][],
                TRUE
        ),
        1, FALSE
    ) AS poly
) foo
ORDER BY 1, 2;</programlisting>
<screen role="text-primary"> x | y | val
---+---+-----
 1 | 1 |   0
 1 | 2 |   1
 1 | 3 |   9
 2 | 1 |   9
 2 | 2 |   0
 2 | 3 |   9
 3 | 1 |   9
 3 | 2 |   9
 3 | 3 |   9</screen>


                <para>Variant 2.</para>

                <para>Use <literal>-1</literal> as the value that should not be
                written; only the lower-right 2 by 2 block changes.</para>
                <programlisting language="sql">SELECT
    (poly).x,
    (poly).y,
    (poly).val
FROM (
SELECT
    ST_PixelAsPolygons(ST_SetValues(ST_AddBand(ST_MakeEmptyRaster(3, 3, 0, 0, 1, -1, 0, 0, 0),
                1, '8BUI', 1, 0
            ),
            1, 1, 1, ARRAY[[-1, -1, -1], [-1, 9, 9], [-1, 9, 9]]::double precision[][], -1
        ),
        1, FALSE
    ) AS poly
) foo
ORDER BY 1, 2;</programlisting>
<screen role="text-primary"> x | y | val
---+---+-----
 1 | 1 |   1
 1 | 2 |   1
 1 | 3 |   1
 2 | 1 |   1
 2 | 2 |   9
 2 | 3 |   9
 3 | 1 |   1
 3 | 2 |   9
 3 | 3 |   9</screen>

                <para>The same update can use <literal>NULL</literal> as the
                value that should not be written.</para>
                <programlisting language="sql">SELECT
    (poly).x,
    (poly).y,
    (poly).val
FROM (
SELECT
    ST_PixelAsPolygons(ST_SetValues(ST_AddBand(ST_MakeEmptyRaster(3, 3, 0, 0, 1, -1, 0, 0, 0),
                1, '8BUI', 1, 0
            ),
            1, 1, 1, ARRAY[[NULL, NULL, NULL], [NULL, 9, 9], [NULL, 9, 9]]::double precision[][], NULL::double precision
        ),
        1, FALSE
    ) AS poly
) foo
ORDER BY 1, 2;</programlisting>
<screen role="text-primary"> x | y | val
---+---+-----
 1 | 1 |   1
 1 | 2 |   1
 1 | 3 |   1
 2 | 1 |   1
 2 | 2 |   9
 2 | 3 |   9
 3 | 1 |   1
 3 | 2 |   9
 3 | 3 |   9</screen>


                <para>Variant 3.</para>

                <para>Set a 2 by 2 rectangle starting at column 2, row 2.</para>
                <programlisting language="sql">SELECT
    (poly).x,
    (poly).y,
    (poly).val
FROM (
SELECT
    ST_PixelAsPolygons(ST_SetValues(ST_AddBand(ST_MakeEmptyRaster(3, 3, 0, 0, 1, -1, 0, 0, 0),
                1, '8BUI', 1, 0
            ),
            1, 2, 2, 2, 2, 9
        ),
        1, FALSE
    ) AS poly
) foo
ORDER BY 1, 2;</programlisting>
<screen role="text-primary"> x | y | val
---+---+-----
 1 | 1 |   1
 1 | 2 |   1
 1 | 3 |   1
 2 | 1 |   1
 2 | 2 |   9
 2 | 3 |   9
 3 | 1 |   1
 3 | 2 |   9
 3 | 3 |   9</screen>

                <para>When <parameter>keepnodata</parameter> is true, the
                NODATA cell inside the rectangle remains unchanged.</para>
                <programlisting language="sql">SELECT
    (poly).x,
    (poly).y,
    (poly).val
FROM (
SELECT
    ST_PixelAsPolygons(ST_SetValues(ST_SetValue(ST_AddBand(ST_MakeEmptyRaster(3, 3, 0, 0, 1, -1, 0, 0, 0),
                    1, '8BUI', 1, 0
                ),
                1, 2, 2, NULL
            ),
            1, 2, 2, 2, 2, 9, TRUE
        ),
        1, FALSE
    ) AS poly
) foo
ORDER BY 1, 2;</programlisting>
<screen role="text-primary"> x | y | val
---+---+-----
 1 | 1 |   1
 1 | 2 |   1
 1 | 3 |   1
 2 | 1 |   1
 2 | 2 |   0
 2 | 3 |   9
 3 | 1 |   1
 3 | 2 |   9
 3 | 3 |   9</screen>


                <para>Variant 5.</para>

                <programlisting language="sql">
WITH foo AS (
    SELECT 1 AS rid, ST_AddBand(ST_MakeEmptyRaster(5, 5, 0, 0, 1, -1, 0, 0, 0), 1, '8BUI', 0, 0) AS rast
), bar AS (
    SELECT 1 AS gid, 'SRID=0;POINT(2.5 -2.5)'::geometry geom UNION ALL
    SELECT 2 AS gid, 'SRID=0;POLYGON((1 -1,4 -1,4 -4,1 -4,1 -1))'::geometry geom UNION ALL
    SELECT 3 AS gid, 'SRID=0;POLYGON((0 0,5 0,5 -1,1 -1,1 -4,0 -4,0 0))'::geometry geom UNION ALL
    SELECT 4 AS gid, 'SRID=0;MULTIPOINT(0 0,4 4,4 -4)'::geometry
), changed AS (
    SELECT rid, gid, ST_SetValue(rast, 1, geom, gid) AS rast
    FROM foo
    CROSS JOIN bar
)
SELECT
    rid,
    gid,
    y,
    array_agg(ST_Value(rast, 1, x, y) ORDER BY x) AS values
FROM changed
CROSS JOIN generate_series(1, 5) AS x
CROSS JOIN generate_series(1, 5) AS y
GROUP BY rid, gid, y
ORDER BY rid, gid, y;</programlisting>
<screen role="text-primary"> rid | gid | y |           values
-----+-----+---+----------------------------
   1 |   1 | 1 | {NULL,NULL,NULL,NULL,NULL}
   1 |   1 | 2 | {NULL,NULL,NULL,NULL,NULL}
   1 |   1 | 3 | {NULL,NULL,1,NULL,NULL}
   1 |   1 | 4 | {NULL,NULL,NULL,NULL,NULL}
   1 |   1 | 5 | {NULL,NULL,NULL,NULL,NULL}
   1 |   2 | 1 | {NULL,NULL,NULL,NULL,NULL}
   1 |   2 | 2 | {NULL,2,2,2,NULL}
   1 |   2 | 3 | {NULL,2,2,2,NULL}
   1 |   2 | 4 | {NULL,2,2,2,NULL}
   1 |   2 | 5 | {NULL,NULL,NULL,NULL,NULL}
   1 |   3 | 1 | {3,3,3,3,3}
   1 |   3 | 2 | {3,NULL,NULL,NULL,NULL}
   1 |   3 | 3 | {3,NULL,NULL,NULL,NULL}
   1 |   3 | 4 | {3,NULL,NULL,NULL,NULL}
   1 |   3 | 5 | {NULL,NULL,NULL,NULL,NULL}
   1 |   4 | 1 | {4,NULL,NULL,NULL,NULL}
   1 |   4 | 2 | {NULL,NULL,NULL,NULL,NULL}
   1 |   4 | 3 | {NULL,NULL,NULL,NULL,NULL}
   1 |   4 | 4 | {NULL,NULL,NULL,NULL,NULL}
   1 |   4 | 5 | {NULL,NULL,NULL,NULL,4}
(20 rows)</screen>

                <para>The following shows that geomvals later in the array can overwrite prior geomvals</para>
                <programlisting language="sql">
WITH foo AS (
    SELECT 1 AS rid, ST_AddBand(ST_MakeEmptyRaster(5, 5, 0, 0, 1, -1, 0, 0, 0), 1, '8BUI', 0, 0) AS rast
), bar AS (
    SELECT 1 AS gid, 'SRID=0;POINT(2.5 -2.5)'::geometry geom UNION ALL
    SELECT 2 AS gid, 'SRID=0;POLYGON((1 -1,4 -1,4 -4,1 -4,1 -1))'::geometry geom UNION ALL
    SELECT 3 AS gid, 'SRID=0;POLYGON((0 0,5 0,5 -1,1 -1,1 -4,0 -4,0 0))'::geometry geom UNION ALL
    SELECT 4 AS gid, 'SRID=0;MULTIPOINT(0 0,4 4,4 -4)'::geometry
), changed AS (
    SELECT ST_SetValues(
        rast,
        1,
        ARRAY[
            ROW((SELECT geom FROM bar WHERE gid = 1), 1),
            ROW((SELECT geom FROM bar WHERE gid = 2), 2)
        ]::geomval[]
    ) AS rast
    FROM foo
)
SELECT
    y,
    array_agg(ST_Value(rast, 1, x, y) ORDER BY x) AS values
FROM changed
CROSS JOIN generate_series(1, 5) AS x
CROSS JOIN generate_series(1, 5) AS y
GROUP BY y
ORDER BY y;</programlisting>
<screen role="text-primary"> y |           values
---+----------------------------
 1 | {NULL,NULL,NULL,NULL,NULL}
 2 | {NULL,2,2,2,NULL}
 3 | {NULL,2,2,2,NULL}
 4 | {NULL,2,2,2,NULL}
 5 | {NULL,NULL,NULL,NULL,NULL}
(5 rows)</screen>

                <para>This example is the opposite of the prior example</para>
                <programlisting language="sql">
WITH foo AS (
    SELECT 1 AS rid, ST_AddBand(ST_MakeEmptyRaster(5, 5, 0, 0, 1, -1, 0, 0, 0), 1, '8BUI', 0, 0) AS rast
), bar AS (
    SELECT 1 AS gid, 'SRID=0;POINT(2.5 -2.5)'::geometry geom UNION ALL
    SELECT 2 AS gid, 'SRID=0;POLYGON((1 -1,4 -1,4 -4,1 -4,1 -1))'::geometry geom UNION ALL
    SELECT 3 AS gid, 'SRID=0;POLYGON((0 0,5 0,5 -1,1 -1,1 -4,0 -4,0 0))'::geometry geom UNION ALL
    SELECT 4 AS gid, 'SRID=0;MULTIPOINT(0 0,4 4,4 -4)'::geometry
), changed AS (
    SELECT ST_SetValues(
        rast,
        1,
        ARRAY[
            ROW((SELECT geom FROM bar WHERE gid = 2), 2),
            ROW((SELECT geom FROM bar WHERE gid = 1), 1)
        ]::geomval[]
    ) AS rast
    FROM foo
)
SELECT
    y,
    array_agg(ST_Value(rast, 1, x, y) ORDER BY x) AS values
FROM changed
CROSS JOIN generate_series(1, 5) AS x
CROSS JOIN generate_series(1, 5) AS y
GROUP BY y
ORDER BY y;</programlisting>
<screen role="text-primary"> y |           values
---+----------------------------
 1 | {NULL,NULL,NULL,NULL,NULL}
 2 | {NULL,2,2,2,NULL}
 3 | {NULL,2,1,2,NULL}
 4 | {NULL,2,2,2,NULL}
 5 | {NULL,NULL,NULL,NULL,NULL}
(5 rows)</screen>

            </refsection>


            <refsection>
                <title>See Also</title>
                <para>
                    <xref linkend="RT_ST_Value"/>,
                    <xref linkend="RT_ST_SetValue"/>,
                    <xref linkend="RT_ST_PixelAsPolygons"/>
                </para>
            </refsection>
        </refentry>

        <refentry xml:id="RT_ST_DumpValues">
            <refnamediv>
                <refname>ST_DumpValues</refname>
                <refpurpose>
                    Get the values of the specified band as a 2-dimension array.
                </refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                    <funcprototype>
                        <funcdef>setof record <function>ST_DumpValues</function></funcdef>
                        <paramdef>
                            <type>raster </type> <parameter>rast</parameter>
                        </paramdef>
                        <paramdef>
                            <type>integer[] </type> <parameter>nband=NULL</parameter>
                        </paramdef>
                        <paramdef>
                            <type>boolean </type> <parameter>exclude_nodata_value=true</parameter>
                        </paramdef>
                    </funcprototype>
                    <funcprototype>
                        <funcdef>double precision[][] <function>ST_DumpValues</function></funcdef>
                        <paramdef>
                            <type>raster </type> <parameter>rast</parameter>
                        </paramdef>
                        <paramdef>
                            <type>integer </type> <parameter>nband</parameter>
                        </paramdef>
                        <paramdef>
                            <type>boolean </type> <parameter>exclude_nodata_value=true</parameter>
                        </paramdef>
                    </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>
                    Get the values of the specified band as a 2-dimension array (first index is row, second is column). If <varname>nband</varname> is NULL or not provided, all raster bands are processed.
                </para>

                <para role="availability" conformance="2.1.0">Availability: 2.1.0</para>
            </refsection>

            <refsection>
                <title>Examples</title>

                <programlisting language="sql">
WITH foo AS (
    SELECT ST_AddBand(ST_AddBand(ST_AddBand(ST_MakeEmptyRaster(3, 3, 0, 0, 1, -1, 0, 0, 0), 1, '8BUI'::text, 1, 0), 2, '32BF'::text, 3, -9999), 3, '16BSI', 0, 0) AS rast
)
SELECT
    (ST_DumpValues(rast)).*
FROM foo;</programlisting>
<screen role="text-primary"> nband |                       valarray
-------+------------------------------------------------------
     1 | {{1,1,1},{1,1,1},{1,1,1}}
     2 | {{3,3,3},{3,3,3},{3,3,3}}
     3 | {{NULL,NULL,NULL},{NULL,NULL,NULL},{NULL,NULL,NULL}}
(3 rows)</screen>

                <programlisting language="sql">
WITH foo AS (
    SELECT ST_AddBand(ST_AddBand(ST_AddBand(ST_MakeEmptyRaster(3, 3, 0, 0, 1, -1, 0, 0, 0), 1, '8BUI'::text, 1, 0), 2, '32BF'::text, 3, -9999), 3, '16BSI', 0, 0) AS rast
)
SELECT
    (ST_DumpValues(rast, ARRAY[3, 1])).*
FROM foo;</programlisting>
<screen role="text-primary"> nband |                       valarray
-------+------------------------------------------------------
     3 | {{NULL,NULL,NULL},{NULL,NULL,NULL},{NULL,NULL,NULL}}
     1 | {{1,1,1},{1,1,1},{1,1,1}}
(2 rows)</screen>
                <programlisting language="sql">
WITH foo AS (
    SELECT ST_SetValue(ST_AddBand(ST_MakeEmptyRaster(3, 3, 0, 0, 1, -1, 0, 0, 0), 1, '8BUI', 1, 0), 1, 2, 5) AS rast
)
SELECT
    (ST_DumpValues(rast, 1))[2][1]
FROM foo;</programlisting>
<screen role="text-primary">5</screen>
            </refsection>

            <refsection>
                <title>See Also</title>
                <para>
                    <xref linkend="RT_ST_Value"/>,
                    <xref linkend="RT_ST_SetValue"/>,
                    <xref linkend="RT_ST_SetValues"/>
                </para>
            </refsection>

        </refentry>

        <refentry xml:id="RT_ST_PixelOfValue">
            <refnamediv>
                <refname>ST_PixelOfValue</refname>
                <refpurpose>
                    Get the columnx, rowy coordinates of the pixel whose value equals the search value.
                </refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                    <funcprototype>
                        <funcdef>setof record <function>ST_PixelOfValue</function></funcdef>
                        <paramdef>
                            <type>raster </type> <parameter>rast</parameter>
                        </paramdef>
                        <paramdef>
                            <type>integer </type> <parameter>nband</parameter>
                        </paramdef>
                        <paramdef>
                            <type>double precision[] </type> <parameter>search</parameter>
                        </paramdef>
                        <paramdef>
                            <type>boolean </type> <parameter>exclude_nodata_value=true</parameter>
                        </paramdef>
                    </funcprototype>
                    <funcprototype>
                        <funcdef>setof record <function>ST_PixelOfValue</function></funcdef>
                        <paramdef>
                            <type>raster </type> <parameter>rast</parameter>
                        </paramdef>
                        <paramdef>
                            <type>double precision[] </type> <parameter>search</parameter>
                        </paramdef>
                        <paramdef>
                            <type>boolean </type> <parameter>exclude_nodata_value=true</parameter>
                        </paramdef>
                    </funcprototype>
                    <funcprototype>
                        <funcdef>setof record <function>ST_PixelOfValue</function></funcdef>
                        <paramdef>
                            <type>raster </type> <parameter>rast</parameter>
                        </paramdef>
                        <paramdef>
                            <type>integer </type> <parameter>nband</parameter>
                        </paramdef>
                        <paramdef>
                            <type>double precision </type> <parameter>search</parameter>
                        </paramdef>
                        <paramdef>
                            <type>boolean </type> <parameter>exclude_nodata_value=true</parameter>
                        </paramdef>
                    </funcprototype>
                    <funcprototype>
                        <funcdef>setof record <function>ST_PixelOfValue</function></funcdef>
                        <paramdef>
                            <type>raster </type> <parameter>rast</parameter>
                        </paramdef>
                        <paramdef>
                            <type>double precision </type> <parameter>search</parameter>
                        </paramdef>
                        <paramdef>
                            <type>boolean </type> <parameter>exclude_nodata_value=true</parameter>
                        </paramdef>
                    </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>
                    Get the columnx, rowy coordinates of the pixel whose value equals the search value. If no band is specified, then band 1 is assumed.
                </para>

                <para role="availability" conformance="2.1.0">Availability: 2.1.0</para>
            </refsection>
            <refsection>
                <title>Examples</title>

                <programlisting language="sql">WITH source AS (
    SELECT ST_SetValues(
        ST_AddBand(
            ST_MakeEmptyRaster(5, 5, -2, 2, 1, -1, 0, 0, 0),
            1, '8BUI', 1, 0
        ),
        1, 1, 1,
        ARRAY[
            [0, 1, 1, 1, 1],
            [1, 1, 1, 0, 1],
            [1, 0, 1, 1, 1],
            [1, 1, 1, 1, 255],
            [1, 1, 0, 1, 1]
        ]::double precision[][]
    ) AS rast
)
SELECT (ST_PixelOfValue(rast, 1, ARRAY[1, 255])).*
FROM source</programlisting>
<screen role="text-primary"> val | x | y
-----+---+---
   1 | 1 | 2
   1 | 1 | 3
   1 | 1 | 4
   1 | 1 | 5
   1 | 2 | 1
   1 | 2 | 2
   1 | 2 | 4
   1 | 2 | 5
   1 | 3 | 1
   1 | 3 | 2
   1 | 3 | 3
   1 | 3 | 4
   1 | 4 | 1
   1 | 4 | 3
   1 | 4 | 4
   1 | 4 | 5
   1 | 5 | 1
   1 | 5 | 2
   1 | 5 | 3
 255 | 5 | 4
   1 | 5 | 5</screen>
            </refsection>

        </refentry>

    </section>

    <section xml:id="Raster_Editors">
        <title>Raster Editors</title>

        <refentry xml:id="RT_ST_SetGeoReference">
            <refnamediv>
                <refname>ST_SetGeoReference</refname>
                <refpurpose>Set Georeference 6 georeference parameters  in a single call. Numbers should be separated by white space.  Accepts inputs in GDAL or ESRI format.  Default is GDAL.</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>

                  <funcprototype>
                        <funcdef>raster <function>ST_SetGeoReference</function></funcdef>
                        <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                        <paramdef><type>text </type> <parameter>georefcoords</parameter></paramdef>
                        <paramdef choice="opt"><type>text </type> <parameter>format=GDAL</parameter></paramdef>
                  </funcprototype>

                  <funcprototype>
                        <funcdef>raster <function>ST_SetGeoReference</function></funcdef>
                        <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                        <paramdef><type>double precision </type> <parameter>upperleftx</parameter></paramdef>
                        <paramdef><type>double precision </type> <parameter>upperlefty</parameter></paramdef>
                        <paramdef><type>double precision </type> <parameter>scalex</parameter></paramdef>
                        <paramdef><type>double precision </type> <parameter>scaley</parameter></paramdef>
                        <paramdef><type>double precision </type> <parameter>skewx</parameter></paramdef>
                        <paramdef><type>double precision </type> <parameter>skewy</parameter></paramdef>
                  </funcprototype>

                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>Set Georeference 6 georeference parameters in a single call.  Accepts inputs in 'GDAL' or 'ESRI' format.  Default is GDAL. If 6 coordinates are not provided will return null.</para>
                <para>Difference between format representations is as follows:</para>
                <para><varname>GDAL</varname> uses the value order shown below.</para>
                <programlisting language="text">scalex skewy skewx scaley upperleftx upperlefty</programlisting>
                <para><varname>ESRI</varname> uses the value order shown below.</para>
                <programlisting language="text">scalex skewy skewx scaley upperleftx + scalex*0.5 upperlefty + scaley*0.5</programlisting>

                <note>
                    <para>
                        If the raster has out-db bands, changing the georeference may result in incorrect access of the band's externally stored data.
                    </para>
                </note>

                <para role="enhanced" conformance="2.1.0">Enhanced: 2.1.0 Addition of ST_SetGeoReference(raster, double precision, ...) variant</para>

            </refsection>

            <refsection>
                <title>Examples</title>

                <programlisting language="sql">
WITH source AS (
    SELECT ST_MakeEmptyRaster(5, 5, 0, 0, 1, -1, 0, 0, 0) AS rast
), variants AS (
    SELECT 0 AS rid, rast FROM source
    UNION ALL
    SELECT 1, ST_SetGeoReference(rast, '10 0 0 -10 0.1 0.1', 'GDAL')
    FROM source
    UNION ALL
    SELECT 2, ST_SetGeoReference(rast, '10 0 0 -10 5.1 -4.9', 'ESRI')
    FROM source
    UNION ALL
    SELECT 3, ST_SetGeoReference(rast, 1, 1, 10, -10, 0.001, 0.001)
    FROM source
)
SELECT
    rid,
    round(ST_UpperLeftX(rast)::numeric, 3) AS upperleftx,
    round(ST_UpperLeftY(rast)::numeric, 3) AS upperlefty,
    ST_ScaleX(rast) AS scalex,
    ST_ScaleY(rast) AS scaley,
    ST_SkewX(rast) AS skewx,
    ST_SkewY(rast) AS skewy
FROM variants
ORDER BY rid;</programlisting>
<screen role="text-primary"> rid | upperleftx | upperlefty | scalex | scaley | skewx | skewy
-----+------------+------------+--------+--------+-------+-------
   0 |      0.000 |      0.000 |      1 |     -1 |     0 |     0
   1 |      0.100 |      0.100 |     10 |    -10 |     0 |     0
   2 |      0.100 |      0.100 |     10 |    -10 |     0 |     0
   3 |      1.000 |      1.000 |     10 |    -10 | 0.001 | 0.001
(4 rows)</screen>
            </refsection>

            <refsection>
                <title>See Also</title>
                <para><xref linkend="RT_ST_GeoReference"/>, <xref linkend="RT_ST_ScaleX"/>, <xref linkend="RT_ST_ScaleY"/>, <xref linkend="RT_ST_UpperLeftX"/>, <xref linkend="RT_ST_UpperLeftY"/></para>
            </refsection>
        </refentry>

        <refentry xml:id="RT_ST_SetRotation">
            <refnamediv>
                <refname>ST_SetRotation</refname>
                <refpurpose>Set the rotation of the raster in radian.</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                    <funcprototype>
                        <funcdef>raster <function>ST_SetRotation</function></funcdef>
                        <paramdef><type>raster</type> <parameter>rast</parameter></paramdef>
                        <paramdef><type>float8</type> <parameter>rotation</parameter></paramdef>
                    </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>Uniformly rotate the raster. Rotation is in radian. Refer to <link xlink:href="http://en.wikipedia.org/wiki/World_file">World File</link> for more details.</para>
            </refsection>

            <refsection>
                <title>Examples</title>

                <programlisting language="sql">WITH variants AS (
    SELECT rid, 'rotated' AS kind, ST_SetRotation(rast, 15) AS rast
    FROM dummy_rast
    UNION ALL
    SELECT rid, 'original', rast
    FROM dummy_rast
)
SELECT
    rid,
    kind,
    round(ST_ScaleX(rast)::numeric, 4) AS scale_x,
    round(ST_ScaleY(rast)::numeric, 4) AS scale_y,
    round(ST_SkewX(rast)::numeric, 4) AS skew_x,
    round(ST_SkewY(rast)::numeric, 4) AS skew_y
FROM variants
ORDER BY rid, kind;</programlisting>
<screen role="text-primary"> rid |   kind   | scale_x | scale_y | skew_x | skew_y
-----+----------+---------+---------+--------+--------
   1 | original |  2.0000 |  3.0000 | 0.0000 | 0.0000
   1 | rotated  | -1.5194 | -2.2791 | 1.9509 | 1.3006
   2 | original |  0.0500 | -0.0500 | 0.0000 | 0.0000
   2 | rotated  | -0.0380 | -0.0380 | 0.0325 | 0.0325
(4 rows)</screen>
            </refsection>

            <!-- Optionally add a "See Also" section -->
            <refsection>
                <title>See Also</title>
                <para><xref linkend="RT_ST_Rotation"/>, <xref linkend="RT_ST_ScaleX"/>, <xref linkend="RT_ST_ScaleY"/>, <xref linkend="RT_ST_SkewX"/>, <xref linkend="RT_ST_SkewY"/></para>
            </refsection>
        </refentry>


        <refentry xml:id="RT_ST_SetScale">
            <refnamediv>
                <refname>ST_SetScale</refname>
                <refpurpose>Sets the X and Y size of pixels in units of coordinate reference system. Number units/pixel width/height.</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                  <funcprototype>
                    <funcdef>raster <function>ST_SetScale</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    <paramdef><type>float8 </type> <parameter>xy</parameter></paramdef>
                  </funcprototype>

                  <funcprototype>
                    <funcdef>raster <function>ST_SetScale</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    <paramdef><type>float8 </type> <parameter>x</parameter></paramdef>
                    <paramdef><type>float8 </type> <parameter>y</parameter></paramdef>
                  </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>Sets the X and Y size of pixels in units of coordinate reference system. Number units/pixel width/height.  If
                only one unit passed in, assumed X and Y are the same number.</para>

                <note><para>ST_SetScale is different from <xref linkend="RT_ST_Rescale"/> in that ST_SetScale do not resample the raster to match the raster extent. It only changes the metadata (or georeference) of the raster to correct an originally mis-specified scaling. ST_Rescale results in a raster having different width and height computed to fit the geographic extent of the input raster. ST_SetScale do not modify the width, nor the height of the raster.</para></note>

                <para role="changed" conformance="2.0.0">Changed: 2.0.0 In WKTRaster versions this was called ST_SetPixelSize.  This was changed in 2.0.0.</para>
                </refsection>

                <refsection>
                    <title>Examples</title>

                    <programlisting language="sql">UPDATE dummy_rast
    SET rast = ST_SetScale(rast, 1.5)
WHERE rid = 2;

SELECT ST_ScaleX(rast) As pixx, ST_ScaleY(rast) As pixy, Box3D(rast) As newbox
FROM dummy_rast
WHERE rid = 2;</programlisting>
<screen role="text-primary"> pixx | pixy |                    newbox
------+------+----------------------------------------------
  1.5 |  1.5 | BOX(3427927.75 5793244 0, 3427935.25 5793251.5 0)</screen>
                <programlisting language="sql">UPDATE dummy_rast
    SET rast = ST_SetScale(rast, 1.5, 0.55)
WHERE rid = 2;

SELECT ST_ScaleX(rast) As pixx, ST_ScaleY(rast) As pixy, Box3D(rast) As newbox
FROM dummy_rast
WHERE rid = 2;</programlisting>
<screen role="text-primary"> pixx | pixy |                   newbox
------+------+--------------------------------------------
  1.5 | 0.55 | BOX(3427927.75 5793244 0,3427935.25 5793247 0)</screen>

            </refsection>

            <refsection>
                <title>See Also</title>
                <para><xref linkend="RT_ST_ScaleX"/>, <xref linkend="RT_ST_ScaleY"/>, <xref linkend="RT_Box3D"/></para>
            </refsection>
        </refentry>

        <refentry xml:id="RT_ST_SetSkew">
            <refnamediv>
                <refname>ST_SetSkew</refname>
                <refpurpose>Sets the georeference X and Y skew (or rotation parameter).  If only one is passed in, sets X and Y to the same value.</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                  <funcprototype>
                    <funcdef>raster <function>ST_SetSkew</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    <paramdef><type>float8 </type> <parameter>skewxy</parameter></paramdef>
                  </funcprototype>
                  <funcprototype>
                    <funcdef>raster <function>ST_SetSkew</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    <paramdef><type>float8 </type> <parameter>skewx</parameter></paramdef>
                    <paramdef><type>float8 </type> <parameter>skewy</parameter></paramdef>
                  </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>Sets the georeference X and Y skew (or rotation parameter).  If only one is passed in, sets X and Y to the same value.  Refer to <link xlink:href="http://en.wikipedia.org/wiki/World_file">World File</link>
                for more details.</para>
                </refsection>

                <refsection>
                    <title>Examples</title>

                    <para>This is the first example.</para>
                    <programlisting language="sql">UPDATE dummy_rast SET rast = ST_SetSkew(rast, 1, 2) WHERE rid = 1;
SELECT
    rid,
    format('(%s, %s)', skewx, skewy) AS skew,
    term,
    georef[idx] AS value
FROM (
    SELECT
        rid,
        ST_SkewX(rast) AS skewx,
        ST_SkewY(rast) AS skewy,
        string_to_array(ST_GeoReference(rast), E'\n') AS georef
    FROM dummy_rast
    WHERE rid = 1
) AS refs
CROSS JOIN (VALUES
    (1, 'scaleX'),
    (2, 'skewY'),
    (3, 'skewX'),
    (4, 'scaleY'),
    (5, 'originX'),
    (6, 'originY')
) AS parts(idx, term)
ORDER BY idx;</programlisting>
<screen role="text-primary"> rid |  skew  |  term   |    value
-----+--------+---------+--------------
   1 | (1, 2) | scaleX  | 2.0000000000
   1 | (1, 2) | skewY   | 2.0000000000
   1 | (1, 2) | skewX   | 1.0000000000
   1 | (1, 2) | scaleY  | 3.0000000000
   1 | (1, 2) | originX | 0.5000000000
   1 | (1, 2) | originY | 0.5000000000
(6 rows)</screen>

                <para>This second example sets both values to the same number.</para>
                <programlisting language="sql">UPDATE dummy_rast SET rast = ST_SetSkew(rast, 0) WHERE rid = 1;
SELECT
    rid,
    format('(%s, %s)', skewx, skewy) AS skew,
    term,
    georef[idx] AS value
FROM (
    SELECT
        rid,
        ST_SkewX(rast) AS skewx,
        ST_SkewY(rast) AS skewy,
        string_to_array(ST_GeoReference(rast), E'\n') AS georef
    FROM dummy_rast
    WHERE rid = 1
) AS refs
CROSS JOIN (VALUES
    (1, 'scaleX'),
    (2, 'skewY'),
    (3, 'skewX'),
    (4, 'scaleY'),
    (5, 'originX'),
    (6, 'originY')
) AS parts(idx, term)
ORDER BY idx;</programlisting>
<screen role="text-primary"> rid |  skew  |  term   |    value
-----+--------+---------+--------------
   1 | (0, 0) | scaleX  | 2.0000000000
   1 | (0, 0) | skewY   | 0.0000000000
   1 | (0, 0) | skewX   | 0.0000000000
   1 | (0, 0) | scaleY  | 3.0000000000
   1 | (0, 0) | originX | 0.5000000000
   1 | (0, 0) | originY | 0.5000000000
(6 rows)</screen>

            </refsection>

            <!-- Optionally add a "See Also" section -->
            <refsection>
                <title>See Also</title>
                <para><xref linkend="RT_ST_GeoReference"/>, <xref linkend="RT_ST_SetGeoReference"/>, <xref linkend="RT_ST_SkewX"/>, <xref linkend="RT_ST_SkewY"/></para>
            </refsection>
        </refentry>

        <refentry xml:id="RT_ST_SetSRID">
          <refnamediv>
            <refname>ST_SetSRID</refname>

            <refpurpose>Sets the SRID of a raster to a particular integer srid defined in the spatial_ref_sys table.</refpurpose>
          </refnamediv>

          <refsynopsisdiv>
            <funcsynopsis>
              <funcprototype>
                <funcdef>raster <function>ST_SetSRID</function></funcdef>

                <paramdef><type>raster </type>
                <parameter>rast</parameter></paramdef>

                <paramdef><type>integer </type>
                <parameter>srid</parameter></paramdef>
              </funcprototype>
            </funcsynopsis>
          </refsynopsisdiv>

          <refsection>
            <title>Description</title>

            <para>Sets the SRID on a raster to a particular integer value.</para>

            <note>
              <para>This function does not transform the raster in any way -
              it simply sets meta data defining the spatial ref of the coordinate reference system that it's currently in.
              Useful for transformations later.
              </para>
            </note>
          </refsection>

          <refsection>
            <title>See Also</title>

            <para><xref linkend="spatial_ref_sys"/>, <xref linkend="RT_ST_SRID"/></para>
          </refsection>

        </refentry>

        <refentry xml:id="RT_ST_SetUpperLeft">
            <refnamediv>
                <refname>ST_SetUpperLeft</refname>
                <refpurpose>Sets the value of the upper left corner of the pixel of the raster to projected X and Y coordinates.</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                  <funcprototype>
                    <funcdef>raster <function>ST_SetUpperLeft</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    <paramdef><type>double precision </type> <parameter>x</parameter></paramdef>
                    <paramdef><type>double precision </type> <parameter>y</parameter></paramdef>
                  </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>Set the value of the upper left corner of raster to the projected X and Y coordinates</para>
                </refsection>

                <refsection>
                    <title>Examples</title>

                    <programlisting language="sql">
SELECT ST_SetUpperLeft(rast, -71.01, 42.37)
FROM dummy_rast
WHERE rid = 2;
                    </programlisting>

            </refsection>

            <refsection>
                <title>See Also</title>
                <para><xref linkend="RT_ST_UpperLeftX"/>, <xref linkend="RT_ST_UpperLeftY"/></para>
            </refsection>
        </refentry>

        <refentry xml:id="RT_ST_Resample">
            <refnamediv>
                <refname>ST_Resample</refname>
                <refpurpose>
                    Resample a raster using a specified resampling algorithm, new dimensions, an arbitrary grid corner and a set of raster georeferencing attributes defined or borrowed from another raster.
                </refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                    <funcprototype>
                        <funcdef>raster <function>ST_Resample</function></funcdef>
                        <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                        <paramdef><type>integer </type> <parameter>width</parameter></paramdef>
                        <paramdef><type>integer </type> <parameter>height</parameter></paramdef>
                        <paramdef choice="opt"><type>double precision </type> <parameter>gridx=NULL</parameter></paramdef>
                        <paramdef choice="opt"><type>double precision </type> <parameter>gridy=NULL</parameter></paramdef>
                        <paramdef choice="opt"><type>double precision </type> <parameter>skewx=0</parameter></paramdef>
                        <paramdef choice="opt"><type>double precision </type> <parameter>skewy=0</parameter></paramdef>
                        <paramdef choice="opt"><type>text </type> <parameter>algorithm=NearestNeighbor</parameter></paramdef>
                        <paramdef choice="opt"><type>double precision </type> <parameter>maxerr=0.125</parameter></paramdef>
                    </funcprototype>

                    <funcprototype>
                        <funcdef>raster <function>ST_Resample</function></funcdef>
                        <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                        <paramdef choice="opt"><type>double precision </type> <parameter>scalex=0</parameter></paramdef>
                        <paramdef choice="opt"><type>double precision </type> <parameter>scaley=0</parameter></paramdef>
                        <paramdef choice="opt"><type>double precision </type> <parameter>gridx=NULL</parameter></paramdef>
                        <paramdef choice="opt"><type>double precision </type> <parameter>gridy=NULL</parameter></paramdef>
                        <paramdef choice="opt"><type>double precision </type> <parameter>skewx=0</parameter></paramdef>
                        <paramdef choice="opt"><type>double precision </type> <parameter>skewy=0</parameter></paramdef>
                        <paramdef choice="opt"><type>text </type> <parameter>algorithm=NearestNeighbor</parameter></paramdef>
                        <paramdef choice="opt"><type>double precision </type> <parameter>maxerr=0.125</parameter></paramdef>
                    </funcprototype>

                    <funcprototype>
                        <funcdef>raster <function>ST_Resample</function></funcdef>
                        <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                        <paramdef><type>raster </type> <parameter>ref</parameter></paramdef>
                        <paramdef choice="opt"><type>text </type> <parameter>algorithm=NearestNeighbor</parameter></paramdef>
                        <paramdef choice="opt"><type>double precision </type> <parameter>maxerr=0.125</parameter></paramdef>
                        <paramdef choice="opt"><type>boolean </type> <parameter>usescale=true</parameter></paramdef>
                    </funcprototype>

                    <funcprototype>
                        <funcdef>raster <function>ST_Resample</function></funcdef>
                        <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                        <paramdef><type>raster </type> <parameter>ref</parameter></paramdef>
                        <paramdef><type>boolean </type> <parameter>usescale</parameter></paramdef>
                        <paramdef choice="opt"><type>text </type> <parameter>algorithm=NearestNeighbor</parameter></paramdef>
                        <paramdef choice="opt"><type>double precision </type> <parameter>maxerr=0.125</parameter></paramdef>
                    </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>
                    Resample a raster using a specified resampling algorithm, new dimensions (width &amp; height), a grid corner (gridx &amp; gridy) and a set of raster georeferencing attributes (scalex, scaley, skewx &amp; skewy) defined or borrowed from another raster. If using a reference raster, the two rasters must have the same SRID.
                </para>

                <para>New pixel values are computed using one of the following resampling algorithms:</para>

                <para><itemizedlist mark="bullet">
                    <listitem><para>NearestNeighbor (english or american spelling)</para></listitem>
                    <listitem><para>Bilinear</para></listitem>
                    <listitem><para>Cubic</para></listitem>
                    <listitem><para>CubicSpline</para></listitem>
                    <listitem><para>Lanczos</para></listitem>
                    <listitem><para>Max</para></listitem>
                    <listitem><para>Min</para></listitem>
                </itemizedlist></para>

                <para>The default is NearestNeighbor which is the fastest but results in the worst interpolation.</para>
                <para>
                    A maxerror percent of 0.125 is used if no <varname>maxerr</varname> is specified.
                </para>

                <note>
                    <para>
                        Refer to: <link xlink:href="http://www.gdal.org/gdalwarp.html">GDAL Warp resampling methods</link> for more details.
                    </para>
                </note>
                <para role="availability" conformance="2.0.0">Availability: 2.0.0 Requires GDAL 1.6.1+</para>
                <para role="enhanced" conformance="3.4.0">Enhanced: 3.4.0 max and min resampling options added</para>
            </refsection>

            <refsection>
                <title>Examples</title>

                <programlisting language="sql">
SELECT
    ST_Width(orig) AS orig_width,
    ST_Width(reduce_100) AS new_width
FROM (
    SELECT
        rast AS orig,
        ST_Resample(rast, 100, 100) AS reduce_100
    FROM aerials.boston
    WHERE ST_Intersects(
        rast,
        ST_Transform(ST_MakeEnvelope(-71.128, 42.2392, -71.1277, 42.2397, 4326),
            26986)
    )
    LIMIT 1
) AS foo;</programlisting>
<screen role="text-primary"> orig_width | new_width
------------+-------------
        200 |         100</screen>
            </refsection>

            <refsection>
                <title>See Also</title>
                <para>
                    <xref linkend="RT_ST_Rescale"/>,
                    <xref linkend="RT_ST_Resize"/>,
                    <xref linkend="RT_ST_Transform"/>
                </para>
            </refsection>
        </refentry>

        <refentry xml:id="RT_ST_Rescale">
            <refnamediv>
                <refname>ST_Rescale</refname>
                <refpurpose>Resample a raster by adjusting only its scale (or pixel size). New pixel values are computed using the NearestNeighbor (english or american spelling), Bilinear, Cubic, CubicSpline, Lanczos, Max or Min resampling algorithm. Default is NearestNeighbor.
                    </refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                    <funcprototype>
                        <funcdef>raster <function>ST_Rescale</function></funcdef>
                        <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                        <paramdef><type>double precision </type> <parameter>scalexy</parameter></paramdef>
                        <paramdef choice="opt"><type>text </type> <parameter>algorithm=NearestNeighbor</parameter></paramdef>
                        <paramdef choice="opt"><type>double precision </type> <parameter>maxerr=0.125</parameter></paramdef>
                    </funcprototype>

                    <funcprototype>
                        <funcdef>raster <function>ST_Rescale</function></funcdef>
                        <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                        <paramdef><type>double precision </type> <parameter>scalex</parameter></paramdef>
                        <paramdef><type>double precision </type> <parameter>scaley</parameter></paramdef>
                        <paramdef choice="opt"><type>text </type> <parameter>algorithm=NearestNeighbor</parameter></paramdef>
                        <paramdef choice="opt"><type>double precision </type> <parameter>maxerr=0.125</parameter></paramdef>
                    </funcprototype>

                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>Resample a raster by adjusting only its scale (or pixel size). New pixel values are computed using one of the following resampling algorithms:</para>

                <para><itemizedlist mark="bullet">
                    <listitem><para>NearestNeighbor (english or american spelling)</para></listitem>
                    <listitem><para>Bilinear</para></listitem>
                    <listitem><para>Cubic</para></listitem>
                    <listitem><para>CubicSpline</para></listitem>
                    <listitem><para>Lanczos</para></listitem>
                    <listitem><para>Max</para></listitem>
                    <listitem><para>Min</para></listitem>
                </itemizedlist></para>

                <para>The default is NearestNeighbor which is the fastest but results in the worst interpolation.</para>

                <para><varname>scalex</varname> and <varname>scaley</varname> define the new pixel size. scaley must often be negative to get well oriented raster.</para>

                <para>When the new scalex or scaley is not a divisor of the raster width or height, the extent of the resulting raster is expanded to encompass the extent of the provided raster. If you want to be sure to retain exact input extent see <xref linkend="RT_ST_Resize"/></para>

                <para><varname>maxerr</varname> is the threshold for transformation approximation by the resampling algorithm (in pixel units). A default of 0.125 is used if no <varname>maxerr</varname> is specified, which is the same value used in GDAL gdalwarp utility. If set to zero, no approximation takes place.</para>

                <note><para>Refer to: <link xlink:href="http://www.gdal.org/gdalwarp.html">GDAL Warp resampling methods</link> for more details. </para></note>

                <note><para>ST_Rescale is different from <xref linkend="RT_ST_SetScale"/> in that ST_SetScale do not resample the raster to match the raster extent. ST_SetScale only changes the metadata (or georeference) of the raster to correct an originally mis-specified scaling. ST_Rescale results in a raster having different width and height computed to fit the geographic extent of the input raster. ST_SetScale do not modify the width, nor the height of the raster.</para></note>

                <para role="availability" conformance="2.0.0">Availability: 2.0.0  Requires GDAL 1.6.1+</para>
                <para role="enhanced" conformance="3.4.0">Enhanced: 3.4.0 max and min resampling options added</para>
                <para role="changed" conformance="2.1.0">Changed: 2.1.0 Works on rasters with no SRID</para>
            </refsection>

            <refsection>
                    <title>Examples</title>
                    <para>A simple example rescaling a raster from a pixel size of 0.001 degree to a pixel size of 0.0015 degree.</para>

                    <para>This example returns the original raster pixel size.</para>
                    <programlisting language="sql">SELECT ST_PixelWidth(ST_AddBand(ST_MakeEmptyRaster(100, 100, 0, 0, 0.001, -0.001, 0, 0, 4269), '8BUI'::text, 1, 0)) width</programlisting>
<screen role="text-primary">0.001</screen>
<para>This example returns the pixel size of the rescaled raster.</para>
<programlisting language="sql">SELECT ST_PixelWidth(ST_Rescale(ST_AddBand(ST_MakeEmptyRaster(100, 100, 0, 0, 0.001, -0.001, 0, 0, 4269), '8BUI'::text, 1, 0), 0.0015)) width</programlisting>
<screen role="text-primary">0.0015</screen>
            </refsection>

            <refsection>
                <title>See Also</title>
                <para>
                    <xref linkend="RT_ST_Resize"/>,
                    <xref linkend="RT_ST_Resample"/>,
                    <xref linkend="RT_ST_SetScale"/>,
                    <xref linkend="RT_ST_ScaleX"/>,
                    <xref linkend="RT_ST_ScaleY"/>,
                    <xref linkend="RT_ST_Transform"/>
                </para>
            </refsection>
        </refentry>

        <refentry xml:id="RT_ST_Reskew">
            <refnamediv>
                <refname>ST_Reskew</refname>
                <refpurpose>Resample a raster by adjusting only its skew (or rotation parameters). New pixel values are computed using the NearestNeighbor (english or american spelling), Bilinear, Cubic, CubicSpline or Lanczos resampling algorithm. Default is NearestNeighbor.
                    </refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                    <funcprototype>
                        <funcdef>raster <function>ST_Reskew</function></funcdef>
                        <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                        <paramdef><type>double precision </type> <parameter>skewxy</parameter></paramdef>
                        <paramdef choice="opt"><type>text </type> <parameter>algorithm=NearestNeighbor</parameter></paramdef>
                        <paramdef choice="opt"><type>double precision </type> <parameter>maxerr=0.125</parameter></paramdef>
                    </funcprototype>

                    <funcprototype>
                        <funcdef>raster <function>ST_Reskew</function></funcdef>
                        <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                        <paramdef><type>double precision </type> <parameter>skewx</parameter></paramdef>
                        <paramdef><type>double precision </type> <parameter>skewy</parameter></paramdef>
                        <paramdef choice="opt"><type>text </type> <parameter>algorithm=NearestNeighbor</parameter></paramdef>
                        <paramdef choice="opt"><type>double precision </type> <parameter>maxerr=0.125</parameter></paramdef>
                    </funcprototype>

                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>Resample a raster by adjusting only its skew (or rotation parameters). New pixel values are computed using the NearestNeighbor (english or american spelling), Bilinear, Cubic, CubicSpline or Lanczos resampling algorithm. The default is NearestNeighbor which is the fastest but results in the worst interpolation.</para>

                <para><varname>skewx</varname> and <varname>skewy</varname> define the new skew.</para>

                <para>The extent of the new raster will encompass the extent of the provided raster.</para>

                <para>A maxerror percent of 0.125 if no <varname>maxerr</varname> is specified.</para>

                <note><para>Refer to: <link xlink:href="http://www.gdal.org/gdalwarp.html">GDAL Warp resampling methods</link> for more details. </para></note>

                <note><para>ST_Reskew is different from <xref linkend="RT_ST_SetSkew"/> in that ST_SetSkew do not resample the raster to match the raster extent. ST_SetSkew only changes the metadata (or georeference) of the raster to correct an originally mis-specified skew. ST_Reskew results in a raster having different width and height computed to fit the geographic extent of the input raster. ST_SetSkew do not modify the width, nor the height of the raster.</para></note>

                <para role="availability" conformance="2.0.0">Availability: 2.0.0  Requires GDAL 1.6.1+</para>
                <para role="changed" conformance="2.1.0">Changed: 2.1.0 Works on rasters with no SRID</para>
            </refsection>

            <refsection>
                    <title>Examples</title>
                    <para>A simple example reskewing a raster from a skew of 0.0 to a skew of 0.0015.</para>

                    <para>This example uses the original non-rotated raster.</para>
                    <programlisting language="sql">
SELECT ST_Rotation(ST_AddBand(ST_MakeEmptyRaster(100, 100, 0, 0, 0.001, -0.001, 0, 0, 4269), '8BUI'::text, 1, 0));</programlisting>
<screen role="text-primary"> st_rotation
-------------
           0
(1 row)</screen>

<para>The reskewed raster rotation.</para>
<programlisting language="sql">SELECT ST_Rotation(ST_Reskew(ST_AddBand(ST_MakeEmptyRaster(100, 100, 0, 0, 0.001, -0.001, 0, 0, 4269), '8BUI'::text, 1, 0), 0.0015));</programlisting>
<screen role="text-primary">    st_rotation
------------------
 -0.982793723247329
(1 row)</screen>

            </refsection>

            <refsection>
                <title>See Also</title>
                <para><xref linkend="RT_ST_Resample"/>, <xref linkend="RT_ST_Rescale"/>, <xref linkend="RT_ST_SetSkew"/>, <xref linkend="RT_ST_SetRotation"/>, <xref linkend="RT_ST_SkewX"/>, <xref linkend="RT_ST_SkewY"/>, <xref linkend="RT_ST_Transform"/></para>
            </refsection>
        </refentry>

        <refentry xml:id="RT_ST_SnapToGrid">
            <refnamediv>
                <refname>ST_SnapToGrid</refname>
                <refpurpose>Resample a raster by snapping it to a grid. New pixel values are computed using the NearestNeighbor (english or american spelling), Bilinear, Cubic, CubicSpline or Lanczos resampling algorithm. Default is NearestNeighbor.
                    </refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                    <funcprototype>
                        <funcdef>raster <function>ST_SnapToGrid</function></funcdef>
                        <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                        <paramdef><type>double precision </type> <parameter>gridx</parameter></paramdef>
                        <paramdef><type>double precision </type> <parameter>gridy</parameter></paramdef>
                        <paramdef choice="opt"><type>text </type> <parameter>algorithm=NearestNeighbor</parameter></paramdef>
                        <paramdef choice="opt"><type>double precision </type> <parameter>maxerr=0.125</parameter></paramdef>
                        <paramdef choice="opt"><type>double precision </type> <parameter>scalex=DEFAULT 0</parameter></paramdef>
                        <paramdef choice="opt"><type>double precision </type> <parameter>scaley=DEFAULT 0</parameter></paramdef>
                    </funcprototype>

                    <funcprototype>
                        <funcdef>raster <function>ST_SnapToGrid</function></funcdef>
                        <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                        <paramdef><type>double precision </type> <parameter>gridx</parameter></paramdef>
                        <paramdef><type>double precision </type> <parameter>gridy</parameter></paramdef>
                        <paramdef><type>double precision </type> <parameter>scalex</parameter></paramdef>
                        <paramdef><type>double precision </type> <parameter>scaley</parameter></paramdef>
                        <paramdef choice="opt"><type>text </type> <parameter>algorithm=NearestNeighbor</parameter></paramdef>
                        <paramdef choice="opt"><type>double precision </type> <parameter>maxerr=0.125</parameter></paramdef>
                    </funcprototype>

                    <funcprototype>
                        <funcdef>raster <function>ST_SnapToGrid</function></funcdef>
                        <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                        <paramdef><type>double precision </type> <parameter>gridx</parameter></paramdef>
                        <paramdef><type>double precision </type> <parameter>gridy</parameter></paramdef>
                        <paramdef><type>double precision </type> <parameter>scalexy</parameter></paramdef>
                        <paramdef choice="opt"><type>text </type> <parameter>algorithm=NearestNeighbor</parameter></paramdef>
                        <paramdef choice="opt"><type>double precision </type> <parameter>maxerr=0.125</parameter></paramdef>
                    </funcprototype>

                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>Resample a raster by snapping it to a grid defined by an arbitrary pixel corner (gridx &amp; gridy) and optionally a pixel size (scalex &amp; scaley). New pixel values are computed using the NearestNeighbor (english or american spelling), Bilinear, Cubic, CubicSpline or Lanczos resampling algorithm. The default is NearestNeighbor which is the fastest but results in the worst interpolation.</para>

                <para><varname>gridx</varname> and <varname>gridy</varname> define any arbitrary pixel corner of the new grid. This is not necessarily the upper left corner of the new raster and it does not have to be inside or on the edge of the new raster extent.</para>

                <para>You can optionally define the pixel size of the new grid with <varname>scalex</varname> and <varname>scaley</varname>.</para>
                <para>The extent of the new raster will encompass the extent of the provided raster.</para>

                <para>A maxerror percent of 0.125 if no <varname>maxerr</varname> is specified.</para>

                <note><para>Refer to: <link xlink:href="http://www.gdal.org/gdalwarp.html">GDAL Warp resampling methods</link> for more details. </para></note>

                <note><para>Use <xref linkend="RT_ST_Resample"/> if you need more control over the grid parameters.</para></note>

                <para role="availability" conformance="2.0.0">Availability: 2.0.0  Requires GDAL 1.6.1+</para>
                <para role="changed" conformance="2.1.0">Changed: 2.1.0 Works on rasters with no SRID</para>
            </refsection>

            <refsection>
                    <title>Examples</title>
                    <para>A simple example snapping a raster to a slightly different grid.</para>

                    <para>This example returns the upper-left X coordinate of the original raster.</para>
                    <programlisting language="sql">
SELECT ST_UpperLeftX(ST_AddBand(ST_MakeEmptyRaster(10, 10, 0, 0, 0.001, -0.001, 0, 0, 4269), '8BUI'::text, 1, 0));</programlisting>
<screen role="text-primary"> st_upperleftx
---------------
             0
(1 row)</screen>

                    <para>The upper left of raster after snapping.</para>
                    <programlisting language="sql">SELECT ST_UpperLeftX(ST_SnapToGrid(ST_AddBand(ST_MakeEmptyRaster(10, 10, 0, 0, 0.001, -0.001, 0, 0, 4269), '8BUI'::text, 1, 0), 0.0002, 0.0002));</programlisting>
<screen role="text-primary"> st_upperleftx
---------------
       -0.0008
(1 row)</screen>

            </refsection>

            <refsection>
                <title>See Also</title>
                <para><xref linkend="RT_ST_Resample"/>, <xref linkend="RT_ST_Rescale"/>, <xref linkend="RT_ST_UpperLeftX"/>, <xref linkend="RT_ST_UpperLeftY"/></para>
            </refsection>
        </refentry>

        <refentry xml:id="RT_ST_Resize">
            <refnamediv>
                <refname>ST_Resize</refname>
                <refpurpose>Resize a raster to a new width/height</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                  <funcprototype>
                        <funcdef>raster <function>ST_Resize</function></funcdef>
                        <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                        <paramdef><type>integer </type> <parameter>width</parameter></paramdef>
                        <paramdef><type>integer </type> <parameter>height</parameter></paramdef>
                        <paramdef choice="opt"><type>text </type> <parameter>algorithm=NearestNeighbor</parameter></paramdef>
                        <paramdef choice="opt"><type>double precision </type> <parameter>maxerr=0.125</parameter></paramdef>
                  </funcprototype>

                  <funcprototype>
                        <funcdef>raster <function>ST_Resize</function></funcdef>
                        <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                        <paramdef><type>double precision </type> <parameter>percentwidth</parameter></paramdef>
                        <paramdef><type>double precision </type> <parameter>percentheight</parameter></paramdef>
                        <paramdef choice="opt"><type>text </type> <parameter>algorithm=NearestNeighbor</parameter></paramdef>
                        <paramdef choice="opt"><type>double precision </type> <parameter>maxerr=0.125</parameter></paramdef>
                  </funcprototype>

                  <funcprototype>
                        <funcdef>raster <function>ST_Resize</function></funcdef>
                        <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                        <paramdef><type>text </type> <parameter>width</parameter></paramdef>
                        <paramdef><type>text </type> <parameter>height</parameter></paramdef>
                        <paramdef choice="opt"><type>text </type> <parameter>algorithm=NearestNeighbor</parameter></paramdef>
                        <paramdef choice="opt"><type>double precision </type> <parameter>maxerr=0.125</parameter></paramdef>
                  </funcprototype>

                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>
                    Resize a raster to a new width/height. The new width/height can be specified in exact number of pixels or a percentage of the raster's width/height. The extent of the the new raster will be the same as the extent of the provided raster.
                </para>

                <para>
                    New pixel values are computed using the NearestNeighbor (english or american spelling), Bilinear, Cubic, CubicSpline or Lanczos resampling algorithm. The default is NearestNeighbor which is the fastest but results in the worst interpolation.
                </para>

                <para>
                    Variant 1 expects the actual width/height of the output raster.
                </para>

                <para>
                    Variant 2 expects decimal values between zero (0) and one (1) indicating the percentage of the input raster's width/height.
                </para>

                <para>
                    Variant 3 takes either the actual width/height of the output raster or a textual percentage ("20%") indicating the percentage of the input raster's width/height.
                </para>

                <para role="availability" conformance="2.1.0">Availability: 2.1.0  Requires GDAL 1.6.1+</para>
            </refsection>
            <refsection>
                <title>Examples</title>
                <programlisting language="sql">
WITH foo AS(
SELECT
    1 AS rid,
    ST_Resize(ST_AddBand(ST_MakeEmptyRaster(1000, 1000, 0, 0, 1, -1, 0, 0, 0),
            1, '8BUI', 255, 0
        ),
    '50%', '500') AS rast
UNION ALL
SELECT
    2 AS rid,
    ST_Resize(ST_AddBand(ST_MakeEmptyRaster(1000, 1000, 0, 0, 1, -1, 0, 0, 0),
            1, '8BUI', 255, 0
        ),
    500, 100) AS rast
UNION ALL
SELECT
    3 AS rid,
    ST_Resize(ST_AddBand(ST_MakeEmptyRaster(1000, 1000, 0, 0, 1, -1, 0, 0, 0),
            1, '8BUI', 255, 0
        ),
    0.25, 0.9) AS rast
)
SELECT
    rid,
    ST_Width(rast) AS width,
    ST_Height(rast) AS height,
    ST_ScaleX(rast) AS scale_x,
    round(ST_ScaleY(rast)::numeric, 4) AS scale_y
FROM foo
ORDER BY rid</programlisting>
<screen role="text-primary"> rid | width | height | scale_x | scale_y
-----+-------+--------+---------+---------
   1 |   500 |    500 |       2 | -2.0000
   2 |   500 |    100 |       2 | -10.0000
   3 |   250 |    900 |       4 | -1.1111
(3 rows)</screen>
            </refsection>

            <refsection>
                <title>See Also</title>
                <para>
                    <xref linkend="RT_ST_Resample"/>,
                    <xref linkend="RT_ST_Rescale"/>,
                    <xref linkend="RT_ST_Reskew"/>,
                    <xref linkend="RT_ST_SnapToGrid"/>
                </para>
            </refsection>
        </refentry>

        <refentry xml:id="RT_ST_Transform">
            <refnamediv>
                <refname>ST_Transform</refname>
                <refpurpose>Reprojects a raster in a known spatial reference system to another known spatial reference system using specified resampling algorithm. Options are NearestNeighbor, Bilinear, Cubic, CubicSpline, Lanczos defaulting to NearestNeighbor.</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                  <funcprototype>
                    <funcdef>raster <function>ST_Transform</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    <paramdef><type>integer </type> <parameter>srid</parameter></paramdef>
                    <paramdef choice="opt"><type>text </type> <parameter>algorithm=NearestNeighbor</parameter></paramdef>
                    <paramdef choice="opt"><type>double precision </type> <parameter>maxerr=0.125</parameter></paramdef>
                    <paramdef choice="opt"><type>double precision </type> <parameter>scalex</parameter></paramdef>
                    <paramdef choice="opt"><type>double precision </type> <parameter>scaley</parameter></paramdef>
                  </funcprototype>

                  <funcprototype>
                    <funcdef>raster <function>ST_Transform</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    <paramdef><type>integer </type> <parameter>srid</parameter></paramdef>
                    <paramdef><type>double precision </type> <parameter>scalex</parameter></paramdef>
                    <paramdef><type>double precision </type> <parameter>scaley</parameter></paramdef>
                    <paramdef choice="opt"><type>text </type> <parameter>algorithm=NearestNeighbor</parameter></paramdef>
                    <paramdef choice="opt"><type>double precision </type> <parameter>maxerr=0.125</parameter></paramdef>
                  </funcprototype>

                  <funcprototype>
                    <funcdef>raster <function>ST_Transform</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    <paramdef><type>raster </type> <parameter>alignto</parameter></paramdef>
                    <paramdef choice="opt"><type>text </type> <parameter>algorithm=NearestNeighbor</parameter></paramdef>
                    <paramdef choice="opt"><type>double precision </type> <parameter>maxerr=0.125</parameter></paramdef>
                  </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>Reprojects a raster in a known spatial reference system to another known spatial reference system using specified pixel warping algorithm.
                    Uses 'NearestNeighbor' if no algorithm is specified and maxerror percent of 0.125 if no maxerr is specified.</para>
                <para>Algorithm options are: 'NearestNeighbor', 'Bilinear', 'Cubic', 'CubicSpline', and 'Lanczos'.  Refer to: <link xlink:href="http://www.gdal.org/gdalwarp.html">GDAL Warp resampling methods</link> for more details.</para>

                <para>
                    ST_Transform is often confused with ST_SetSRID(). ST_Transform actually changes the coordinates of a raster (and resamples the pixel values) from one spatial reference system to another, while ST_SetSRID() simply changes the SRID identifier of the raster.
                </para>

                <para>
                    Unlike the other variants, Variant 3 requires a reference raster as <varname>alignto</varname>. The transformed raster will be transformed to the spatial reference system (SRID) of the reference raster and be aligned (ST_SameAlignment = TRUE) to the reference raster.
                </para>

                <note>
                    <para>
                        If you find your transformation support is not working right, you may need to set the environment variable PROJSO to the projection library your PostGIS build is using.  This just needs to have the name of the file. So for example on windows, you would in Control Panel -&gt; System -&gt; Environment Variables add a system variable called <varname>PROJSO</varname> and set it to <varname>libproj.dll</varname>.  You'll have to restart your PostgreSQL service/daemon after this change.
                    </para>
                </note>

                <warning>
                    <para>
                        When transforming a coverage of tiles, you almost always want to use a reference raster to insure same alignment and no gaps in your tiles as demonstrated in example: Variant 3.
                    </para>
                </warning>

                <para role="availability" conformance="2.0.0">Availability: 2.0.0  Requires GDAL 1.6.1+</para>
                <para role="enhanced" conformance="2.1.0">Enhanced: 2.1.0 Addition of ST_Transform(rast, alignto) variant</para>
            </refsection>

            <refsection>
                    <title>Examples</title>

                    <para>Compare a source raster with nearest-neighbor and
                    bilinear reprojections. The diagonal bands make the
                    resampling behavior visible: nearest-neighbor keeps hard
                    pixel steps, while bilinear smooths values between pixels.
                    All three figures are generated from this query at manual
                    build time.</para>
                    <programlisting language="sql">WITH rows AS (
    SELECT
        y,
        array_agg(
            ((
                    x * 3 + y * 5
                    + CASE WHEN (x + y) % 8 &lt; 4 THEN 80 ELSE 0 END
                ) % 255)::double precision
            ORDER BY x
        ) AS row_values
    FROM generate_series(1, 80) AS y
    CROSS JOIN generate_series(1, 80) AS x
    GROUP BY y
), source AS (
    SELECT ST_SetValues(
        ST_AddBand(
            ST_MakeEmptyRaster(
                80, 80,
                -500000, 600000,
                2500, -2500,
                0, 0,
                2163
            ),
            1, '8BUI', 0, NULL
        ),
        1, 1, 1,
        array_agg(row_values ORDER BY y)::double precision[][]
    ) AS rast
    FROM rows
), transformed AS (
    SELECT
        rast,
        ST_Transform(rast, 4326, 'NearestNeighbor') AS nearest,
        ST_Transform(rast, 4326, 'Bilinear') AS bilinear
    FROM source
)
SELECT
    ST_AsPNG(rast) AS "source (EPSG:2163)",
    ST_AsPNG(nearest) AS "nearest (EPSG:4326)",
    ST_AsPNG(bilinear) AS "bilinear (EPSG:4326)"
FROM transformed;</programlisting>
                    <screen role="visual-primary">PNG image, 80 x 80 pixels | PNG image, 98 x 64 pixels | PNG image, 98 x 64 pixels</screen>
                    <para>Raster reprojection and resampling.</para>
<informaltable>
                      <tgroup cols="3">
                        <tbody>
                          <row>
                            <entry><para><informalfigure>
                                <mediaobject>
                                  <imageobject><imagedata fileref="images/rt_st_transform01.png"/></imageobject>
                                  <caption><para>Massachusetts State Plane source</para></caption>
                                </mediaobject>
                              </informalfigure></para></entry>
                            <entry><para><informalfigure>
                                <mediaobject>
                                  <imageobject><imagedata fileref="images/rt_st_transform02.png"/></imageobject>
                                  <caption><para>WGS 84 nearest-neighbor</para></caption>
                                </mediaobject>
                              </informalfigure></para></entry>
                            <entry><para><informalfigure>
                                <mediaobject>
                                  <imageobject><imagedata fileref="images/rt_st_transform03.png"/></imageobject>
                                  <caption><para>WGS 84 bilinear</para></caption>
                                </mediaobject>
                              </informalfigure></para></entry>
                          </row>
                        </tbody>
                      </tgroup>
                    </informaltable>

                <para>Variant 3.</para>

                <para>The following shows the difference between using ST_Transform(raster, srid) and ST_Transform(raster, alignto)</para>
<programlisting language="sql">
WITH foo AS (
    SELECT 0 AS rid, ST_AddBand(ST_MakeEmptyRaster(2, 2, -500000, 600000, 100, -100, 0, 0, 2163), 1, '16BUI', 1, 0) AS rast UNION ALL
    SELECT 1, ST_AddBand(ST_MakeEmptyRaster(2, 2, -499800, 600000, 100, -100, 0, 0, 2163), 1, '16BUI', 2, 0) AS rast UNION ALL
    SELECT 2, ST_AddBand(ST_MakeEmptyRaster(2, 2, -499600, 600000, 100, -100, 0, 0, 2163), 1, '16BUI', 3, 0) AS rast UNION ALL

    SELECT 3, ST_AddBand(ST_MakeEmptyRaster(2, 2, -500000, 599800, 100, -100, 0, 0, 2163), 1, '16BUI', 10, 0) AS rast UNION ALL
    SELECT 4, ST_AddBand(ST_MakeEmptyRaster(2, 2, -499800, 599800, 100, -100, 0, 0, 2163), 1, '16BUI', 20, 0) AS rast UNION ALL
    SELECT 5, ST_AddBand(ST_MakeEmptyRaster(2, 2, -499600, 599800, 100, -100, 0, 0, 2163), 1, '16BUI', 30, 0) AS rast UNION ALL

    SELECT 6, ST_AddBand(ST_MakeEmptyRaster(2, 2, -500000, 599600, 100, -100, 0, 0, 2163), 1, '16BUI', 100, 0) AS rast UNION ALL
    SELECT 7, ST_AddBand(ST_MakeEmptyRaster(2, 2, -499800, 599600, 100, -100, 0, 0, 2163), 1, '16BUI', 200, 0) AS rast UNION ALL
    SELECT 8, ST_AddBand(ST_MakeEmptyRaster(2, 2, -499600, 599600, 100, -100, 0, 0, 2163), 1, '16BUI', 300, 0) AS rast
), bar AS (
    SELECT
        ST_Transform(rast, 4269) AS alignto
    FROM foo
    LIMIT 1
), baz AS (
    SELECT
        rid,
        rast,
        ST_Transform(rast, 4269) AS not_aligned,
        ST_Transform(rast, alignto) AS aligned
    FROM foo
    CROSS JOIN bar
)
SELECT
    ST_Collect(ST_ConvexHull(not_aligned) ORDER BY rid) AS not_aligned,
    ST_Collect(ST_ConvexHull(aligned) ORDER BY rid) AS aligned
FROM baz</programlisting>
<screen role="visual-separate-output visual-primary text-primary">MULTIPOLYGON(((-107.007 50.2,-107.005 50.2,-107.005 50.198,-107.007 50.198,-107.007 50.2)),((-107.004 50.201,-107.002 50.201,-107.002 50.198,-107.004 50.198,-107.004 50.201)),((-107.001 50.201,-106.999 50.201,-106.999 50.198,-107.001 50.198,-107.001 50.201)),((-107.007 50.199,-107.004 50.199,-107.004 50.196,-107.007 50.196,-107.007 50.199)),((-107.004 50.199,-107.001 50.199,-107.001 50.196,-107.004 50.196,-107.004 50.199)),((-107.001 50.199,-106.999 50.199,-106.999 50.196,-107.001 50.196,-107.001 50.199)),((-107.006 50.197,-107.004 50.197,-107.004 50.194,-107.006 50.194,-107.006 50.197)),((-107.004 50.197,-107.001 50.197,-107.001 50.194,-107.004 50.194,-107.004 50.197)),((-107.001 50.197,-106.998 50.197,-106.998 50.195,-107.001 50.195,-107.001 50.197))) | MULTIPOLYGON(((-107.007 50.2,-107.005 50.2,-107.005 50.198,-107.007 50.198,-107.007 50.2)),((-107.005 50.202,-107.001 50.202,-107.001 50.198,-107.005 50.198,-107.005 50.202)),((-107.002 50.202,-106.998 50.202,-106.998 50.198,-107.002 50.198,-107.002 50.202)),((-107.007 50.199,-107.003 50.199,-107.003 50.195,-107.007 50.195,-107.007 50.199)),((-107.005 50.199,-107.001 50.199,-107.001 50.195,-107.005 50.195,-107.005 50.199)),((-107.002 50.199,-106.998 50.199,-106.998 50.195,-107.002 50.195,-107.002 50.199)),((-107.007 50.198,-107.003 50.198,-107.003 50.194,-107.007 50.194,-107.007 50.198)),((-107.005 50.198,-107.001 50.198,-107.001 50.194,-107.005 50.194,-107.005 50.198)),((-107.002 50.198,-106.998 50.198,-106.998 50.194,-107.002 50.194,-107.002 50.198)))</screen>
            </refsection>

            <refsection>
                <title>See Also</title>
                <para><xref linkend="ST_Transform"/>, <xref linkend="RT_ST_SetSRID"/></para>
            </refsection>
        </refentry>

    </section>
    <section xml:id="RasterBand_Editors">
        <title>Raster Band Editors</title>

        <refentry xml:id="RT_ST_SetBandNoDataValue">
            <refnamediv>
                <refname>ST_SetBandNoDataValue</refname>
                <refpurpose>Sets the value for the given band that represents no data. Band 1 is assumed if no band is specified.  To mark a band as having no nodata value, set the nodata value = NULL.</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                 <funcprototype>
                    <funcdef>raster <function>ST_SetBandNoDataValue</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    <paramdef><type>double precision </type> <parameter>nodatavalue</parameter></paramdef>
                  </funcprototype>

                  <funcprototype>
                    <funcdef>raster <function>ST_SetBandNoDataValue</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    <paramdef><type>integer </type> <parameter>band</parameter></paramdef>
                    <paramdef><type>double precision </type> <parameter>nodatavalue</parameter></paramdef>
                    <paramdef choice="opt"><type>boolean </type> <parameter>forcechecking=false</parameter></paramdef>
                  </funcprototype>

                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>Sets the value that represents no data for the band.  Band 1 is assumed if not specified. This will affect results from <xref linkend="RT_ST_Polygon"/>, <xref linkend="RT_ST_DumpAsPolygons"/>, and the ST_PixelAs...() functions.</para>
                </refsection>

                <refsection>
                    <title>Examples</title>

                    <para>This example changes only the first band NODATA value.</para>
                    <programlisting language="sql">
UPDATE dummy_rast
    SET rast = ST_SetBandNoDataValue(rast, 1, 254)
WHERE rid = 2;</programlisting>

                    <para>This example changes the NODATA value for bands 1, 2, and 3.</para>
                    <programlisting language="sql">
UPDATE dummy_rast
    SET rast =
        ST_SetBandNoDataValue(ST_SetBandNoDataValue(ST_SetBandNoDataValue(rast, 1, 254),
                2, 99),
                3, 108)
        WHERE rid = 2;</programlisting>

                    <para>This example removes the NODATA value so that all pixels are considered by processing functions.</para>
                    <programlisting language="sql">
UPDATE dummy_rast
    SET rast = ST_SetBandNoDataValue(rast, 1, NULL)
WHERE rid = 2;
                    </programlisting>

            </refsection>

            <refsection>
                <title>See Also</title>
                <para><xref linkend="RT_ST_BandNoDataValue"/>, <xref linkend="RT_ST_NumBands"/></para>
            </refsection>
        </refentry>

        <refentry xml:id="RT_ST_SetBandIsNoData">
            <refnamediv>
                <refname>ST_SetBandIsNoData</refname>
                <refpurpose>Sets the isnodata flag of the band to TRUE.</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                 <funcprototype>
                    <funcdef>raster <function>ST_SetBandIsNoData</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    <paramdef choice="opt"><type>integer </type> <parameter>band=1</parameter></paramdef>
                  </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>Sets the isnodata flag for the band to true. Band 1 is
                assumed if not specified. This function should be called only
                when the flag is considered dirty. That is, when the result
                calling <xref linkend="RT_ST_BandIsNoData"/> is different using
                TRUE as last argument and without using it</para>

                <para role="availability" conformance="2.0.0">Availability: 2.0.0</para>
                </refsection>

                <refsection>
                    <title>Examples</title>

                    <para>This example creates a dummy table with one raster
                    column. The raster has two bands and one pixel per band. In
                    the first band, the NODATA value and pixel value are both 3.
                    In the second band, the NODATA value is 13 and the pixel
                    value is 4.</para>
                    <programlisting language="sql">
create table dummy_rast (rid integer, rast raster);

insert into dummy_rast values(
1,
(
'01' -- little endian (uint8 ndr)
||
'0000' -- version (uint16 0)
||
'0200' -- nBands (uint16 0)
||
'17263529ED684A3F' -- scaleX (float64 0.000805965234044584)
||
'F9253529ED684ABF' -- scaleY (float64 -0.00080596523404458)
||
'1C9F33CE69E352C0' -- ipX (float64 -75.5533328537098)
||
'718F0E9A27A44840' -- ipY (float64 49.2824585505576)
||
'ED50EB853EC32B3F' -- skewX (float64 0.000211812383858707)
||
'7550EB853EC32B3F' -- skewY (float64 0.000211812383858704)
||
'E6100000' -- SRID (int32 4326)
||
'0100' -- width (uint16 1)
||
'0100' -- height (uint16 1)
||
'4' -- hasnodatavalue set to true, isnodata value set to false (when it should be true)
||
'2' -- first band type (4BUI)
||
'03' -- novalue==3
||
'03' -- pixel(0,0)==3 (same that nodata)
||
'0' -- hasnodatavalue set to false
||
'5' -- second band type (16BSI)
||
'0D00' -- novalue==13
||
'0400' -- pixel(0,0)==4
)::raster
);

select ST_BandIsNoData(rast, 1) from dummy_rast where rid = 1; -- Expected false
select ST_BandIsNoData(rast, 1, TRUE) from dummy_rast where rid = 1; -- Expected true
                    </programlisting>

                    <para>The <varname>isnodata</varname> flag is dirty, so set
                    it to true.</para>
                    <programlisting language="sql">
update dummy_rast set rast = ST_SetBandIsNoData(rast, 1) where rid = 1;


select ST_BandIsNoData(rast, 1) from dummy_rast where rid = 1; -- Expected true

                    </programlisting>

            </refsection>

            <refsection>
                <title>See Also</title>
                <para><xref linkend="RT_ST_BandNoDataValue"/>, <xref linkend="RT_ST_NumBands"/>, <xref linkend="RT_ST_SetBandNoDataValue"/>, <xref linkend="RT_ST_BandIsNoData"/></para>
            </refsection>
        </refentry>

        <refentry xml:id="RT_ST_SetBandPath">
            <refnamediv>
                <refname>ST_SetBandPath</refname>
                <refpurpose>Update the external path and band number of an out-db band</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                  <funcprototype>
                        <funcdef>raster <function>ST_SetBandPath</function></funcdef>
                        <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                        <paramdef><type>integer </type> <parameter>band</parameter></paramdef>
                        <paramdef><type>text </type> <parameter>outdbpath</parameter></paramdef>
                        <paramdef><type>integer </type> <parameter>outdbindex</parameter></paramdef>
                        <paramdef choice="opt"><type>boolean </type> <parameter>force=false</parameter></paramdef>
                  </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>Updates an out-db band's external raster file path and external band number.</para>

                <note>
                    <para>
                        If <varname>force</varname> is set to true, no tests are done to ensure compatibility (e.g. alignment, pixel support) between the external raster file and the PostGIS raster. This mode is intended for file system changes where the external raster resides.
                    </para>
                </note>

                <para role="availability" conformance="2.5.0">Availability: 2.5.0</para>
            </refsection>

            <refsection>
                <title>Examples</title>
                <programlisting language="sql">
WITH foo AS (
    SELECT ST_AddBand(
        NULL::raster,
        '/home/pele/devel/geo/postgis-git/raster/test/regress/loader/Projected.tif',
        NULL::int[]
    ) AS rast
)
SELECT
    1 AS query,
    bandnum,
    regexp_replace(path, '^.*/', '') AS path,
    outdbbandnum
FROM ST_BandMetaData(
    (SELECT rast FROM foo),
    ARRAY[1, 3, 2]::int[]
) AS metadata
UNION ALL
SELECT
    2, bandnum,
    regexp_replace(path, '^.*/', ''),
    outdbbandnum
FROM ST_BandMetaData((
        SELECT
            ST_SetBandPath(rast,
                2,
                '/home/pele/devel/geo/postgis-git/raster/test/regress/loader/Projected2.tif',
                1
            ) AS rast
        FROM foo
    ),
    ARRAY[1, 3, 2]::int[]
) AS metadata
ORDER BY 1, 2;</programlisting>
                <para>In the second result set, band 2 now points at <literal>Projected2.tif</literal> and uses out-db band 1.</para>
<screen role="text-primary"> query | bandnum | path           | outdbbandnum
-------+---------+----------------+--------------
     1 |       1 | Projected.tif  |            1
     1 |       2 | Projected.tif  |            2
     1 |       3 | Projected.tif  |            3
     2 |       1 | Projected.tif  |            1
     2 |       2 | Projected2.tif |            1
     2 |       3 | Projected.tif  |            3</screen>
            </refsection>

            <refsection>
                <title>See Also</title>
                <para>
                    <xref linkend="RT_ST_BandMetaData"/>,
                    <xref linkend="RT_ST_SetBandIndex"/>
                </para>
            </refsection>

        </refentry>

        <refentry xml:id="RT_ST_SetBandIndex">
            <refnamediv>
                <refname>ST_SetBandIndex</refname>
                <refpurpose>Update the external band number of an out-db band</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                  <funcprototype>
                        <funcdef>raster <function>ST_SetBandIndex</function></funcdef>
                        <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                        <paramdef><type>integer </type> <parameter>band</parameter></paramdef>
                        <paramdef><type>integer </type> <parameter>outdbindex</parameter></paramdef>
                        <paramdef choice="opt"><type>boolean </type> <parameter>force=false</parameter></paramdef>
                  </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>Updates an out-db band's external band number. This does not touch the external raster file associated with the out-db band</para>

                <note>
                    <para>
                        If <varname>force</varname> is set to true, no tests are done to ensure compatibility (e.g. alignment, pixel support) between the external raster file and the PostGIS raster. This mode is intended for where bands are moved around in the external raster file.
                    </para>
                </note>

                <note>
                    <para>
                        Internally, this method replaces the PostGIS raster's band at index <varname>band</varname> with a new band instead of updating the existing path information.
                    </para>
                </note>

                <para role="availability" conformance="2.5.0">Availability: 2.5.0</para>
            </refsection>

            <refsection>
                <title>Examples</title>
                <programlisting language="sql">
WITH foo AS (
    SELECT ST_AddBand(
        NULL::raster,
        '/home/pele/devel/geo/postgis-git/raster/test/regress/loader/Projected.tif',
        NULL::int[]
    ) AS rast
)
SELECT
    1 AS query,
    bandnum,
    regexp_replace(path, '^.*/', '') AS path,
    outdbbandnum
FROM ST_BandMetaData(
    (SELECT rast FROM foo),
    ARRAY[1, 3, 2]::int[]
) AS metadata
UNION ALL
SELECT
    2, bandnum,
    regexp_replace(path, '^.*/', ''),
    outdbbandnum
FROM ST_BandMetaData((
        SELECT
            ST_SetBandIndex(rast,
                2,
                1
            ) AS rast
        FROM foo
    ),
    ARRAY[1, 3, 2]::int[]
) AS metadata
ORDER BY 1, 2;</programlisting>
                <para>In the second result set, band 2 still points at the same file but now reads external band 1.</para>
<screen role="text-primary"> query | bandnum | path          | outdbbandnum
-------+---------+---------------+--------------
     1 |       1 | Projected.tif |            1
     1 |       2 | Projected.tif |            2
     1 |       3 | Projected.tif |            3
     2 |       1 | Projected.tif |            1
     2 |       2 | Projected.tif |            1
     2 |       3 | Projected.tif |            3</screen>
            </refsection>

            <refsection>
                <title>See Also</title>
                <para>
                    <xref linkend="RT_ST_BandMetaData"/>,
                    <xref linkend="RT_ST_SetBandPath"/>
                </para>
            </refsection>

        </refentry>

    </section>

    <section xml:id="RasterBand_Stats">
        <title>Raster Band Statistics and Analytics</title>

        <refentry xml:id="RT_ST_Count">
            <refnamediv>
                <refname>ST_Count</refname>
                <refpurpose>Returns the number of pixels in a given band of a raster or raster coverage.  If no band is specified defaults to band 1.  If exclude_nodata_value is set to true, will only count pixels that are not equal to the nodata value.</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                  <funcprototype>
                    <funcdef>bigint <function>ST_Count</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    <paramdef choice="opt"><type>integer </type> <parameter>nband=1</parameter></paramdef>
                    <paramdef choice="opt"><type>boolean </type> <parameter>exclude_nodata_value=true</parameter></paramdef>
                  </funcprototype>
                  <funcprototype>
                    <funcdef>bigint <function>ST_Count</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    <paramdef><type>boolean </type> <parameter>exclude_nodata_value</parameter></paramdef>
                  </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>Returns the number of pixels in a given band of a raster or raster coverage.  If no band is specified <varname>nband</varname> defaults to 1. </para>
                <note><para>If <varname>exclude_nodata_value</varname> is set to true, will only count pixels with value not equal to the <varname>nodata</varname> value of the raster. Set <varname>exclude_nodata_value</varname> to false to get count all pixels</para></note>
                <para role="changed" conformance="3.1.0">Changed: 3.1.0 - The ST_Count(rastertable, rastercolumn, ...) variants removed. Use <xref linkend="RT_ST_CountAgg"/> instead.</para>
                <para role="availability" conformance="2.0.0">Availability: 2.0.0 </para>
            </refsection>

            <refsection>
                <title>Examples</title>
                <!-- TODO: Fix once we confirm the right behavior -->
                <para>Example will count all pixels not 249 and one will count all pixels.</para>
                <programlisting language="sql">
SELECT rid, ST_Count(ST_SetBandNoDataValue(rast, 249)) As exclude_nodata,
        ST_Count(ST_SetBandNoDataValue(rast, 249), false) As include_nodata
    FROM dummy_rast WHERE rid=2;</programlisting>
<screen role="text-primary">rid | exclude_nodata | include_nodata
-----+----------------+----------------
   2 |             23 |             25</screen>
            </refsection>

            <refsection>
                <title>See Also</title>
                <para>
                    <xref linkend="RT_ST_CountAgg"/>,
                    <xref linkend="RT_ST_SummaryStats"/>,
                    <xref linkend="RT_ST_SetBandNoDataValue"/>
                </para>
            </refsection>
        </refentry>

      <refentry xml:id="RT_ST_CountAgg">
            <refnamediv>
                <refname>ST_CountAgg</refname>
                <refpurpose>
                    Aggregate. Returns the number of pixels in a given band of a set of rasters. If no band is specified defaults to band 1. If exclude_nodata_value is set to true, will only count pixels that are not equal to the NODATA value.
                </refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                    <funcprototype>
                        <funcdef>bigint <function>ST_CountAgg</function></funcdef>
                        <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                        <paramdef><type>integer </type> <parameter>nband</parameter></paramdef>
                        <paramdef><type>boolean </type> <parameter>exclude_nodata_value</parameter></paramdef>
                        <paramdef><type>double precision </type> <parameter>sample_percent</parameter></paramdef>
                    </funcprototype>

                    <funcprototype>
                        <funcdef>bigint <function>ST_CountAgg</function></funcdef>
                        <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                        <paramdef><type>integer </type> <parameter>nband</parameter></paramdef>
                        <paramdef><type>boolean </type> <parameter>exclude_nodata_value</parameter></paramdef>
                    </funcprototype>

                    <funcprototype>
                        <funcdef>bigint <function>ST_CountAgg</function></funcdef>
                        <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                        <paramdef><type>boolean </type> <parameter>exclude_nodata_value</parameter></paramdef>
                    </funcprototype>

                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>Returns the number of pixels in a given band of a set of rasters.  If no band is specified <varname>nband</varname> defaults to 1.</para>
                <para>
                    If <varname>exclude_nodata_value</varname> is set to true, will only count pixels with value not equal to the <varname>NODATA</varname> value of the raster. Set <varname>exclude_nodata_value</varname> to false to get count all pixels
                </para>
                <para>By default will sample all pixels. To get faster response, set <varname>sample_percent</varname> to value between zero (0) and one (1)</para>

                <para role="availability" conformance="2.2.0">Availability: 2.2.0 </para>
            </refsection>

            <refsection>
                <title>Examples</title>
                <programlisting language="sql">
WITH foo AS (
    SELECT
        rast.rast
    FROM (
        SELECT ST_SetValue(ST_SetValue(ST_SetValue(ST_AddBand(ST_MakeEmptyRaster(10, 10, 10, 10, 2, 2, 0, 0, 0),
                        1, '64BF', 0, 0
                    ),
                    1, 1, 1, -10
                ),
                1, 5, 4, 0
            ),
            1, 5, 5, 3.14159
        ) AS rast
    ) AS rast
    FULL JOIN (
        SELECT generate_series(1, 10) AS id
    ) AS id
        ON 1 = 1
)
SELECT
    ST_CountAgg(rast, 1, TRUE) AS non_nodata_pixels
FROM foo;</programlisting>
<screen role="text-primary"> non_nodata_pixels
-------------------
                20
(1 row)</screen>
            </refsection>

            <refsection>
                <title>See Also</title>
                <para>
                    <xref linkend="RT_ST_Count"/>,
                    <xref linkend="RT_ST_SummaryStats"/>,
                    <xref linkend="RT_ST_SetBandNoDataValue"/>
                </para>
            </refsection>
        </refentry>

        <refentry xml:id="RT_ST_Histogram">
            <refnamediv>
                <refname>ST_Histogram</refname>
                <refpurpose>Returns a set of record summarizing a raster or raster coverage data distribution separate bin ranges. Number of bins are autocomputed if not specified.</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                  <funcprototype>
                    <funcdef>SETOF record <function>ST_Histogram</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    <paramdef choice="opt"><type>integer </type> <parameter>nband=1</parameter></paramdef>
                    <paramdef choice="opt"><type>boolean </type> <parameter>exclude_nodata_value=true</parameter></paramdef>
                    <paramdef choice="opt"><type>integer </type> <parameter>bins=autocomputed</parameter></paramdef>
                    <paramdef choice="opt"><type>double precision[] </type> <parameter>width=NULL</parameter></paramdef>
                    <paramdef choice="opt"><type>boolean </type> <parameter>right=false</parameter></paramdef>
                  </funcprototype>

                  <funcprototype>
                    <funcdef>SETOF record <function>ST_Histogram</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    <paramdef><type>integer </type> <parameter>nband</parameter></paramdef>
                    <paramdef><type>integer </type> <parameter>bins</parameter></paramdef>
                    <paramdef choice="opt"><type>double precision[] </type> <parameter>width=NULL</parameter></paramdef>
                    <paramdef choice="opt"><type>boolean </type> <parameter>right=false</parameter></paramdef>
                  </funcprototype>

                  <funcprototype>
                    <funcdef>SETOF record <function>ST_Histogram</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    <paramdef><type>integer </type> <parameter>nband</parameter></paramdef>
                    <paramdef><type>boolean </type> <parameter>exclude_nodata_value</parameter></paramdef>
                    <paramdef><type>integer </type> <parameter>bins</parameter></paramdef>
                    <paramdef><type>boolean </type> <parameter>right</parameter></paramdef>
                  </funcprototype>

                  <funcprototype>
                    <funcdef>SETOF record <function>ST_Histogram</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    <paramdef><type>integer </type> <parameter>nband</parameter></paramdef>
                    <paramdef><type>integer </type> <parameter>bins</parameter></paramdef>
                    <paramdef><type>boolean </type> <parameter>right</parameter></paramdef>
                  </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>Returns set of records consisting of min, max, count, percent for a given raster band for each bin. If no band is specified <varname>nband</varname> defaults to 1. </para>
                <note><para>By default only considers pixel values not equal to the <varname>nodata</varname> value . Set <varname>exclude_nodata_value</varname> to false to get count all pixels.</para></note>

                <variablelist>
                    <varlistentry>
                        <term><varname>width</varname></term>
                        <listitem><para>width: an array indicating the width of each category/bin. If the number of bins is greater than the number of widths, the widths are repeated. </para>
                        <para>Example: 9 bins, widths are [a, b, c] will have the output be [a, b, c, a, b, c, a, b, c]</para></listitem>
                    </varlistentry>
                    <varlistentry>
                        <term><varname>bins</varname></term>
                        <listitem><para>Number of breakouts -- this is the number of records you'll get back from the function if specified. If not specified
                            then the number of breakouts is autocomputed.</para></listitem>
                    </varlistentry>
                    <varlistentry>
                        <term><varname>right</varname></term>
                        <listitem><para>compute the histogram from the right rather than from the left (default). This changes the criteria for evaluating a value x from [a, b) to (a, b]</para></listitem>
                    </varlistentry>
                </variablelist>
                <para role="changed" conformance="3.1.0">Changed: 3.1.0 Removed ST_Histogram(table_name, column_name) variant. </para>
                <para role="availability" conformance="2.0.0">Availability: 2.0.0 </para>
            </refsection>

            <refsection>
                <title>Examples</title>
                <para>Single raster tile - compute histograms for bands 1, 2, 3 and autocompute bins.</para>
                <programlisting language="sql">SELECT band, (stats).*
FROM (SELECT rid, band, ST_Histogram(rast, band) As stats
    FROM dummy_rast CROSS JOIN generate_series(1, 3) As band
     WHERE rid=2) As foo;</programlisting>
<screen role="text-primary"> band |  min  |  max  | count | percent
------+-------+-------+-------+---------
    1 |   249 |   250 |     2 |    0.08
    1 |   250 |   251 |     2 |    0.08
    1 |   251 |   252 |     1 |    0.04
    1 |   252 |   253 |     2 |    0.08
    1 |   253 |   254 |    18 |    0.72
    2 |    78 | 113.2 |    11 |    0.44
    2 | 113.2 | 148.4 |     4 |    0.16
    2 | 148.4 | 183.6 |     4 |    0.16
    2 | 183.6 | 218.8 |     1 |    0.04
    2 | 218.8 |   254 |     5 |     0.2
    3 |    62 | 100.4 |    11 |    0.44
    3 | 100.4 | 138.8 |     5 |     0.2
    3 | 138.8 | 177.2 |     4 |    0.16
    3 | 177.2 | 215.6 |     1 |    0.04
    3 | 215.6 |   254 |     4 |    0.16</screen>

                <para>Just band 2 but for 6 bins.</para>
                <programlisting language="sql">SELECT (stats).*
FROM (SELECT rid, ST_Histogram(rast, 2, 6) As stats
    FROM dummy_rast
     WHERE rid=2) As foo;</programlisting>
<screen role="text-primary">    min     |    max     | count | percent
------------+------------+-------+---------
         78 | 107.333333 |     9 |    0.36
 107.333333 | 136.666667 |     6 |    0.24
 136.666667 |        166 |     0 |       0
        166 | 195.333333 |     4 |    0.16
 195.333333 | 224.666667 |     1 |    0.04
 224.666667 |        254 |     5 |     0.2
(6 rows)</screen>
<para>Same as previous but we explicitly control the pixel value range of each bin.</para>
<programlisting language="sql">
SELECT (stats).*
FROM (SELECT rid, ST_Histogram(rast, 2, 6, ARRAY[0.5, 1, 4, 100, 5]) As stats
    FROM dummy_rast
     WHERE rid=2) As foo;</programlisting>
<screen role="text-primary">  min  |  max  | count | percent
-------+-------+-------+----------
    78 |  78.5 |     1 |     0.08
  78.5 |  79.5 |     1 |     0.04
  79.5 |  83.5 |     0 |        0
  83.5 | 183.5 |    17 |   0.0068
 183.5 | 188.5 |     0 |        0
 188.5 |   254 |     6 | 0.003664
(6 rows)</screen>
            </refsection>

            <refsection>
                <title>See Also</title>
                <para>
                    <xref linkend="RT_ST_Count"/>,
                    <xref linkend="RT_ST_SummaryStats"/>,
                    <xref linkend="RT_ST_SummaryStatsAgg"/>
                </para>
            </refsection>
        </refentry>

        <refentry xml:id="RT_ST_Quantile">
            <refnamediv>
                <refname>ST_Quantile</refname>
                <refpurpose>Compute quantiles for a raster or raster table coverage in the context of the sample or population. Thus, a value could be examined to be at the raster's 25%, 50%, 75% percentile.</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                  <funcprototype>
                    <funcdef>SETOF record <function>ST_Quantile</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    <paramdef choice="opt"><type>integer </type> <parameter>nband=1</parameter></paramdef>
                    <paramdef choice="opt"><type>boolean </type> <parameter>exclude_nodata_value=true</parameter></paramdef>
                    <paramdef choice="opt"><type>double precision[] </type> <parameter>quantiles=NULL</parameter></paramdef>
                  </funcprototype>
                  <funcprototype>
                    <funcdef>SETOF record <function>ST_Quantile</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    <paramdef><type>double precision[] </type> <parameter>quantiles</parameter></paramdef>
                  </funcprototype>
                  <funcprototype>
                    <funcdef>SETOF record <function>ST_Quantile</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    <paramdef><type>integer </type> <parameter>nband</parameter></paramdef>
                    <paramdef><type>double precision[] </type> <parameter>quantiles</parameter></paramdef>
                  </funcprototype>
                  <funcprototype>
                    <funcdef>double precision <function>ST_Quantile</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    <paramdef><type>double precision </type> <parameter>quantile</parameter></paramdef>
                  </funcprototype>
                  <funcprototype>
                    <funcdef>double precision <function>ST_Quantile</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    <paramdef><type>boolean </type> <parameter>exclude_nodata_value</parameter></paramdef>
                    <paramdef choice="opt"><type>double precision </type> <parameter>quantile=NULL</parameter></paramdef>
                  </funcprototype>
                  <funcprototype>
                    <funcdef>double precision <function>ST_Quantile</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    <paramdef><type>integer </type> <parameter>nband</parameter></paramdef>
                    <paramdef><type>double precision </type> <parameter>quantile</parameter></paramdef>
                  </funcprototype>
                  <funcprototype>
                    <funcdef>double precision <function>ST_Quantile</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    <paramdef><type>integer </type> <parameter>nband</parameter></paramdef>
                    <paramdef><type>boolean </type> <parameter>exclude_nodata_value</parameter></paramdef>
                    <paramdef><type>double precision </type> <parameter>quantile</parameter></paramdef>
                  </funcprototype>
                  <funcprototype>
                    <funcdef>double precision <function>ST_Quantile</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    <paramdef><type>integer </type> <parameter>nband</parameter></paramdef>
                    <paramdef><type>double precision </type> <parameter>quantile</parameter></paramdef>
                  </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>Compute quantiles for a raster or raster table coverage in the context of the sample or population. Thus, a value could be examined to be at the raster's 25%, 50%, 75% percentile.</para>
                <note><para>If <varname>exclude_nodata_value</varname> is set to false, will also count pixels with no data.</para></note>
                <para role="changed" conformance="3.1.0">Changed: 3.1.0 Removed ST_Quantile(table_name, column_name) variant. </para>
                <para role="availability" conformance="2.0.0">Availability: 2.0.0 </para>
            </refsection>

            <refsection>
                <title>Examples</title>

                <para>Example will consider only pixels of band 1 that are not 249 and in named quantiles.</para>
                <programlisting language="sql">UPDATE dummy_rast SET rast = ST_SetBandNoDataValue(rast, 249) WHERE rid=2;

SELECT (pvq).*
FROM (SELECT ST_Quantile(rast, ARRAY[0.25, 0.75]) As pvq
    FROM dummy_rast WHERE rid=2) As foo
    ORDER BY (pvq).quantile;</programlisting>
<screen role="text-primary"> quantile | value
----------+-------
     0.25 |   253
     0.75 |   254</screen>
<programlisting language="sql">SELECT ST_Quantile(rast, 0.75) As value
FROM dummy_rast WHERE rid=2;</programlisting>
<screen role="text-primary">254</screen>
<para>Real live example. Quantile of all pixels in band 2 intersecting a geometry.</para>
<programlisting language="sql">
SELECT rid, (ST_Quantile(rast, 2)).* As pvc
    FROM o_4_boston
        WHERE ST_Intersects(
            rast,
            ST_GeomFromText('POLYGON((224486 892151,224486 892200,224706 892200,224706 892151,224486 892151))', 26986)
            )
ORDER BY value, quantile, rid
;</programlisting>
<screen role="text-primary"> rid | quantile | value
-----+----------+-------
   1 |        0 |     0
   2 |        0 |     0
  14 |        0 |     1
  15 |        0 |     2
  14 |     0.25 |    37
   1 |     0.25 |    42
  15 |     0.25 |    47
   2 |     0.25 |    50
  14 |      0.5 |    56
   1 |      0.5 |    64
  15 |      0.5 |    66
   2 |      0.5 |    77
  14 |     0.75 |    81
  15 |     0.75 |    87
   1 |     0.75 |    94
   2 |     0.75 |   106
  14 |        1 |   199
   1 |        1 |   244
   2 |        1 |   255
  15 |        1 |   255</screen>
            </refsection>

            <refsection>
                <title>See Also</title>
                <para>
                    <xref linkend="RT_ST_Count"/>,
                    <xref linkend="RT_ST_SummaryStats"/>,
                    <xref linkend="RT_ST_SummaryStatsAgg"/>,
                    <xref linkend="RT_ST_SetBandNoDataValue"/>
                </para>
            </refsection>
        </refentry>

        <refentry xml:id="RT_ST_SummaryStats">
            <refnamediv>
                <refname>ST_SummaryStats</refname>
                <refpurpose>Returns summarystats consisting of count, sum, mean, stddev, min, max for a given raster band of a raster or raster coverage. Band 1 is assumed if no band is specified.</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                  <funcprototype>
                    <funcdef>summarystats <function>ST_SummaryStats</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    <paramdef><type>boolean </type> <parameter>exclude_nodata_value</parameter></paramdef>
                  </funcprototype>

                 <funcprototype>
                    <funcdef>summarystats <function>ST_SummaryStats</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    <paramdef><type>integer </type> <parameter>nband</parameter></paramdef>
                    <paramdef><type>boolean </type> <parameter>exclude_nodata_value</parameter></paramdef>
                  </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>Returns <xref linkend="summarystats"/> consisting of count, sum, mean, stddev, min, max for a given raster band of a raster or raster coverage.  If no band is specified <varname>nband</varname> defaults to 1.</para>

                <note><para>By default only considers pixel values not equal to the <varname>nodata</varname> value. Set <varname>exclude_nodata_value</varname> to false to get count of all pixels.</para></note>

                <note><para>By default will sample all pixels. To get faster response, set <varname>sample_percent</varname> to lower than 1</para></note>

                <para role="changed" conformance="3.1.0">Changed: 3.1.0 ST_SummaryStats(rastertable, rastercolumn, ...) variants are removed. Use <xref linkend="RT_ST_SummaryStatsAgg"/> instead. </para>
                <para role="availability" conformance="2.0.0">Availability: 2.0.0 </para>

            </refsection>

            <refsection>
                <title>Examples</title>
                <para>Single raster tile.</para>
                <programlisting language="sql">
SELECT rid, band, (stats).*
FROM (SELECT rid, band, ST_SummaryStats(rast, band) As stats
    FROM dummy_rast CROSS JOIN generate_series(1, 3) As band
     WHERE rid=2) As foo;</programlisting>
<screen role="text-primary"> rid | band | count | sum  |    mean    |  stddev   | min | max
-----+------+-------+------+------------+-----------+-----+-----
   2 |    1 |    23 | 5821 | 253.086957 |  1.248061 | 250 | 254
   2 |    2 |    25 | 3682 |     147.28 | 59.862188 |  78 | 254
   2 |    3 |    25 | 3290 |      131.6 | 61.647384 |  62 | 254</screen>

                <para>Summarize pixels that intersect buildings of interest.</para>
                <para>This example selects the target buildings, clips band 2 of
                the raster tiles to each building boundary, computes statistics
                for each clipped region, and then summarizes those statistics by
                building. It took 574ms on PostGIS Windows 64-bit with all of
                Boston Buildings and aerial Tiles (tiles each 150x150 pixels
                ~ 134,000 tiles), ~102,000 building records.</para>
                <programlisting language="sql"><![CDATA[WITH
-- our features of interest
feat AS (
    SELECT gid AS building_id, geom_26986 AS geom
    FROM buildings AS b
    WHERE gid IN (100, 103, 150)
),
-- clip band 2 of raster tiles to boundaries of builds
-- then get stats for these clipped regions
b_stats AS (
    SELECT building_id, (stats).*
    FROM (
        SELECT
            building_id,
            ST_SummaryStats(ST_Clip(rast, 2, geom)) AS stats
        FROM aerials.boston
        INNER JOIN feat
            ON ST_Intersects(feat.geom, rast)
    ) AS foo
)
-- finally summarize stats
SELECT
    building_id,
    SUM(count) AS num_pixels,
    MIN(min) AS min_pval,
    MAX(max) AS max_pval,
    SUM(mean * count) / SUM(count) AS avg_pval
FROM b_stats
WHERE count > 0
GROUP BY building_id
ORDER BY building_id;]]></programlisting>
<screen role="text-primary"> building_id | num_pixels | min_pval | max_pval |     avg_pval
-------------+------------+----------+----------+------------------
        100 |       1090 |        1 |      255 | 61.0697247706422
        103 |        655 |        7 |      182 | 70.5038167938931
        150 |        895 |        2 |      252 | 185.642458100559
</screen>

                <para>Raster coverage.</para>
                <para>This example returns statistics for each band.</para>
                <programlisting language="sql">
SELECT band, (stats).*
FROM (SELECT band, ST_SummaryStats('o_4_boston', 'rast', band) As stats
    FROM generate_series(1, 3) As band) As foo;</programlisting>
<screen role="text-primary"> band |  count  |  sum   |       mean       |      stddev      | min | max
------+---------+--------+------------------+------------------+-----+-----
    1 | 8450000 | 725799 | 82.7064349112426 | 45.6800222638537 |   0 | 255
    2 | 8450000 | 700487 | 81.4197705325444 | 44.2161184161765 |   0 | 255
    3 | 8450000 | 575943 |  74.682739408284 | 44.2143885481407 |   0 | 255</screen>
<para>For a table, sampling less than 100% can improve speed. Here the
sampling is set to 25%.</para>
<programlisting language="sql">
SELECT band, (stats).*
FROM (SELECT band, ST_SummaryStats('o_4_boston', 'rast', band, true, 0.25) As stats
    FROM generate_series(1, 3) As band) As foo;</programlisting>
<screen role="text-primary"> band |  count  |  sum   |       mean       |      stddev      | min | max
------+---------+--------+------------------+------------------+-----+-----
    1 | 2112500 | 180686 | 82.6890480473373 | 45.6961043857248 |   0 | 255
    2 | 2112500 | 174571 |  81.448503668639 | 44.2252623171821 |   0 | 255
    3 | 2112500 | 144364 | 74.6765884023669 | 44.2014869384578 |   0 | 255
                </screen>
            </refsection>

            <refsection>
                <title>See Also</title>
                <para>
                    <xref linkend="summarystats"/>,
                    <xref linkend="RT_ST_SummaryStatsAgg"/>,
                    <xref linkend="RT_ST_Count"/>,
                    <xref linkend="RT_ST_Clip"/>
                </para>
            </refsection>
        </refentry>

        <refentry xml:id="RT_ST_SummaryStatsAgg">
            <refnamediv>
                <refname>ST_SummaryStatsAgg</refname>
                <refpurpose>Aggregate. Returns summarystats consisting of count, sum, mean, stddev, min, max for a given raster band of a set of raster. Band 1 is assumed if no band is specified.</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                    <funcprototype>
                        <funcdef>summarystats <function>ST_SummaryStatsAgg</function></funcdef>
                        <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                        <paramdef><type>integer </type> <parameter>nband</parameter></paramdef>
                        <paramdef><type>boolean </type> <parameter>exclude_nodata_value</parameter></paramdef>
                        <paramdef><type>double precision </type> <parameter>sample_percent</parameter></paramdef>
                    </funcprototype>

                    <funcprototype>
                        <funcdef>summarystats <function>ST_SummaryStatsAgg</function></funcdef>
                        <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                        <paramdef><type>boolean </type> <parameter>exclude_nodata_value</parameter></paramdef>
                        <paramdef><type>double precision </type> <parameter>sample_percent</parameter></paramdef>
                    </funcprototype>

                    <funcprototype>
                        <funcdef>summarystats <function>ST_SummaryStatsAgg</function></funcdef>
                        <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                        <paramdef><type>integer </type> <parameter>nband</parameter></paramdef>
                        <paramdef><type>boolean </type> <parameter>exclude_nodata_value</parameter></paramdef>
                    </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>Returns <xref linkend="summarystats"/> consisting of count, sum, mean, stddev, min, max for a given raster band of a raster or raster coverage.  If no band is specified <varname>nband</varname> defaults to 1.</para>

                <note><para>By default only considers pixel values not equal to the <varname>NODATA</varname> value. Set <varname>exclude_nodata_value</varname> to False to get count of all pixels.</para></note>

                <note><para>By default will sample all pixels. To get faster response, set <varname>sample_percent</varname> to value between 0 and 1</para></note>

                <para role="availability" conformance="2.2.0">Availability: 2.2.0 </para>
            </refsection>

            <refsection>
                <title>Examples</title>
                <programlisting language="sql">
WITH foo AS (
    SELECT
        rast.rast
    FROM (
        SELECT ST_SetValue(ST_SetValue(ST_SetValue(ST_AddBand(ST_MakeEmptyRaster(10, 10, 10, 10, 2, 2, 0, 0, 0),
                        1, '64BF', 0, 0
                    ),
                    1, 1, 1, -10
                ),
                1, 5, 4, 0
            ),
            1, 5, 5, 3.14159
        ) AS rast
    ) AS rast
    FULL JOIN (
        SELECT generate_series(1, 10) AS id
    ) AS id
        ON 1 = 1
)
SELECT
    (stats).count AS count,
    round((stats).sum::numeric, 3) AS sum,
    round((stats).mean::numeric, 3) AS mean,
    round((stats).stddev::numeric, 3) AS stddev,
    round((stats).min::numeric, 3) AS min,
    round((stats).max::numeric, 3) AS max
FROM (
    SELECT
        ST_SummaryStatsAgg(rast, 1, TRUE, 1) AS stats
    FROM foo
) bar;</programlisting>
<screen role="text-primary"> count |   sum   |  mean  | stddev |   min   |  max
-------+---------+--------+--------+---------+-------
    20 | -68.584 | -3.429 |  6.571 | -10.000 | 3.142
(1 row)</screen>
            </refsection>

            <refsection>
                <title>See Also</title>
                <para>
                    <xref linkend="summarystats"/>,
                    <xref linkend="RT_ST_SummaryStats"/>,
                    <xref linkend="RT_ST_Count"/>,
                    <xref linkend="RT_ST_Clip"/>
                </para>
            </refsection>
        </refentry>

        <refentry xml:id="RT_ST_ValueCount">
            <refnamediv>
                <refname>ST_ValueCount</refname>
                <refpurpose>Returns a set of records containing a pixel band value  and count of the number of pixels in a given band of a raster (or a raster coverage) that have a given set of values.  If no band is specified defaults to band 1.  By default nodata value pixels are not counted.
                    and all other values in the pixel are output and pixel band values are rounded to the nearest integer.</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                  <funcprototype>
                    <funcdef>SETOF record <function>ST_ValueCount</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    <paramdef choice="opt"><type>integer </type> <parameter>nband=1</parameter></paramdef>
                    <paramdef choice="opt"><type>boolean </type> <parameter>exclude_nodata_value=true</parameter></paramdef>
                    <paramdef choice="opt"><type>double precision[] </type> <parameter>searchvalues=NULL</parameter></paramdef>
                    <paramdef choice="opt"><type>double precision </type> <parameter>roundto=0</parameter></paramdef>
                    <paramdef><type>double precision </type> <parameter>OUT value</parameter></paramdef>
                    <paramdef><type>integer </type> <parameter>OUT count</parameter></paramdef>
                  </funcprototype>
                  <funcprototype>
                    <funcdef>SETOF record <function>ST_ValueCount</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    <paramdef><type>integer </type> <parameter>nband</parameter></paramdef>
                    <paramdef><type>double precision[] </type> <parameter>searchvalues</parameter></paramdef>
                    <paramdef choice="opt"><type>double precision </type> <parameter>roundto=0</parameter></paramdef>
                    <paramdef><type>double precision </type> <parameter>OUT value</parameter></paramdef>
                    <paramdef><type>integer </type> <parameter>OUT count</parameter></paramdef>
                  </funcprototype>
                  <funcprototype>
                    <funcdef>SETOF record <function>ST_ValueCount</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    <paramdef><type>double precision[] </type> <parameter>searchvalues</parameter></paramdef>
                    <paramdef choice="opt"><type>double precision </type> <parameter>roundto=0</parameter></paramdef>
                    <paramdef><type>double precision </type> <parameter>OUT value</parameter></paramdef>
                    <paramdef><type>integer </type> <parameter>OUT count</parameter></paramdef>
                  </funcprototype>

                  <funcprototype>
                    <funcdef>bigint <function>ST_ValueCount</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    <paramdef><type>double precision </type> <parameter>searchvalue</parameter></paramdef>
                    <paramdef choice="opt"><type>double precision </type> <parameter>roundto=0</parameter></paramdef>
                  </funcprototype>

                  <funcprototype>
                    <funcdef>bigint <function>ST_ValueCount</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    <paramdef><type>integer </type> <parameter>nband</parameter></paramdef>
                    <paramdef><type>boolean </type> <parameter>exclude_nodata_value</parameter></paramdef>
                    <paramdef><type>double precision </type> <parameter>searchvalue</parameter></paramdef>
                    <paramdef choice="opt"><type>double precision </type> <parameter>roundto=0</parameter></paramdef>
                  </funcprototype>

                  <funcprototype>
                    <funcdef>bigint <function>ST_ValueCount</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    <paramdef><type>integer </type> <parameter>nband</parameter></paramdef>
                    <paramdef><type>double precision </type> <parameter>searchvalue</parameter></paramdef>
                    <paramdef choice="opt"><type>double precision </type> <parameter>roundto=0</parameter></paramdef>
                  </funcprototype>

                  <funcprototype>
                    <funcdef>SETOF record <function>ST_ValueCount</function></funcdef>
                    <paramdef><type>text </type> <parameter>rastertable</parameter></paramdef>
                    <paramdef><type>text </type> <parameter>rastercolumn</parameter></paramdef>
                    <paramdef choice="opt"><type>integer </type> <parameter>nband=1</parameter></paramdef>
                    <paramdef choice="opt"><type>boolean </type> <parameter>exclude_nodata_value=true</parameter></paramdef>
                    <paramdef choice="opt"><type>double precision[] </type> <parameter>searchvalues=NULL</parameter></paramdef>
                    <paramdef choice="opt"><type>double precision </type> <parameter>roundto=0</parameter></paramdef>
                    <paramdef><type>double precision </type> <parameter>OUT value</parameter></paramdef>
                    <paramdef><type>integer </type> <parameter>OUT count</parameter></paramdef>
                  </funcprototype>
                  <funcprototype>
                    <funcdef>SETOF record <function>ST_ValueCount</function></funcdef>
                    <paramdef><type>text </type> <parameter>rastertable</parameter></paramdef>
                    <paramdef><type>text </type> <parameter>rastercolumn</parameter></paramdef>
                    <paramdef><type>double precision[] </type> <parameter>searchvalues</parameter></paramdef>
                    <paramdef choice="opt"><type>double precision </type> <parameter>roundto=0</parameter></paramdef>
                    <paramdef><type>double precision </type> <parameter>OUT value</parameter></paramdef>
                    <paramdef><type>integer </type> <parameter>OUT count</parameter></paramdef>
                  </funcprototype>
                  <funcprototype>
                    <funcdef>SETOF record <function>ST_ValueCount</function></funcdef>
                    <paramdef><type>text </type> <parameter>rastertable</parameter></paramdef>
                    <paramdef><type>text </type> <parameter>rastercolumn</parameter></paramdef>
                    <paramdef><type>integer </type> <parameter>nband</parameter></paramdef>
                    <paramdef><type>double precision[] </type> <parameter>searchvalues</parameter></paramdef>
                    <paramdef choice="opt"><type>double precision </type> <parameter>roundto=0</parameter></paramdef>
                    <paramdef><type>double precision </type> <parameter>OUT value</parameter></paramdef>
                    <paramdef><type>integer </type> <parameter>OUT count</parameter></paramdef>
                  </funcprototype>
                  <funcprototype>
                    <funcdef>bigint<function>ST_ValueCount</function></funcdef>
                    <paramdef><type>text </type> <parameter>rastertable</parameter></paramdef>
                    <paramdef><type>text </type> <parameter>rastercolumn</parameter></paramdef>
                    <paramdef><type>integer </type> <parameter>nband</parameter></paramdef>
                    <paramdef><type>boolean </type> <parameter>exclude_nodata_value</parameter></paramdef>
                    <paramdef><type>double precision </type> <parameter>searchvalue</parameter></paramdef>
                    <paramdef choice="opt"><type>double precision </type> <parameter>roundto=0</parameter></paramdef>
                  </funcprototype>
                  <funcprototype>
                    <funcdef>bigint <function>ST_ValueCount</function></funcdef>
                    <paramdef><type>text </type> <parameter>rastertable</parameter></paramdef>
                    <paramdef><type>text </type> <parameter>rastercolumn</parameter></paramdef>
                    <paramdef><type>double precision </type> <parameter>searchvalue</parameter></paramdef>
                    <paramdef choice="opt"><type>double precision </type> <parameter>roundto=0</parameter></paramdef>
                  </funcprototype>
                  <funcprototype>
                    <funcdef>bigint <function>ST_ValueCount</function></funcdef>
                    <paramdef><type>text </type> <parameter>rastertable</parameter></paramdef>
                    <paramdef><type>text </type> <parameter>rastercolumn</parameter></paramdef>
                    <paramdef><type>integer </type> <parameter>nband</parameter></paramdef>
                    <paramdef><type>double precision </type> <parameter>searchvalue</parameter></paramdef>
                    <paramdef choice="opt"><type>double precision </type> <parameter>roundto=0</parameter></paramdef>
                  </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>Returns a set of records with columns <varname>value</varname>  <varname>count</varname> which contain the pixel band value and count of pixels in the raster tile or raster coverage of selected band. </para>
                <para>If no band is specified <varname>nband</varname> defaults to 1. If no <varname>searchvalues</varname> are specified, will return all pixel values found in the raster or raster coverage.  If one searchvalue is given, will return an integer instead of records denoting the count of pixels having that pixel band value</para>
                <note><para>If <varname>exclude_nodata_value</varname> is set to false, will also count pixels with no data.</para></note>
                <para role="availability" conformance="2.0.0">Availability: 2.0.0 </para>
            </refsection>

            <refsection>
                <title>Examples</title>

                <para>Example will count only pixels of band 1 that are not 249.</para>
                <programlisting language="sql">UPDATE dummy_rast SET rast = ST_SetBandNoDataValue(rast, 249) WHERE rid=2;

SELECT (pvc).*
FROM (SELECT ST_ValueCount(rast) As pvc
    FROM dummy_rast WHERE rid=2) As foo
    ORDER BY (pvc).value;</programlisting>
<screen role="text-primary"> value | count
-------+-------
   250 |     2
   251 |     1
   252 |     2
   253 |     6
   254 |    12</screen>
<para>Example will coount all pixels of band 1 including 249.</para>
<programlisting language="sql">
SELECT (pvc).*
FROM (SELECT ST_ValueCount(rast, 1, false) As pvc
    FROM dummy_rast WHERE rid=2) As foo
    ORDER BY (pvc).value;</programlisting>
<screen role="text-primary"> value | count
-------+-------
   249 |     2
   250 |     2
   251 |     1
   252 |     2
   253 |     6
   254 |    12</screen>
<para>Example will count only non-nodata value pixels of band 2.</para>
<programlisting language="sql">
SELECT (pvc).*
FROM (SELECT ST_ValueCount(rast, 2) As pvc
    FROM dummy_rast WHERE rid=2) As foo
    ORDER BY (pvc).value;</programlisting>
<screen role="text-primary"> value | count
-------+-------
    78 |     1
    79 |     1
    88 |     1
    89 |     1
    96 |     1
    97 |     1
    98 |     1
    99 |     2
   112 |     2
:

                </screen>
<para>Real live example. Count all the pixels in an aerial raster tile band 2 intersecting a geometry. And return only the pixel band values that have a count &gt; 500.</para>
<programlisting language="sql">
SELECT (pvc).value, SUM((pvc).count) As total
FROM (SELECT ST_ValueCount(rast, 2) As pvc
    FROM o_4_boston
        WHERE ST_Intersects(
            rast,
            ST_GeomFromText('POLYGON((224486 892151,224486 892200,224706 892200,224706 892151,224486 892151))', 26986)
             )
        ) As foo
    GROUP BY (pvc).value
    HAVING SUM((pvc).count) &gt; 500
    ORDER BY (pvc).value;</programlisting>
<screen role="text-primary"> value | total
-------+-----
    51 | 502
    54 | 521</screen>

<para>Just return count of pixels in each raster tile that have value of 100 of tiles that intersect a specific geometry.</para>
<programlisting language="sql">
SELECT rid, ST_ValueCount(rast, 2, 100) As count
    FROM o_4_boston
        WHERE ST_Intersects(
            rast,
            ST_GeomFromText('POLYGON((224486 892151,224486 892200,224706 892200,224706 892151,224486 892151))', 26986)
             ) ;</programlisting>
<screen role="text-primary"> rid | count
-----+-------
   1 |    56
   2 |    95
  14 |    37
  15 |    64</screen>
            </refsection>

            <refsection>
                <title>See Also</title>
                <para><xref linkend="RT_ST_Count"/>, <xref linkend="RT_ST_SetBandNoDataValue"/></para>
            </refsection>
        </refentry>
    </section>

    <section xml:id="Raster_Inputs">
        <title>Raster Inputs</title>
        <refentry xml:id="RT_ST_RastFromWKB">
            <refnamediv>
                <refname>ST_RastFromWKB</refname>
                <refpurpose>Return a raster value from a Well-Known Binary (WKB) raster.</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                  <funcprototype>
                        <funcdef>raster <function>ST_RastFromWKB</function></funcdef>
                        <paramdef><type>bytea </type> <parameter>wkb</parameter></paramdef>
                  </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>
                    Given a Well-Known Binary (WKB) raster, return a raster.
                </para>

                <para role="availability" conformance="2.5.0">Availability: 2.5.0</para>
            </refsection>

            <refsection>
                <title>Examples</title>

                <programlisting language="sql">
SELECT (ST_MetaData(ST_RastFromWKB('\001\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\010@\000\000\000\000\000\000\340?\000\000\000\000\000\000\340?\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\012\000\000\000\012\000\024\000'::bytea
    )
)).* AS metadata;</programlisting>
<screen role="text-primary"> upperleftx | upperlefty | width | height | scalex | scaley | skewx | skewy | srid | numbands
------------+------------+-------+--------+--------+--------+-------+-------+------+----------
        0.5 |        0.5 |    10 |     20 |      2 |      3 |     0 |     0 |   10 |        0</screen>

            </refsection>

            <refsection>
                <title>See Also</title>
                <para>
                    <xref linkend="RT_ST_MetaData"/>,
                    <xref linkend="RT_ST_RastFromHexWKB"/>,
                    <xref linkend="RT_ST_AsBinary"/>,
                    <xref linkend="RT_ST_AsHexWKB"/>
                </para>
            </refsection>
        </refentry>

        <refentry xml:id="RT_ST_RastFromHexWKB">
            <refnamediv>
                <refname>ST_RastFromHexWKB</refname>
                <refpurpose>Return a raster value from a Hex representation of Well-Known Binary (WKB) raster.</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                  <funcprototype>
                        <funcdef>raster <function>ST_RastFromHexWKB</function></funcdef>
                        <paramdef><type>text </type> <parameter>wkb</parameter></paramdef>
                  </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>
                    Given a Well-Known Binary (WKB) raster in Hex representation, return a raster.
                </para>

                <para role="availability" conformance="2.5.0">Availability: 2.5.0</para>
            </refsection>

            <refsection>
                <title>Examples</title>

                <programlisting language="sql">
SELECT (ST_MetaData(ST_RastFromHexWKB('010000000000000000000000400000000000000840000000000000E03F000000000000E03F000000000000000000000000000000000A0000000A001400'
    )
)).* AS metadata;</programlisting>
<screen role="text-primary"> upperleftx | upperlefty | width | height | scalex | scaley | skewx | skewy | srid | numbands
------------+------------+-------+--------+--------+--------+-------+-------+------+----------
        0.5 |        0.5 |    10 |     20 |      2 |      3 |     0 |     0 |   10 |        0</screen>

            </refsection>

            <refsection>
                <title>See Also</title>
                <para>
                    <xref linkend="RT_ST_MetaData"/>,
                    <xref linkend="RT_ST_RastFromWKB"/>,
                    <xref linkend="RT_ST_AsBinary"/>,
                    <xref linkend="RT_ST_AsHexWKB"/>
                </para>
            </refsection>
        </refentry>

    </section>

    <section xml:id="Raster_Outputs">
        <title>Raster Outputs</title>

        <refentry xml:id="RT_ST_AsBinary">
            <refnamediv>
                <refname>ST_AsBinary/ST_AsWKB</refname>
                <refpurpose>Return the Well-Known Binary (WKB) representation of the raster.</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                  <funcprototype>
                        <funcdef>bytea <function>ST_AsBinary</function></funcdef>
                        <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                        <paramdef choice="opt"><type>boolean </type> <parameter>outasin=FALSE</parameter></paramdef>
                  </funcprototype>
                  <funcprototype>
                        <funcdef>bytea <function>ST_AsWKB</function></funcdef>
                        <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                        <paramdef choice="opt"><type>boolean </type> <parameter>outasin=FALSE</parameter></paramdef>
                  </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>
                    Returns the Binary representation of the raster. If <varname>outasin</varname> is TRUE, out-db bands are treated as in-db.
                    Refer to raster/doc/RFC2-WellKnownBinaryFormat located in the PostGIS source folder for details of the representation.
                </para>

                <para>
                    This is useful in binary cursors to pull data out of the database without converting it to a string representation.
                </para>

                <note>
                    <para>
                        By default, WKB output contains the external file path for out-db bands. If the client does not have access to the raster file underlying an out-db band, set <varname>outasin</varname> to TRUE.</para>
                </note>

                <para role="enhanced" conformance="2.1.0">Enhanced: 2.1.0 Addition of <varname>outasin</varname></para>
                <para role="enhanced" conformance="2.5.0">Enhanced: 2.5.0 Addition of <varname>ST_AsWKB</varname></para>
            </refsection>

                <refsection>
                    <title>Examples</title>

                    <programlisting language="sql">SELECT ST_AsBinary(rast) AS rastbin FROM dummy_rast WHERE rid=1;</programlisting>
<screen role="text-primary">\001\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\010@\000\000\000\000\000\000\340?\000\000\000\000\000\000\340?\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\012\000\000\000\012\000\024\000</screen>

            </refsection>

            <refsection>
                <title>See Also</title>
                <para>
                    <xref linkend="RT_ST_RastFromWKB"/>,
                    <xref linkend="RT_ST_AsHexWKB"/>
                </para>
            </refsection>
        </refentry>

        <refentry xml:id="RT_ST_AsHexWKB">
            <refnamediv>
                <refname>ST_AsHexWKB</refname>
                <refpurpose>Return the Well-Known Binary (WKB) in Hex representation of the raster.</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                  <funcprototype>
                        <funcdef>bytea <function>ST_AsHexWKB</function></funcdef>
                        <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                        <paramdef choice="opt"><type>boolean </type> <parameter>outasin=FALSE</parameter></paramdef>
                  </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>
                    Returns the Binary representation in Hex representation of the raster. If <varname>outasin</varname> is TRUE, out-db bands are treated as in-db.
                    Refer to raster/doc/RFC2-WellKnownBinaryFormat located in the PostGIS source folder for details of the representation.
                </para>

                <note>
                    <para>
                        By default, Hex WKB output contains the external file path for out-db bands. If the client does not have access to the raster file underlying an out-db band, set <varname>outasin</varname> to TRUE.</para>
                </note>

                <para role="availability" conformance="2.5.0">Availability: 2.5.0 </para>
            </refsection>

                <refsection>
                    <title>Examples</title>

                    <programlisting language="sql">SELECT ST_AsHexWKB(rast) AS rastbin FROM dummy_rast WHERE rid=1;</programlisting>
<screen role="text-primary">010000000000000000000000400000000000000840000000000000E03F000000000000E03F000000000000000000000000000000000A0000000A001400</screen>

            </refsection>

            <refsection>
                <title>See Also</title>
                <para>
                    <xref linkend="RT_ST_RastFromHexWKB"/>,
                    <xref linkend="RT_ST_AsBinary"/>
                </para>
            </refsection>

        </refentry>

        <refentry xml:id="RT_ST_AsGDALRaster">
            <refnamediv>
                <refname>ST_AsGDALRaster</refname>
                <refpurpose>Return the raster tile in the designated GDAL Raster format.  Raster formats are one of those supported by your compiled library. Use ST_GDALDrivers() to get a list of formats supported by your library.</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                  <funcprototype>
                    <funcdef>bytea <function>ST_AsGDALRaster</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    <paramdef><type>text </type> <parameter>format</parameter></paramdef>
                    <paramdef choice="opt"><type>text[] </type> <parameter>options=NULL</parameter></paramdef>
                    <paramdef choice="opt"><type>integer </type> <parameter>srid=sameassource</parameter></paramdef>
                  </funcprototype>

                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>Returns the raster tile in the designated format. Arguments are itemized below:</para>
                <itemizedlist>
                    <listitem>
            <para>
                       <varname>format</varname> format to output.  This is dependent on the drivers compiled in your libgdal library.  Generally available are 'JPEG', 'GTIff', 'PNG'. Use <xref linkend="RT_ST_GDALDrivers"/> to get a list of formats supported by your library.
            </para>
                    </listitem>
                   <listitem>
            <para>
            <varname>options</varname> text array of GDAL options. Valid options are dependent on the format. Refer to <link xlink:href="http://www.gdal.org/frmt_various.html">GDAL Raster format options</link> for more details.
            </para>
                   </listitem>
                   <listitem>
            <para>
            <varname>srid</varname> the spatial reference identifier to embed in the output raster
            </para>
                   </listitem>
                </itemizedlist>
                <para role="availability" conformance="2.0.0">Availability: 2.0.0 - requires GDAL &gt;= 1.6.0. </para>
            </refsection>


            <refsection>
                <title>Examples</title>

                <para>Export multiple raster tiles as a single JPEG image with 50 percent quality.</para>

                <programlisting language="sql"><![CDATA[
SELECT ST_AsGDALRaster(ST_Union(rast), 'JPEG', ARRAY['QUALITY=50']) As rastjpg
FROM dummy_rast
WHERE rast && ST_MakeEnvelope(10, 10, 11, 11);
]]></programlisting>

                <para>One way to export raster into another format is using <link xlink:href="https://www.postgresql.org/docs/current/static/lo-funcs.html">PostgreSQL large object export functions</link>.
                The following repeats the JPEG example and exports the result. Note that this requires superuser access because it uses server-side large object functions.
                It will also export to path on server network.  If you need export locally,
                use the psql equivalent lo_ functions which export to the local file system instead of the server file system.</para>
                <programlisting role="requires-external-state"><![CDATA[
DROP TABLE IF EXISTS tmp_out ;

CREATE TABLE tmp_out AS
SELECT lo_from_bytea(
       0,
       ST_AsGDALRaster(ST_Union(rast), 'JPEG', ARRAY['QUALITY=50'])
        ) AS loid
  FROM dummy_rast
WHERE rast && ST_MakeEnvelope(10, 10, 11, 11);

SELECT lo_export(loid, '/tmp/dummy.jpg')
   FROM tmp_out;

SELECT lo_unlink(loid)
  FROM tmp_out;
]]></programlisting>

                <para>Export a raster as a GeoTIFF using the default creation options.</para>
                <programlisting language="sql">SELECT ST_AsGDALRaster(rast, 'GTiff') AS rasttiff
FROM dummy_rast WHERE rid = 2;</programlisting>

                <para>Export a GeoTIFF using JPEG compression at 90 percent quality and embed SRID 4269.</para>
                <programlisting language="sql">SELECT ST_AsGDALRaster(
  rast,
  'GTiff',
  ARRAY['COMPRESS=JPEG', 'JPEG_QUALITY=90'],
  4269) AS rasttiff
FROM dummy_rast WHERE rid = 2;
                </programlisting>

            </refsection>

            <!-- Optionally add a "See Also" section -->
            <refsection>
                <title>See Also</title>
                <para><xref linkend="RT_Raster_Applications"/>, <xref linkend="RT_ST_GDALDrivers"/>, <xref linkend="RT_ST_SRID"/></para>
            </refsection>
        </refentry>

        <refentry xml:id="RT_ST_AsJPEG">
            <refnamediv>
                <refname>ST_AsJPEG</refname>
                <refpurpose>Return the raster tile selected bands as a single Joint Photographic Exports Group (JPEG) image (byte array).  If no band is specified and 1 or more than 3 bands, then only the first band is used.  If only 3 bands then all 3 bands are used and mapped to RGB.</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                  <funcprototype>
                    <funcdef>bytea <function>ST_AsJPEG</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    <paramdef choice="opt"><type>text[] </type> <parameter>options=NULL</parameter></paramdef>
                  </funcprototype>
                  <funcprototype>
                    <funcdef>bytea <function>ST_AsJPEG</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    <paramdef><type>integer </type> <parameter>nband</parameter></paramdef>
                    <paramdef><type>integer </type> <parameter>quality</parameter></paramdef>
                  </funcprototype>
                  <funcprototype>
                    <funcdef>bytea <function>ST_AsJPEG</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    <paramdef><type>integer </type> <parameter>nband</parameter></paramdef>
                    <paramdef choice="opt"><type>text[] </type> <parameter>options=NULL</parameter></paramdef>
                  </funcprototype>
                  <funcprototype>
                    <funcdef>bytea <function>ST_AsJPEG</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    <paramdef><type>integer[] </type> <parameter>nbands</parameter></paramdef>
                    <paramdef choice="opt"><type>text[] </type> <parameter>options=NULL</parameter></paramdef>
                  </funcprototype>
                  <funcprototype>
                    <funcdef>bytea <function>ST_AsJPEG</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    <paramdef><type>integer[] </type> <parameter>nbands</parameter></paramdef>
                    <paramdef><type>integer </type> <parameter>quality</parameter></paramdef>
                  </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>Returns the selected bands of the raster as a single  Joint Photographic Exports Group Image (JPEG).  Use <xref linkend="RT_ST_AsGDALRaster"/> if you need to export as less common raster types. If no band is specified and 1 or more than 3 bands, then only the first band is used.  If 3 bands then all 3 bands are used.  There are many variants of the function with many options. These are itemized below:</para>
                <itemizedlist>
                    <listitem>
                      <para>
                       <varname>nband</varname> is for single band exports.
                      </para>
                    </listitem>
                    <listitem>
                      <para>
                        <varname>nbands</varname> is an array of bands to export (note that max is 3 for JPEG) and the order of the bands is RGB. e.g ARRAY[3,2,1] means map band 3 to Red, band 2 to green and band 1 to blue
                      </para>
                    </listitem>
                   <listitem>
                      <para>
                        <varname>quality</varname> number from 0 to 100.  The higher the number the crisper the image.
                      </para>
                   </listitem>
                   <listitem>
                      <para>
                        <varname>options</varname> text Array
                        of GDAL options as defined for JPEG
                        (look at create_options for JPEG <xref linkend="RT_ST_GDALDrivers"/>). For JPEG
                        valid ones are <varname>PROGRESSIVE</varname>
                        ON or OFF and <varname>QUALITY</varname> a range
                        from 0 to 100 and default to 75. Refer to <link xlink:href="http://www.gdal.org/frmt_various.html">GDAL
                        Raster format options</link> for more details.
                      </para>
                   </listitem>
                </itemizedlist>
                <para role="availability" conformance="2.0.0">Availability: 2.0.0 - requires GDAL &gt;= 1.6.0. </para>
            </refsection>

                <refsection>
                    <title>Examples: Output</title>

                    <para>Output the first three bands at 75 percent quality.</para>
                    <programlisting language="sql">SELECT ST_AsJPEG(rast) As rastjpg
FROM dummy_rast WHERE rid=2;
</programlisting>
                    <para>Output only the first band at 90 percent quality.</para>
                    <programlisting language="sql">SELECT ST_AsJPEG(rast, 1, 90) As rastjpg
FROM dummy_rast WHERE rid=2;
</programlisting>
                    <para>Output the first three bands, mapping band 2 to red, band 1 to green, and band 3 to blue, using progressive encoding at 90 percent quality.</para>
                    <programlisting language="sql">SELECT ST_AsJPEG(rast, ARRAY[2, 1, 3], ARRAY['QUALITY=90', 'PROGRESSIVE=ON']) As rastjpg
FROM dummy_rast WHERE rid=2;</programlisting>

            </refsection>

            <!-- Optionally add a "See Also" section -->
            <refsection>
                <title>See Also</title>
                <para><xref linkend="RT_Raster_Applications"/>, <xref linkend="RT_ST_GDALDrivers"/>, <xref linkend="RT_ST_AsGDALRaster"/>, <xref linkend="RT_ST_AsPNG"/>, <xref linkend="RT_ST_AsTIFF"/> </para>
            </refsection>
        </refentry>

        <refentry xml:id="RT_ST_AsPNG">
            <refnamediv>
                <refname>ST_AsPNG</refname>
                <refpurpose>Return the raster tile selected bands as a single portable network graphics (PNG) image (byte array).  If 1, 3, or 4 bands in raster and no bands are specified, then all bands are used.  If more 2 or more than 4 bands and no bands specified, then only band 1 is used.  Bands are mapped to RGB or RGBA space.</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                  <funcprototype>
                    <funcdef>bytea <function>ST_AsPNG</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    <paramdef choice="opt"><type>text[] </type> <parameter>options=NULL</parameter></paramdef>
                  </funcprototype>
                  <funcprototype>
                    <funcdef>bytea <function>ST_AsPNG</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    <paramdef><type>integer </type> <parameter>nband</parameter></paramdef>
                    <paramdef><type>integer </type> <parameter>compression</parameter></paramdef>
                  </funcprototype>
                  <funcprototype>
                    <funcdef>bytea <function>ST_AsPNG</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    <paramdef><type>integer </type> <parameter>nband</parameter></paramdef>
                    <paramdef choice="opt"><type>text[] </type> <parameter>options=NULL</parameter></paramdef>
                  </funcprototype>
                  <funcprototype>
                    <funcdef>bytea <function>ST_AsPNG</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    <paramdef><type>integer[] </type> <parameter>nbands</parameter></paramdef>
                    <paramdef><type>integer </type> <parameter>compression</parameter></paramdef>
                  </funcprototype>
                  <funcprototype>
                    <funcdef>bytea <function>ST_AsPNG</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    <paramdef><type>integer[] </type> <parameter>nbands</parameter></paramdef>
                    <paramdef choice="opt"><type>text[] </type> <parameter>options=NULL</parameter></paramdef>
                  </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>Returns the selected bands of the raster as a single Portable Network Graphics Image (PNG).  Use <xref linkend="RT_ST_AsGDALRaster"/> if you need to export as less common raster types. If no band is specified, then the first 3 bands are exported.  There are many variants of the function with many options. If no <varname>srid</varname> is specified then then srid of the raster is used.  These are itemized below:</para>
                <itemizedlist>
                    <listitem>
                      <para>
                       <varname>nband</varname> is for single band exports.
                      </para>
                    </listitem>
                    <listitem>
                      <para>
                        <varname>nbands</varname> is an array of bands to export (note that max is 4 for PNG) and the order of the bands is RGBA. e.g ARRAY[3,2,1] means map band 3 to Red, band 2 to green and band 1 to blue
                      </para>
                    </listitem>
                   <listitem>
                      <para>
                        <varname>compression</varname> number from 1 to 9.  The higher the number the greater the compression.
                      </para>
                   </listitem>
                   <listitem>
                      <para>
                        <varname>options</varname> text Array of GDAL
                        options as defined for PNG (look at create_options
                        for PNG of <xref linkend="RT_ST_GDALDrivers"/>). For PNG valid one is only ZLEVEL (amount
                        of time to spend on compression -- default 6)
                        e.g. ARRAY['ZLEVEL=9'].
                        WORLDFILE is not allowed since the function
                        would have to output two outputs. Refer to <link xlink:href="http://www.gdal.org/frmt_various.html">GDAL
                        Raster format options</link> for more details.
                      </para>
                   </listitem>
                </itemizedlist>
                <para role="availability" conformance="2.0.0">Availability: 2.0.0 - requires GDAL &gt;= 1.6.0. </para>
            </refsection>

                <refsection>
                    <title>Examples</title>

                    <para>Export the first 3 bands and map band 3 to red, band 1 to green, and band 2 to blue.</para>
                    <programlisting language="sql">SELECT ST_AsPNG(rast) As rastpng
FROM dummy_rast WHERE rid=2;
SELECT ST_AsPNG(rast, ARRAY[3, 1, 2]) As rastpng
FROM dummy_rast WHERE rid=2;
                </programlisting>

            </refsection>

            <!-- Optionally add a "See Also" section -->
            <refsection>
                <title>See Also</title>
                <para><xref linkend="RT_ST_AsGDALRaster"/>, <xref linkend="RT_ST_ColorMap"/>, <xref linkend="RT_ST_GDALDrivers"/>,  <xref linkend="RT_Raster_Applications"/></para>
            </refsection>
        </refentry>

        <refentry xml:id="RT_ST_AsTIFF">
            <refnamediv>
                <refname>ST_AsTIFF</refname>
                <refpurpose>Return the raster selected bands as a single TIFF image (byte array).  If no band is specified or any of specified bands does not exist in the raster, then will try to use all bands.</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                  <funcprototype>
                    <funcdef>bytea <function>ST_AsTIFF</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    <paramdef choice="opt"><type>text[] </type> <parameter>options=''</parameter></paramdef>
                    <paramdef><type>integer </type> <parameter>srid=sameassource</parameter></paramdef>
                  </funcprototype>
                  <funcprototype>
                    <funcdef>bytea <function>ST_AsTIFF</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    <paramdef choice="opt"><type>text </type> <parameter>compression=''</parameter></paramdef>
                    <paramdef choice="opt"><type>integer </type> <parameter>srid=sameassource</parameter></paramdef>
                  </funcprototype>
                  <funcprototype>
                    <funcdef>bytea <function>ST_AsTIFF</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    <paramdef><type>integer[] </type> <parameter>nbands</parameter></paramdef>
                    <paramdef choice="opt"><type>text </type> <parameter>compression=''</parameter></paramdef>
                    <paramdef choice="opt"><type>integer </type> <parameter>srid=sameassource</parameter></paramdef>
                  </funcprototype>
                  <funcprototype>
                    <funcdef>bytea <function>ST_AsTIFF</function></funcdef>
                    <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    <paramdef><type>integer[] </type> <parameter>nbands</parameter></paramdef>
                    <paramdef><type>text[] </type> <parameter>options</parameter></paramdef>
                    <paramdef><type>integer </type> <parameter>srid=sameassource</parameter></paramdef>
                  </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>Returns the selected bands of the raster as a single Tagged Image File Format (TIFF). If no band is specified, will try to use all bands. This is a wrapper around <xref linkend="RT_ST_AsGDALRaster"/>. Use <xref linkend="RT_ST_AsGDALRaster"/> if you need to export as less common raster types. There are many variants of the function with many options.  If no spatial reference SRS text is present, the spatial reference of the raster is used. These are itemized below:</para>
                <itemizedlist>
                    <listitem>
                      <para>
                        <varname>nbands</varname> is an array of bands to export (note that max is 3 for PNG) and the order of the bands is RGB. e.g ARRAY[3,2,1] means map band 3 to Red, band 2 to green and band 1 to blue
                      </para>
                    </listitem>
                   <listitem>
                      <para>
<varname>compression</varname> Compression expression -- JPEG90 (or some other percent), LZW, JPEG, DEFLATE9.
                      </para>
                   </listitem>
                   <listitem>
                      <para>
<varname>options</varname> text Array of GDAL create options as defined for GTiff (look at create_options for GTiff of <xref linkend="RT_ST_GDALDrivers"/>). or refer to <link xlink:href="http://www.gdal.org/frmt_various.html">GDAL Raster format options</link> for more details.
                      </para>
                   </listitem>
                   <listitem>
                      <para>
<varname>srid</varname> srid of spatial_ref_sys of the raster. This is used to populate the georeference information
                      </para>
                   </listitem>
                </itemizedlist>
                <para role="availability" conformance="2.0.0">Availability: 2.0.0 - requires GDAL &gt;= 1.6.0. </para>
            </refsection>

                <refsection>
                    <title>Examples: Use jpeg compression 90%</title>

                    <programlisting language="sql">SELECT ST_AsTIFF(rast, 'JPEG90') As rasttiff
FROM dummy_rast WHERE rid=2;
                </programlisting>

            </refsection>

            <!-- Optionally add a "See Also" section -->
            <refsection>
                <title>See Also</title>
                <para><xref linkend="RT_ST_GDALDrivers"/>, <xref linkend="RT_ST_AsGDALRaster"/>, <xref linkend="RT_ST_SRID"/></para>
            </refsection>
        </refentry>
    </section>

    <section xml:id="Raster_Processing_MapAlgebra">
        <title>Raster Processing: Map Algebra</title>

            <refentry xml:id="RT_ST_Clip">
                <refnamediv>
                    <refname>ST_Clip</refname>
                    <refpurpose>Returns the raster clipped by the input geometry.  If band number is not specified, all bands are processed. If <varname>crop</varname> is not specified or TRUE, the output raster is cropped. If <varname>touched</varname> is set to TRUE, then touched pixels are included, otherwise only if the center of the pixel is in the geometry it is included.</refpurpose>
                </refnamediv>

                <refsynopsisdiv>
                    <funcsynopsis>

                        <funcprototype>
                            <funcdef>raster <function>ST_Clip</function></funcdef>
                            <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                            <paramdef><type>integer[] </type> <parameter>nband</parameter></paramdef>
                            <paramdef><type>geometry </type> <parameter>geom</parameter></paramdef>
                            <paramdef choice="opt"><type>double precision[] </type> <parameter>nodataval=NULL</parameter></paramdef>
                            <paramdef choice="opt"><type>boolean </type> <parameter>crop=TRUE</parameter></paramdef>
                            <paramdef choice="opt"><type>boolean </type> <parameter>touched=FALSE</parameter></paramdef>
                        </funcprototype>

                        <funcprototype>
                            <funcdef>raster <function>ST_Clip</function></funcdef>
                            <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                            <paramdef><type>integer </type> <parameter>nband</parameter></paramdef>
                            <paramdef><type>geometry </type> <parameter>geom</parameter></paramdef>
                            <paramdef><type>double precision </type> <parameter>nodataval</parameter></paramdef>
                            <paramdef choice="opt"><type>boolean </type> <parameter>crop=TRUE</parameter></paramdef>
                            <paramdef choice="opt"><type>boolean </type> <parameter>touched=FALSE</parameter></paramdef>
                        </funcprototype>

                        <funcprototype>
                            <funcdef>raster <function>ST_Clip</function></funcdef>
                            <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                            <paramdef><type>integer </type> <parameter>nband</parameter></paramdef>
                            <paramdef><type>geometry </type> <parameter>geom</parameter></paramdef>
                            <paramdef><type>boolean </type> <parameter>crop</parameter></paramdef>
                            <paramdef choice="opt"><type>boolean </type> <parameter>touched=FALSE</parameter></paramdef>
                        </funcprototype>

                        <funcprototype>
                            <funcdef>raster <function>ST_Clip</function></funcdef>
                            <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                            <paramdef><type>geometry </type> <parameter>geom</parameter></paramdef>
                            <paramdef choice="opt"><type>double precision[] </type> <parameter>nodataval=NULL</parameter></paramdef>
                            <paramdef choice="opt"><type>boolean </type> <parameter>crop=TRUE</parameter></paramdef>
                            <paramdef choice="opt"><type>boolean </type> <parameter>touched=FALSE</parameter></paramdef>
                        </funcprototype>

                        <funcprototype>
                            <funcdef>raster <function>ST_Clip</function></funcdef>
                            <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                            <paramdef><type>geometry </type> <parameter>geom</parameter></paramdef>
                            <paramdef><type>double precision </type> <parameter>nodataval</parameter></paramdef>
                            <paramdef choice="opt"><type>boolean </type> <parameter>crop=TRUE</parameter></paramdef>
                            <paramdef choice="opt"><type>boolean </type> <parameter>touched=FALSE</parameter></paramdef>
                        </funcprototype>

                        <funcprototype>
                            <funcdef>raster <function>ST_Clip</function></funcdef>
                            <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                            <paramdef><type>geometry </type> <parameter>geom</parameter></paramdef>
                            <paramdef><type>boolean </type> <parameter>crop</parameter></paramdef>
                            <paramdef choice="opt"><type>boolean </type> <parameter>touched=FALSE</parameter></paramdef>
                        </funcprototype>

                    </funcsynopsis>
                </refsynopsisdiv>

                <refsection>
                    <title>Description</title>

                    <para>
                        Returns a raster that is clipped by the input geometry <varname>geom</varname>. If band index is not specified, all bands are processed.
                    </para>

                    <para>
                        Rasters resulting from ST_Clip must have a nodata value assigned for areas clipped, one for each band. If none are provided and the input raster do not have a nodata value defined, nodata values of the resulting raster are set to ST_MinPossibleValue(ST_BandPixelType(rast, band)). When the number of nodata value in the array is smaller than the number of band, the last one in the array is used for the remaining bands. If the number of nodata value is greater than the number of band, the extra nodata values are ignored. All variants accepting an array of nodata values also accept a single value which will be assigned to each band.
                    </para>

                    <para>
                        If <varname>crop</varname> is not specified, true is assumed meaning the output raster is cropped to the intersection of the <varname>geom</varname>and <varname>rast</varname> extents. If <varname>crop</varname> is set to false, the new raster gets the same extent as <varname>rast</varname>.  If <varname>touched</varname> is set to true, then all pixels in the <varname>rast</varname> that intersect the geometry are selected.
                    </para>
                    <note><para>The default behavior is touched=false, which will only select pixels where the center of the pixel is covered by the geometry.</para></note>
	                <para role="enhanced" conformance="3.5.0">Enhanced: 3.5.0 - touched argument added.</para>
                    <para role="availability" conformance="2.0.0">Availability: 2.0.0 </para>

                    <para role="enhanced" conformance="2.1.0">Enhanced: 2.1.0 Rewritten in C</para>

                    <para>
                        Examples here use Massachusetts aerial data available on MassGIS site <link xlink:href="https://www.mass.gov/info-details/massgis-data-20082009-aerial-imagery">MassGIS Aerial Orthos</link>.
                    </para>
                </refsection>

                <refsection><title>Examples</title>
<para>Comparing selecting all touched vs. not all touched.</para>
                        <programlisting language="sql"><![CDATA[WITH source AS (
    SELECT rast, geom
    FROM ST_AsRaster(ST_Letters('R'), scalex => 1.0, scaley => -1.0) AS r(rast)
    INNER JOIN ST_GeomFromText('LINESTRING(0 1,5 6,10 10)') AS g(geom)
        ON ST_Intersects(r.rast, g.geom)
), clipped AS (
    SELECT rast,
        ST_Clip(rast, geom, touched => true) AS rast_touched,
        ST_Clip(rast, geom, touched => false) AS rast_not_touched
    FROM source
), variants AS (
    SELECT 'original' AS title, ST_Count(rast) AS pixel_count, rast AS rendered
    FROM clipped
    UNION ALL
    SELECT 'all touched', ST_Count(rast_touched), rast_touched
    FROM clipped
    UNION ALL
    SELECT 'default clip', ST_Count(rast_not_touched), rast_not_touched
    FROM clipped
)
SELECT title, pixel_count, ST_AsPNG(rendered) AS image
FROM variants
ORDER BY CASE title
    WHEN 'original' THEN 1
    WHEN 'all touched' THEN 2
    ELSE 3
END;]]></programlisting>
<screen role="visual-primary"> title        | pixel_count | image
--------------+-------------+----------------------------
 original     |        2605 | PNG image, 48 x 74 pixels
 all touched  |          16 | PNG image, 11 x 11 pixels
 default clip |          10 | PNG image, 11 x 11 pixels
(3 rows)</screen>

<para>The following self-contained example uses three simple shapes as RGB bands. It compares cropping band 1, clipping band 1 without cropping and then restoring bands 2 and 3, and clipping every band without cropping.</para>
                    <programlisting language="sql">WITH canvas AS (
    SELECT ST_AddBand(
        ST_AddBand(
            ST_AddBand(
                ST_MakeEmptyRaster(128, 128, 0, 128, 1, -1, 0, 0, 0),
                '8BUI'::text, 0::double precision, 0::double precision
            ),
            '8BUI'::text, 0::double precision, 0::double precision
        ),
        '8BUI'::text, 0::double precision, 0::double precision
    ) AS rast
), source AS (
    SELECT ST_SetValue(
        ST_SetValue(
            ST_SetValue(rast, 1, ST_Buffer('POINT(32 96)'::geometry, 22), 220),
            2, ST_Buffer('LINESTRING(18 20,110 110)'::geometry, 6,
                         'endcap=flat join=bevel'), 210
        ),
        3, ST_Buffer('LINESTRING(10 48,118 48)'::geometry, 7,
                     'endcap=flat'), 180
    ) AS rast,
    ST_Buffer('POINT(64 64)'::geometry, 34) AS clipper
    FROM canvas
), variants AS (
    SELECT 'original RGB' AS title, rast AS rendered FROM source
    UNION ALL
    SELECT 'band 1 cropped', ST_Clip(rast, 1, clipper, true) FROM source
    UNION ALL
    SELECT
        'band 1 only',
        ST_AddBand(
            ST_Clip(rast, 1, clipper, false),
            ARRAY[ST_Band(rast, 2), ST_Band(rast, 3)]
        )
    FROM source
    UNION ALL
    SELECT 'all bands clipped', ST_Clip(rast, clipper, false) FROM source
)
SELECT title, ST_AsPNG(rendered) AS image
FROM variants
ORDER BY CASE title
    WHEN 'original RGB' THEN 1
    WHEN 'band 1 cropped' THEN 2
    WHEN 'band 1 only' THEN 3
    ELSE 4
END;</programlisting>
<screen role="visual-primary"> title             | image
-------------------+-----------------------------
 original RGB      | PNG image, 128 x 128 pixels
 band 1 cropped    | PNG image, 68 x 68 pixels
 band 1 only       | PNG image, 128 x 128 pixels
 all bands clipped | PNG image, 128 x 128 pixels
(4 rows)</screen>
<para>Crop, single-band clipping, and all-band clipping.</para>
<informaltable>
  <tgroup cols="2">
    <tbody>
      <row>
        <entry><para><informalfigure>
            <mediaobject>
              <imageobject><imagedata fileref="images/st_clip01.png"/></imageobject>
              <caption><para>Source tile</para></caption>
            </mediaobject>
          </informalfigure></para></entry>
        <entry><para><informalfigure>
            <mediaobject>
              <imageobject><imagedata fileref="images/st_clip02.png"/></imageobject>
              <caption><para>Cropped</para></caption>
            </mediaobject>
          </informalfigure></para></entry>
      </row>
      <row>
        <entry><para><informalfigure>
            <mediaobject>
              <imageobject><imagedata fileref="images/st_clip04.png"/></imageobject>
              <caption><para>One-band source</para></caption>
            </mediaobject>
          </informalfigure></para></entry>
        <entry><para><informalfigure>
            <mediaobject>
              <imageobject><imagedata fileref="images/st_clip05.png"/></imageobject>
              <caption><para>One-band clip</para></caption>
            </mediaobject>
          </informalfigure></para></entry>
      </row>
      <row>
        <entry><para><informalfigure>
            <mediaobject>
              <imageobject><imagedata fileref="images/st_clip01.png"/></imageobject>
              <caption><para>All-band source</para></caption>
            </mediaobject>
          </informalfigure></para></entry>
        <entry><para><informalfigure>
            <mediaobject>
              <imageobject><imagedata fileref="images/st_clip03.png"/></imageobject>
              <caption><para>All-band clip</para></caption>
            </mediaobject>
          </informalfigure></para></entry>
      </row>
    </tbody>
  </tgroup>
</informaltable>
                </refsection>

                <!-- Optionally add a "See Also" section -->
                <refsection>
                    <title>See Also</title>
                    <para>
                        <xref linkend="RT_ST_AddBand"/>,
                        <xref linkend="RT_ST_Count"/>,
                        <xref linkend="RT_ST_MapAlgebra"/>,
                        <xref linkend="RT_ST_Intersection"/>
                    </para>
                </refsection>
            </refentry>

            <refentry xml:id="RT_ST_ColorMap">
                <refnamediv>
                    <refname>ST_ColorMap</refname>
                    <refpurpose>Creates a new raster of up to four 8BUI bands (grayscale, RGB, RGBA) from the source raster and a specified band. Band 1 is assumed if not specified.</refpurpose>
                </refnamediv>

                <refsynopsisdiv>
                    <funcsynopsis>
                      <funcprototype>
                            <funcdef>raster <function>ST_ColorMap</function></funcdef>
                            <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                            <paramdef choice="opt"><type>integer </type> <parameter>nband=1</parameter></paramdef>
                            <paramdef choice="opt"><type>text </type> <parameter>colormap=grayscale</parameter></paramdef>
                            <paramdef choice="opt"><type>text </type> <parameter>method=INTERPOLATE</parameter></paramdef>
                      </funcprototype>
                    </funcsynopsis>

                    <funcsynopsis>
                      <funcprototype>
                            <funcdef>raster <function>ST_ColorMap</function></funcdef>
                            <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                            <paramdef><type>text </type> <parameter>colormap</parameter></paramdef>
                            <paramdef choice="opt"><type>text </type> <parameter>method=INTERPOLATE</parameter></paramdef>
                      </funcprototype>
                    </funcsynopsis>
                </refsynopsisdiv>

                <refsection>
                    <title>Description</title>

                    <para>
                        Apply a <varname>colormap</varname> to the band at <varname>nband</varname> of <varname>rast</varname> resulting a new raster comprised of up to four 8BUI bands. The number of 8BUI bands in the new raster is determined by the number of color components defined in <varname>colormap</varname>.
                    </para>

                    <para>If <varname>nband</varname> is not specified, then band 1 is assumed.</para>

                    <para>
                        <varname>colormap</varname> can be a keyword of a pre-defined colormap or a set of lines defining the value and the color components.
                    </para>

                    <para>
                        Valid pre-defined <varname>colormap</varname> keyword:
                    </para>

                    <itemizedlist>
                        <listitem>
                            <para>
                                <varname>grayscale</varname> or <varname>greyscale</varname> for a one 8BUI band raster of shades of gray.
                            </para>
                        </listitem>
                        <listitem>
                            <para>
                                <varname>pseudocolor</varname> for a four 8BUI (RGBA) band raster with colors going from blue to green to red.
                            </para>
                        </listitem>
                        <listitem>
                            <para>
                                <varname>fire</varname> for a four 8BUI (RGBA) band raster with colors going from black to red to pale yellow.
                            </para>
                        </listitem>
                        <listitem>
                            <para>
                                <varname>bluered</varname> for a four 8BUI (RGBA) band raster with colors going from blue to pale white to red.
                            </para>
                        </listitem>
                    </itemizedlist>

                    <para>
                        Users can pass a set of entries (one per line) to <varname>colormap</varname> to specify custom colormaps. Each entry generally consists of five values: the pixel value and corresponding Red, Green, Blue, Alpha components (color components between 0 and 255). Percent values can be used instead of pixel values where 0% and 100% are the minimum and maximum values found in the raster band. Values can be separated with commas (','), tabs, colons (':') and/or spaces. The pixel value can be set to <emphasis>nv</emphasis>, <emphasis>null</emphasis> or <emphasis>nodata</emphasis> for the NODATA value. An example is provided below.
                    </para>

                    <programlisting language="bash" role="text-primary">
5 0 0 0 255
4 100:50 55 255
1 150, 100 150 255
0% 255 255 255 255
nv 0 0 0 0
                    </programlisting>

                    <para>
                        The syntax of <varname>colormap</varname> is similar to that of the color-relief mode of GDAL <link xlink:href="http://www.gdal.org/gdaldem.html#gdaldem_color_relief">gdaldem</link>.
                    </para>

                    <para>
                        Valid keywords for <varname>method</varname>:
                    </para>

                    <itemizedlist>
                        <listitem>
                            <para>
                                <varname>INTERPOLATE</varname> to use linear interpolation to smoothly blend the colors between the given pixel values
                            </para>
                        </listitem>
                        <listitem>
                            <para>
                                <varname>EXACT</varname> to strictly match only those pixels values found in the colormap. Pixels whose value does not match a colormap entry will be set to 0 0 0 0 (RGBA)
                            </para>
                        </listitem>
                        <listitem>
                            <para>
                                <varname>NEAREST</varname> to use the colormap entry whose value is closest to the pixel value
                            </para>
                        </listitem>
                    </itemizedlist>

                    <note>
                        <para>
                            A great reference for colormaps is <link xlink:href="http://www.colorbrewer2.org">ColorBrewer</link>.
                        </para>
                    </note>
                    <warning>
                        <para>
                            The resulting bands of new raster will have no NODATA value set.  Use <xref linkend="RT_ST_SetBandNoDataValue"/> to set a NODATA value if one is needed.
                        </para>
                    </warning>

                    <para role="availability" conformance="2.1.0">Availability: 2.1.0 </para>
                </refsection>

                <refsection>
                    <title>Examples</title>
                    <para>This example builds a raster from rotated buffered lines and compares the original values with predefined and custom color maps.</para>
                    <programlisting language="sql">WITH ref AS (
    SELECT ST_MakeEmptyRaster(200, 200, 0, 200, 1, -1, 0, 0) AS rast
), source AS (
    SELECT ST_Union(rast) AS rast
    FROM (
    SELECT
        ST_AsRaster(ST_Rotate(ST_Buffer('LINESTRING(0 2,50 50,150 150,125 50)'::geometry,
                    i*2
                ),
                pi() * i * 0.125, ST_Point(50, 50)
            ),
            ref.rast, '8BUI'::text, i * 5
        ) AS rast
    FROM ref
    CROSS JOIN generate_series(1, 10, 3) AS i
) AS shapes
)
SELECT title, ST_AsPNG(rendered) AS image
FROM source
CROSS JOIN LATERAL (VALUES
    ('original', rast),
    ('grayscale', ST_ColorMap(rast, 1, 'greyscale')),
    ('pseudocolor', ST_ColorMap(rast, 1, 'pseudocolor')),
    ('fire', ST_ColorMap(rast, 1, 'fire')),
    ('blue-red', ST_ColorMap(rast, 1, 'bluered')),
    ('custom red', ST_ColorMap(
        rast,
        1,
        E'100% 255 0 0 255\n80% 160 0 0 255\n50% 130 0 0 255\n' ||
        E'30% 30 0 0 255\n20% 60 0 0 255\n0% 0 0 0 255\n' ||
        E'nv 255 255 255 0'
    ))
) AS variants(title, rendered);</programlisting>
                    <screen role="visual-primary"> title      | image
------------+--------------------------------
 original   | PNG image, 224 x 295 pixels
 grayscale | PNG image, 224 x 295 pixels
 pseudocolor| PNG image, 224 x 295 pixels
 fire       | PNG image, 224 x 295 pixels
 blue-red   | PNG image, 224 x 295 pixels
 custom red | PNG image, 224 x 295 pixels
                    </screen>
                </refsection>

                <refsection>
                    <title>See Also</title>
                    <para>
                        <xref linkend="RT_ST_AsPNG"/>,
                        <xref linkend="RT_ST_AsRaster"/>
                        <xref linkend="RT_ST_MapAlgebra"/>,
                        <xref linkend="RT_ST_Grayscale"/>
                        <xref linkend="RT_ST_NumBands"/>,
                        <xref linkend="RT_ST_Reclass"/>,
                        <xref linkend="RT_ST_SetBandNoDataValue"/>,
                        <xref linkend="RT_ST_Union"/>
                    </para>
                </refsection>
            </refentry>

            <refentry xml:id="RT_ST_Grayscale">
                <refnamediv>
                    <refname>ST_Grayscale</refname>
                    <refpurpose>Creates a new one-8BUI band raster from the source raster and specified bands representing Red, Green and Blue</refpurpose>
                </refnamediv>

                <refsynopsisdiv>
                    <funcsynopsis>
                      <funcprototype>
                            <funcdef>(1) raster <function>ST_Grayscale</function></funcdef>
                            <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                            <paramdef choice="opt"><type>integer </type> <parameter>redband=1</parameter></paramdef>
                            <paramdef choice="opt"><type>integer </type> <parameter>greenband=2</parameter></paramdef>
                            <paramdef choice="opt"><type>integer </type> <parameter>blueband=3</parameter></paramdef>
                            <paramdef choice="opt"><type>text </type> <parameter>extenttype=INTERSECTION</parameter></paramdef>
                      </funcprototype>
                    </funcsynopsis>

                    <funcsynopsis>
                      <funcprototype>
                            <funcdef>(2) raster <function>ST_Grayscale</function></funcdef>
                            <paramdef><type>rastbandarg[] </type> <parameter>rastbandargset</parameter></paramdef>
                            <paramdef choice="opt"><type>text </type> <parameter>extenttype=INTERSECTION</parameter></paramdef>
                      </funcprototype>
                    </funcsynopsis>
                </refsynopsisdiv>

                <refsection>
                    <title>Description</title>

                    <para>
                        Create a raster with one 8BUI band given three input bands (from one or more rasters). Any input band whose pixel type is not 8BUI will be reclassified using <xref linkend="RT_ST_Reclass"/>.
                    </para>

                    <note>
                        <para>
                            This function is not like <xref linkend="RT_ST_ColorMap"/> with the <varname>grayscale</varname> keyword as ST_ColorMap operates on only one band while this function expects three bands for RGB.  This function applies the following equation for converting RGB to Grayscale: 0.2989 * RED + 0.5870 * GREEN + 0.1140 * BLUE
                        </para>
                    </note>

                    <para role="availability" conformance="2.5.0">Availability: 2.5.0 </para>

                </refsection>

                <refsection>
                    <title>Examples</title>
                    <para>This self-contained example paints an apple with
                    gradients and highlights into three raster bands. It
                    compares the original RGB raster with the equivalent
                    grayscale results produced by both function variants.</para>

                    <programlisting language="sql">WITH pixels AS (
    SELECT
        col,
        row,
        x,
        y,
        (((x - 48.0)^2 / (25.0^2) + (y - 54.0)^2 / (29.0^2) &lt; 1)
         OR ((x - 72.0)^2 / (25.0^2) + (y - 54.0)^2 / (29.0^2) &lt; 1))
         AND NOT ((x - 60.0)^2 / (8.0^2) + (y - 26.0)^2 / (5.0^2) &lt; 1) AS fruit,
        ((x - 82.0) * 0.84 + (y - 28.0) * 0.54)^2 / (22.0^2)
          + (-(x - 82.0) * 0.54 + (y - 28.0) * 0.84)^2 / (8.0^2) &lt; 1 AS leaf,
        abs((x - 62.0) * 0.96 - (y - 29.0) * 0.28) &lt; 3
          AND x BETWEEN 60 AND 69 AND y BETWEEN 21 AND 45 AS stem
    FROM (
        SELECT
            col,
            row,
            col / 2.0 AS x,
            row / 2.0 AS y
        FROM generate_series(1, 180) AS row
        CROSS JOIN generate_series(1, 240) AS col
    ) AS source_pixels
), shaded AS (
    SELECT
        col,
        row,
        x,
        y,
        CASE
            WHEN stem THEN 95 + y * 0.7 + (x % 3) * 8
            WHEN leaf THEN 28 + (90 - x) * 0.5
            WHEN fruit THEN LEAST(255, GREATEST(0,
                150
                + (85 - sqrt((x - 39.0)^2 + (y - 37.0)^2)) * 1.1
                + CASE
                    WHEN (x - 43.0)^2 / (10.0^2) + (y - 43.0)^2 / (7.0^2) &lt; 1
                    THEN 35
                    ELSE 0
                END
                - CASE
                    WHEN (x - 77.0)^2 / (20.0^2) + (y - 67.0)^2 / (13.0^2) &lt; 1
                    THEN 35
                    ELSE 0
                END
                + ((x * 13 + y * 7) % 19 - 9)
            ))
            ELSE 245
        END AS red,
        CASE
            WHEN stem THEN 50 + y * 0.35
            WHEN leaf THEN LEAST(190, GREATEST(40,
                105 + (95 - x) * 1.2 + (y - 20) * 1.5
                + CASE
                    WHEN (x - 76.0)^2 / (12.0^2) + (y - 24.0)^2 / (4.0^2) &lt; 1
                    THEN 45
                    ELSE 0
                END
            ))
            WHEN fruit THEN LEAST(95, GREATEST(15,
                24 + (68 - y) * 0.35
                + CASE
                    WHEN (x - 43.0)^2 / (10.0^2) + (y - 43.0)^2 / (7.0^2) &lt; 1
                    THEN 30
                    ELSE 0
                END
                + ((x * 5 + y * 11) % 13 - 6)
            ))
            ELSE 245
        END AS green,
        CASE
            WHEN stem THEN 22 + (x % 4) * 3
            WHEN leaf THEN 42 + (100 - x) * 0.4
            WHEN fruit THEN LEAST(75, GREATEST(10,
                18
                + CASE
                    WHEN (x - 43.0)^2 / (10.0^2) + (y - 43.0)^2 / (7.0^2) &lt; 1
                    THEN 25
                    ELSE 0
                END
                + ((x * 3 + y * 5) % 11 - 5)
            ))
            ELSE 245
        END AS blue
    FROM pixels
), rows AS (
    SELECT
        row,
        array_agg(red::double precision ORDER BY col) AS red_values,
        array_agg(green::double precision ORDER BY col) AS green_values,
        array_agg(blue::double precision ORDER BY col) AS blue_values
    FROM shaded
    GROUP BY row
), source AS (
    SELECT ST_SetValues(ST_SetValues(ST_SetValues(
        ST_AddBand(ST_AddBand(ST_AddBand(
            ST_MakeEmptyRaster(240, 180, 0, 180, 1, -1, 0, 0, 0),
            '8BUI'::text, 245::double precision, 0::double precision),
            '8BUI'::text, 245::double precision, 0::double precision),
            '8BUI'::text, 245::double precision, 0::double precision),
        1, 1, 1, array_agg(red_values ORDER BY row)::double precision[][]),
        2, 1, 1, array_agg(green_values ORDER BY row)::double precision[][]),
        3, 1, 1, array_agg(blue_values ORDER BY row)::double precision[][]) AS rast
    FROM rows
)
SELECT ST_AsPNG(rast) AS "original RGB",
    ST_AsPNG(ST_Grayscale(rast)) AS "grayscale (variant 1)",
    ST_AsPNG(ST_Grayscale(ARRAY[
        ROW(rast, 1)::rastbandarg,
        ROW(rast, 2)::rastbandarg,
        ROW(rast, 3)::rastbandarg
    ]::rastbandarg[])) AS "grayscale (variant 2)"
FROM source;</programlisting>
<screen role="visual-primary"> original RGB                | grayscale (variant 1)      | grayscale (variant 2)
-----------------------------+----------------------------+----------------------------
 PNG image, 240 x 180 pixels | PNG image, 240 x 180 pixels | PNG image, 240 x 180 pixels
(1 row)</screen>
<para>Original photographic illustration:</para>
<informaltable>
  <tgroup cols="2">
    <tbody>
      <row>
        <entry><para><informalfigure>
            <mediaobject>
              <imageobject><imagedata fileref="images/apple.png"/></imageobject>
              <caption><para>original apple</para></caption>
            </mediaobject>
          </informalfigure></para></entry>
        <entry><para><informalfigure>
            <mediaobject>
              <imageobject><imagedata fileref="images/apple_st_grayscale.png"/></imageobject>
              <caption><para>grayscale apple</para></caption>
            </mediaobject>
          </informalfigure></para></entry>
      </row>
    </tbody>
  </tgroup>
</informaltable>
                </refsection>

                <refsection>
                    <title>See Also</title>
                    <para>
                        <xref linkend="RT_ST_AsPNG"/>,
                        <xref linkend="RT_ST_Reclass"/>,
                        <xref linkend="RT_ST_ColorMap"/>
                    </para>
                </refsection>

            </refentry>

            <refentry xml:id="RT_ST_Intersection">
                <refnamediv>
                    <refname>ST_Intersection</refname>
                    <refpurpose>Returns a raster or a set of geometry-pixelvalue pairs representing the shared portion of two rasters or the geometrical intersection of a vectorization of the raster and a geometry.</refpurpose>
                </refnamediv>

                <refsynopsisdiv>
                    <funcsynopsis>
                      <funcprototype>
                            <funcdef>setof geomval <function>ST_Intersection</function></funcdef>
                            <paramdef><type>geometry </type> <parameter>geom</parameter></paramdef>
                            <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                            <paramdef choice="opt"><type>integer </type> <parameter>band_num=1</parameter></paramdef>
                      </funcprototype>

                      <funcprototype>
                            <funcdef>setof geomval <function>ST_Intersection</function></funcdef>
                            <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                            <paramdef><type>geometry </type> <parameter>geom</parameter></paramdef>
                      </funcprototype>

                      <funcprototype>
                            <funcdef>setof geomval <function>ST_Intersection</function></funcdef>
                            <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                            <paramdef><type>integer </type> <parameter>band</parameter></paramdef>
                            <paramdef><type>geometry </type> <parameter>geomin</parameter></paramdef>
                      </funcprototype>

                      <funcprototype>
                            <funcdef>raster <function>ST_Intersection</function></funcdef>
                            <paramdef><type>raster </type> <parameter>rast1</parameter></paramdef>
                            <paramdef><type>raster </type> <parameter>rast2</parameter></paramdef>
                            <paramdef><type>double precision[] </type> <parameter>nodataval</parameter></paramdef>
                      </funcprototype>

                      <funcprototype>
                            <funcdef>raster <function>ST_Intersection</function></funcdef>
                            <paramdef><type>raster </type> <parameter>rast1</parameter></paramdef>
                            <paramdef><type>raster </type> <parameter>rast2</parameter></paramdef>
                            <paramdef choice="opt"><type>text </type> <parameter>returnband</parameter></paramdef>
                            <paramdef choice="opt"><type>double precision[] </type> <parameter>nodataval</parameter></paramdef>
                      </funcprototype>

                      <funcprototype>
                            <funcdef>raster <function>ST_Intersection</function></funcdef>
                            <paramdef><type>raster </type> <parameter>rast1</parameter></paramdef>
                            <paramdef><type>integer </type> <parameter>band1</parameter></paramdef>
                            <paramdef><type>raster </type> <parameter>rast2</parameter></paramdef>
                            <paramdef><type>integer </type> <parameter>band2</parameter></paramdef>
                            <paramdef><type>double precision[] </type> <parameter>nodataval</parameter></paramdef>
                      </funcprototype>

                      <funcprototype>
                            <funcdef>raster <function>ST_Intersection</function></funcdef>
                            <paramdef><type>raster </type> <parameter>rast1</parameter></paramdef>
                            <paramdef><type>integer </type> <parameter>band1</parameter></paramdef>
                            <paramdef><type>raster </type> <parameter>rast2</parameter></paramdef>
                            <paramdef><type>integer </type> <parameter>band2</parameter></paramdef>
                            <paramdef choice="opt"><type>text </type> <parameter>returnband</parameter></paramdef>
                            <paramdef choice="opt"><type>double precision[] </type> <parameter>nodataval</parameter></paramdef>
                      </funcprototype>

                    </funcsynopsis>
                </refsynopsisdiv>

                <refsection>
                    <title>Description</title>
                    <para>
                        Returns a raster or a set of geometry-pixelvalue pairs representing the shared portion of two rasters or the geometrical intersection of a vectorization of the raster and a geometry.
                    </para>

                    <para>
                        The first three variants, returning a setof geomval, works in vector space. The raster is first vectorized (using <xref linkend="RT_ST_DumpAsPolygons"/>) into a set of geomval rows and those rows are then intersected with the geometry using the <xref linkend="ST_Intersection"/> (geometry, geometry) PostGIS function. Geometries intersecting only with a nodata value area of a raster returns an empty geometry. They are normally excluded from the results by the proper usage of <xref linkend="RT_ST_Intersects"/> in the WHERE clause.
                    </para>

                    <para>
                        You can access the geometry and the value parts of the resulting set of geomval by surrounding them with parenthesis and adding '.geom' or '.val' at the end of the expression. e.g. (ST_Intersection(rast, geom)).geom
                    </para>

                    <para>
                        The other variants, returning a raster, works in raster space. They are using the two rasters version of ST_MapAlgebraExpr to perform the intersection.
                    </para>

                    <para>
                        The extent of the resulting raster corresponds to the geometrical intersection of the two raster extents. The resulting raster includes 'BAND1', 'BAND2' or 'BOTH' bands, following what is passed as the <varname>returnband</varname> parameter. Nodata value areas present in any band results in nodata value areas in every bands of the result. In other words, any pixel intersecting with a nodata value pixel becomes a nodata value pixel in the result.
                    </para>

                    <para>
                        Rasters resulting from ST_Intersection must have a nodata value assigned for areas not intersecting. You can define or replace the nodata value for any resulting band by providing a <varname>nodataval[]</varname> array of one or two nodata values depending if you request 'BAND1', 'BAND2' or 'BOTH' bands. The first value in the array replace the nodata value in the first band and the second value replace the nodata value in the second band. If one input band do not have a nodata value defined and none are provided as an array, one is chosen using the ST_MinPossibleValue function. All variant accepting an array of nodata value can also accept a single value which will be assigned to each requested band.
                    </para>

                    <para>
                        In all variants, if no band number is specified band 1 is assumed.  If you need an intersection between a raster and geometry that returns a raster, refer to <xref linkend="RT_ST_Clip"/>.
                    </para>

                    <note>
                        <para>For more control over the result extent or NODATA
                        handling, use the two-raster variant of <xref
                        linkend="RT_ST_MapAlgebraExpr2"/>. To compute a
                        raster-space intersection with a geometry, use <xref
                        linkend="RT_ST_Clip"/>.</para>
                        <para>Use this function together with <xref
                        linkend="RT_ST_Intersects"/> and an index on the raster
                        or geometry column when filtering table data.</para>
                    </note>

                    <para>
                        Enhanced: 2.0.0 - Intersection in the raster space was introduced. In earlier pre-2.0.0 versions, only intersection performed in vector space were supported.
                    </para>
                </refsection>

                <refsection>
                    <title>Examples: Geometry, Raster -- resulting in geometry vals</title>

                    <programlisting language="sql">
SELECT
    foo.rid,
    foo.gid,
    GeometryType((foo.geomval).geom) AS geom_type,
    (foo.geomval).val AS value
FROM (
    SELECT
        A.rid,
        g.gid,
        ST_Intersection(A.rast, g.geom) As geomval
    FROM dummy_rast AS A
    CROSS JOIN (
        VALUES
            (1, ST_Point(3427928, 5793243.85) ),
            (2, 'LINESTRING(3427927.85 5793243.75,3427927.8 5793243.75,3427927.8 5793243.8)'::geometry),
            (3, 'LINESTRING(1 2,3 4)'::geometry)
    ) As g(gid, geom)
    WHERE A.rid = 2
) AS foo;</programlisting>
<screen role="text-primary"> rid | gid |      geom_type       | value
-----+-----+----------------------+-------
   2 |   1 | POINT                |   249
   2 |   1 | POINT                |   253
   2 |   2 | POINT                |   254
   2 |   2 | POINT                |   251
   2 |   2 | POINT                |   253
   2 |   2 | LINESTRING           |   252
   2 |   2 | MULTILINESTRING      |   250
   2 |   3 | GEOMETRYCOLLECTION   |</screen>

                    <para>The same line example rendered in a common coordinate
                    frame. The raster footprint and complete input line remain
                    visible behind the returned intersection pieces.</para>
                    <programlisting language="sql">WITH source AS (
    SELECT
        rast,
        ST_GeomFromText(
            'LINESTRING(3427927.85 5793243.75,'
            '3427927.8 5793243.75,3427927.8 5793243.8)'
        ) AS input_geometry
    FROM dummy_rast
    WHERE rid = 2
), intersection AS (
SELECT
    rast,
    input_geometry,
    ST_Collect(gv.geom) AS result_geometry
FROM source
CROSS JOIN LATERAL ST_Intersection(rast, input_geometry) AS gv
GROUP BY rast, input_geometry
), layers AS (
    SELECT
        'raster' AS title,
        ST_Translate(ST_Envelope(rast), -3427927.75, -5793243.75) AS geom
    FROM intersection
    UNION ALL
    SELECT
        'input',
        ST_Translate(input_geometry, -3427927.75, -5793243.75)
    FROM intersection
    UNION ALL
    SELECT
        'intersection',
        ST_Translate(result_geometry, -3427927.75, -5793243.75)
    FROM intersection
)
SELECT title, geom AS geom
FROM layers
ORDER BY CASE title
    WHEN 'raster' THEN 1
    WHEN 'input' THEN 2
    ELSE 3
END;</programlisting>
                    <screen role="visual-primary visual-overlay"> title        | geom
--------------+-------------------------------------------------------------
 raster       | POLYGON((0 0,0 0.25,0.25 0.25,0.25 0,0 0))
 input        | LINESTRING(0.1 0,0.05 0,0.05 0.05)
 intersection | GEOMETRYCOLLECTION</screen>
                </refsection>

                <refsection>
                    <title>See Also</title>
                    <para>
                        <xref linkend="geomval"/>,
                        <xref linkend="RT_ST_Intersects"/>,
                        <xref linkend="RT_ST_MapAlgebraExpr2"/>,
                        <xref linkend="RT_ST_Clip"/>,
                        <xref linkend="ST_AsText"/>
                    </para>
                </refsection>
            </refentry>

            <refentry xml:id="RT_ST_MapAlgebra">
                <refnamediv>
                    <refname>ST_MapAlgebra (callback function version)</refname>
                    <refpurpose>
                        Callback function version - Returns a one-band raster given one or more input rasters, band indexes and one user-specified callback function.
                    </refpurpose>
                </refnamediv>

                <refsynopsisdiv>
                    <funcsynopsis>
                        <funcprototype>
                            <funcdef>raster <function>ST_MapAlgebra</function></funcdef>
                            <paramdef><type>rastbandarg[] </type> <parameter>rastbandargset</parameter></paramdef>
                            <paramdef><type>regprocedure </type> <parameter>callbackfunc</parameter></paramdef>
                            <paramdef choice="opt"><type>text </type> <parameter>pixeltype=NULL</parameter></paramdef>
                            <paramdef choice="opt"><type>text </type> <parameter>extenttype=INTERSECTION</parameter></paramdef>
                            <paramdef choice="opt"><type>raster </type> <parameter>customextent=NULL</parameter></paramdef>
                            <paramdef choice="opt"><type>integer </type> <parameter>distancex=0</parameter></paramdef>
                            <paramdef choice="opt"><type>integer </type> <parameter>distancey=0</parameter></paramdef>
                            <paramdef choice="opt"><type>text[] </type> <parameter>VARIADIC userargs=NULL</parameter></paramdef>
                        </funcprototype>

                        <funcprototype>
                            <funcdef>raster <function>ST_MapAlgebra</function></funcdef>
                            <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                            <paramdef><type>integer[] </type> <parameter>nband</parameter></paramdef>
                            <paramdef><type>regprocedure </type> <parameter>callbackfunc</parameter></paramdef>
                            <paramdef choice="opt"><type>text </type> <parameter>pixeltype=NULL</parameter></paramdef>
                            <paramdef choice="opt"><type>text </type> <parameter>extenttype=FIRST</parameter></paramdef>
                            <paramdef choice="opt"><type>raster </type> <parameter>customextent=NULL</parameter></paramdef>
                            <paramdef choice="opt"><type>integer </type> <parameter>distancex=0</parameter></paramdef>
                            <paramdef choice="opt"><type>integer </type> <parameter>distancey=0</parameter></paramdef>
                            <paramdef choice="opt"><type>text[] </type> <parameter>VARIADIC userargs=NULL</parameter></paramdef>
                        </funcprototype>

                        <funcprototype>
                            <funcdef>raster <function>ST_MapAlgebra</function></funcdef>
                            <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                            <paramdef><type>integer </type> <parameter>nband</parameter></paramdef>
                            <paramdef><type>regprocedure </type> <parameter>callbackfunc</parameter></paramdef>
                            <paramdef choice="opt"><type>text </type> <parameter>pixeltype=NULL</parameter></paramdef>
                            <paramdef choice="opt"><type>text </type> <parameter>extenttype=FIRST</parameter></paramdef>
                            <paramdef choice="opt"><type>raster </type> <parameter>customextent=NULL</parameter></paramdef>
                            <paramdef choice="opt"><type>integer </type> <parameter>distancex=0</parameter></paramdef>
                            <paramdef choice="opt"><type>integer </type> <parameter>distancey=0</parameter></paramdef>
                            <paramdef choice="opt"><type>text[] </type> <parameter>VARIADIC userargs=NULL</parameter></paramdef>
                        </funcprototype>

                        <funcprototype>
                            <funcdef>raster <function>ST_MapAlgebra</function></funcdef>
                            <paramdef><type>raster </type> <parameter>rast1</parameter></paramdef>
                            <paramdef><type>integer </type> <parameter>nband1</parameter></paramdef>
                            <paramdef><type>raster </type> <parameter>rast2</parameter></paramdef>
                            <paramdef><type>integer </type> <parameter>nband2</parameter></paramdef>
                            <paramdef><type>regprocedure </type> <parameter>callbackfunc</parameter></paramdef>
                            <paramdef choice="opt"><type>text </type> <parameter>pixeltype=NULL</parameter></paramdef>
                            <paramdef choice="opt"><type>text </type> <parameter>extenttype=INTERSECTION</parameter></paramdef>
                            <paramdef choice="opt"><type>raster </type> <parameter>customextent=NULL</parameter></paramdef>
                            <paramdef choice="opt"><type>integer </type> <parameter>distancex=0</parameter></paramdef>
                            <paramdef choice="opt"><type>integer </type> <parameter>distancey=0</parameter></paramdef>
                            <paramdef choice="opt"><type>text[] </type> <parameter>VARIADIC userargs=NULL</parameter></paramdef>
                        </funcprototype>

                        <funcprototype>
                            <funcdef>raster <function>ST_MapAlgebra</function></funcdef>
                            <paramdef><type>raster</type> <parameter>rast</parameter></paramdef>
                            <paramdef><type>integer</type> <parameter>nband</parameter></paramdef>
                            <paramdef><type>regprocedure </type> <parameter>callbackfunc</parameter></paramdef>
                            <paramdef><type>float8[] </type> <parameter>mask</parameter></paramdef>
                            <paramdef><type>boolean </type> <parameter>weighted</parameter></paramdef>
                            <paramdef choice="opt"><type>text </type> <parameter>pixeltype=NULL</parameter></paramdef>
                            <paramdef choice="opt"><type>text </type> <parameter>extenttype=INTERSECTION</parameter></paramdef>
                            <paramdef choice="opt"><type>raster </type> <parameter>customextent=NULL</parameter></paramdef>
                            <paramdef choice="opt"><type>text[] </type> <parameter>VARIADIC userargs=NULL</parameter></paramdef>
                        </funcprototype>

                    </funcsynopsis>
                </refsynopsisdiv>

                <refsection>
                    <title>Description</title>

                    <para>
                        Returns a one-band raster given one or more input rasters, band indexes and one user-specified callback function.
                    </para>

                    <variablelist>
                        <varlistentry>
                            <term><varname>rast,rast1,rast2, rastbandargset</varname></term>
                            <listitem>
                                <para>
                                    Rasters on which the map algebra process is evaluated.</para><para><varname>rastbandargset</varname> allows the use of a map algebra operation on many rasters and/or many bands. See example Variant 1.
                                </para>
                            </listitem>
                        </varlistentry>
                        <varlistentry>
                            <term><varname>nband, nband1, nband2</varname></term>
                            <listitem>
                                <para>
                                    Band numbers of the raster to be evaluated. nband can be an integer or integer[] denoting the bands. nband1 is band on rast1 and nband2 is band on rast2 for the 2 raster/2band case.
                                </para>
                            </listitem>
                        </varlistentry>
                        <varlistentry>
                            <term><varname>callbackfunc</varname></term>
                            <listitem>
                                <para>
                                    The <varname>callbackfunc</varname> parameter must be the name and signature of an SQL or PL/pgSQL function, cast to a regprocedure. An example PL/pgSQL function example is:
                                </para>
                                    <programlisting language="sql">
CREATE OR REPLACE FUNCTION sample_callbackfunc(value double precision[][][], pos integer[][], VARIADIC userargs text[])
    RETURNS double precision
    AS $$
    BEGIN
        RETURN 0;
    END;
    $$ LANGUAGE 'plpgsql' IMMUTABLE;
                                    </programlisting>

                                <para>
                                    The <varname>callbackfunc</varname> must have two or three arguments: a 3-dimension double precision array, a 2-dimension integer array and, optionally, a variadic 1-dimension text array. The first argument <varname>value</varname> is the set of values (as double precision) from all input rasters. The three dimensions (where indexes are 1-based) are: raster #, row y, column x. The second argument <varname>position</varname> is the set of pixel positions from the output raster and input rasters. The outer dimension (where indexes are 0-based) is the raster #.  The position at outer dimension index 0 is the output raster's pixel position.  For each outer dimension, there are two elements in the inner dimension for X and Y.  The optional third argument <varname>userargs</varname> is for passing through any user-specified arguments.
                                </para>

                                <para>
                                    The callback return value is used as the value of the output pixel. If the callback returns <varname>NULL</varname>, the output pixel is set to NODATA when the output band has a NODATA value. If the output band has no NODATA value, a <varname>NULL</varname> callback result raises an error.
                                </para>

                                <para>
                                    Passing a <type>regprocedure</type> argument to a SQL function requires the full function signature to be passed, then cast to a <type>regprocedure</type> type. To pass the above example PL/pgSQL function as an argument, the SQL for the argument is:
                                </para>

                                    <programlisting language="sql">'sample_callbackfunc(double precision[], integer[], text[])'::regprocedure</programlisting>

                                <para>
                                    Note that PostgreSQL array types do not encode dimensions in function signatures, so multidimensional callback arguments are written as <type>double precision[]</type> and <type>integer[]</type> in the <type>regprocedure</type> signature.
                                </para>

                            </listitem>
                        </varlistentry>

                        <varlistentry>
                            <term><varname>mask</varname></term>
                            <listitem>
                                <para>
                                    An n-dimensional array (matrix) of numbers used to filter what cells get passed to map algebra call-back function. 0 means a neighbor cell value should be treated as no-data and 1 means value should be treated as data.  If weight is set to true, then the values, are used as multipliers to multiple the pixel value of that value in the neighborhood position.
                                </para>
                            </listitem>
                        </varlistentry>

                        <varlistentry>
                            <term><varname>weighted</varname></term>
                            <listitem>
                                <para>
                                    boolean (true/false) to denote if a mask value should be weighted (multiplied by original value) or not (only applies to proto that takes a mask).
                                </para>
                            </listitem>
                        </varlistentry>

                        <varlistentry>
                            <term><varname>pixeltype</varname></term>
                            <listitem>
                                <para>
                                    If <varname>pixeltype</varname> is passed in, the one band of the new raster will be of that pixeltype. If pixeltype is passed NULL or left out, the new raster band will have the same pixeltype as the specified band of the first raster (for extent types: INTERSECTION, UNION, FIRST, CUSTOM) or the specified band of the appropriate raster (for extent types: SECOND, LAST).  If in doubt, always specify <varname>pixeltype</varname>.
                                </para>
                                <para>
                                    The resulting pixel type of the output raster must be one listed in <xref linkend="RT_ST_BandPixelType"/> or left out or set to NULL.
                                </para>
                            </listitem>
                        </varlistentry>

                        <varlistentry>
                            <term><varname>extenttype</varname></term>
                            <listitem>
                                <para>
                                    Possible values are INTERSECTION (default), UNION, FIRST (default for one raster variants), SECOND, LAST, CUSTOM.
                                </para>
                            </listitem>
                        </varlistentry>

                        <varlistentry>
                            <term><varname>customextent</varname></term>
                            <listitem>
                                <para>
                                    If <varname>extentype</varname> is CUSTOM, a raster must be provided for <varname>customextent</varname>. See example 4 of Variant 1.
                                </para>
                            </listitem>
                        </varlistentry>

                        <varlistentry>
                            <term><varname>distancex</varname></term>
                            <listitem>
                                <para>
                                    The distance in pixels from the reference cell in x direction. So width of resulting matrix would be <code>2*distancex + 1</code>.If not specified only the reference cell is considered (neighborhood of 0).
                                </para>
                            </listitem>
                        </varlistentry>

                        <varlistentry>
                            <term><varname>distancey</varname></term>
                            <listitem>
                                <para>
                                    The distance in pixels from reference cell in y direction. Height of resulting matrix would be <code>2*distancey + 1</code> .If not specified only the reference cell is considered (neighborhood of 0).
                                </para>
                            </listitem>
                        </varlistentry>

                        <varlistentry>
                            <term><varname>userargs</varname></term>
                            <listitem>
                                <para>
                                    If the <varname>callbackfunc</varname> declares a third argument, that argument is a <type>variadic text</type> array. All trailing text arguments are passed through to the specified <varname>callbackfunc</varname>, and are contained in the <varname>userargs</varname> argument.
                                </para>
                            </listitem>
                        </varlistentry>
                    </variablelist>

                    <note>
                        <para>
                            For more information about the VARIADIC keyword, please refer to the PostgreSQL documentation and the "SQL Functions with Variable Numbers of Arguments" section of <link xlink:href="http://www.postgresql.org/docs/current/static/xfunc-sql.html">Query Language (SQL) Functions</link>.
                        </para>
                    </note>

                    <para>
                        Variant 1 accepts an array of <varname>rastbandarg</varname> allowing the use of a map algebra operation on many rasters and/or many bands. See example Variant 1.
                    </para>

                    <para>
                        Variants 2 and 3 operate upon one or more bands of one raster. See example Variant 2 and 3.
                    </para>

                    <para>
                        Variant 4 operate upon two rasters with one band per raster. See example Variant 4.
                    </para>

                    <para role="availability" conformance="2.2.0">Availability: 2.2.0: Ability to add a mask</para>
                    <para role="availability" conformance="2.1.0">Availability: 2.1.0</para>

                </refsection>

                <refsection>
                    <title>Examples</title>
                    <para>Compare an unmasked mean with neighbor-only and weighted-neighbor masks. The weighted mask multiplies neighboring values by 2 before computing the result.</para>
                    <programlisting language="sql">WITH foo AS (
    SELECT ST_SetBandNoDataValue(
        ST_SetValue(
            ST_SetValue(
                ST_AsRaster(
                    ST_Buffer('LINESTRING(50 50,100 90,100 50)'::geometry, 5, 'join=bevel'),
                    200, 200, ARRAY['8BUI'], ARRAY[100], ARRAY[0]
                ),
                ST_Buffer('POINT(70 70)'::geometry, 10, 'quad_segs=1'),
                50
            ),
            'LINESTRING(20 20,100 100,150 98)'::geometry,
            1
        ),
        0
    ) AS rast
), variants AS (
    SELECT 'original' AS title, rast
    FROM foo
    UNION ALL
    SELECT 'unmasked mean' AS title,
        ST_MapAlgebra(rast, 1, 'ST_Mean4ma(double precision[], int[], text[])'::regprocedure) AS rast
    FROM foo
    UNION ALL
    SELECT 'neighbor-only mean' AS title,
        ST_MapAlgebra(
            rast,
            1,
            'ST_Mean4ma(double precision[], int[], text[])'::regprocedure,
            '{{1,1,1}, {1,0,1}, {1,1,1}}'::double precision[],
            false
        ) AS rast
    FROM foo
    UNION ALL
    SELECT 'weighted neighbor mean' AS title,
        ST_MapAlgebra(
            rast,
            1,
            'ST_Mean4ma(double precision[], int[], text[])'::regprocedure,
            '{{2,2,2}, {2,0,2}, {2,2,2}}'::double precision[],
            true
        ) AS rast
    FROM foo
)
SELECT title, ST_AsPNG(rast) AS image
FROM variants;</programlisting>
                    <screen role="visual-primary"> title                  | image
------------------------+--------------------------------
 original               | PNG image, 200 x 200 pixels
 unmasked mean          | PNG image, 200 x 200 pixels
 neighbor-only mean     | PNG image, 200 x 200 pixels
 weighted neighbor mean | PNG image, 200 x 200 pixels
                    </screen>
                    <para>Variant 1.</para>

                    <para>One raster, one band</para>
                    <programlisting language="sql">
WITH foo AS (
    SELECT 1 AS rid, ST_AddBand(ST_MakeEmptyRaster(2, 2, 0, 0, 1, -1, 0, 0, 0), 1, '16BUI', 1, 0) AS rast
)
SELECT
    ST_MapAlgebra(ARRAY[ROW(rast, 1)]::rastbandarg[],
        'sample_callbackfunc(double precision[], int[], text[])'::regprocedure
    ) AS rast
FROM foo
                    </programlisting>

                    <para>One raster, several bands</para>
                    <programlisting language="sql">
WITH foo AS (
    SELECT 1 AS rid, ST_AddBand(ST_AddBand(ST_AddBand(ST_MakeEmptyRaster(2, 2, 0, 0, 1, -1, 0, 0, 0), 1, '16BUI', 1, 0), 2, '8BUI', 10, 0), 3, '32BUI', 100, 0) AS rast
)
SELECT
    ST_MapAlgebra(ARRAY[ROW(rast, 3), ROW(rast, 1), ROW(rast, 3), ROW(rast, 2)]::rastbandarg[],
        'sample_callbackfunc(double precision[], int[], text[])'::regprocedure
    ) AS rast
FROM foo
                    </programlisting>

                    <para>Several rasters, several bands</para>
                    <programlisting language="sql">
WITH foo AS (
    SELECT 1 AS rid, ST_AddBand(ST_AddBand(ST_AddBand(ST_MakeEmptyRaster(2, 2, 0, 0, 1, -1, 0, 0, 0), 1, '16BUI', 1, 0), 2, '8BUI', 10, 0), 3, '32BUI', 100, 0) AS rast UNION ALL
    SELECT 2 AS rid, ST_AddBand(ST_AddBand(ST_AddBand(ST_MakeEmptyRaster(2, 2, 0, 1, 1, -1, 0, 0, 0), 1, '16BUI', 2, 0), 2, '8BUI', 20, 0), 3, '32BUI', 300, 0) AS rast
)
SELECT
    ST_MapAlgebra(ARRAY[ROW(t1.rast, 3), ROW(t2.rast, 1), ROW(t2.rast, 3), ROW(t1.rast, 2)]::rastbandarg[],
        'sample_callbackfunc(double precision[], int[], text[])'::regprocedure
    ) AS rast
FROM foo t1
CROSS JOIN foo t2
WHERE t1.rid = 1
    AND t2.rid = 2
                    </programlisting>

                    <para>Complete example of tiles of a coverage with neighborhood.</para>
                    <programlisting language="sql">
WITH foo AS (
    SELECT 0 AS rid, ST_AddBand(ST_MakeEmptyRaster(2, 2, 0, 0, 1, -1, 0, 0, 0), 1, '16BUI', 1, 0) AS rast UNION ALL
    SELECT 1, ST_AddBand(ST_MakeEmptyRaster(2, 2, 2, 0, 1, -1, 0, 0, 0), 1, '16BUI', 2, 0) AS rast UNION ALL
    SELECT 2, ST_AddBand(ST_MakeEmptyRaster(2, 2, 4, 0, 1, -1, 0, 0, 0), 1, '16BUI', 3, 0) AS rast UNION ALL

    SELECT 3, ST_AddBand(ST_MakeEmptyRaster(2, 2, 0, -2, 1, -1, 0, 0, 0), 1, '16BUI', 10, 0) AS rast UNION ALL
    SELECT 4, ST_AddBand(ST_MakeEmptyRaster(2, 2, 2, -2, 1, -1, 0, 0, 0), 1, '16BUI', 20, 0) AS rast UNION ALL
    SELECT 5, ST_AddBand(ST_MakeEmptyRaster(2, 2, 4, -2, 1, -1, 0, 0, 0), 1, '16BUI', 30, 0) AS rast UNION ALL

    SELECT 6, ST_AddBand(ST_MakeEmptyRaster(2, 2, 0, -4, 1, -1, 0, 0, 0), 1, '16BUI', 100, 0) AS rast UNION ALL
    SELECT 7, ST_AddBand(ST_MakeEmptyRaster(2, 2, 2, -4, 1, -1, 0, 0, 0), 1, '16BUI', 200, 0) AS rast UNION ALL
    SELECT 8, ST_AddBand(ST_MakeEmptyRaster(2, 2, 4, -4, 1, -1, 0, 0, 0), 1, '16BUI', 300, 0) AS rast
)
SELECT
    t1.rid,
    ST_MapAlgebra(ARRAY[ROW(ST_Union(t2.rast), 1)]::rastbandarg[],
        'sample_callbackfunc(double precision[], int[], text[])'::regprocedure,
        '32BUI',
        'CUSTOM', t1.rast,
        1, 1
    ) AS rast
FROM foo t1
CROSS JOIN foo t2
WHERE t1.rid = 4
    AND t2.rid BETWEEN 0 AND 8
    AND ST_Intersects(t1.rast, t2.rast)
GROUP BY t1.rid, t1.rast
                    </programlisting>

                    <para>Example like the prior one for tiles of a coverage with neighborhood but using only basic SQL features.</para>
                    <programlisting language="sql">
WITH src AS (
    SELECT 0 AS rid, ST_AddBand(ST_MakeEmptyRaster(2, 2, 0, 0, 1, -1, 0, 0, 0), 1, '16BUI', 1, 0) AS rast UNION ALL
    SELECT 1, ST_AddBand(ST_MakeEmptyRaster(2, 2, 2, 0, 1, -1, 0, 0, 0), 1, '16BUI', 2, 0) AS rast UNION ALL
    SELECT 2, ST_AddBand(ST_MakeEmptyRaster(2, 2, 4, 0, 1, -1, 0, 0, 0), 1, '16BUI', 3, 0) AS rast UNION ALL

    SELECT 3, ST_AddBand(ST_MakeEmptyRaster(2, 2, 0, -2, 1, -1, 0, 0, 0), 1, '16BUI', 10, 0) AS rast UNION ALL
    SELECT 4, ST_AddBand(ST_MakeEmptyRaster(2, 2, 2, -2, 1, -1, 0, 0, 0), 1, '16BUI', 20, 0) AS rast UNION ALL
    SELECT 5, ST_AddBand(ST_MakeEmptyRaster(2, 2, 4, -2, 1, -1, 0, 0, 0), 1, '16BUI', 30, 0) AS rast UNION ALL

    SELECT 6, ST_AddBand(ST_MakeEmptyRaster(2, 2, 0, -4, 1, -1, 0, 0, 0), 1, '16BUI', 100, 0) AS rast UNION ALL
    SELECT 7, ST_AddBand(ST_MakeEmptyRaster(2, 2, 2, -4, 1, -1, 0, 0, 0), 1, '16BUI', 200, 0) AS rast UNION ALL
    SELECT 8, ST_AddBand(ST_MakeEmptyRaster(2, 2, 4, -4, 1, -1, 0, 0, 0), 1, '16BUI', 300, 0) AS rast
), foo AS (
    SELECT
        t1.rid,
        ST_Union(t2.rast) AS rast
    FROM src t1
    JOIN src t2
        ON ST_Intersects(t1.rast, t2.rast)
        AND t2.rid BETWEEN 0 AND 8
    WHERE t1.rid = 4
    GROUP BY t1.rid
), bar AS (
    SELECT
        t1.rid,
        ST_MapAlgebra(
            ARRAY[ROW(t2.rast, 1)]::rastbandarg[],
            'sample_callbackfunc(double precision[], int[], text[])'::regprocedure,
            '32BUI',
            'CUSTOM', t1.rast,
            1, 1
        ) AS rast
    FROM src t1
    JOIN foo t2
        ON t1.rid = t2.rid
)
SELECT
    rid,
    (ST_MetaData(rast)),
    (ST_BandMetaData(rast, 1)),
    ST_Value(rast, 1, 1, 1)
FROM bar;
                    </programlisting>

                    <para>Variants 2 and 3.</para>

                    <para>One raster, several bands</para>
                    <programlisting language="sql">
WITH foo AS (
    SELECT 1 AS rid, ST_AddBand(ST_AddBand(ST_AddBand(ST_MakeEmptyRaster(2, 2, 0, 0, 1, -1, 0, 0, 0), 1, '16BUI', 1, 0), 2, '8BUI', 10, 0), 3, '32BUI', 100, 0) AS rast
)
SELECT
    ST_MapAlgebra(
        rast,
        ARRAY[3, 1, 3, 2]::integer[],
        'sample_callbackfunc(double precision[], int[], text[])'::regprocedure
    ) AS rast
FROM foo
                    </programlisting>

                    <para>One raster, one band</para>
                    <programlisting language="sql">
WITH foo AS (
    SELECT 1 AS rid, ST_AddBand(ST_AddBand(ST_AddBand(ST_MakeEmptyRaster(2, 2, 0, 0, 1, -1, 0, 0, 0), 1, '16BUI', 1, 0), 2, '8BUI', 10, 0), 3, '32BUI', 100, 0) AS rast
)
SELECT
    ST_MapAlgebra(
        rast,
        2,
        'sample_callbackfunc(double precision[], int[], text[])'::regprocedure
    ) AS rast
FROM foo
                    </programlisting>

                    <para>Variant 4.</para>

                    <para>Two rasters, two bands</para>
                    <programlisting language="sql">
WITH foo AS (
    SELECT 1 AS rid, ST_AddBand(ST_AddBand(ST_AddBand(ST_MakeEmptyRaster(2, 2, 0, 0, 1, -1, 0, 0, 0), 1, '16BUI', 1, 0), 2, '8BUI', 10, 0), 3, '32BUI', 100, 0) AS rast UNION ALL
    SELECT 2 AS rid, ST_AddBand(ST_AddBand(ST_AddBand(ST_MakeEmptyRaster(2, 2, 0, 1, 1, -1, 0, 0, 0), 1, '16BUI', 2, 0), 2, '8BUI', 20, 0), 3, '32BUI', 300, 0) AS rast
)
SELECT
    ST_MapAlgebra(
        t1.rast,
        2,
        t2.rast,
        1,
        'sample_callbackfunc(double precision[], int[], text[])'::regprocedure
    ) AS rast
FROM foo t1
CROSS JOIN foo t2
WHERE t1.rid = 1
    AND t2.rid = 2
                    </programlisting>

                </refsection>


                <refsection>
                    <title>See Also</title>

                    <para>
                        <xref linkend="rastbandarg"/>,
                        <xref linkend="RT_ST_Union"/>,
                        <xref linkend="RT_ST_MapAlgebra_expr"/>
                    </para>
                </refsection>

            </refentry>

            <refentry xml:id="RT_ST_MapAlgebra_expr">
                <refnamediv>
                    <refname>ST_MapAlgebra (expression version)</refname>
                    <refpurpose>
                        Expression version - Returns a one-band raster given one or two input rasters, band indexes and one or more user-specified SQL expressions.
                    </refpurpose>
                </refnamediv>

                <refsynopsisdiv>
                    <funcsynopsis>

                        <funcprototype>
                            <funcdef>raster <function>ST_MapAlgebra</function></funcdef>
                            <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                            <paramdef><type>integer </type> <parameter>nband</parameter></paramdef>
                            <paramdef><type>text </type> <parameter>pixeltype</parameter></paramdef>
                            <paramdef><type>text </type> <parameter>expression</parameter></paramdef>
                            <paramdef choice="opt"><type>double precision </type> <parameter>nodataval=NULL</parameter></paramdef>
                        </funcprototype>

                        <funcprototype>
                            <funcdef>raster <function>ST_MapAlgebra</function></funcdef>
                            <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                            <paramdef><type>text </type> <parameter>pixeltype</parameter></paramdef>
                            <paramdef><type>text </type> <parameter>expression</parameter></paramdef>
                            <paramdef choice="opt"><type>double precision </type> <parameter>nodataval=NULL</parameter></paramdef>
                        </funcprototype>

                        <funcprototype>
                            <funcdef>raster <function>ST_MapAlgebra</function></funcdef>
                            <paramdef><type>raster </type> <parameter>rast1</parameter></paramdef>
                            <paramdef><type>integer </type> <parameter>nband1</parameter></paramdef>
                            <paramdef><type>raster </type> <parameter>rast2</parameter></paramdef>
                            <paramdef><type>integer </type> <parameter>nband2</parameter></paramdef>
                            <paramdef><type>text </type> <parameter>expression</parameter></paramdef>
                            <paramdef choice="opt"><type>text </type> <parameter>pixeltype=NULL</parameter></paramdef>
                            <paramdef choice="opt"><type>text </type> <parameter>extenttype=INTERSECTION</parameter></paramdef>
                            <paramdef choice="opt"><type>text </type> <parameter>nodata1expr=NULL</parameter></paramdef>
                            <paramdef choice="opt"><type>text </type> <parameter>nodata2expr=NULL</parameter></paramdef>
                            <paramdef choice="opt"><type>double precision </type> <parameter>nodatanodataval=NULL</parameter></paramdef>
                        </funcprototype>

                        <funcprototype>
                            <funcdef>raster <function>ST_MapAlgebra</function></funcdef>
                            <paramdef><type>raster </type> <parameter>rast1</parameter></paramdef>
                            <paramdef><type>raster </type> <parameter>rast2</parameter></paramdef>
                            <paramdef><type>text </type> <parameter>expression</parameter></paramdef>
                            <paramdef choice="opt"><type>text </type> <parameter>pixeltype=NULL</parameter></paramdef>
                            <paramdef choice="opt"><type>text </type> <parameter>extenttype=INTERSECTION</parameter></paramdef>
                            <paramdef choice="opt"><type>text </type> <parameter>nodata1expr=NULL</parameter></paramdef>
                            <paramdef choice="opt"><type>text </type> <parameter>nodata2expr=NULL</parameter></paramdef>
                            <paramdef choice="opt"><type>double precision </type> <parameter>nodatanodataval=NULL</parameter></paramdef>
                        </funcprototype>

                    </funcsynopsis>
                </refsynopsisdiv>

                <refsection>
                    <title>Description</title>

                    <para>
                        Expression version - Returns a one-band raster given one or two input rasters, band indexes and one or more user-specified SQL expressions.
                    </para>

                    <para role="availability" conformance="2.1.0">Availability: 2.1.0</para>
                </refsection>

                <refsection>
                    <title>Description: Variants 1 and 2 (one raster)</title>

                    <para>
                        Creates a new one band raster formed by applying a valid PostgreSQL algebraic operation defined by the <varname>expression</varname> on the input raster (<varname>rast</varname>). If <varname>nband</varname> is not provided, band 1 is assumed. The new raster will have the same georeference, width, and height as the original raster but will only have one band.
                    </para>

                    <para>
                        If <varname>pixeltype</varname> is passed in, then the new raster will have a band of that pixeltype.  If pixeltype is passed NULL, then the new raster band will have the same pixeltype as the input <varname>rast</varname> band.
                    </para>

                    <itemizedlist>
                        <listitem><para>Keywords permitted for <varname>expression</varname></para>
                         <orderedlist>
                            <listitem>
                                <para><varname>[rast]</varname> - Pixel value of the pixel of interest</para>
                            </listitem>
                            <listitem>
                                <para><varname>[rast.val]</varname> - Pixel value of the pixel of interest</para>
                            </listitem>
                            <listitem>
                                <para><varname>[rast.x]</varname> - 1-based pixel column of the pixel of interest</para>
                            </listitem>
                            <listitem>
                                <para><varname>[rast.y]</varname> - 1-based pixel row of the pixel of interest</para>
                            </listitem>
                         </orderedlist>
                        </listitem>
                    </itemizedlist>

                </refsection>

                <refsection>
                    <title>Description: Variants 3 and 4 (two raster)</title>

                    <para>
                        Creates a new one band raster formed by applying a valid PostgreSQL algebraic operation to the two bands defined by the <varname>expression</varname> on the two input raster bands <varname>rast1</varname>, (<varname>rast2</varname>). If no <varname>band1</varname>,  <varname>band2</varname> is specified band 1 is assumed. The resulting raster will be aligned (scale, skew and pixel corners) on the grid defined by the first raster. The resulting raster will have the extent defined by the <varname>extenttype</varname> parameter.
                    </para>

                    <variablelist>
                        <varlistentry>
                            <term><varname>expression</varname></term>
                            <listitem>
                                <para>
                                    A PostgreSQL algebraic expression involving the two rasters and PostgreSQL defined functions/operators that will define the pixel value when pixels intersect. e.g. (([rast1] + [rast2])/2.0)::integer
                                </para>
                            </listitem>
                        </varlistentry>
                        <varlistentry>
                            <term><varname>pixeltype</varname></term>
                            <listitem>
                                <para>
                                    The resulting pixel type of the output raster.  Must be one listed in <xref linkend="RT_ST_BandPixelType"/>, left out or set to NULL.  If not passed in or set to NULL, will default to the pixeltype of the first raster.
                                </para>
                            </listitem>
                        </varlistentry>
                        <varlistentry>
                            <term><varname>extenttype</varname></term>
                            <listitem>
                                <para>
                                    Controls the extent of resulting raster
                                </para>

                                <orderedlist>
                                    <listitem>
                                        <para>
                                            <varname>INTERSECTION</varname> - The extent of the new raster is the intersection of the two rasters. This is the default.
                                        </para>
                                    </listitem>
                                    <listitem>
                                        <para>
                                            <varname>UNION</varname> - The extent of the new raster is the union of the two rasters.
                                        </para>
                                    </listitem>
                                    <listitem>
                                        <para>
                                            <varname>FIRST</varname> - The extent of the new raster is the  same as the one of the first raster.
                                        </para>
                                    </listitem>
                                    <listitem>
                                        <para>
                                            <varname>SECOND</varname> - The extent of the new raster is the  same as the one of the second raster.
                                        </para>
                                    </listitem>
                                </orderedlist>
                            </listitem>
                        </varlistentry>
                        <varlistentry>
                            <term><varname>nodata1expr</varname></term>
                            <listitem>
                                <para>
                                    An algebraic expression involving only <varname>rast2</varname> or a constant that defines what to return when pixels of <varname>rast1</varname> are nodata values and spatially corresponding rast2 pixels have values.
                                </para>
                            </listitem>
                        </varlistentry>
                        <varlistentry>
                            <term><varname>nodata2expr</varname></term>
                            <listitem>
                                <para>
                                    An algebraic expression involving only <varname>rast1</varname> or a constant that defines what to return when pixels of <varname>rast2</varname> are nodata values and spatially corresponding rast1 pixels have values.
                                </para>
                            </listitem>
                        </varlistentry>
                        <varlistentry>
                            <term><varname>nodatanodataval</varname></term>
                            <listitem>
                                <para>
                                    A numeric constant to return when spatially corresponding rast1 and rast2 pixels are both nodata values.
                                </para>
                            </listitem>
                        </varlistentry>
                    </variablelist>

                    <itemizedlist>
                        <listitem><para>Keywords permitted in <varname>expression</varname>, <varname>nodata1expr</varname> and <varname>nodata2expr</varname></para>
                         <orderedlist>
                            <listitem>
                                <para><varname>[rast1]</varname> - Pixel value of the pixel of interest from <varname>rast1</varname></para>
                            </listitem>
                            <listitem>
                                <para><varname>[rast1.val]</varname> - Pixel value of the pixel of interest from <varname>rast1</varname></para>
                            </listitem>
                            <listitem>
                                <para><varname>[rast1.x]</varname> - 1-based pixel column of the pixel of interest from <varname>rast1</varname></para>
                            </listitem>
                            <listitem>
                                <para><varname>[rast1.y]</varname> - 1-based pixel row of the pixel of interest from <varname>rast1</varname></para>
                            </listitem>
                            <listitem>
                                <para><varname>[rast2]</varname> - Pixel value of the pixel of interest from <varname>rast2</varname></para>
                            </listitem>
                            <listitem>
                                <para><varname>[rast2.val]</varname> - Pixel value of the pixel of interest from <varname>rast2</varname></para>
                            </listitem>
                            <listitem>
                                <para><varname>[rast2.x]</varname> - 1-based pixel column of the pixel of interest from <varname>rast2</varname></para>
                            </listitem>
                            <listitem>
                                <para><varname>[rast2.y]</varname> - 1-based pixel row of the pixel of interest from <varname>rast2</varname></para>
                            </listitem>
                         </orderedlist>
                        </listitem>
                    </itemizedlist>
                </refsection>

                <refsection>
                    <title>Examples</title>
                    <para>Variants 1 and 2.</para>

                    <programlisting language="sql">
WITH foo AS (
    SELECT ST_AddBand(ST_MakeEmptyRaster(10, 10, 0, 0, 1, 1, 0, 0, 0), '32BF'::text, 1, -1) AS rast
)
SELECT
    ST_MapAlgebra(rast, 1, NULL, 'ceil([rast]*[rast.x]/[rast.y]+[rast.val])')
FROM foo;
                    </programlisting>

                    <para>Variant 3 and 4.</para>

                    <programlisting language="sql">
WITH foo AS (
    SELECT 1 AS rid, ST_AddBand(ST_AddBand(ST_AddBand(ST_MakeEmptyRaster(2, 2, 0, 0, 1, -1, 0, 0, 0), 1, '16BUI', 1, 0), 2, '8BUI', 10, 0), 3, '32BUI'::text, 100, 0) AS rast UNION ALL
    SELECT 2 AS rid, ST_AddBand(ST_AddBand(ST_AddBand(ST_MakeEmptyRaster(2, 2, 0, 1, 1, -1, 0, 0, 0), 1, '16BUI', 2, 0), 2, '8BUI', 20, 0), 3, '32BUI'::text, 300, 0) AS rast
)
SELECT
    ST_MapAlgebra(
        t1.rast,
        2,
        t2.rast,
        1,
        '([rast2] + [rast1.val]) / 2'
    ) AS rast
FROM foo t1
CROSS JOIN foo t2
WHERE t1.rid = 1
    AND t2.rid = 2;
                    </programlisting>
                </refsection>

                <refsection>
                    <title>See Also</title>

                    <para>
                        <xref linkend="rastbandarg"/>,
                        <xref linkend="RT_ST_Union"/>,
                        <xref linkend="RT_ST_MapAlgebra"/>
                    </para>
                </refsection>
            </refentry>

            <refentry xml:id="RT_ST_MapAlgebraExpr">
                <refnamediv>
                    <refname>ST_MapAlgebraExpr</refname>
                    <refpurpose>1 raster band version: Creates a new one band raster formed by applying a valid PostgreSQL algebraic operation on the input raster band and of pixeltype provided.  Band 1 is assumed if no band is specified.</refpurpose>
                </refnamediv>

                <refsynopsisdiv>
                    <funcsynopsis>

                      <funcprototype>
                            <funcdef>raster <function>ST_MapAlgebraExpr</function></funcdef>
                            <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                            <paramdef><type>integer </type> <parameter>band</parameter></paramdef>
                            <paramdef><type>text </type> <parameter>pixeltype</parameter></paramdef>
                            <paramdef><type>text </type> <parameter>expression</parameter></paramdef>
                            <paramdef choice="opt"><type>double precision </type> <parameter>nodataval=NULL</parameter></paramdef>
                      </funcprototype>

                      <funcprototype>
                            <funcdef>raster <function>ST_MapAlgebraExpr</function></funcdef>
                            <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                            <paramdef><type>text </type> <parameter>pixeltype</parameter></paramdef>
                            <paramdef><type>text </type> <parameter>expression</parameter></paramdef>
                            <paramdef choice="opt"><type>double precision </type> <parameter>nodataval=NULL</parameter></paramdef>
                      </funcprototype>
                    </funcsynopsis>
                </refsynopsisdiv>

                <refsection>
                    <title>Description</title>

                    <warning>
                        <para>
                            <xref linkend="RT_ST_MapAlgebraExpr"/> is deprecated as of 2.1.0. Use <xref linkend="RT_ST_MapAlgebra_expr"/> instead.
                        </para>
                    </warning>

                    <para>
                        Creates a new one band raster formed by applying a valid PostgreSQL algebraic operation defined by the <varname>expression</varname> on the input raster (<varname>rast</varname>). If no <varname>band</varname> is specified band 1 is assumed.  The new raster will have the same georeference, width, and height as the original raster but will only have one band.
                    </para>

                    <para>
                        If <varname>pixeltype</varname> is passed in, then the new raster will have a band of that pixeltype.  If pixeltype is passed NULL, then the new raster band will have the same pixeltype as the input <varname>rast</varname> band.
                    </para>

                    <para>
                        In the expression you can use the term <varname>[rast]</varname> to refer to the pixel value of the original band, <varname>[rast.x]</varname> to refer to the 1-based pixel column index, <varname>[rast.y]</varname> to refer to the 1-based pixel row index.
                    </para>

                    <para role="availability" conformance="2.0.0">Availability: 2.0.0 </para>
                </refsection>

                <refsection>
                    <title>Examples</title>

                    <para>Create a new 1 band raster from our original that is  a function of modulo 2 of the original raster band.</para>
                    <programlisting language="sql">
ALTER TABLE dummy_rast ADD COLUMN map_rast raster;
UPDATE dummy_rast SET map_rast = ST_MapAlgebraExpr(rast, NULL, 'mod([rast]::numeric,2)') WHERE rid = 2;

SELECT
    ST_Value(rast, 1, i, j) As origval,
    ST_Value(map_rast, 1, i, j) As mapval
FROM dummy_rast
CROSS JOIN generate_series(1, 3) AS i
CROSS JOIN generate_series(1, 3) AS j
WHERE rid = 2;</programlisting>
<screen role="text-primary"> origval | mapval
---------+--------
     253 |      1
     254 |      0
     253 |      1
     253 |      1
     254 |      0
     254 |      0
     250 |      0
     254 |      0
     254 |      0</screen>

                    <para>Create a new 1 band raster of pixel-type 2BUI from our original that is reclassified and set the nodata value to be 0.</para>
                    <programlisting language="sql">ALTER TABLE dummy_rast ADD COLUMN map_rast2 raster;
UPDATE dummy_rast SET
    map_rast2 = ST_MapAlgebraExpr(rast, '2BUI'::text, 'CASE WHEN [rast] BETWEEN 100 and 250 THEN 1 WHEN [rast] = 252 THEN 2 WHEN [rast] BETWEEN 253 and 254 THEN 3 ELSE 0 END'::text, '0')
WHERE rid = 2;

SELECT DISTINCT
    ST_Value(rast, 1, i, j) As origval,
    ST_Value(map_rast2, 1, i, j) As mapval
FROM dummy_rast
CROSS JOIN generate_series(1, 5) AS i
CROSS JOIN generate_series(1, 5) AS j
WHERE rid = 2;</programlisting>
<screen role="text-primary"> origval | mapval
---------+--------
     249 |      1
     250 |      1
     251 |
     252 |      2
     253 |      3
     254 |      3</screen>
<programlisting language="sql">SELECT
    ST_BandPixelType(map_rast2) As b1pixtyp
FROM dummy_rast
WHERE rid = 2;</programlisting>
<screen role="text-primary">2BUI</screen>

                    <para>A self-contained source raster and the raster produced
                    by classifying its values into four display levels.</para>
                    <programlisting language="sql">WITH source AS (
    SELECT ST_SetValues(
        ST_AddBand(
            ST_MakeEmptyRaster(8, 8, 0, 8, 1, -1, 0, 0, 0),
            1, '8BUI', 0, 0
        ),
        1, 1, 1,
        ARRAY[
            [0, 1, 2, 3, 4, 5, 6, 7],
            [8, 9, 10, 11, 12, 13, 14, 15],
            [16, 17, 18, 19, 20, 21, 22, 23],
            [24, 25, 26, 27, 28, 29, 30, 31],
            [32, 33, 34, 35, 36, 37, 38, 39],
            [40, 41, 42, 43, 44, 45, 46, 47],
            [48, 49, 50, 51, 52, 53, 54, 55],
            [56, 57, 58, 59, 60, 61, 62, 63]
        ]::double precision[][]
    ) AS rast
), variants AS (
    SELECT 'source' AS title, rast AS rendered
    FROM source
    UNION ALL
    SELECT
        'classified',
        ST_MapAlgebraExpr(rast, '8BUI', 'floor([rast] / 16) * 85')
    FROM source
)
SELECT title, ST_AsPNG(rendered) AS image
FROM variants
ORDER BY title DESC;</programlisting>
                    <screen role="visual-primary"> title      | image
------------+-------------------------
 source     | PNG image, 8 x 8 pixels
 classified | PNG image, 8 x 8 pixels</screen>
                    <para>Map algebra altering the first band of a three-band raster.</para>
<informaltable>
                      <tgroup cols="2">
                        <tbody>
                          <row>
                            <entry><para><informalfigure>
                                <mediaobject>
                                  <imageobject><imagedata fileref="images/st_mapalgebraexpr01.png"/></imageobject>
                                  <caption><para>original (column rast_view)</para></caption>
                                </mediaobject>
                              </informalfigure></para></entry>
                            <entry><para><informalfigure>
                                <mediaobject>
                                  <imageobject><imagedata fileref="images/st_mapalgebraexpr02.png"/></imageobject>
                                  <caption><para>rast_view_ma</para></caption>
                                </mediaobject>
                              </informalfigure></para></entry>
                          </row>
                        </tbody>
                      </tgroup>
                    </informaltable>

                    <para>Create a new 3 band raster same pixel type from our original 3 band raster with first band altered by map algebra and remaining 2 bands unaltered.</para>
                    <programlisting language="sql">
SELECT
    ST_AddBand(ST_AddBand(ST_AddBand(ST_MakeEmptyRaster(rast_view),
                ST_MapAlgebraExpr(rast_view, 1, NULL, 'tan([rast])*[rast]')
            ),
            ST_Band(rast_view, 2)
        ),
        ST_Band(rast_view, 3)
    )  As rast_view_ma
FROM wind
WHERE rid=167;
                    </programlisting>
                </refsection>

                <refsection>
                    <title>See Also</title>
                    <para>
                        <xref linkend="RT_ST_MapAlgebraExpr2"/>,
                        <xref linkend="RT_ST_MapAlgebraFct"/>,
                        <xref linkend="RT_ST_BandPixelType"/>,
                        <xref linkend="RT_ST_GeoReference"/>,
                        <xref linkend="RT_ST_Value"/>
                    </para>
                </refsection>
            </refentry>

            <refentry xml:id="RT_ST_MapAlgebraExpr2">
                <refnamediv>
                    <refname>ST_MapAlgebraExpr</refname>
                    <refpurpose>
                        2 raster band version: Creates a new one band raster formed by applying a valid PostgreSQL algebraic operation on the two input raster bands and of pixeltype provided.  band 1 of each raster is assumed if no band numbers are specified. The resulting raster will be aligned (scale, skew and pixel corners) on the grid defined by the first raster and have its extent defined by the "extenttype" parameter. Values for "extenttype" can be: INTERSECTION, UNION, FIRST, SECOND.
                    </refpurpose>
                </refnamediv>

                <refsynopsisdiv>
                    <funcsynopsis>
                        <funcprototype>
                            <funcdef>raster <function>ST_MapAlgebraExpr</function></funcdef>
                            <paramdef><type>raster </type> <parameter>rast1</parameter></paramdef>
                            <paramdef><type>raster </type> <parameter>rast2</parameter></paramdef>
                            <paramdef><type>text </type> <parameter>expression</parameter></paramdef>
                            <paramdef choice="opt"><type>text </type> <parameter>pixeltype=same_as_rast1_band</parameter></paramdef>
                            <paramdef choice="opt"><type>text </type> <parameter>extenttype=INTERSECTION</parameter></paramdef>
                            <paramdef choice="opt"><type>text </type> <parameter>nodata1expr=NULL</parameter></paramdef>
                            <paramdef choice="opt"><type>text </type> <parameter>nodata2expr=NULL</parameter></paramdef>
                            <paramdef choice="opt"><type>double precision </type> <parameter>nodatanodataval=NULL</parameter></paramdef>
                      </funcprototype>

                      <funcprototype>
                            <funcdef>raster <function>ST_MapAlgebraExpr</function></funcdef>
                            <paramdef><type>raster </type> <parameter>rast1</parameter></paramdef>
                            <paramdef><type>integer </type> <parameter>band1</parameter></paramdef>
                            <paramdef><type>raster </type> <parameter>rast2</parameter></paramdef>
                            <paramdef><type>integer </type> <parameter>band2</parameter></paramdef>
                            <paramdef><type>text </type> <parameter>expression</parameter></paramdef>
                            <paramdef choice="opt"><type>text </type> <parameter>pixeltype=same_as_rast1_band</parameter></paramdef>
                            <paramdef choice="opt"><type>text </type> <parameter>extenttype=INTERSECTION</parameter></paramdef>
                            <paramdef choice="opt"><type>text </type> <parameter>nodata1expr=NULL</parameter></paramdef>
                            <paramdef choice="opt"><type>text </type> <parameter>nodata2expr=NULL</parameter></paramdef>
                            <paramdef choice="opt"><type>double precision </type> <parameter>nodatanodataval=NULL</parameter></paramdef>
                      </funcprototype>
                    </funcsynopsis>
                </refsynopsisdiv>

                <refsection>
                    <title>Description</title>

                    <warning>
                        <para>
                            <xref linkend="RT_ST_MapAlgebraExpr2"/> is deprecated as of 2.1.0. Use <xref linkend="RT_ST_MapAlgebra_expr"/> instead.
                        </para>
                    </warning>

                    <para>
                        Creates a new one band raster formed by applying a valid PostgreSQL algebraic operation to the two bands defined by the <varname>expression</varname> on the two input raster bands <varname>rast1</varname>, (<varname>rast2</varname>). If no <varname>band1</varname>,  <varname>band2</varname> is specified band 1 is assumed. The resulting raster will be aligned (scale, skew and pixel corners) on the grid defined by the first raster. The resulting raster will have the extent defined by the <varname>extenttype</varname> parameter.
                    </para>

                    <variablelist>
                        <varlistentry>
                            <term><varname>expression</varname></term>
                            <listitem>
                                <para>
                                    A PostgreSQL algebraic expression involving the two rasters and PostgreSQL defined functions/operators that will define the pixel value when pixels intersect. e.g. (([rast1] + [rast2])/2.0)::integer
                                </para>
                            </listitem>
                        </varlistentry>

                        <varlistentry>
                            <term><varname>pixeltype</varname></term>
                            <listitem>
                                <para>
                                    The resulting pixel type of the output raster.  Must be one listed in <xref linkend="RT_ST_BandPixelType"/>, left out or set to NULL.  If not passed in or set to NULL, will default to the pixeltype of the first raster.
                                </para>
                            </listitem>
                        </varlistentry>

                        <varlistentry>
                            <term><varname>extenttype</varname></term>
                            <listitem>
                                <para>Controls the extent of resulting raster</para>
                                <orderedlist>
                                    <listitem>
                                        <para>
                                            <varname>INTERSECTION</varname> - The extent of the new raster is the intersection of the two rasters. This is the default.
                                        </para>
                                    </listitem>
                                    <listitem>
                                        <para>
                                            <varname>UNION</varname> - The extent of the new raster is the union of the two rasters.
                                        </para>
                                    </listitem>
                                    <listitem>
                                        <para>
                                            <varname>FIRST</varname> - The extent of the new raster is the  same as the one of the first raster.
                                        </para>
                                    </listitem>
                                    <listitem>
                                        <para>
                                            <varname>SECOND</varname> - The extent of the new raster is the  same as the one of the second raster.
                                        </para>
                                    </listitem>
                                </orderedlist>
                            </listitem>
                        </varlistentry>

                        <varlistentry>
                            <term><varname>nodata1expr</varname></term>
                            <listitem>
                                <para>
                                    An algebraic expression involving only <varname>rast2</varname> or a constant that defines what to return when pixels of <varname>rast1</varname> are nodata values and spatially corresponding rast2 pixels have values.
                                </para>
                            </listitem>
                        </varlistentry>

                        <varlistentry>
                            <term><varname>nodata2expr</varname></term>
                            <listitem>
                                <para>
                                    An algebraic expression involving only <varname>rast1</varname> or a constant that defines what to return when pixels of <varname>rast2</varname> are nodata values and spatially corresponding rast1 pixels have values.
                                </para>
                            </listitem>
                        </varlistentry>

                        <varlistentry>
                            <term><varname>nodatanodataval</varname></term>
                            <listitem>
                                <para>
                                    A numeric constant to return when spatially corresponding rast1 and rast2 pixels are both nodata values.
                                </para>
                            </listitem>
                        </varlistentry>
                    </variablelist>

                    <para>
                        If <varname>pixeltype</varname> is passed in, then the new raster will have a band of that pixeltype.  If pixeltype is passed NULL or no pixel type specified, then the new raster band will have the same pixeltype as the input <varname>rast1</varname> band.
                    </para>
                    <para>
                        Use the term <varname>[rast1.val]</varname>  <varname>[rast2.val]</varname> to refer to the pixel value of the original raster bands and <varname>[rast1.x]</varname>, <varname>[rast1.y]</varname> etc. to refer to the column / row positions of the pixels.
                    </para>

                    <para role="availability" conformance="2.0.0">Availability: 2.0.0 </para>
                </refsection>

                <refsection>
                    <title>Examples</title>
                    <para>2 Band Intersection and Union.</para>

                    <para>Create a new 1 band raster from our original that is  a function of modulo 2 of the original raster band.</para>
                    <para>Create a cool set of rasters.</para>
                    <para>Insert some cool shapes around Boston in Massachusetts state plane meters, then map their intersection and union.</para>
                    <programlisting language="sql">
DROP TABLE IF EXISTS fun_shapes;
CREATE TABLE fun_shapes(rid serial PRIMARY KEY, fun_name text, rast raster);

INSERT INTO fun_shapes(fun_name, rast)
VALUES ('ref', ST_AsRaster(ST_MakeEnvelope(235229, 899970, 237229, 901930, 26986), 200, 200, '8BUI', 0, 0));

INSERT INTO fun_shapes(fun_name, rast)
WITH ref(rast) AS (SELECT rast FROM fun_shapes WHERE fun_name = 'ref' )
SELECT 'area' AS fun_name, ST_AsRaster(ST_Buffer(ST_SetSRID(ST_Point(236229, 900930), 26986), 1000),
            ref.rast, '8BUI', 10, 0) As rast
FROM ref
UNION ALL
SELECT 'rand bubbles',
       ST_AsRaster(
           (
               SELECT ST_Collect(geom)
               FROM (
                   SELECT ST_Buffer(
                       ST_SetSRID(ST_Point(236229 + i*random()*100, 900930 + j*random()*100), 26986),
                       random()*20
                   ) AS geom
                   FROM generate_series(1, 10) AS i,
                        generate_series(1, 10) AS j
               ) AS foo
           ),
           ref.rast, '8BUI', 200, 0
       )
FROM ref;

SELECT  ST_MapAlgebraExpr(area.rast, bub.rast, '[rast2.val]', '8BUI', 'INTERSECTION', '[rast2.val]', '[rast1.val]') As interrast,
        ST_MapAlgebraExpr(area.rast, bub.rast, '[rast2.val]', '8BUI', 'UNION', '[rast2.val]', '[rast1.val]') As unionrast
FROM
  (SELECT rast FROM fun_shapes WHERE fun_name = 'area') As area
CROSS JOIN
  (SELECT rast FROM fun_shapes WHERE fun_name = 'rand bubbles') As bub
                    </programlisting>

                    <para>The same intersection and union operations using two
                    deterministic, self-contained rasters.</para>
                    <programlisting language="sql">WITH canvas AS (
    SELECT ST_AddBand(
        ST_MakeEmptyRaster(80, 80, 0, 80, 1, -1, 0, 0, 0),
        1, '8BUI', 40, 0
    ) AS rast
), inputs AS (
    SELECT
        rast AS raster_1,
        ST_AsRaster(
            ST_Buffer(ST_Point(40, 40), 28),
            rast,
            '8BUI', 220, 0
        ) AS raster_2
    FROM canvas
), variants AS (
    SELECT 'raster 1' AS title, raster_1 AS rendered FROM inputs
    UNION ALL
    SELECT 'raster 2', raster_2 FROM inputs
    UNION ALL
    SELECT 'intersection', ST_MapAlgebraExpr(
        raster_1, raster_2,
        '[rast2.val]', '8BUI', 'INTERSECTION',
        '[rast2.val]', '[rast1.val]'
    ) FROM inputs
    UNION ALL
    SELECT 'union', ST_MapAlgebraExpr(
        raster_1, raster_2,
        '[rast2.val]', '8BUI', 'UNION',
        '[rast2.val]', '[rast1.val]'
    ) FROM inputs
)
SELECT title, ST_AsPNG(rendered) AS image
FROM variants
ORDER BY CASE title
    WHEN 'raster 1' THEN 1
    WHEN 'raster 2' THEN 2
    WHEN 'intersection' THEN 3
    ELSE 4
END;</programlisting>
                    <screen role="visual-primary"> title        | image
--------------+---------------------------
 raster 1     | PNG image, 80 x 80 pixels
 raster 2     | PNG image, 56 x 56 pixels
 intersection | PNG image, 56 x 56 pixels
 union        | PNG image, 80 x 80 pixels</screen>

                    <para>Overlaying rasters on a one-unit-per-pixel canvas as separate bands. We use ST_AsPNG to render the image so all single band ones look grey.</para>
                    <programlisting language="sql">WITH mygeoms AS (
    SELECT 2 AS bnum, ST_Buffer(ST_Point(1, 5), 10) AS geom
    UNION ALL
    SELECT 3,
        ST_Buffer(
            ST_GeomFromText('LINESTRING(50 50,150 150,150 50)'),
            10,
            'join=bevel'
        )
    UNION ALL
    SELECT 1,
        ST_Buffer(
            ST_GeomFromText('LINESTRING(60 50,150 150,150 50)'),
            5,
            'join=bevel'
        )
), canvas AS (
    SELECT ST_AddBand(
        ST_MakeEmptyRaster(
            200,
            200,
            ST_XMin(e)::integer,
            ST_YMax(e)::integer,
            1, -1, 0, 0),
        '8BUI'::text,
        0
    ) AS rast
    FROM (
      SELECT ST_Extent(geom) AS e
      FROM mygeoms
    ) AS bounds
), rbands AS (
    SELECT ARRAY(
        SELECT ST_MapAlgebraExpr(
            canvas.rast,
            ST_AsRaster(m.geom, canvas.rast, '8BUI', 100),
            '[rast2.val]', '8BUI', 'FIRST',
            '[rast2.val]', '[rast1.val]'
        )
        FROM mygeoms AS m
        CROSS JOIN canvas
        ORDER BY m.bnum
    ) AS rasts
)
SELECT title, ST_AsPNG(rendered) AS image
FROM rbands
CROSS JOIN LATERAL (VALUES
    ('band 1', rasts[1]),
    ('band 2', rasts[2]),
    ('band 3', rasts[3]),
    ('RGB', ST_AddBand(ST_AddBand(rasts[1], rasts[2]), rasts[3]))
) AS variants(title, rendered);</programlisting>
                    <screen role="visual-primary"> title  | image
--------+-----------------------------
 band 1 | PNG image, 200 x 200 pixels
 band 2 | PNG image, 200 x 200 pixels
 band 3 | PNG image, 200 x 200 pixels
 RGB    | PNG image, 200 x 200 pixels</screen>

                    <para>Overlay a two-meter boundary of selected parcels over aerial imagery. The query first unions the parcel geometries, clips the source raster shards to the region, unions those smaller shards, and finally adds the first two bands plus a third-band map algebra overlay.</para>

                    <para>Create a new three-band raster composed of the first two clipped bands and the third band overlaid with the geometry. This query took 3.6 seconds on a 64-bit PostGIS Windows installation.</para>
                    <programlisting language="sql">WITH pr AS (
    SELECT ST_Clip(rast, ST_Expand(geom, 50)) AS rast, g.geom
    FROM aerials.o_2_boston AS r
    INNER JOIN (
        SELECT ST_Union(ST_Transform(geom, 26986)) AS geom
        FROM landparcels
        WHERE pid IN ('0303890000', '0303900000')
    ) AS g
        ON ST_Intersects(rast::geometry, ST_Expand(g.geom, 50))
), prunion AS (
    SELECT ST_AddBand(
        NULL,
        ARRAY[
            ST_Union(rast, 1),
            ST_Union(rast, 2),
            ST_Union(rast, 3)
        ]
    ) AS clipped,
    geom
    FROM pr
    GROUP BY geom
)
SELECT ST_AddBand(
    ST_Band(clipped, ARRAY[1, 2]),
    ST_MapAlgebraExpr(
     ST_Band(clipped, 3),
     ST_AsRaster(ST_Buffer(ST_Boundary(geom), 2), clipped, '8BUI', 250),
     '[rast2.val]',
     '8BUI',
     'FIRST',
     '[rast2.val]',
     '[rast1.val]') ) As rast
FROM prunion;
                    </programlisting>


                    <para>Parcel-boundary overlay.</para>
                    <informaltable>
                      <tgroup cols="1">
                        <tbody>
                          <row>
                            <entry><para><informalfigure>
                                <mediaobject>
                                  <imageobject><imagedata fileref="images/st_mapalgebraexpr2_08.png"/></imageobject>
                                  <caption><para>The blue lines are the boundaries of selected parcels</para></caption>
                                </mediaobject>
                              </informalfigure></para></entry>
                          </row>
                        </tbody>
                      </tgroup>
                    </informaltable>

                    <para>The generated four-panel canvas example above shows
                    the same band-overlay technique without requiring an
                    external aerial-imagery or parcel table.</para>
                </refsection>

                <refsection>
                    <title>See Also</title>
                    <para>
                        <xref linkend="RT_ST_MapAlgebraExpr"/>,
                        <xref linkend="RT_ST_AddBand"/>,
                        <xref linkend="RT_ST_AsPNG"/>,
                        <xref linkend="RT_ST_AsRaster"/>,
                        <xref linkend="RT_ST_MapAlgebraFct"/>,
                        <xref linkend="RT_ST_BandPixelType"/>,
                        <xref linkend="RT_ST_GeoReference"/>,
                        <xref linkend="RT_ST_Value"/>,
                        <xref linkend="RT_ST_Union"/>,
                        <xref linkend="ST_Union"/>
                    </para>
                </refsection>
            </refentry>

            <refentry xml:id="RT_ST_MapAlgebraFct">
                <refnamediv>
                    <refname>ST_MapAlgebraFct</refname>
                    <refpurpose>1 band version - Creates a new one band raster formed by applying a valid PostgreSQL function on the input raster band and of pixeltype provided. Band 1 is assumed if no band is specified.</refpurpose>
                </refnamediv>

                <refsynopsisdiv>
                    <funcsynopsis>
                        <funcprototype>
                            <funcdef>raster <function>ST_MapAlgebraFct</function></funcdef>
                            <paramdef><type>raster</type> <parameter>rast</parameter></paramdef>
                            <paramdef><type>regprocedure</type> <parameter>onerasteruserfunc</parameter></paramdef>
                        </funcprototype>
                        <funcprototype>
                            <funcdef>raster <function>ST_MapAlgebraFct</function></funcdef>
                            <paramdef><type>raster</type> <parameter>rast</parameter></paramdef>
                            <paramdef><type>regprocedure</type> <parameter>onerasteruserfunc</parameter></paramdef>
                            <paramdef><type>text[]</type> <parameter>VARIADIC args</parameter></paramdef>
                        </funcprototype>

                        <funcprototype>
                            <funcdef>raster <function>ST_MapAlgebraFct</function></funcdef>
                            <paramdef><type>raster</type> <parameter>rast</parameter></paramdef>
                            <paramdef><type>text</type> <parameter>pixeltype</parameter></paramdef>
                            <paramdef><type>regprocedure</type> <parameter>onerasteruserfunc</parameter></paramdef>
                        </funcprototype>
                        <funcprototype>
                            <funcdef>raster <function>ST_MapAlgebraFct</function></funcdef>
                            <paramdef><type>raster</type> <parameter>rast</parameter></paramdef>
                            <paramdef><type>text</type> <parameter>pixeltype</parameter></paramdef>
                            <paramdef><type>regprocedure</type> <parameter>onerasteruserfunc</parameter></paramdef>
                            <paramdef><type>text[]</type> <parameter>VARIADIC args</parameter></paramdef>
                        </funcprototype>

                        <funcprototype>
                            <funcdef>raster <function>ST_MapAlgebraFct</function></funcdef>
                            <paramdef><type>raster</type> <parameter>rast</parameter></paramdef>
                            <paramdef><type>integer</type> <parameter>band</parameter></paramdef>
                            <paramdef><type>regprocedure</type> <parameter>onerasteruserfunc</parameter></paramdef>
                        </funcprototype>
                        <funcprototype>
                            <funcdef>raster <function>ST_MapAlgebraFct</function></funcdef>
                            <paramdef><type>raster</type> <parameter>rast</parameter></paramdef>
                            <paramdef><type>integer</type> <parameter>band</parameter></paramdef>
                            <paramdef><type>regprocedure</type> <parameter>onerasteruserfunc</parameter></paramdef>
                            <paramdef><type>text[]</type> <parameter>VARIADIC args</parameter></paramdef>
                        </funcprototype>

                        <funcprototype>
                            <funcdef>raster <function>ST_MapAlgebraFct</function></funcdef>
                            <paramdef><type>raster</type> <parameter>rast</parameter></paramdef>
                            <paramdef><type>integer</type> <parameter>band</parameter></paramdef>
                            <paramdef><type>text</type> <parameter>pixeltype</parameter></paramdef>
                            <paramdef><type>regprocedure</type> <parameter>onerasteruserfunc</parameter></paramdef>
                        </funcprototype>
                        <funcprototype>
                            <funcdef>raster <function>ST_MapAlgebraFct</function></funcdef>
                            <paramdef><type>raster</type> <parameter>rast</parameter></paramdef>
                            <paramdef><type>integer</type> <parameter>band</parameter></paramdef>
                            <paramdef><type>text</type> <parameter>pixeltype</parameter></paramdef>
                            <paramdef><type>regprocedure</type> <parameter>onerasteruserfunc</parameter></paramdef>
                            <paramdef><type>text[]</type> <parameter>VARIADIC args</parameter></paramdef>
                        </funcprototype>

                    </funcsynopsis>
                </refsynopsisdiv>

                <refsection>
                    <title>Description</title>

                    <warning>
                        <para>
                            <xref linkend="RT_ST_MapAlgebraFct"/> is deprecated as of 2.1.0. Use <xref linkend="RT_ST_MapAlgebra"/> instead.
                        </para>
                    </warning>

                    <para>Creates a new one band raster formed by applying a valid PostgreSQL function specified by the <varname>onerasteruserfunc</varname> on the input raster (<varname>rast</varname>). If no <varname>band</varname> is specified, band 1 is assumed. The new raster will have the same georeference, width, and height as the original raster but will only have one band.</para>

                    <para>If <varname>pixeltype</varname> is passed in, then the new raster will have a band of that pixeltype. If pixeltype is passed NULL, then the new raster band will have the same pixeltype as the input <varname>rast</varname> band.</para>

                    <para>The <varname>onerasteruserfunc</varname> parameter must be the name and signature of a SQL or PL/pgSQL function, cast to a regprocedure. A very simple and quite useless PL/pgSQL function example is:
                    </para>
                <programlisting language="sql">CREATE OR REPLACE FUNCTION simple_function(pixel FLOAT, pos INTEGER[], VARIADIC args TEXT[])
RETURNS FLOAT
AS $$ BEGIN
    RETURN 0.0;
END; $$
LANGUAGE 'plpgsql' IMMUTABLE;</programlisting>
                    <para>
                The <varname>userfunction</varname> may accept two or three arguments: a float value, an optional integer array, and a variadic text array. The first argument is the value of an individual raster cell (regardless of the raster datatype). The second argument is the position of the current processing cell in the form '{x,y}'. The third argument indicates that all remaining parameters to <xref linkend="RT_ST_MapAlgebraFct"/> shall be passed through to the <varname>userfunction</varname>.
                    </para>

                    <para>
                        Passing a <type>regprodedure</type> argument to a SQL function requires the full function signature to be passed, then cast to a <type>regprocedure</type> type. To pass the above example PL/pgSQL function as an argument, the SQL for the argument is:
                    </para>
                    <programlisting language="sql">'simple_function(float,integer[],text[])'::regprocedure</programlisting>
                    <para>
Note that the argument contains the name of the function, the types of the function arguments, quotes around the name and argument types, and a cast to a <type>regprocedure</type>.
                    </para>

                    <para>
                        The third argument to the <varname>userfunction</varname> is a <type>variadic text</type> array. All trailing text arguments to any <xref linkend="RT_ST_MapAlgebraFct"/> call are passed through to the specified <varname>userfunction</varname>, and are contained in the <varname>args</varname> argument.
                    </para>

                    <note>
                        <para>For more information about the VARIADIC keyword, please refer to the PostgreSQL documentation and the "SQL Functions with Variable Numbers of Arguments" section of <link xlink:href="http://www.postgresql.org/docs/current/static/xfunc-sql.html">Query Language (SQL) Functions</link>.</para>
                    </note>

                    <note>
                        <para>The <type>text[]</type> argument to the <varname>userfunction</varname> is required, regardless of whether you choose to pass any arguments to your user function for processing or not.</para>
                    </note>

                    <para role="availability" conformance="2.0.0">Availability: 2.0.0</para>
                </refsection>

                <refsection>
                    <title>Examples</title>

                    <para>Create a new 1 band raster from our original that is a function of modulo 2 of the original raster band.</para>
                    <programlisting language="sql">ALTER TABLE dummy_rast ADD COLUMN map_rast raster;
CREATE FUNCTION mod_fct(pixel float, pos integer[], variadic args text[])
RETURNS float
AS $$
BEGIN
    RETURN pixel::integer % 2;
END;
$$
LANGUAGE 'plpgsql' IMMUTABLE;

UPDATE dummy_rast SET map_rast = ST_MapAlgebraFct(rast, NULL, 'mod_fct(float,integer[],text[])'::regprocedure) WHERE rid = 2;

SELECT ST_Value(rast, 1, i, j) As origval, ST_Value(map_rast, 1, i, j) As mapval
FROM dummy_rast CROSS JOIN generate_series(1, 3) AS i CROSS JOIN generate_series(1, 3) AS j
WHERE rid = 2;</programlisting>
<screen role="text-primary"> origval | mapval
---------+--------
     253 |      1
     254 |      0
     253 |      1
     253 |      1
     254 |      0
     254 |      0
     250 |      0
     254 |      0
     254 |      0</screen>

                    <para>Create a new 1 band raster of pixel-type 2BUI from our original that is reclassified and set the nodata value to a passed parameter to the user function (0).</para>
                    <programlisting language="sql"><![CDATA[
ALTER TABLE dummy_rast ADD COLUMN map_rast2 raster;
CREATE FUNCTION classify_fct(pixel float, pos integer[], variadic args text[])
RETURNS float
AS
$$
DECLARE
    nodata float := 0;
BEGIN
    IF NOT args[1] IS NULL THEN
        nodata := args[1];
    END IF;
    IF pixel < 251 THEN
        RETURN 1;
    ELSIF pixel = 252 THEN
        RETURN 2;
    ELSIF pixel > 252 THEN
        RETURN 3;
    ELSE
        RETURN nodata;
    END IF;
END;
$$
LANGUAGE 'plpgsql';
UPDATE dummy_rast SET map_rast2 = ST_MapAlgebraFct(rast,'2BUI','classify_fct(float,integer[],text[])'::regprocedure, '0') WHERE rid = 2;

SELECT DISTINCT ST_Value(rast,1,i,j) As origval, ST_Value(map_rast2, 1, i, j) As mapval
FROM dummy_rast CROSS JOIN generate_series(1, 5) AS i CROSS JOIN generate_series(1,5) AS j
WHERE rid = 2;]]></programlisting>
<screen role="text-primary"><![CDATA[ origval | mapval
---------+--------
     249 |      1
     250 |      1
     251 |
     252 |      2
     253 |      3
     254 |      3]]></screen>

                    <programlisting language="sql">SELECT ST_BandPixelType(map_rast2) As b1pixtyp
FROM dummy_rast WHERE rid = 2;</programlisting>
<screen role="text-primary"><![CDATA[ b1pixtyp
----------
 2BUI]]></screen>

                    <para>Create a new 3 band raster same pixel type from our original 3 band raster with first band altered by map algebra and remaining 2 bands unaltered.</para>
                    <programlisting language="sql">CREATE FUNCTION rast_plus_tan(pixel float, pos integer[], variadic args text[])
RETURNS float
AS
$$
BEGIN
    RETURN tan(pixel) * pixel;
END;
$$
LANGUAGE 'plpgsql';

SELECT ST_AddBand(ST_AddBand(ST_AddBand(ST_MakeEmptyRaster(rast_view),
            ST_MapAlgebraFct(rast_view, 1, NULL, 'rast_plus_tan(float,integer[],text[])'::regprocedure)
        ),
        ST_Band(rast_view, 2)
    ),
    ST_Band(rast_view, 3) As rast_view_ma
)
FROM wind
WHERE rid=167;
                    </programlisting>

                    <para>The deprecated callback form above is equivalent to a
                    modern <xref linkend="RT_ST_MapAlgebra"/> expression for
                    simple per-pixel transforms. This build-time example renders
                    the original raster and a modulo-2 classification.</para>
                    <programlisting language="sql">WITH pixels AS (
    SELECT x, y, (x + y * 2)::double precision AS value
    FROM generate_series(1, 48) AS x
    CROSS JOIN generate_series(1, 48) AS y
), rows AS (
    SELECT y, array_agg(value ORDER BY x) AS values
    FROM pixels
    GROUP BY y
), source AS (
    SELECT ST_SetValues(
        ST_AddBand(
            ST_MakeEmptyRaster(48, 48, 0, 48, 1, -1, 0, 0, 0),
            1, '8BUI', 0, 0
        ),
        1, 1, 1, array_agg(values ORDER BY y)::double precision[][]
    ) AS rast
    FROM rows
), variants AS (
    SELECT 'source' AS title, rast AS rendered FROM source
    UNION ALL
    SELECT 'modulo 2', ST_MapAlgebra(
        rast, 1,
        '8BUI',
        'mod([rast]::integer,2) * 255'
    )
    FROM source
)
SELECT title, ST_AsPNG(rendered) AS image
FROM variants
ORDER BY title DESC;</programlisting>
                    <screen role="visual-primary">  title   | image
----------+-------------------------
 source   | PNG image, 48 x 48 pixels
 modulo 2 | PNG image, 48 x 48 pixels</screen>
                </refsection>

                <refsection>
                    <title>See Also</title>
                    <para>
                        <xref linkend="RT_ST_MapAlgebraExpr"/>,
                        <xref linkend="RT_ST_BandPixelType"/>,
                        <xref linkend="RT_ST_GeoReference"/>,
                        <xref linkend="RT_ST_SetValue"/>
                    </para>
                </refsection>
            </refentry>

            <refentry xml:id="RT_ST_MapAlgebraFct2">
                <refnamediv>
                    <refname>ST_MapAlgebraFct</refname>
                    <refpurpose>2 band version - Creates a new one band raster formed by applying a valid PostgreSQL function on the 2 input raster bands and of pixeltype provided. Band 1 is assumed if no band is specified. Extent type defaults to INTERSECTION if not specified.</refpurpose>
                </refnamediv>

                <refsynopsisdiv>
                    <funcsynopsis>
                        <funcprototype>
                            <funcdef>raster <function>ST_MapAlgebraFct</function></funcdef>
                            <paramdef><type>raster</type> <parameter>rast1</parameter></paramdef>
                            <paramdef><type>raster</type> <parameter>rast2</parameter></paramdef>
                            <paramdef><type>regprocedure</type> <parameter>tworastuserfunc</parameter></paramdef>
                            <paramdef choice="opt"><type>text</type> <parameter>pixeltype=same_as_rast1</parameter></paramdef>
                            <paramdef choice="opt"><type>text</type> <parameter>extenttype=INTERSECTION</parameter></paramdef>
                            <paramdef><type>text[]</type> <parameter>VARIADIC userargs</parameter></paramdef>
                        </funcprototype>

                        <funcprototype>
                            <funcdef>raster <function>ST_MapAlgebraFct</function></funcdef>
                            <paramdef><type>raster</type> <parameter>rast1</parameter></paramdef>
                            <paramdef><type>integer</type> <parameter>band1</parameter></paramdef>
                            <paramdef><type>raster</type> <parameter>rast2</parameter></paramdef>
                            <paramdef><type>integer</type> <parameter>band2</parameter></paramdef>
                            <paramdef><type>regprocedure</type> <parameter>tworastuserfunc</parameter></paramdef>
                            <paramdef choice="opt"><type>text</type> <parameter>pixeltype=same_as_rast1</parameter></paramdef>
                            <paramdef choice="opt"><type>text</type> <parameter>extenttype=INTERSECTION</parameter></paramdef>
                            <paramdef><type>text[]</type> <parameter>VARIADIC userargs</parameter></paramdef>
                        </funcprototype>
                    </funcsynopsis>
                </refsynopsisdiv>

                <refsection>
                    <title>Description</title>

                    <warning>
                        <para>
                            <xref linkend="RT_ST_MapAlgebraFct2"/> is deprecated as of 2.1.0. Use <xref linkend="RT_ST_MapAlgebra"/> instead.
                        </para>
                    </warning>

                    <para>Creates a new one band raster formed by applying a valid PostgreSQL function specified by the <varname>tworastuserfunc</varname> on the input raster <varname>rast1</varname>, <varname>rast2</varname>. If no <varname>band1</varname> or <varname>band2</varname> is specified, band 1 is assumed. The new raster will have the same georeference, width, and height as the original rasters but will only have one band.
                    </para>

                    <para>If <varname>pixeltype</varname> is passed in, then the new raster will have a band of that pixeltype. If pixeltype is passed NULL or left out, then the new raster band will have the same pixeltype as the input <varname>rast1</varname> band.
                    </para>

                    <para>The <varname>tworastuserfunc</varname> parameter must be the name and signature of an SQL or PL/pgSQL function, cast to a regprocedure. An example PL/pgSQL function example is:
                    </para>
                <programlisting language="sql">CREATE OR REPLACE FUNCTION simple_function_for_two_rasters(pixel1 FLOAT, pixel2 FLOAT, pos INTEGER[], VARIADIC args TEXT[])
RETURNS FLOAT
AS $$ BEGIN
    RETURN 0.0;
END; $$
LANGUAGE 'plpgsql' IMMUTABLE;</programlisting>

                    <para>
                        The <varname>tworastuserfunc</varname> may accept three or four arguments: a double precision value, a double precision value, an optional integer array, and a variadic text array. The first argument is the value of an individual raster cell in <varname>rast1</varname> (regardless of the raster datatype). The second argument is an individual raster cell value in <varname>rast2</varname>.  The third argument is the position of the current processing cell in the form '{x,y}'. The fourth argument indicates that all remaining parameters to <xref linkend="RT_ST_MapAlgebraFct2"/> shall be passed through to the <varname>tworastuserfunc</varname>.
                    </para>

                    <para>Passing a <type>regprodedure</type> argument to a SQL function requires the full function signature to be passed, then cast to a <type>regprocedure</type> type. To pass the above example PL/pgSQL function as an argument, the SQL for the argument is:
                    </para>

<programlisting language="sql">'simple_function(double precision, double precision, integer[], text[])'::regprocedure</programlisting>

                    <para>
Note that the argument contains the name of the function, the types of the function arguments, quotes around the name and argument types, and a cast to a <type>regprocedure</type>.
                    </para>

                    <para>The fourth argument to the <varname>tworastuserfunc</varname> is a <type>variadic text</type> array. All trailing text arguments to any <xref linkend="RT_ST_MapAlgebraFct2"/> call are passed through to the specified <varname>tworastuserfunc</varname>, and are contained in the <varname>userargs</varname> argument.
                    </para>

                    <note>
                        <para>For more information about the VARIADIC keyword, please refer to the PostgreSQL documentation and the "SQL Functions with Variable Numbers of Arguments" section of <link xlink:href="http://www.postgresql.org/docs/current/static/xfunc-sql.html">Query Language (SQL) Functions</link>.</para>
                    </note>

                    <note>
                        <para>The <type>text[]</type> argument to the <varname>tworastuserfunc</varname> is required, regardless of whether you choose to pass any arguments to your user function for processing or not.</para>
                    </note>

                    <para role="availability" conformance="2.0.0">Availability: 2.0.0</para>
                </refsection>

                <refsection>
                    <title>Example: Overlaying rasters on a canvas as separate bands</title>
                    <para>The deprecated two-raster callback form can often be
                    expressed with the modern two-raster
                    <xref linkend="RT_ST_MapAlgebra"/> expression variant. This
                    build-time example renders two input rasters and their
                    averaged overlap.</para>
                    <programlisting language="sql">WITH canvas AS (
    SELECT ST_AddBand(
        ST_MakeEmptyRaster(80, 80, 0, 80, 1, -1, 0, 0, 0),
        1, '8BUI', 0, 0
    ) AS rast
), inputs AS (
    SELECT
        ST_AsRaster(ST_Buffer(ST_Point(30, 40), 25), rast, '8BUI', 80, 0)
            AS raster_1,
        ST_AsRaster(ST_Buffer(ST_Point(50, 40), 25), rast, '8BUI', 220, 0)
            AS raster_2
    FROM canvas
), variants AS (
    SELECT 'raster 1' AS title, raster_1 AS rendered FROM inputs
    UNION ALL
    SELECT 'raster 2', raster_2 FROM inputs
    UNION ALL
    SELECT 'averaged', ST_MapAlgebra(
        raster_1, 1,
        raster_2, 1,
        '([rast1] + [rast2]) / 2',
        '8BUI',
        'UNION'
    ) FROM inputs
)
SELECT title, ST_AsPNG(rendered) AS image
FROM variants
ORDER BY title DESC;</programlisting>
                    <screen role="visual-primary">  title   | image
----------+-------------------------
 raster 2 | PNG image, 50 x 50 pixels
 raster 1 | PNG image, 50 x 50 pixels
 averaged | PNG image, 70 x 50 pixels</screen>
                    <para>Define our user defined function.</para>
                    <programlisting language="sql">
<![CDATA[

CREATE OR REPLACE FUNCTION raster_mapalgebra_union(
    rast1 double precision,
    rast2 double precision,
    pos integer[],
    VARIADIC userargs text[]
)
    RETURNS double precision
    AS $$
    DECLARE
    BEGIN
        CASE
            WHEN rast1 IS NOT NULL AND rast2 IS NOT NULL THEN
                RETURN ((rast1 + rast2)/2.);
            WHEN rast1 IS NULL AND rast2 IS NULL THEN
                RETURN NULL;
            WHEN rast1 IS NULL THEN
                RETURN rast2;
            ELSE
                RETURN rast1;
        END CASE;

        RETURN NULL;
    END;
    $$ LANGUAGE 'plpgsql' IMMUTABLE COST 1000;
]]></programlisting>

                    <para>Prepare a test table of rasters.</para>
                    <programlisting language="sql">
<![CDATA[
DROP TABLE IF EXISTS map_shapes;
CREATE TABLE map_shapes(rid serial PRIMARY KEY, rast raster, bnum integer, descrip text);
INSERT INTO map_shapes(rast,bnum, descrip)
WITH mygeoms
    AS ( SELECT 2 As bnum, ST_Buffer(ST_Point(90,90),30) As geom, 'circle' As descrip
            UNION ALL
            SELECT 3 AS bnum,
                ST_Buffer(ST_GeomFromText('LINESTRING(50 50,150 150,150 50)'), 15) As geom, 'big road' As descrip
            UNION ALL
            SELECT 1 As bnum,
                ST_Translate(ST_Buffer(ST_GeomFromText('LINESTRING(60 50,150 150,150 50)'), 8,'join=bevel'), 10,-6) As geom, 'small road' As descrip
            ),
   -- define our canvas to be 1 to 1 pixel to geometry
   canvas
    AS ( SELECT ST_AddBand(
        ST_MakeEmptyRaster(
            250,
            250,
            ST_XMin(e)::integer,
            ST_YMax(e)::integer,
            1, -1, 0, 0),
        '8BUI'::text,
        0) As rast
        FROM (SELECT ST_Extent(geom) As e,
                    Max(ST_SRID(geom)) As srid
                    from mygeoms
                    ) As foo
            )
-- return our rasters aligned with our canvas
SELECT ST_AsRaster(m.geom, canvas.rast, '8BUI', 240) As rast, bnum, descrip
                FROM mygeoms AS m CROSS JOIN canvas
UNION ALL
SELECT canvas.rast, 4, 'canvas'
FROM canvas;
]]></programlisting>

                    <para>Map algebra on single-band rasters and then collect
                    the result with <xref linkend="RT_ST_AddBand"/>.</para>
                    <programlisting language="sql">
<![CDATA[
INSERT INTO map_shapes(rast,bnum,descrip)
SELECT ST_AddBand(ST_AddBand(rasts[1], rasts[2]),rasts[3]), 4, 'map bands overlay fct union (canvas)'
    FROM (SELECT ARRAY(SELECT ST_MapAlgebraFct(
            m1.rast,
            m2.rast,
            'raster_mapalgebra_union(double precision, double precision, integer[], text[])'::regprocedure,
            '8BUI',
            'FIRST')
                FROM map_shapes As m1 CROSS JOIN map_shapes As m2
    WHERE m1.descrip = 'canvas' AND m2.descrip <> 'canvas' ORDER BY m2.bnum) As rasts) As foo;

]]></programlisting>

                    <para>A compact, executable callback example. The source
                    rasters and their averaged overlap are rendered at build
                    time.</para>
                    <programlisting language="sql">CREATE OR REPLACE FUNCTION pg_temp.raster_average(
    value_1 double precision,
    value_2 double precision,
    position integer[],
    VARIADIC userargs text[]
) RETURNS double precision
LANGUAGE SQL IMMUTABLE
AS 'SELECT COALESCE(($1 + $2) / 2.0, $1, $2)';

WITH canvas AS (
    SELECT ST_AddBand(
        ST_MakeEmptyRaster(80, 80, 0, 80, 1, -1, 0, 0, 0),
        1, '8BUI', 0, 0
    ) AS rast
), inputs AS (
    SELECT
        ST_AsRaster(ST_Buffer(ST_Point(30, 40), 25), rast, '8BUI', 80, 0)
            AS raster_1,
        ST_AsRaster(ST_Buffer(ST_Point(50, 40), 25), rast, '8BUI', 220, 0)
            AS raster_2
    FROM canvas
), variants AS (
    SELECT 'raster 1' AS title, raster_1 AS rendered FROM inputs
    UNION ALL
    SELECT 'raster 2', raster_2 FROM inputs
    UNION ALL
    SELECT 'averaged', ST_MapAlgebraFct(
        raster_1,
        raster_2,
        'pg_temp.raster_average(double precision,double precision,integer[],text[])'::regprocedure,
        '8BUI',
        'UNION'
    ) FROM inputs
)
SELECT title, ST_AsPNG(rendered) AS image
FROM variants
ORDER BY title DESC;</programlisting>
                    <screen role="visual-primary"> title    | image
----------+---------------------------
 raster 2 | PNG image, 50 x 50 pixels
 raster 1 | PNG image, 50 x 50 pixels
 averaged | PNG image, 70 x 50 pixels</screen>
                </refsection>

                <refsection>
                    <title>User Defined function that takes extra args</title>
                    <programlisting language="sql">
CREATE OR REPLACE FUNCTION raster_mapalgebra_userargs(
    rast1 double precision,
    rast2 double precision,
    pos integer[],
    VARIADIC userargs text[]
)
    RETURNS double precision
    AS $$
    DECLARE
    BEGIN
        CASE
            WHEN rast1 IS NOT NULL AND rast2 IS NOT NULL THEN
                RETURN least(userargs[1]::integer,(rast1 + rast2)/2.);
            WHEN rast1 IS NULL AND rast2 IS NULL THEN
                RETURN userargs[2]::integer;
            WHEN rast1 IS NULL THEN
                RETURN greatest(rast2, random()*userargs[3]::integer)::integer;
            ELSE
                RETURN greatest(rast1, random()*userargs[4]::integer)::integer;
        END CASE;

        RETURN NULL;
    END;
    $$ LANGUAGE 'plpgsql' VOLATILE COST 1000;

SELECT ST_MapAlgebraFct(
    m1.rast,
    1,
    m1.rast,
    3,
    'raster_mapalgebra_userargs(double precision, double precision, integer[], text[])'::regprocedure,
    '8BUI',
    'INTERSECT',
    '100', '200', '200', '0')
                FROM map_shapes As m1
    WHERE m1.descrip = 'map bands overlay fct union (canvas)';
                    </programlisting>

                    <para>The generated callback figure above demonstrates the
                    raster alignment and overlap used by this variant; the
                    exact callback result remains available as text.</para>
                </refsection>

                <refsection>
                    <title>See Also</title>
                    <para>
                        <xref linkend="RT_ST_MapAlgebraExpr2"/>,
                        <xref linkend="RT_ST_BandPixelType"/>,
                        <xref linkend="RT_ST_GeoReference"/>,
                        <xref linkend="RT_ST_SetValue"/>
                    </para>
                </refsection>
            </refentry>

            <refentry xml:id="RT_ST_MapAlgebraFctNgb">
                <refnamediv>
                    <refname>ST_MapAlgebraFctNgb</refname>
                    <refpurpose>1-band version: Map Algebra Nearest Neighbor using user-defined PostgreSQL function. Return a raster which values are the result of a PLPGSQL user function involving a neighborhood of values from the input raster band.</refpurpose>
                </refnamediv>

                <refsynopsisdiv>
                    <funcsynopsis>
                        <funcprototype>
                            <funcdef>raster <function>ST_MapAlgebraFctNgb</function></funcdef>
                            <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                            <paramdef><type>integer </type> <parameter>band</parameter></paramdef>
                            <paramdef><type>text </type> <parameter>pixeltype</parameter></paramdef>
                            <paramdef><type>integer </type> <parameter>ngbwidth</parameter></paramdef>
                            <paramdef><type>integer </type> <parameter>ngbheight</parameter></paramdef>
                            <paramdef><type>regprocedure </type> <parameter>onerastngbuserfunc</parameter></paramdef>
                            <paramdef><type>text </type> <parameter>nodatamode</parameter></paramdef>
                            <paramdef><type>text[] </type> <parameter>VARIADIC args</parameter></paramdef>
                      </funcprototype>
                    </funcsynopsis>
                </refsynopsisdiv>

                <refsection>
                    <title>Description</title>

                    <warning>
                        <para>
                            <xref linkend="RT_ST_MapAlgebraFctNgb"/> is deprecated as of 2.1.0. Use <xref linkend="RT_ST_MapAlgebra"/> instead.
                        </para>
                    </warning>

                    <para>(one raster version) Return a raster which values are the result of a PLPGSQL user function involving a neighborhood of values from the input raster band. The user function takes the neighborhood of pixel values as an array of numbers, for each pixel, returns the result from the user function, replacing pixel value of currently inspected pixel with the function result. </para>

                    <variablelist>
                        <varlistentry>
                            <term><varname>rast</varname></term>
                            <listitem><para>Raster on which the user function is evaluated.</para></listitem>
                        </varlistentry>
                        <varlistentry>
                            <term><varname>band</varname></term>
                            <listitem><para>Band number of the raster to be evaluated. Default to 1.</para></listitem>
                        </varlistentry>
                        <varlistentry>
                            <term><varname>pixeltype</varname></term>
                            <listitem><para>The resulting pixel type of the output raster.  Must be one listed in <xref linkend="RT_ST_BandPixelType"/> or left out or set to NULL.  If not passed in or set to NULL, will default to the pixeltype of the <varname>rast</varname>. Results are truncated if they are larger than what is allowed for the pixeltype.</para></listitem>
                        </varlistentry>
                        <varlistentry>
                            <term><varname>ngbwidth</varname></term>
                            <listitem><para>The width of the neighborhood, in cells.</para></listitem>
                        </varlistentry>
                        <varlistentry>
                            <term><varname>ngbheight</varname></term>
                            <listitem><para>The height of the neighborhood, in cells.</para></listitem>
                        </varlistentry>
                        <varlistentry>
                            <term><varname>onerastngbuserfunc</varname></term>
                            <listitem><para>PLPGSQL/psql user function to apply to neighborhood pixels of a single band of a raster. The first element is a 2-dimensional array of numbers representing the rectangular pixel neighborhood</para></listitem>
                        </varlistentry>
                        <varlistentry>
                            <term><varname>nodatamode</varname></term>
                            <listitem>
                                <para>Defines what value to pass to the function for a neighborhood pixel that is nodata or NULL</para>
                                <para>'ignore': any NODATA values encountered in the neighborhood are ignored by the computation -- this flag must be sent to the user callback function, and the user function decides how to ignore it.</para>
                                <para>'NULL': any NODATA values encountered in the neighborhood will cause the resulting pixel to be NULL -- the user callback function is skipped in this case.</para>
                                <para>'value': any NODATA values encountered in the neighborhood are replaced by the reference pixel (the one in the center of the neighborhood). Note that if this value is NODATA, the behavior is the same as 'NULL' (for the affected neighborhood)</para>
                            </listitem>
                        </varlistentry>
                        <varlistentry>
                            <term><varname>args</varname></term>
                            <listitem><para>Arguments to pass into the user function.</para></listitem>
                        </varlistentry>
                    </variablelist>

                    <para role="availability" conformance="2.0.0">Availability: 2.0.0 </para>
                </refsection>

                <refsection>
                    <title>Examples</title>

                    <para>Examples utilize the katrina raster loaded as a single tile described in <link xlink:href="https://gdal.org/user/drivers/raster/postgisraster.html">https://gdal.org/user/drivers/raster/postgisraster.html</link> and then prepared in the <xref linkend="RT_ST_Rescale"/> examples </para>

                    <para>A simple 'callback' user function that averages up all the values in a neighborhood.</para>
                    <programlisting language="sql">
CREATE OR REPLACE FUNCTION rast_avg(matrix float[][], nodatamode text, variadic args text[])
    RETURNS float AS
    $$
    DECLARE
        _matrix float[][];
        x1 integer;
        x2 integer;
        y1 integer;
        y2 integer;
        sum float;
    BEGIN
        _matrix := matrix;
        sum := 0;
        FOR x in array_lower(matrix, 1)..array_upper(matrix, 1) LOOP
            FOR y in array_lower(matrix, 2)..array_upper(matrix, 2) LOOP
                sum := sum + _matrix[x][y];
            END LOOP;
        END LOOP;
        RETURN (sum*1.0/(array_upper(matrix,1)*array_upper(matrix,2) ))::integer ;
    END;
    $$
LANGUAGE 'plpgsql' IMMUTABLE COST 1000;
                    </programlisting>

                    <para>Apply the raster averaging callback within two pixels
                    of each input pixel in the X and Y directions.</para>
                    <programlisting language="sql">
SELECT ST_MapAlgebraFctNgb(
        rast,
        1,
        '8BUI',
        4,
        4,
        'rast_avg(float[][], text, text[])'::regprocedure,
        'NULL',
        NULL) As nn_with_border
    FROM katrinas_rescaled
    limit 1;
                    </programlisting>

                    <para>A self-contained neighborhood average. The source
                    raster has a sharp central square, while the result spreads
                    those values across neighboring pixels. The source uses a
                    non-NODATA background so <varname>nodatamode</varname>
                    <literal>ignore</literal> averages background values with
                    the square values, instead of treating the background as
                    absent.</para>
                    <programlisting language="sql">WITH source AS (
    SELECT ST_SetValues(
        ST_AddBand(
            ST_MakeEmptyRaster(16, 16, 0, 16, 1, -1, 0, 0, 0),
            1, '8BUI', 25, NULL
        ),
        1, 6, 6,
        ARRAY[
            [240, 240, 240, 240, 240, 240],
            [240, 240, 240, 240, 240, 240],
            [240, 240, 240, 240, 240, 240],
            [240, 240, 240, 240, 240, 240],
            [240, 240, 240, 240, 240, 240],
            [240, 240, 240, 240, 240, 240]
        ]::double precision[][]
    ) AS rast
), variants AS (
    SELECT 'source' AS title, rast AS rendered FROM source
    UNION ALL
    SELECT 'averaged', ST_SetBandNoDataValue(ST_MapAlgebraFctNgb(
        rast,
        1,
        '8BUI',
        2,
        2,
        'ST_Mean4ma(float[][],text,text[])'::regprocedure,
        'ignore',
        NULL
    ), NULL) FROM source
)
SELECT title, ST_AsPNG(rendered) AS image
FROM variants
ORDER BY title DESC;</programlisting>
                    <screen role="visual-primary"> title    | image
----------+-------------------------
 source   | PNG image, 16 x 16 pixels
 averaged | PNG image, 16 x 16 pixels</screen>
                    <para>Neighborhood averaging.</para>
<informaltable>
                      <tgroup cols="2">
                        <tbody>
                          <row>
                            <entry><para><informalfigure>
                                <mediaobject>
                                  <imageobject><imagedata fileref="images/st_mapalgebrafctngb01.png"/></imageobject>
                                  <caption><para>First band of our raster</para></caption>
                                </mediaobject>
                              </informalfigure></para></entry>
                            <entry><para><informalfigure>
                                <mediaobject>
                                  <imageobject><imagedata fileref="images/st_mapalgebrafctngb02.png"/></imageobject>
                                  <caption><para>Averaged result</para></caption>
                                </mediaobject>
                              </informalfigure></para></entry>
                          </row>
                        </tbody>
                      </tgroup>
                    </informaltable>
                </refsection>

                <!-- Optionally add a "See Also" section -->
                <refsection>
                    <title>See Also</title>
                    <para>
                        <xref linkend="RT_ST_MapAlgebraFct"/>,
                        <xref linkend="RT_ST_MapAlgebraExpr"/>,
                        <xref linkend="RT_ST_Rescale"/>
                    </para>
                </refsection>
            </refentry>

            <refentry xml:id="RT_ST_Reclass">
                <refnamediv>
                    <refname>ST_Reclass</refname>
                    <refpurpose>Creates a new raster composed of band types reclassified from original.  The nband is the band to be changed.  If nband is not specified assumed to be 1.  All other bands are returned unchanged. Use case: convert a 16BUI band to a 8BUI and so forth for simpler rendering as viewable formats.</refpurpose>
                </refnamediv>

                <refsynopsisdiv>
                    <funcsynopsis>
                      <funcprototype>
                            <funcdef>raster <function>ST_Reclass</function></funcdef>
                            <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                            <paramdef><type>integer </type> <parameter>nband</parameter></paramdef>
                            <paramdef><type>text </type> <parameter>reclassexpr</parameter></paramdef>
                            <paramdef><type>text </type> <parameter>pixeltype</parameter></paramdef>
                            <paramdef choice="opt"><type>double precision </type> <parameter>nodataval=NULL</parameter></paramdef>
                      </funcprototype>

                      <funcprototype>
                            <funcdef>raster <function>ST_Reclass</function></funcdef>
                            <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                            <paramdef><type>reclassarg[] </type> <parameter>VARIADIC reclassargset</parameter></paramdef>
                      </funcprototype>

                      <funcprototype>
                            <funcdef>raster <function>ST_Reclass</function></funcdef>
                            <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                            <paramdef><type>text </type> <parameter>reclassexpr</parameter></paramdef>
                            <paramdef><type>text </type> <parameter>pixeltype</parameter></paramdef>
                      </funcprototype>
                    </funcsynopsis>
                </refsynopsisdiv>

                <refsection>
                    <title>Description</title>

                    <para>Creates a new raster formed by applying a reclassification operation defined by the <varname>reclassexpr</varname> on the input raster (<varname>rast</varname>).
                    Refer to <xref linkend="reclassarg"/> for the description of reclassification expressions.
                    If no <varname>band</varname> is specified band 1 is assumed.
                    </para>

                    <para>The new raster will have the same georeference, width, and height as the original raster.
                    The bands of the new raster have pixel type of <varname>pixeltype</varname>.
                    If <varname>reclassargset</varname> is specified then each <varname>reclassarg</varname> defines the type of the target band.
                    Bands not designated are returned unchanged.
                    </para>

                    <para role="availability" conformance="2.0.0">Availability: 2.0.0 </para>
                </refsection>

                <refsection>
                    <title>Examples</title>
                    <para>Basic.</para>
                    <para>Create a new raster from the original where band 2 is converted from 8BUI to 4BUI and all values from 101-254 are set to nodata value.</para>
                    <programlisting language="sql">
ALTER TABLE dummy_rast ADD COLUMN reclass_rast raster;
UPDATE dummy_rast SET reclass_rast = ST_Reclass(rast, 2, '0-87:1-10, 88-100:11-15, 101-254:0-0', '4BUI', 0) WHERE rid = 2;

SELECT i as col, j as row, ST_Value(rast, 2, i, j) As origval,
    ST_Value(reclass_rast, 2, i, j) As reclassval,
    ST_Value(reclass_rast, 2, i, j, false) As reclassval_include_nodata
FROM dummy_rast CROSS JOIN generate_series(1, 3) AS i CROSS JOIN generate_series(1, 3) AS j
WHERE rid = 2;</programlisting>
<screen role="text-primary"> col | row | origval | reclassval | reclassval_include_nodata
-----+-----+---------+------------+---------------------------
   1 |   1 |      78 |          9 |                         9
   2 |   1 |      98 |         14 |                        14
   3 |   1 |     122 |            |                         0
   1 |   2 |      96 |         14 |                        14
   2 |   2 |     118 |            |                         0
   3 |   2 |     180 |            |                         0
   1 |   3 |      99 |         15 |                        15
   2 |   3 |     112 |            |                         0
   3 |   3 |     169 |            |                         0</screen>

                    <para>Advanced using multiple reclassargs.</para>

                    <para>Create a new raster from the original where band 1,2,3 is converted to 1BB,4BUI, 4BUI respectively and reclassified. Note this uses the variadic <varname>reclassarg</varname> argument which can take as input an indefinite number of reclassargs (theoretically as many bands as you have) </para>
                    <programlisting language="sql">
UPDATE dummy_rast SET reclass_rast =
    ST_Reclass(
        rast,
        ROW(2, '0-87]:1-10, (87-100]:11-15, (101-254]:0-0', '4BUI', NULL)::reclassarg,
        ROW(1, '0-253]:1, 254:0', '1BB', NULL)::reclassarg,
        ROW(3, '0-70]:1, (70-86:2, [86-150):3, [150-255:4', '4BUI', NULL)::reclassarg
        ) WHERE rid = 2;

SELECT i as col, j as row, ST_Value(rast, 1, i, j) As ov1, ST_Value(reclass_rast, 1, i, j) As rv1,
    ST_Value(rast, 2, i, j) As ov2, ST_Value(reclass_rast, 2, i, j) As rv2,
    ST_Value(rast, 3, i, j) As ov3, ST_Value(reclass_rast, 3, i, j) As rv3
FROM dummy_rast CROSS JOIN generate_series(1, 3) AS i CROSS JOIN generate_series(1, 3) AS j
WHERE rid = 2;</programlisting>
<screen role="text-primary">col | row | ov1 | rv1 | ov2 | rv2 | ov3 | rv3
----+-----+-----+-----+-----+-----+-----+-----
  1 |   1 | 253 |   1 |  78 |   9 |  70 |   1
  2 |   1 | 254 |   0 |  98 |  14 |  86 |   3
  3 |   1 | 253 |   1 | 122 |   0 | 100 |   3
  1 |   2 | 253 |   1 |  96 |  14 |  80 |   2
  2 |   2 | 254 |   0 | 118 |   0 | 108 |   3
  3 |   2 | 254 |   0 | 180 |   0 | 162 |   4
  1 |   3 | 250 |   1 |  99 |  15 |  90 |   3
  2 |   3 | 254 |   0 | 112 |   0 | 108 |   3
  3 |   3 | 254 |   0 | 169 |   0 | 175 |   4</screen>

                    <para>Advanced Map a single band 32BF raster to multiple viewable bands.</para>
                    <para>Create a new 3 band (8BUI,8BUI,8BUI viewable raster) from a raster that has only one 32bf band </para>
                    <programlisting language="sql">
ALTER TABLE wind ADD COLUMN rast_view raster;
UPDATE wind
    set rast_view = ST_AddBand(
        NULL,
        ARRAY[
    ST_Reclass(rast, 1, '0.1-10]:1-10,9-10]:11,(11-33:0'::text, '8BUI'::text, 0),
    ST_Reclass(rast, 1, '11-33):0-255,[0-32:0,(34-1000:0'::text, '8BUI'::text, 0),
    ST_Reclass(rast, 1, '0-32]:0,(32-100:100-255'::text, '8BUI'::text, 0)
    ]
    );
                    </programlisting>
                </refsection>

                <refsection>
                    <title>See Also</title>
                    <para>
                        <xref linkend="RT_ST_AddBand"/>,
                        <xref linkend="RT_ST_Band"/>,
                        <xref linkend="RT_ST_BandPixelType"/>,
                        <xref linkend="RT_ST_MakeEmptyRaster"/>,
                        <xref linkend="reclassarg"/>,
                        <xref linkend="RT_ST_Value"/>
                    </para>
                </refsection>
            </refentry>

            <refentry xml:id="RT_ST_ReclassExact">
                <refnamediv>
                    <refname>ST_ReclassExact</refname>
                    <refpurpose>Creates a new raster composed of bands reclassified from original, using a 1:1 mapping from values in the original band to new values in the destination band.</refpurpose>
                </refnamediv>

                <refsynopsisdiv>
                    <funcsynopsis>
                      <funcprototype>
                            <funcdef>raster <function>ST_ReclassExact</function></funcdef>
                            <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                            <paramdef><type>double precision[] </type> <parameter>inputvalues</parameter></paramdef>
                            <paramdef><type>double precision[] </type> <parameter>outputvalues</parameter></paramdef>
                            <paramdef choice="opt"><type>integer </type> <parameter>bandnumber=1</parameter></paramdef>
                            <paramdef choice="opt"><type>text </type> <parameter>pixeltype=32BF</parameter></paramdef>
                            <paramdef choice="opt"><type>double precision </type> <parameter>nodatavalue=NULL</parameter></paramdef>
                      </funcprototype>
                    </funcsynopsis>
                </refsynopsisdiv>

                <refsection>
                    <title>Description</title>

                    <para>Creates a new raster formed by applying a reclassification operation
                    defined by the <varname>inputvalues</varname> and
                    <varname>outputvalues</varname> arrays. Pixel values found in the
                    input array are mapped to the corresponding value in the output array.
                    All other pixel values are mapped to the <varname>nodatavalue</varname>.
                    </para>
                    <para>The output pixel type defaults to float, but can be specified
                    using the <varname>pixeltype</varname> parameter.
                    If no <varname>bandnumber</varname> is specified band 1 is assumed.
                    </para>

                    <para>The new raster will have the same georeference, width,
                    and height as the original raster.
                    Bands not designated are returned unchanged.
                    </para>

                    <para role="availability" conformance="3.6.0">Availability: 3.6.0 </para>
                </refsection>

                <refsection>
                    <title>Example: Basic</title>
                    <para>Create a small raster and map its pixels to new values.</para>
                    <para>Create a raster with four pixels: first row 1 2, second row 3 4.</para>
                    <programlisting language="sql">
CREATE TABLE reclassexact (
    id integer,
    rast raster
);
INSERT INTO reclassexact (id, rast)
SELECT 1, ST_SetValues(ST_AddBand(ST_MakeEmptyRaster(2, -- width in pixels
        2, -- height in pixels
        0, -- upper-left x-coordinate
        0, -- upper-left y-coordinate
        1, -- pixel size in x-direction
        -1, -- pixel size in y-direction (negative for north-up)
        0, -- skew in x-direction
        0, -- skew in y-direction
        4326  -- SRID (e.g., WGS 84)
      ),
      '32BUI'::text, -- pixel type (e.g., '32BF' for float, '8BUI' for unsigned 8-bit int)
      0.0, -- initial value for the band (e.g., 0.0 or a no-data value)
      -99            -- nodatavalue
    ),
    1, -- band number (usually 1 for single-band rasters)
    1, -- x origin for setting values (usually 1)
    1, -- y origin for setting values (usually 1)
    ARRAY[
      ARRAY[1, 2],
      ARRAY[3, 4]
    ]::double precision[][] -- 2D array of values
  );
                    </programlisting>
                    <para>Reclass the values to new values and dump the values
                    of the new raster for display.</para>
                    <programlisting language="sql">
WITH rc AS (
  SELECT ST_ReclassExact(rast, -- input raster
    ARRAY[4, 3, 2, 1], -- input map
    ARRAY[14, 13, 12, 11], -- output map
    1, -- band number to remap
    '32BUI'              -- output raster pixel type
    ) AS rast
  FROM reclassexact
  WHERE id = 1
  )
SELECT 'rce-1', (ST_DumpValues(rc.rast)).*
FROM rc;
                    </programlisting>
                </refsection>
                <refsection>
                    <title>See Also</title>
                    <para>
                        <xref linkend="RT_ST_Reclass"/>,
                        <xref linkend="RT_ST_AddBand"/>,
                        <xref linkend="RT_ST_Band"/>,
                        <xref linkend="RT_ST_MakeEmptyRaster"/>
                    </para>
                </refsection>
            </refentry>

            <refentry xml:id="RT_ST_Union">
                <refnamediv>
                    <refname>ST_Union</refname>
                    <refpurpose>Returns the union of a set of raster tiles into a single raster composed of 1 or more bands.</refpurpose>
                </refnamediv>

                <refsynopsisdiv>
                    <funcsynopsis>
                        <funcprototype>
                            <funcdef>raster <function>ST_Union</function></funcdef>
                            <paramdef><type>setof raster </type> <parameter>rast</parameter></paramdef>
                        </funcprototype>

                        <funcprototype>
                            <funcdef>raster <function>ST_Union</function></funcdef>
                            <paramdef><type>setof raster </type> <parameter>rast</parameter></paramdef>
                            <paramdef><type>unionarg[] </type> <parameter>unionargset</parameter></paramdef>
                        </funcprototype>

                        <funcprototype>
                            <funcdef>raster <function>ST_Union</function></funcdef>
                            <paramdef><type>setof raster</type> <parameter>rast</parameter></paramdef>
                            <paramdef><type>integer</type> <parameter>nband</parameter></paramdef>
                        </funcprototype>

                        <funcprototype>
                            <funcdef>raster <function>ST_Union</function></funcdef>
                            <paramdef><type>setof raster</type> <parameter>rast</parameter></paramdef>
                            <paramdef><type>text</type> <parameter>uniontype</parameter></paramdef>
                        </funcprototype>

                        <funcprototype>
                            <funcdef>raster <function>ST_Union</function></funcdef>
                            <paramdef><type>setof raster</type> <parameter>rast</parameter></paramdef>
                            <paramdef><type>integer</type> <parameter>nband</parameter></paramdef>
                            <paramdef><type>text</type> <parameter>uniontype</parameter></paramdef>
                        </funcprototype>
                    </funcsynopsis>
                </refsynopsisdiv>

                <refsection>
                    <title>Description</title>

                    <para>Returns the union of a set of raster tiles into a single raster composed of at least one band.  The resulting raster's extent is the extent of the whole set.  In the case of intersection, the resulting value is defined by <varname>uniontype</varname> which is one of the following: LAST (default), FIRST, MIN, MAX, COUNT, SUM, MEAN, RANGE.</para>

                    <note>
                      <para>In order for rasters to be unioned, they must all have the same alignment.  Use <xref linkend="RT_ST_SameAlignment"/> and <xref linkend="RT_ST_NotSameAlignmentReason"/> for more details and help. One way to fix alignment issues is to use <xref linkend="RT_ST_Resample"/> and use the same reference raster for alignment.</para>
                    </note>

                    <para role="availability" conformance="2.0.0">Availability: 2.0.0 </para>
                    <para role="enhanced" conformance="2.1.0">Enhanced: 2.1.0 Improved Speed (fully C-Based).</para>
                    <para role="availability" conformance="2.1.0">Availability: 2.1.0 ST_Union(rast, unionarg) variant was introduced.</para>
                    <para role="enhanced" conformance="2.1.0">Enhanced: 2.1.0 ST_Union(rast) (variant 1) unions all bands of all input rasters.  Prior versions of PostGIS assumed the first band.</para>
                    <para role="enhanced" conformance="2.1.0">Enhanced: 2.1.0 ST_Union(rast, uniontype) (variant 4) unions all bands of all input rasters.</para>
                </refsection>
                <refsection>
                    <title>Examples</title>
                    <para>Reconstitute a single band chunked raster tile.</para>
                    <para>This creates a single band from first band of raster tiles. That form the original file system tile.</para>
                    <programlisting language="sql">
SELECT filename, ST_Union(rast, 1) As file_rast
FROM sometable WHERE filename IN('dem01', 'dem02') GROUP BY filename;
                    </programlisting>

                    <para>Return a multi-band raster that is the union of tiles intersecting geometry.</para>
                    <para>This creates a multi band raster collecting all the tiles that intersect a line. Note that In 2.0, this would have just returned a single band raster. , new union works on all bands by default. This is equivalent to unionarg: ARRAY[ROW(1, 'LAST'), ROW(2, 'LAST'), ROW(3, 'LAST')]::unionarg[].</para>
                    <programlisting language="sql">
SELECT ST_Union(rast)
FROM aerials.boston
WHERE ST_Intersects(rast, ST_GeomFromText('LINESTRING(230486 887771,230500 88772)', 26986) );
                    </programlisting>

                    <para>Select and reorder bands while unioning tiles that intersect a geometry.</para>
                    <para>Here we use the longer syntax if we only wanted a subset of bands or we want to change order of bands</para>
                    <para>This creates a multi band raster collecting all the tiles that intersect a line.</para>
                    <programlisting language="sql">
SELECT ST_Union(rast, ARRAY[ROW(2, 'LAST'), ROW(1, 'LAST'), ROW(3, 'LAST')]::unionarg[])
FROM aerials.boston
WHERE ST_Intersects(rast, ST_GeomFromText('LINESTRING(230486 887771,230500 88772)', 26986) );
                    </programlisting>
                </refsection>

                <!-- Optionally add a "See Also" section -->
                <refsection>
                    <title>See Also</title>
                    <para>
                        <xref linkend="unionarg"/>,
                        <xref linkend="RT_ST_Envelope"/>,
                        <xref linkend="RT_ST_ConvexHull"/>,
                        <xref linkend="RT_ST_Clip"/>,
                        <xref linkend="ST_Union"/>
                    </para>
                </refsection>
            </refentry>

        </section> <!-- /map algebra -->

        <section xml:id="Raster_Processing_MapAlgebra_Callbacks">
            <title>Built-in Map Algebra Callback Functions</title>

        <refentry xml:id="RT_ST_Distinct4ma">
            <refnamediv>
                <refname>ST_Distinct4ma</refname>
                <refpurpose>Raster processing function that calculates the number of unique pixel values in a neighborhood.</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                  <funcprototype>
                    <funcdef>float8 <function>ST_Distinct4ma</function></funcdef>
                    <paramdef><type>float8[][]</type> <parameter>matrix</parameter></paramdef>
                    <paramdef><type>text</type> <parameter>nodatamode</parameter></paramdef>
                    <paramdef><type>text[]</type> <parameter>VARIADIC args</parameter></paramdef>
                  </funcprototype>

                    <funcprototype>
                        <funcdef>double precision <function>ST_Distinct4ma</function></funcdef>
                        <paramdef><type>double precision[][][]</type> <parameter>value</parameter></paramdef>
                        <paramdef><type>integer[][] </type> <parameter>pos</parameter></paramdef>
                        <paramdef><type>text[]</type> <parameter>VARIADIC userargs</parameter></paramdef>
                    </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>Calculate the number of unique pixel values in a neighborhood of pixels.</para>

                <note>
                    <para>Variant 1 is a specialized callback function for use as a callback parameter to <xref linkend="RT_ST_MapAlgebraFctNgb"/>.</para>
                </note>

                <note>
                    <para>
                        Variant 2 is a specialized callback function for use as a callback parameter to <xref linkend="RT_ST_MapAlgebra"/>.
                    </para>
                </note>

                <warning>
                    <para>
                        Use of Variant 1 is discouraged since <xref linkend="RT_ST_MapAlgebraFctNgb"/> has been deprecated as of 2.1.0.
                    </para>
                </warning>

                <para role="availability" conformance="2.0.0">Availability: 2.0.0</para>
                <para role="enhanced" conformance="2.1.0">Enhanced: 2.1.0 Addition of Variant 2</para>
            </refsection>

                <refsection>
                    <title>Examples</title>

                    <programlisting language="sql">SELECT
    rid,
    ST_Value(ST_MapAlgebraFctNgb(rast, 1, NULL, 1, 1, 'ST_Distinct4ma(float[][],text,text[])'::regprocedure, 'ignore', NULL), 2, 2
    )
FROM dummy_rast
WHERE rid = 2;</programlisting>
<screen role="text-primary"> rid | st_value
-----+----------
   2 |        3
(1 row)</screen>

            </refsection>

            <refsection>
                <title>See Also</title>
                <para>
                    <xref linkend="RT_ST_MapAlgebraFctNgb"/>,
                    <xref linkend="RT_ST_MapAlgebra"/>,
                    <xref linkend="RT_ST_Min4ma"/>,
                    <xref linkend="RT_ST_Max4ma"/>,
                    <xref linkend="RT_ST_Sum4ma"/>,
                    <xref linkend="RT_ST_Mean4ma"/>,
                    <xref linkend="RT_ST_Distinct4ma"/>,
                    <xref linkend="RT_ST_StdDev4ma"/>
                </para>
            </refsection>
        </refentry>

        <refentry xml:id="RT_ST_InvDistWeight4ma">
            <refnamediv>
                <refname>ST_InvDistWeight4ma</refname>
                <refpurpose>Raster processing function that interpolates a pixel's value from the pixel's neighborhood.</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                    <funcprototype>
                        <funcdef>double precision <function>ST_InvDistWeight4ma</function></funcdef>
                        <paramdef><type>double precision[][][]</type> <parameter>value</parameter></paramdef>
                        <paramdef><type>integer[][]</type> <parameter>pos</parameter></paramdef>
                        <paramdef><type>text[]</type> <parameter>VARIADIC userargs</parameter></paramdef>
                    </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>Calculate an interpolated value for a pixel using the Inverse Distance Weighted method.</para>

                <para>
                    There are two optional parameters that can be passed through <varname>userargs</varname>. The first parameter is the power factor (variable k in the equation below) between 0 and 1 used in the Inverse Distance Weighted equation. If not specified, default value is 1. The second parameter is the weight percentage applied only when the value of the pixel of interest is included with the interpolated value from the neighborhood. If not specified and the pixel of interest has a value, that value is returned.
                </para>

                <para>The basic inverse-distance weighted estimate is:</para>
                <informalequation>
                    <mathphrase>z = (Σᵢ zᵢ / dᵢᵏ) / (Σᵢ 1 / dᵢᵏ)</mathphrase>
                </informalequation>
                <para>Here <literal>zᵢ</literal> is a neighboring pixel value,
                <literal>dᵢ</literal> is its distance from the pixel being
                estimated, and <literal>k</literal> is a real-valued power factor
                between 0 and 1.</para>

                <note>
                    <para>This function is a specialized callback function for use as a callback parameter to <xref linkend="RT_ST_MapAlgebra"/>.</para>
                </note>

                <para role="availability" conformance="2.1.0">Availability: 2.1.0</para>
            </refsection>

            <refsection>
                <title>Examples</title>
                <programlisting language="sql">WITH foo AS (
    SELECT ST_SetValues(ST_AddBand(ST_MakeEmptyRaster(3, 3, 0, 0, 1, -1, 0, 0, 0), 1, '32BF', NULL::double precision, -9999),
        1, 1, 1, ARRAY[
            [10, 10, 10],
            [10, NULL, 20],
            [20, 20, 20]
        ]::double precision[][]
    ) AS rast
)
SELECT ST_Value(
    ST_MapAlgebra(
        rast,
        1,
        'ST_InvDistWeight4ma(double precision[][][],integer[][],text[])'::regprocedure,
        '32BF',
        'FIRST',
        NULL,
        1,
        1
    ),
    2, 2
) AS interpolated_value
FROM foo;</programlisting>
<screen role="text-primary">15</screen>
            </refsection>

            <refsection>
                <title>See Also</title>
                <para>
                    <xref linkend="RT_ST_MapAlgebra"/>,
                    <xref linkend="RT_ST_MinDist4ma"/>
                </para>
            </refsection>
        </refentry>

        <refentry xml:id="RT_ST_Max4ma">
            <refnamediv>
                <refname>ST_Max4ma</refname>
                <refpurpose>Raster processing function that calculates the maximum pixel value in a neighborhood.</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                  <funcprototype>
                    <funcdef>float8 <function>ST_Max4ma</function></funcdef>
                    <paramdef><type>float8[][]</type> <parameter>matrix</parameter></paramdef>
                    <paramdef><type>text</type> <parameter>nodatamode</parameter></paramdef>
                    <paramdef><type>text[]</type> <parameter>VARIADIC args</parameter></paramdef>
                  </funcprototype>

                    <funcprototype>
                        <funcdef>double precision <function>ST_Max4ma</function></funcdef>
                        <paramdef><type>double precision[][][]</type> <parameter>value</parameter></paramdef>
                        <paramdef><type>integer[][] </type> <parameter>pos</parameter></paramdef>
                        <paramdef><type>text[]</type> <parameter>VARIADIC userargs</parameter></paramdef>
                    </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>Calculate the maximum pixel value in a neighborhood of pixels.</para>

                <para>
                    For Variant 2, a substitution value for NODATA pixels can be specified by passing that value to userargs.
                </para>

                <note>
                    <para>Variant 1 is a specialized callback function for use as a callback parameter to <xref linkend="RT_ST_MapAlgebraFctNgb"/>.</para>
                </note>

                <note>
                    <para>
                        Variant 2 is a specialized callback function for use as a callback parameter to <xref linkend="RT_ST_MapAlgebra"/>.
                    </para>
                </note>

                <warning>
                    <para>
                        Use of Variant 1 is discouraged since <xref linkend="RT_ST_MapAlgebraFctNgb"/> has been deprecated as of 2.1.0.
                    </para>
                </warning>

                <para role="availability" conformance="2.0.0">Availability: 2.0.0</para>
                <para role="enhanced" conformance="2.1.0">Enhanced: 2.1.0 Addition of Variant 2</para>
            </refsection>

                <refsection>
                    <title>Examples</title>

                    <programlisting language="sql">SELECT
    rid,
    ST_Value(ST_MapAlgebraFctNgb(rast, 1, NULL, 1, 1, 'ST_Max4ma(float[][],text,text[])'::regprocedure, 'ignore', NULL), 2, 2
    )
FROM dummy_rast
WHERE rid = 2;</programlisting>
<screen role="text-primary"> rid | st_value
-----+----------
   2 |      254
(1 row)</screen>

            </refsection>

            <refsection>
                <title>See Also</title>
                <para>
                    <xref linkend="RT_ST_MapAlgebraFctNgb"/>,
                    <xref linkend="RT_ST_MapAlgebra"/>,
                    <xref linkend="RT_ST_Min4ma"/>,
                    <xref linkend="RT_ST_Sum4ma"/>,
                    <xref linkend="RT_ST_Mean4ma"/>,
                    <xref linkend="RT_ST_Range4ma"/>,
                    <xref linkend="RT_ST_Distinct4ma"/>,
                    <xref linkend="RT_ST_StdDev4ma"/>
                </para>
            </refsection>
        </refentry>

        <refentry xml:id="RT_ST_Mean4ma">
            <refnamediv>
                <refname>ST_Mean4ma</refname>
                <refpurpose>Raster processing function that calculates the mean pixel value in a neighborhood.</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                  <funcprototype>
                    <funcdef>float8 <function>ST_Mean4ma</function></funcdef>
                    <paramdef><type>float8[][]</type> <parameter>matrix</parameter></paramdef>
                    <paramdef><type>text</type> <parameter>nodatamode</parameter></paramdef>
                    <paramdef><type>text[]</type> <parameter>VARIADIC args</parameter></paramdef>
                  </funcprototype>

                    <funcprototype>
                        <funcdef>double precision <function>ST_Mean4ma</function></funcdef>
                        <paramdef><type>double precision[][][]</type> <parameter>value</parameter></paramdef>
                        <paramdef><type>integer[][] </type> <parameter>pos</parameter></paramdef>
                        <paramdef><type>text[]</type> <parameter>VARIADIC userargs</parameter></paramdef>
                    </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>Calculate the mean pixel value in a neighborhood of pixels.</para>

                <para>
                    For Variant 2, a substitution value for NODATA pixels can be specified by passing that value to userargs.
                </para>

                <note>
                    <para>Variant 1 is a specialized callback function for use as a callback parameter to <xref linkend="RT_ST_MapAlgebraFctNgb"/>.</para>
                </note>

                <note>
                    <para>
                        Variant 2 is a specialized callback function for use as a callback parameter to <xref linkend="RT_ST_MapAlgebra"/>.
                    </para>
                </note>

                <warning>
                    <para>
                        Use of Variant 1 is discouraged since <xref linkend="RT_ST_MapAlgebraFctNgb"/> has been deprecated as of 2.1.0.
                    </para>
                </warning>

                <para role="availability" conformance="2.0.0">Availability: 2.0.0</para>
                <para role="enhanced" conformance="2.1.0">Enhanced: 2.1.0 Addition of Variant 2</para>
            </refsection>

                <refsection>
                    <title>Examples</title>
                    <para>Variant 1.</para>

                    <programlisting language="sql">SELECT
    rid,
    ST_Value(ST_MapAlgebraFctNgb(rast, 1, '32BF', 1, 1, 'ST_Mean4ma(float[][],text,text[])'::regprocedure, 'ignore', NULL), 2, 2
    )
FROM dummy_rast
WHERE rid = 2;</programlisting>
<screen role="text-primary"> rid |     st_value
-----+------------------
   2 | 253.222229003906
(1 row)</screen>


                    <para>Variant 2.</para>

                    <programlisting language="sql">SELECT
  rid,
  ST_Value(
      ST_MapAlgebra(rast, 1, 'ST_Mean4ma(double precision[][][], integer[][], text[])'::regprocedure, '32BF', 'FIRST', NULL, 1, 1),
      2,
      2)
FROM dummy_rast
 WHERE rid = 2;</programlisting>
<screen role="text-primary"> rid |     st_value
-----+------------------
   2 | 253.222229003906
(1 row)</screen>

            </refsection>

            <refsection>
                <title>See Also</title>
                <para>
                    <xref linkend="RT_ST_MapAlgebraFctNgb"/>,
                    <xref linkend="RT_ST_MapAlgebra"/>,
                    <xref linkend="RT_ST_Min4ma"/>,
                    <xref linkend="RT_ST_Max4ma"/>,
                    <xref linkend="RT_ST_Sum4ma"/>,
                    <xref linkend="RT_ST_Range4ma"/>,
                    <xref linkend="RT_ST_StdDev4ma"/>
                </para>
            </refsection>
        </refentry>

        <refentry xml:id="RT_ST_Min4ma">
            <refnamediv>
                <refname>ST_Min4ma</refname>
                <refpurpose>
                    Raster processing function that calculates the minimum pixel value in a neighborhood.
                </refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                    <funcprototype>
                        <funcdef>float8 <function>ST_Min4ma</function></funcdef>
                        <paramdef><type>float8[][]</type> <parameter>matrix</parameter></paramdef>
                        <paramdef><type>text </type> <parameter>nodatamode</parameter></paramdef>
                        <paramdef><type>text[]</type> <parameter>VARIADIC args</parameter></paramdef>
                    </funcprototype>

                    <funcprototype>
                        <funcdef>double precision <function>ST_Min4ma</function></funcdef>
                        <paramdef><type>double precision[][][]</type> <parameter>value</parameter></paramdef>
                        <paramdef><type>integer[][] </type> <parameter>pos</parameter></paramdef>
                        <paramdef><type>text[]</type> <parameter>VARIADIC userargs</parameter></paramdef>
                    </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>
                    Calculate the minimum pixel value in a neighborhood of pixels.
                </para>

                <para>
                    For Variant 2, a substitution value for NODATA pixels can be specified by passing that value to userargs.
                </para>

                <note>
                    <para>
                        Variant 1 is a specialized callback function for use as a callback parameter to <xref linkend="RT_ST_MapAlgebraFctNgb"/>.
                    </para>
                </note>

                <note>
                    <para>
                        Variant 2 is a specialized callback function for use as a callback parameter to <xref linkend="RT_ST_MapAlgebra"/>.
                    </para>
                </note>

                <warning>
                    <para>
                        Use of Variant 1 is discouraged since <xref linkend="RT_ST_MapAlgebraFctNgb"/> has been deprecated as of 2.1.0.
                    </para>
                </warning>

                <para role="availability" conformance="2.0.0">Availability: 2.0.0</para>
                <para role="enhanced" conformance="2.1.0">Enhanced: 2.1.0 Addition of Variant 2</para>
            </refsection>

            <refsection>
                <title>Examples</title>

                <programlisting language="sql">
SELECT
    rid,
    ST_Value(ST_MapAlgebraFctNgb(rast, 1, NULL, 1, 1, 'ST_Min4ma(float[][],text,text[])'::regprocedure, 'ignore', NULL), 2, 2
    )
FROM dummy_rast
WHERE rid = 2;</programlisting>
<screen role="text-primary"> rid | st_value
-----+----------
   2 |      250
(1 row)</screen>
            </refsection>

            <refsection>
                <title>See Also</title>
                <para>
                    <xref linkend="RT_ST_MapAlgebraFctNgb"/>,
                    <xref linkend="RT_ST_MapAlgebra"/>,
                    <xref linkend="RT_ST_Max4ma"/>,
                    <xref linkend="RT_ST_Sum4ma"/>,
                    <xref linkend="RT_ST_Mean4ma"/>,
                    <xref linkend="RT_ST_Range4ma"/>,
                    <xref linkend="RT_ST_Distinct4ma"/>,
                    <xref linkend="RT_ST_StdDev4ma"/>
                </para>
            </refsection>
        </refentry>

        <refentry xml:id="RT_ST_MinDist4ma">
            <refnamediv>
                <refname>ST_MinDist4ma</refname>
                <refpurpose>Raster processing function that returns the minimum distance (in number of pixels) between the pixel of interest and a neighboring pixel with value.</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                    <funcprototype>
                        <funcdef>double precision <function>ST_MinDist4ma</function></funcdef>
                        <paramdef><type>double precision[][][]</type> <parameter>value</parameter></paramdef>
                        <paramdef><type>integer[][]</type> <parameter>pos</parameter></paramdef>
                        <paramdef><type>text[]</type> <parameter>VARIADIC userargs</parameter></paramdef>
                    </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>Return the shortest distance (in number of pixels) between the pixel of interest and the closest pixel with value in the neighborhood.</para>

                <note>
                    <para>
                        The intent of this function is to provide an informative data point that helps infer the usefulness of the pixel of interest's interpolated value from <xref linkend="RT_ST_InvDistWeight4ma"/>. This function is particularly useful when the neighborhood is sparsely populated.
                    </para>
                </note>

                <note>
                    <para>This function is a specialized callback function for use as a callback parameter to <xref linkend="RT_ST_MapAlgebra"/>.</para>
                </note>

                <para role="availability" conformance="2.1.0">Availability: 2.1.0</para>
            </refsection>

            <refsection>
                <title>Examples</title>
                <programlisting language="sql">WITH foo AS (
    SELECT ST_SetValues(ST_AddBand(ST_MakeEmptyRaster(3, 3, 0, 0, 1, -1, 0, 0, 0), 1, '32BF', NULL::double precision, -9999),
        1, 1, 1, ARRAY[
            [10, 10, 10],
            [10, NULL, 20],
            [20, 20, 20]
        ]::double precision[][]
    ) AS rast
)
SELECT ST_Value(
    ST_MapAlgebra(
        rast,
        1,
        'ST_MinDist4ma(double precision[][][],integer[][],text[])'::regprocedure,
        '32BF',
        'FIRST',
        NULL,
        1,
        1
    ),
    2, 2
) AS min_distance
FROM foo;</programlisting>
<screen role="text-primary">1</screen>
            </refsection>

            <refsection>
                <title>See Also</title>
                <para>
                    <xref linkend="RT_ST_MapAlgebra"/>,
                    <xref linkend="RT_ST_InvDistWeight4ma"/>
                </para>
            </refsection>
        </refentry>

        <refentry xml:id="RT_ST_Range4ma">
            <refnamediv>
                <refname>ST_Range4ma</refname>
                <refpurpose>Raster processing function that calculates the range of pixel values in a neighborhood.</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                  <funcprototype>
                    <funcdef>float8 <function>ST_Range4ma</function></funcdef>
                    <paramdef><type>float8[][]</type> <parameter>matrix</parameter></paramdef>
                    <paramdef><type>text</type> <parameter>nodatamode</parameter></paramdef>
                    <paramdef><type>text[]</type> <parameter>VARIADIC args</parameter></paramdef>
                  </funcprototype>

                    <funcprototype>
                        <funcdef>double precision <function>ST_Range4ma</function></funcdef>
                        <paramdef><type>double precision[][][]</type> <parameter>value</parameter></paramdef>
                        <paramdef><type>integer[][] </type> <parameter>pos</parameter></paramdef>
                        <paramdef><type>text[]</type> <parameter>VARIADIC userargs</parameter></paramdef>
                    </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>Calculate the range of pixel values in a neighborhood of pixels.</para>

                <para>
                    For Variant 2, a substitution value for NODATA pixels can be specified by passing that value to userargs.
                </para>

                <note>
                    <para>Variant 1 is a specialized callback function for use as a callback parameter to <xref linkend="RT_ST_MapAlgebraFctNgb"/>.</para>
                </note>

                <note>
                    <para>
                        Variant 2 is a specialized callback function for use as a callback parameter to <xref linkend="RT_ST_MapAlgebra"/>.
                    </para>
                </note>

                <warning>
                    <para>
                        Use of Variant 1 is discouraged since <xref linkend="RT_ST_MapAlgebraFctNgb"/> has been deprecated as of 2.1.0.
                    </para>
                </warning>

                <para role="availability" conformance="2.0.0">Availability: 2.0.0</para>
                <para role="enhanced" conformance="2.1.0">Enhanced: 2.1.0 Addition of Variant 2</para>
            </refsection>

                <refsection>
                    <title>Examples</title>

                    <programlisting language="sql">SELECT
    rid,
    ST_Value(ST_MapAlgebraFctNgb(rast, 1, NULL, 1, 1, 'ST_Range4ma(float[][],text,text[])'::regprocedure, 'ignore', NULL), 2, 2
    )
FROM dummy_rast
WHERE rid = 2;</programlisting>
<screen role="text-primary"> rid | st_value
-----+----------
   2 |        4
(1 row)</screen>

            </refsection>

            <refsection>
                <title>See Also</title>
                <para>
                    <xref linkend="RT_ST_MapAlgebraFctNgb"/>,
                    <xref linkend="RT_ST_MapAlgebra"/>,
                    <xref linkend="RT_ST_Min4ma"/>,
                    <xref linkend="RT_ST_Max4ma"/>,
                    <xref linkend="RT_ST_Sum4ma"/>,
                    <xref linkend="RT_ST_Mean4ma"/>,
                    <xref linkend="RT_ST_Distinct4ma"/>,
                    <xref linkend="RT_ST_StdDev4ma"/>
                </para>
            </refsection>
        </refentry>

        <refentry xml:id="RT_ST_StdDev4ma">
            <refnamediv>
                <refname>ST_StdDev4ma</refname>
                <refpurpose>Raster processing function that calculates the standard deviation of pixel values in a neighborhood.</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                  <funcprototype>
                    <funcdef>float8 <function>ST_StdDev4ma</function></funcdef>
                    <paramdef><type>float8[][]</type> <parameter>matrix</parameter></paramdef>
                    <paramdef><type>text </type> <parameter>nodatamode</parameter></paramdef>
                    <paramdef><type>text[]</type> <parameter>VARIADIC args</parameter></paramdef>
                  </funcprototype>

                    <funcprototype>
                        <funcdef>double precision <function>ST_StdDev4ma</function></funcdef>
                        <paramdef><type>double precision[][][]</type> <parameter>value</parameter></paramdef>
                        <paramdef><type>integer[][] </type> <parameter>pos</parameter></paramdef>
                        <paramdef><type>text[]</type> <parameter>VARIADIC userargs</parameter></paramdef>
                    </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>Calculate the standard deviation of pixel values in a neighborhood of pixels.</para>

                <note>
                    <para>Variant 1 is a specialized callback function for use as a callback parameter to <xref linkend="RT_ST_MapAlgebraFctNgb"/>.</para>
                </note>

                <note>
                    <para>
                        Variant 2 is a specialized callback function for use as a callback parameter to <xref linkend="RT_ST_MapAlgebra"/>.
                    </para>
                </note>

                <warning>
                    <para>
                        Use of Variant 1 is discouraged since <xref linkend="RT_ST_MapAlgebraFctNgb"/> has been deprecated as of 2.1.0.
                    </para>
                </warning>

                <para role="availability" conformance="2.0.0">Availability: 2.0.0</para>
                <para role="enhanced" conformance="2.1.0">Enhanced: 2.1.0 Addition of Variant 2</para>
            </refsection>

                <refsection>
                    <title>Examples</title>

                    <programlisting language="sql">SELECT
    rid,
    ST_Value(ST_MapAlgebraFctNgb(rast, 1, '32BF', 1, 1, 'ST_StdDev4ma(float[][],text,text[])'::regprocedure, 'ignore', NULL), 2, 2
    )
FROM dummy_rast
WHERE rid = 2;</programlisting>
<screen role="text-primary"> rid |     st_value
-----+------------------
   2 | 1.30170822143555
(1 row)</screen>

            </refsection>

            <refsection>
                <title>See Also</title>
                <para>
                    <xref linkend="RT_ST_MapAlgebraFctNgb"/>,
                    <xref linkend="RT_ST_MapAlgebra"/>,
                    <xref linkend="RT_ST_Min4ma"/>,
                    <xref linkend="RT_ST_Max4ma"/>,
                    <xref linkend="RT_ST_Sum4ma"/>,
                    <xref linkend="RT_ST_Mean4ma"/>,
                    <xref linkend="RT_ST_Distinct4ma"/>,
                    <xref linkend="RT_ST_StdDev4ma"/>
                </para>
            </refsection>
        </refentry>

        <refentry xml:id="RT_ST_Sum4ma">
            <refnamediv>
                <refname>ST_Sum4ma</refname>
                <refpurpose>Raster processing function that calculates the sum of all pixel values in a neighborhood.</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                  <funcprototype>
                    <funcdef>float8 <function>ST_Sum4ma</function></funcdef>
                    <paramdef><type>float8[][]</type> <parameter>matrix</parameter></paramdef>
                    <paramdef><type>text</type> <parameter>nodatamode</parameter></paramdef>
                    <paramdef><type>text[]</type> <parameter>VARIADIC args</parameter></paramdef>
                  </funcprototype>

                    <funcprototype>
                        <funcdef>double precision <function>ST_Sum4ma</function></funcdef>
                        <paramdef><type>double precision[][][]</type> <parameter>value</parameter></paramdef>
                        <paramdef><type>integer[][] </type> <parameter>pos</parameter></paramdef>
                        <paramdef><type>text[]</type> <parameter>VARIADIC userargs</parameter></paramdef>
                    </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>

                <para>Calculate the sum of all pixel values in a neighborhood of pixels.</para>

                <para>
                    For Variant 2, a substitution value for NODATA pixels can be specified by passing that value to userargs.
                </para>

                <note>
                    <para>Variant 1 is a specialized callback function for use as a callback parameter to <xref linkend="RT_ST_MapAlgebraFctNgb"/>.</para>
                </note>

                <note>
                    <para>
                        Variant 2 is a specialized callback function for use as a callback parameter to <xref linkend="RT_ST_MapAlgebra"/>.
                    </para>
                </note>

                <warning>
                    <para>
                        Use of Variant 1 is discouraged since <xref linkend="RT_ST_MapAlgebraFctNgb"/> has been deprecated as of 2.1.0.
                    </para>
                </warning>

                <para role="availability" conformance="2.0.0">Availability: 2.0.0</para>
                <para role="enhanced" conformance="2.1.0">Enhanced: 2.1.0 Addition of Variant 2</para>
            </refsection>

                <refsection>
                    <title>Examples</title>

                    <programlisting language="sql">SELECT
    rid,
    ST_Value(ST_MapAlgebraFctNgb(rast, 1, '32BF', 1, 1, 'ST_Sum4ma(float[][],text,text[])'::regprocedure, 'ignore', NULL), 2, 2
    )
FROM dummy_rast
WHERE rid = 2;</programlisting>
<screen role="text-primary"> rid | st_value
-----+----------
   2 |     2279
(1 row)</screen>

            </refsection>

            <refsection>
                <title>See Also</title>
                <para>
                    <xref linkend="RT_ST_MapAlgebraFctNgb"/>,
                    <xref linkend="RT_ST_MapAlgebra"/>,
                    <xref linkend="RT_ST_Min4ma"/>,
                    <xref linkend="RT_ST_Max4ma"/>,
                    <xref linkend="RT_ST_Mean4ma"/>,
                    <xref linkend="RT_ST_Range4ma"/>,
                    <xref linkend="RT_ST_Distinct4ma"/>,
                    <xref linkend="RT_ST_StdDev4ma"/>
                </para>
            </refsection>
        </refentry>

        </section> <!-- /callback -->

        <section xml:id="Raster_Processing_DEM">
            <title>Raster Processing: DEM (Elevation)</title>

            <refentry xml:id="RT_ST_Aspect">
                <refnamediv>
                    <refname>ST_Aspect</refname>
                    <refpurpose>Returns the aspect (in degrees by default) of an elevation raster band.  Useful for analyzing terrain.</refpurpose>
                </refnamediv>
                <refsynopsisdiv>
                    <funcsynopsis>
                      <funcprototype>
                            <funcdef>raster <function>ST_Aspect</function></funcdef>
                            <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                            <paramdef choice="opt"><type>integer </type> <parameter>band=1</parameter></paramdef>
                            <paramdef choice="opt"><type>text </type> <parameter>pixeltype=32BF</parameter></paramdef>
                            <paramdef choice="opt"><type>text </type> <parameter>units=DEGREES</parameter></paramdef>
                            <paramdef choice="opt"><type>boolean </type> <parameter>interpolate_nodata=FALSE</parameter></paramdef>
                      </funcprototype>

                      <funcprototype>
                            <funcdef>raster <function>ST_Aspect</function></funcdef>
                            <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                            <paramdef><type>integer </type> <parameter>band</parameter></paramdef>
                            <paramdef><type>raster </type> <parameter>customextent</parameter></paramdef>
                            <paramdef choice="opt"><type>text </type> <parameter>pixeltype=32BF</parameter></paramdef>
                            <paramdef choice="opt"><type>text </type> <parameter>units=DEGREES</parameter></paramdef>
                            <paramdef choice="opt"><type>boolean </type> <parameter>interpolate_nodata=FALSE</parameter></paramdef>
                      </funcprototype>
                    </funcsynopsis>
                </refsynopsisdiv>

                <refsection>
                    <title>Description</title>

                    <para>Returns the aspect (in degrees by default) of an elevation raster band. Utilizes map algebra and applies the aspect equation to neighboring pixels.</para>

                    <para>
                        <varname>units</varname> indicates the units of the aspect. Possible values are: RADIANS, DEGREES (default).
                    </para>

                    <para>
                        When <varname>units</varname> = RADIANS, values are between 0 and 2 * pi radians measured clockwise from North.
                    </para>

                    <para>
                        When <varname>units</varname> = DEGREES, values are between 0 and 360 degrees measured clockwise from North.
                    </para>

                    <para>
                        If slope of pixel is zero, aspect of pixel is -1.
                    </para>

                    <note>
                        <para>
                            For more information about Slope, Aspect and Hillshade, please refer to <link xlink:href="http://webhelp.esri.com/arcgisdesktop/9.3/index.cfm?TopicName=How%20Hillshade%20works">ESRI - How hillshade works</link> and <link xlink:href="http://e2b.erdas.com/fieldguide/wwhelp/wwhimpl/common/html/wwhelp.htm?context=FieldGuide&amp;file=Aspect_Images.html">ERDAS Field Guide - Aspect Images</link>.
                        </para>
                    </note>

                    <para role="availability" conformance="2.0.0">Availability: 2.0.0 </para>
                    <para role="enhanced" conformance="2.1.0">Enhanced: 2.1.0 Uses ST_MapAlgebra() and added optional <varname>interpolate_nodata</varname> function parameter</para>
                    <para role="changed" conformance="2.1.0">Changed: 2.1.0 In prior versions, return values were in radians. Now, return values default to degrees</para>
                </refsection>

                <refsection>
                    <title>Examples</title>
                    <para>Variant 1.</para>
                    <para>This symmetric peak highlights the expected compass
                    directions at the corners and the <literal>-1</literal>
                    aspect at the summit. The generated PNG shows the full
                    aspect surface without relying on a manual illustration.
                    The generated source raster is large enough for the PNG to
                    show the directional field around the summit.</para>
                    <programlisting language="sql">WITH pixels AS (
    SELECT
        x,
        y,
        (20 - greatest(abs(x - 9), abs(y - 9)))::double precision AS value
    FROM generate_series(1, 17) AS y
    CROSS JOIN generate_series(1, 17) AS x
), rows AS (
    SELECT
        y,
        array_agg(value ORDER BY x) AS row_values
    FROM pixels
    GROUP BY y
), source AS (
    SELECT ST_SetValues(
        ST_AddBand(
            ST_MakeEmptyRaster(17, 17, 0, 0, 1, -1, 0, 0, 0),
            1, '32BF', 0, -9999
        ),
        1, 1, 1,
        array_agg(row_values ORDER BY y)::double precision[][]
    ) AS rast
    FROM rows
), aspect AS (
    SELECT ST_Aspect(rast, 1, '32BF') AS rast
    FROM source
)
SELECT
    round(ST_Value(rast, 1, 1, 1)::numeric, 3) AS northwest_degrees,
    round(ST_Value(rast, 1, 9, 9)::numeric, 3) AS summit_degrees,
    round(ST_Value(rast, 1, 17, 17)::numeric, 3) AS southeast_degrees,
    ST_AsPNG(ST_ColorMap(rast, 1, 'bluered')) AS image
FROM aspect;</programlisting>
<screen role="visual-primary"> northwest_degrees | summit_degrees | southeast_degrees | image
-------------------+----------------+-------------------+------------------------
           315.000 |         -1.000 |           135.000 | PNG image, 17 x 17 pixels</screen>

                    <para>Variant 2.</para>

                    <para>Complete example of tiles of a coverage.</para>

                    <programlisting language="sql">
WITH foo AS (
    SELECT ST_Tile(ST_SetValues(ST_AddBand(ST_MakeEmptyRaster(6, 6, 0, 0, 1, -1, 0, 0, 0),
                1, '32BF', 0, -9999
            ),
            1, 1, 1, ARRAY[
                [1, 1, 1, 1, 1, 1],
                [1, 1, 1, 1, 2, 1],
                [1, 2, 2, 3, 3, 1],
                [1, 1, 3, 2, 1, 1],
                [1, 2, 2, 1, 2, 1],
                [1, 1, 1, 1, 1, 1]
            ]::double precision[]
        ),
        2, 2
    ) AS rast
)
SELECT
    t1.rast,
    ST_Aspect(ST_Union(t2.rast), 1, t1.rast)
FROM foo t1
CROSS JOIN foo t2
WHERE ST_Intersects(t1.rast, t2.rast)
GROUP BY t1.rast;
                    </programlisting>
                </refsection>

                <refsection>
                    <title>See Also</title>
                    <para>
                        <xref linkend="RT_ST_MapAlgebra"/>,
                        <xref linkend="RT_ST_TRI"/>,
                        <xref linkend="RT_ST_TPI"/>,
                        <xref linkend="RT_ST_Roughness"/>,
                        <xref linkend="RT_ST_HillShade"/>,
                        <xref linkend="RT_ST_Slope"/>
                    </para>
                </refsection>
            </refentry>

            <refentry xml:id="RT_ST_HillShade">
                <refnamediv>
                    <refname>ST_HillShade</refname>
                    <refpurpose>Returns the hypothetical illumination of an elevation raster band using provided azimuth, altitude, brightness and scale inputs.</refpurpose>
                </refnamediv>
                <refsynopsisdiv>
                    <funcsynopsis>
                      <funcprototype>
                            <funcdef>raster <function>ST_HillShade</function></funcdef>
                            <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                            <paramdef choice="opt"><type>integer </type> <parameter>band=1</parameter></paramdef>
                            <paramdef choice="opt"><type>text </type> <parameter>pixeltype=32BF</parameter></paramdef>
                            <paramdef choice="opt"><type>double precision </type> <parameter>azimuth=315</parameter></paramdef>
                            <paramdef choice="opt"><type>double precision </type> <parameter>altitude=45</parameter></paramdef>
                            <paramdef choice="opt"><type>double precision </type> <parameter>max_bright=255</parameter></paramdef>
                            <paramdef choice="opt"><type>double precision </type> <parameter>scale=1.0</parameter></paramdef>
                            <paramdef choice="opt"><type>boolean </type> <parameter>interpolate_nodata=FALSE</parameter></paramdef>
                    </funcprototype>

                      <funcprototype>
                            <funcdef>raster <function>ST_HillShade</function></funcdef>
                            <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                            <paramdef><type>integer </type> <parameter>band</parameter></paramdef>
                            <paramdef><type>raster </type> <parameter>customextent</parameter></paramdef>
                            <paramdef choice="opt"><type>text </type> <parameter>pixeltype=32BF</parameter></paramdef>
                            <paramdef choice="opt"><type>double precision </type> <parameter>azimuth=315</parameter></paramdef>
                            <paramdef choice="opt"><type>double precision </type> <parameter>altitude=45</parameter></paramdef>
                            <paramdef choice="opt"><type>double precision </type> <parameter>max_bright=255</parameter></paramdef>
                            <paramdef choice="opt"><type>double precision </type> <parameter>scale=1.0</parameter></paramdef>
                            <paramdef choice="opt"><type>boolean </type> <parameter>interpolate_nodata=FALSE</parameter></paramdef>
                      </funcprototype>
                    </funcsynopsis>
                </refsynopsisdiv>

                <refsection>
                    <title>Description</title>

                    <para>Returns the hypothetical illumination of an elevation raster band using the azimuth, altitude, brightness, and scale inputs. Utilizes map algebra and applies the hill shade equation to neighboring pixels. Return pixel values are between 0 and 255.</para>

                    <para>
                        <varname>azimuth</varname> is a value between 0 and 360 degrees measured clockwise from North.
                    </para>

                    <para>
                        <varname>altitude</varname> is a value between 0 and 90 degrees where 0 degrees is at the horizon and 90 degrees is directly overhead.
                    </para>

                    <para>
                        <varname>max_bright</varname> is a value between 0 and 255 with 0 as no brightness and 255 as max brightness.
                    </para>

                    <para>
                        <varname>scale</varname> is the ratio of vertical units to horizontal. For Feet:LatLon use scale=370400, for Meters:LatLon use scale=111120.
                    </para>

                    <para>
                        If <varname>interpolate_nodata</varname> is TRUE, values for NODATA pixels from the input raster will be interpolated using <xref linkend="RT_ST_InvDistWeight4ma"/> before computing the hillshade illumination.
                    </para>

                    <note>
                        <para>
                            For more information about Hillshade, please refer to <link xlink:href="http://webhelp.esri.com/arcgisdesktop/9.3/index.cfm?TopicName=How%20Hillshade%20works">How hillshade works</link>.
                        </para>
                    </note>

                    <para role="availability" conformance="2.0.0">Availability: 2.0.0 </para>
                    <para role="enhanced" conformance="2.1.0">Enhanced: 2.1.0 Uses ST_MapAlgebra() and added optional <varname>interpolate_nodata</varname> function parameter</para>
                    <para role="changed" conformance="2.1.0">Changed: 2.1.0 In prior versions, azimuth and altitude were expressed in radians. Now, azimuth and altitude are expressed in degrees</para>

                </refsection>

                <refsection>
                    <title>Examples</title>
                    <para>Variant 1.</para>
                    <programlisting language="sql">
WITH foo AS (
    SELECT ST_SetValues(ST_AddBand(ST_MakeEmptyRaster(5, 5, 0, 0, 1, -1, 0, 0, 0), 1, '32BF', 0, -9999),
        1, 1, 1, ARRAY[
            [1, 1, 1, 1, 1],
            [1, 2, 2, 2, 1],
            [1, 2, 3, 2, 1],
            [1, 2, 2, 2, 1],
            [1, 1, 1, 1, 1]
        ]::double precision[][]
    ) AS rast
)
SELECT
    ST_DumpValues(ST_HillShade(rast, 1, '32BF'))
FROM foo

                                                                                                                       st_dumpvalues</programlisting>
<screen role="text-primary">------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------
 (1,"{{NULL,NULL,NULL,NULL,NULL},{NULL,251.32763671875,220.749786376953,147.224319458008,NULL},{NULL,220.749786376953,180.312225341797,67.7497863769531,NULL},{NULL,147.224319458008,
67.7497863769531,43.1210060119629,NULL},{NULL,NULL,NULL,NULL,NULL}}")
(1 row)</screen>

                    <para>Variant 2.</para>

                    <para>Complete example of tiles of a coverage.</para>

                    <programlisting language="sql">
WITH foo AS (
    SELECT ST_Tile(ST_SetValues(ST_AddBand(ST_MakeEmptyRaster(6, 6, 0, 0, 1, -1, 0, 0, 0),
                1, '32BF', 0, -9999
            ),
            1, 1, 1, ARRAY[
                [1, 1, 1, 1, 1, 1],
                [1, 1, 1, 1, 2, 1],
                [1, 2, 2, 3, 3, 1],
                [1, 1, 3, 2, 1, 1],
                [1, 2, 2, 1, 2, 1],
                [1, 1, 1, 1, 1, 1]
            ]::double precision[]
        ),
        2, 2
    ) AS rast
)
SELECT
    t1.rast,
    ST_HillShade(ST_Union(t2.rast), 1, t1.rast)
FROM foo t1
CROSS JOIN foo t2
WHERE ST_Intersects(t1.rast, t2.rast)
GROUP BY t1.rast;
                    </programlisting>
                </refsection>

                <refsection>
                    <title>See Also</title>
                    <para>
                        <xref linkend="RT_ST_MapAlgebra"/>,
                        <xref linkend="RT_ST_TRI"/>,
                        <xref linkend="RT_ST_TPI"/>,
                        <xref linkend="RT_ST_Roughness"/>,
                        <xref linkend="RT_ST_Aspect"/>,
                        <xref linkend="RT_ST_Slope"/>
                    </para>
                </refsection>
            </refentry>

            <refentry xml:id="RT_ST_Roughness">
                <refnamediv>
                    <refname>ST_Roughness</refname>
                    <refpurpose>Returns a raster with the calculated "roughness" of a DEM.</refpurpose>
                </refnamediv>

                <refsynopsisdiv>
                    <funcsynopsis>
                        <funcprototype>
                            <funcdef>raster <function>ST_Roughness</function></funcdef>
                            <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                            <paramdef><type>integer </type> <parameter>nband</parameter></paramdef>
                            <paramdef><type>raster </type> <parameter>customextent</parameter></paramdef>
                            <paramdef choice="opt"><type>text </type> <parameter>pixeltype="32BF"</parameter> </paramdef>
                            <paramdef choice="opt"><type>boolean </type> <parameter> interpolate_nodata=FALSE </parameter> </paramdef>
                        </funcprototype>
                    </funcsynopsis>
                </refsynopsisdiv>

                <refsection>
                    <title>Description</title>
                <para>Calculates the "roughness" of a DEM, by subtracting the maximum from the minimum for a given area.</para>
                    <para role="availability" conformance="2.1.0">Availability: 2.1.0</para>
                </refsection>

                <refsection>
                    <title>Examples</title>
                    <programlisting language="sql">WITH foo AS (
    SELECT ST_SetValues(ST_AddBand(ST_MakeEmptyRaster(5, 5, 0, 0, 1, -1, 0, 0, 0), 1, '32BF', 0, -9999),
        1, 1, 1, ARRAY[
            [1, 1, 2, 3, 3],
            [1, 2, 4, 15, 3],
            [2, 4, 10, 7, 5],
            [3, 5, 7, 6, 4],
            [3, 3, 5, 4, 4]
        ]::double precision[][]
    ) AS rast
)
SELECT ST_Value(ST_Roughness(rast, 1, '32BF'), 3, 3) AS roughness
FROM foo;</programlisting>
<screen role="text-primary">13</screen>
              </refsection>

              <refsection>
                <title>See Also</title>
                    <para>
                        <xref linkend="RT_ST_MapAlgebra"/>,
                        <xref linkend="RT_ST_TRI"/>,
                        <xref linkend="RT_ST_TPI"/>,
                        <xref linkend="RT_ST_Slope"/>,
                        <xref linkend="RT_ST_HillShade"/>,
                        <xref linkend="RT_ST_Aspect"/>
                    </para>
                </refsection>
            </refentry>

            <refentry xml:id="RT_ST_Slope">
                <refnamediv>
                    <refname>ST_Slope</refname>
                    <refpurpose>Returns the slope (in degrees by default) of an elevation raster band.  Useful for analyzing terrain.</refpurpose>
                </refnamediv>
                <refsynopsisdiv>
                    <funcsynopsis>
                      <funcprototype>
                            <funcdef>raster <function>ST_Slope</function></funcdef>
                            <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                            <paramdef choice="opt"><type>integer </type> <parameter>nband=1</parameter></paramdef>
                            <paramdef choice="opt"><type>text </type> <parameter>pixeltype=32BF</parameter></paramdef>
                            <paramdef choice="opt"><type>text </type> <parameter>units=DEGREES</parameter></paramdef>
                            <paramdef choice="opt"><type>double precision </type> <parameter>scale=1.0</parameter></paramdef>
                            <paramdef choice="opt"><type>boolean </type> <parameter>interpolate_nodata=FALSE</parameter></paramdef>
                      </funcprototype>

                      <funcprototype>
                            <funcdef>raster <function>ST_Slope</function></funcdef>
                            <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                            <paramdef><type>integer </type> <parameter>nband</parameter></paramdef>
                            <paramdef><type>raster </type> <parameter>customextent</parameter></paramdef>
                            <paramdef choice="opt"><type>text </type> <parameter>pixeltype=32BF</parameter></paramdef>
                            <paramdef choice="opt"><type>text </type> <parameter>units=DEGREES</parameter></paramdef>
                            <paramdef choice="opt"><type>double precision </type> <parameter>scale=1.0</parameter></paramdef>
                            <paramdef choice="opt"><type>boolean </type> <parameter>interpolate_nodata=FALSE</parameter></paramdef>
                      </funcprototype>
                    </funcsynopsis>
                </refsynopsisdiv>

                <refsection>
                    <title>Description</title>

                    <para>Returns the slope (in degrees by default) of an elevation raster band. Utilizes map algebra and applies the slope equation to neighboring pixels.</para>

                    <para>
                        <varname>units</varname> indicates the units of the slope. Possible values are: RADIANS, DEGREES (default), PERCENT.
                    </para>

                    <para>
                        <varname>scale</varname> is the ratio of vertical units to horizontal. For Feet:LatLon use scale=370400, for Meters:LatLon use scale=111120.
                    </para>

                    <para>
                        If <varname>interpolate_nodata</varname> is TRUE, values for NODATA pixels from the input raster will be interpolated using <xref linkend="RT_ST_InvDistWeight4ma"/> before computing the surface slope.
                    </para>

                    <note>
                        <para>
                            For more information about Slope, Aspect and Hillshade, please refer to <link xlink:href="http://webhelp.esri.com/arcgisdesktop/9.3/index.cfm?TopicName=How%20Hillshade%20works">ESRI - How hillshade works</link> and <link xlink:href="http://e2b.erdas.com/fieldguide/wwhelp/wwhimpl/common/html/wwhelp.htm?context=FieldGuide&amp;file=Slope_Images.html">ERDAS Field Guide - Slope Images</link>.
                        </para>
                    </note>

                    <para role="availability" conformance="2.0.0">Availability: 2.0.0 </para>
                    <para role="enhanced" conformance="2.1.0">Enhanced: 2.1.0 Uses ST_MapAlgebra() and added optional <varname>units</varname>, <varname>scale</varname>, <varname>interpolate_nodata</varname> function parameters</para>
                    <para role="changed" conformance="2.1.0">Changed: 2.1.0 In prior versions, return values were in radians. Now, return values default to degrees</para>

                </refsection>

                <refsection>
                    <title>Examples</title>
                    <para>Variant 1.</para>
                    <programlisting language="sql">
WITH foo AS (
    SELECT ST_SetValues(ST_AddBand(ST_MakeEmptyRaster(5, 5, 0, 0, 1, -1, 0, 0, 0), 1, '32BF', 0, -9999),
        1, 1, 1, ARRAY[
            [1, 1, 1, 1, 1],
            [1, 2, 2, 2, 1],
            [1, 2, 3, 2, 1],
            [1, 2, 2, 2, 1],
            [1, 1, 1, 1, 1]
        ]::double precision[][]
    ) AS rast
)
SELECT
    ST_DumpValues(ST_Slope(rast, 1, '32BF'))
FROM foo

                            st_dumpvalues</programlisting>
<screen role="text-primary">------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
---------------------------------------------------------------------
 (1,"{{10.0249881744385,21.5681285858154,26.5650520324707,21.5681285858154,10.0249881744385},{21.5681285858154,35.2643890380859,36.8698959350586,35.2643890380859,21.5681285858154},
{26.5650520324707,36.8698959350586,0,36.8698959350586,26.5650520324707},{21.5681285858154,35.2643890380859,36.8698959350586,35.2643890380859,21.5681285858154},{10.0249881744385,21.
5681285858154,26.5650520324707,21.5681285858154,10.0249881744385}}")
(1 row)</screen>

                    <para>Variant 2.</para>

                    <para>Complete example of tiles of a coverage.</para>

                    <programlisting language="sql">
WITH foo AS (
    SELECT ST_Tile(ST_SetValues(ST_AddBand(ST_MakeEmptyRaster(6, 6, 0, 0, 1, -1, 0, 0, 0),
                1, '32BF', 0, -9999
            ),
            1, 1, 1, ARRAY[
                [1, 1, 1, 1, 1, 1],
                [1, 1, 1, 1, 2, 1],
                [1, 2, 2, 3, 3, 1],
                [1, 1, 3, 2, 1, 1],
                [1, 2, 2, 1, 2, 1],
                [1, 1, 1, 1, 1, 1]
            ]::double precision[]
        ),
        2, 2
    ) AS rast
)
SELECT
    t1.rast,
    ST_Slope(ST_Union(t2.rast), 1, t1.rast)
FROM foo t1
CROSS JOIN foo t2
WHERE ST_Intersects(t1.rast, t2.rast)
GROUP BY t1.rast;
                    </programlisting>
                </refsection>

                <refsection>
                    <title>See Also</title>
                    <para>
                        <xref linkend="RT_ST_MapAlgebra"/>,
                        <xref linkend="RT_ST_TRI"/>,
                        <xref linkend="RT_ST_TPI"/>,
                        <xref linkend="RT_ST_Roughness"/>,
                        <xref linkend="RT_ST_HillShade"/>,
                        <xref linkend="RT_ST_Aspect"/>
                    </para>
                </refsection>
            </refentry>

            <refentry xml:id="RT_ST_TPI">
                <refnamediv>
                    <refname>ST_TPI</refname>
                    <refpurpose>Returns a raster with the calculated Topographic Position Index.</refpurpose>
                </refnamediv>

                <refsynopsisdiv>
                    <funcsynopsis>
                        <funcprototype>
                            <funcdef>raster <function>ST_TPI</function></funcdef>
                            <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                            <paramdef><type>integer </type> <parameter>nband</parameter></paramdef>
                            <paramdef><type>raster </type> <parameter>customextent</parameter></paramdef>
                            <paramdef choice="opt"><type>text </type> <parameter>pixeltype="32BF"</parameter> </paramdef>
                            <paramdef choice="opt"><type>boolean </type> <parameter> interpolate_nodata=FALSE </parameter> </paramdef>
                        </funcprototype>
                    </funcsynopsis>
                </refsynopsisdiv>

                <refsection>
                    <title>Description</title>

                    <para>Calculates the Topographic Position Index, which is defined as the focal mean with radius of one minus the center cell.</para>

                <note>
              <para>This function only supports a focalmean radius of one.</para>
                </note>
                    <para role="availability" conformance="2.1.0">Availability: 2.1.0</para>
                </refsection>

                <refsection>
                    <title>Examples</title>
                    <programlisting language="sql">WITH foo AS (
    SELECT ST_SetValues(ST_AddBand(ST_MakeEmptyRaster(5, 5, 0, 0, 1, -1, 0, 0, 0), 1, '32BF', 0, -9999),
        1, 1, 1, ARRAY[
            [1, 1, 2, 3, 3],
            [1, 2, 4, 15, 3],
            [2, 4, 10, 7, 5],
            [3, 5, 7, 6, 4],
            [3, 3, 5, 4, 4]
        ]::double precision[][]
    ) AS rast
)
SELECT ST_Value(ST_TPI(rast, 1, '32BF'), 3, 3) AS tpi
FROM foo;</programlisting>
<screen role="text-primary">3.75</screen>
              </refsection>

              <refsection>
                <title>See Also</title>
                    <para>
                        <xref linkend="RT_ST_MapAlgebra"/>,
                        <xref linkend="RT_ST_TRI"/>,
                        <xref linkend="RT_ST_Roughness"/>,
                        <xref linkend="RT_ST_Slope"/>,
                        <xref linkend="RT_ST_HillShade"/>,
                        <xref linkend="RT_ST_Aspect"/>
                    </para>
                </refsection>
            </refentry>

            <refentry xml:id="RT_ST_TRI">
                <refnamediv>
                    <refname>ST_TRI</refname>
                    <refpurpose>Returns a raster with the calculated Terrain Ruggedness Index.</refpurpose>
                </refnamediv>

                <refsynopsisdiv>
                    <funcsynopsis>
                        <funcprototype>
                            <funcdef>raster <function>ST_TRI</function></funcdef>
                            <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                            <paramdef><type>integer </type> <parameter>nband</parameter></paramdef>
                            <paramdef><type>raster </type> <parameter>customextent</parameter></paramdef>
                            <paramdef choice="opt"><type>text </type> <parameter>pixeltype="32BF"</parameter> </paramdef>
                            <paramdef choice="opt"><type>boolean </type> <parameter> interpolate_nodata=FALSE </parameter> </paramdef>
                        </funcprototype>
                    </funcsynopsis>
                </refsynopsisdiv>

                <refsection>
                    <title>Description</title>

                    <para>
                        Terrain Ruggedness Index is calculated by comparing a central pixel with its neighbors, taking the absolute values of the differences, and averaging the result.
                    </para>

                    <note>
                        <para>This function only supports a focalmean radius of one.</para>
                    </note>

                    <para role="availability" conformance="2.1.0">Availability: 2.1.0</para>
                </refsection>

                <refsection>
                    <title>Examples</title>
                    <programlisting language="sql">WITH foo AS (
    SELECT ST_SetValues(ST_AddBand(ST_MakeEmptyRaster(5, 5, 0, 0, 1, -1, 0, 0, 0), 1, '32BF', 0, -9999),
        1, 1, 1, ARRAY[
            [1, 1, 2, 3, 3],
            [1, 2, 4, 15, 3],
            [2, 4, 10, 7, 5],
            [3, 5, 7, 6, 4],
            [3, 3, 5, 4, 4]
        ]::double precision[][]
    ) AS rast
)
SELECT ST_Value(ST_TRI(rast, 1, '32BF'), 3, 3) AS tri
FROM foo;</programlisting>
<screen role="text-primary">5</screen>
              </refsection>

                <refsection>
                    <title>See Also</title>
                        <para>
                            <xref linkend="RT_ST_MapAlgebra"/>,
                            <xref linkend="RT_ST_Roughness"/>,
                            <xref linkend="RT_ST_TPI"/>,
                            <xref linkend="RT_ST_Slope"/>,
                            <xref linkend="RT_ST_HillShade"/>,
                            <xref linkend="RT_ST_Aspect"/>
                        </para>
                </refsection>
            </refentry>

            <refentry xml:id="RT_ST_InterpolateRaster">
      <refnamediv>
        <refname>ST_InterpolateRaster</refname>

        <refpurpose>Interpolates a gridded surface based on an input set
        of 3-d points, using the X- and Y-values to position the points on
        the grid and the Z-value of the points as the surface elevation.
        </refpurpose>
      </refnamediv>

      <refsynopsisdiv>
        <funcsynopsis>
          <funcprototype>
            <funcdef>raster <function>ST_InterpolateRaster</function></funcdef>
            <paramdef><type>geometry </type><parameter>input_points</parameter></paramdef>
            <paramdef><type>text </type><parameter>algorithm_options</parameter></paramdef>
            <paramdef><type>raster </type><parameter>template</parameter></paramdef>
            <paramdef choice="opt"><type>integer </type><parameter>template_band_num=1</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>
      </refsynopsisdiv>

      <refsection>
        <title>Description</title>

        <para>
            Interpolates a gridded surface based on an input set
            of 3-d points, using the X- and Y-values to position the points on
            the grid and the Z-value of the points as the surface elevation.

            There are five interpolation algorithms available: inverse distance,
            inverse distance nearest-neighbor, moving average, nearest neighbor,
            and linear interpolation.
            See the <link xlink:href="https://gdal.org/programs/gdal_grid.html#interpolation-algorithms">gdal_grid documentation</link>
            for more details on the algorithms and their parameters. For more
            information on how interpolations are calculated, see the
            <link xlink:href="https://gdal.org/tutorials/gdal_grid_tut.html">GDAL grid
            tutorial</link>.
        </para>
        <para>
            Input parameters are:
        </para>
        <variablelist>
            <varlistentry><term><varname>input_points</varname></term>
                <listitem><para>The points to drive the interpolation. Any
                    geometry with Z-values is acceptable, all points in the
                    input will be used.</para></listitem>
            </varlistentry>
            <varlistentry><term><varname>algorithm_options</varname></term>
                <listitem><para>A string defining the algorithm and
                    algorithm options, in the format used by <link xlink:href="https://gdal.org/programs/gdal_grid.html#interpolation-algorithms">gdal_grid</link>.
                    For example, for an inverse-distance interpolation with a
                    smoothing of 2, you would use "invdist:smoothing=2.0"
                </para></listitem>
            </varlistentry>
            <varlistentry><term><varname>template</varname></term>
                <listitem><para>A raster template to drive the geometry of the
                    output raster. The width, height, pixel size, spatial extent
                    and pixel type will be read from this template.
                </para></listitem>
            </varlistentry>
            <varlistentry><term><varname>template_band_num</varname></term>
                <listitem><para>By default the first band in the template raster
                    is used to drive the output raster, but that can be adjusted
                    with this parameter.
                </para></listitem>
            </varlistentry>
        </variablelist>
        <para role="availability" conformance="3.2.0">Availability: 3.2.0</para>

      </refsection>

      <refsection>
        <title>Example</title>

<programlisting language="sql">SELECT ST_InterpolateRaster('MULTIPOINT(10.5 9.5 1000,11.5 8.5 1000,10.5 8.5 500,11.5 9.5 500)'::geometry,
    'invdist:smoothing:2.0',
    ST_AddBand(ST_MakeEmptyRaster(200, 400, 10, 10, 0.01, -0.005, 0, 0), '16BSI')
)</programlisting>

        </refsection>

        <refsection>
            <title>See Also</title>
            <para>
            <xref linkend="RT_ST_Contour"/>
            </para>
        </refsection>

</refentry>

            <refentry xml:id="RT_ST_Contour">
      <refnamediv>
        <refname>ST_Contour</refname>

        <refpurpose>Generates a set of vector contours from the provided raster
            band, using the <link xlink:href="https://gdal.org/api/gdal_alg.html?highlight=contour#_CPPv421GDALContourGenerateEx15GDALRasterBandHPv12CSLConstList16GDALProgressFuncPv">GDAL contouring algorithm</link>.</refpurpose>
      </refnamediv>

      <refsynopsisdiv>
        <funcsynopsis>
          <funcprototype>
            <funcdef>setof record <function>ST_Contour</function></funcdef>
            <paramdef><type>raster </type><parameter>rast</parameter></paramdef>
            <paramdef choice="opt"><type>integer </type><parameter>bandnumber=1</parameter></paramdef>
            <paramdef choice="opt"><type>double precision </type><parameter>level_interval=100.0</parameter></paramdef>
            <paramdef choice="opt"><type>double precision </type><parameter>level_base=0.0</parameter></paramdef>
            <paramdef choice="opt"><type>double precision[] </type><parameter>fixed_levels=ARRAY[]</parameter></paramdef>
            <paramdef choice="opt"><type>boolean </type><parameter>polygonize=false</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>
      </refsynopsisdiv>

      <refsection>
        <title>Description</title>

        <para>
            Generates a set of vector contours from the provided raster
            band, using the <link xlink:href="https://gdal.org/api/gdal_alg.html?highlight=contour#_CPPv421GDALContourGenerateEx15GDALRasterBandHPv12CSLConstList16GDALProgressFuncPv">GDAL contouring algorithm</link>.</para>
        <para>
            When the <varname>fixed_levels</varname> parameter is a non-empty
            array, the <varname>level_interval</varname> and <varname>level_base</varname> parameters are ignored.
        </para>

        <para>
            Input parameters are:
        </para>
        <variablelist>
            <varlistentry><term><varname>rast</varname></term>
                <listitem><para>The raster to generate the contour of</para></listitem>
            </varlistentry>
            <varlistentry><term><varname>bandnumber</varname></term>
                <listitem><para>The band to generate the contour of</para></listitem>
            </varlistentry>
            <varlistentry><term><varname>level_interval</varname></term>
                <listitem><para>The elevation interval between contours generated</para></listitem>
            </varlistentry>
            <varlistentry><term><varname>level_base</varname></term>
                <listitem><para>The "base" relative to which contour intervals are applied,
                this is normally zero, but could be different.
                To generate 10m contours at 5, 15, 25, ... the LEVEL_BASE would be 5.</para></listitem>
            </varlistentry>
            <varlistentry><term><varname>fixed_levels</varname></term>
                <listitem><para>The elevation interval between contours generated</para></listitem>
            </varlistentry>
            <varlistentry><term><varname>polygonize</varname></term>
                <listitem><para>If <literal>true</literal>, contour polygons will be created, rather than polygon lines.</para></listitem>
            </varlistentry>
        </variablelist>

        <para>
            Return values are a set of records with the following attributes:
        </para>
        <variablelist>
            <varlistentry><term><varname>geom</varname></term>
                <listitem><para>The geometry of the contour line.</para></listitem>
            </varlistentry>
            <varlistentry><term><varname>id</varname></term>
                <listitem><para>A unique identifier given to the contour line by GDAL.</para></listitem>
            </varlistentry>
            <varlistentry><term><varname>value</varname></term>
                <listitem><para>The raster value the line represents. For an elevation DEM input, this would be the elevation of the output contour.</para></listitem>
            </varlistentry>
        </variablelist>
        <para role="availability" conformance="3.2.0">Availability: 3.2.0</para>

      </refsection>

      <refsection>
        <title>Example</title>

        <programlisting language="sql">WITH c AS (
SELECT (ST_Contour(rast, 1, fixed_levels =&gt; ARRAY[100.0, 200.0, 300.0])).*
FROM dem_grid WHERE rid = 1
)
SELECT geom, id, value
FROM c;</programlisting>

    </refsection>
    <refsection>
        <title>See Also</title>
        <para>
        <xref linkend="RT_ST_InterpolateRaster"/>
        </para>
    </refsection>

</refentry>

        </section> <!-- /DEM -->

        <section xml:id="Raster_Processing_Geometry">
            <title>Raster Processing: Raster to Geometry</title>

            <refentry xml:id="RT_Box3D">
                <refnamediv>
                    <refname>Box3D</refname>
                    <refpurpose>Returns the box 3d representation of the enclosing box of the raster.</refpurpose>
                </refnamediv>

                <refsynopsisdiv>
                    <funcsynopsis>
                      <funcprototype>
                            <funcdef>box3d <function>Box3D</function></funcdef>
                            <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    </funcprototype>
                    </funcsynopsis>
                </refsynopsisdiv>

                <refsection>
                    <title>Description</title>

                    <para>Returns the box representing the extent of the raster.</para>
                    <para>
                        The polygon is defined by the corner points of the bounding box ((<varname>MINX</varname>, <varname>MINY</varname>), (<varname>MAXX</varname>, <varname>MAXY</varname>))
                    </para>

                    <para role="changed" conformance="2.0.0">Changed: 2.0.0 In pre-2.0 versions, there used to be a box2d instead of box3d.  Since box2d is a deprecated type, this was changed to box3d.</para>
                </refsection>

                <refsection>
                    <title>Examples</title>

                    <programlisting language="sql">
SELECT
    rid,
    Box3D(rast) AS rastbox
FROM dummy_rast;</programlisting>
<screen role="text-primary">rid |        rastbox
----+-------------------------------------------------
1   | BOX3D(0.5 0.5 0,20.5 60.5 0)
2   | BOX3D(3427927.75 5793243.5 0,3427928 5793244 0)</screen>
                </refsection>

                <refsection>
                    <title>See Also</title>
                    <para>
                        <xref linkend="RT_ST_Envelope"/>
                    </para>
                </refsection>
            </refentry>

            <refentry xml:id="RT_ST_ConvexHull">
                <refnamediv>
                    <refname>ST_ConvexHull</refname>
                    <refpurpose>Return the convex hull geometry of the raster including pixel values equal to BandNoDataValue.
                    For regular shaped and non-skewed
                    rasters, this gives the same result as ST_Envelope so only useful for irregularly shaped or skewed rasters.</refpurpose>
                </refnamediv>

                <refsynopsisdiv>
                    <funcsynopsis>
                      <funcprototype>
                        <funcdef>geometry <function>ST_ConvexHull</function></funcdef>
                        <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                    </funcprototype>
                    </funcsynopsis>
                </refsynopsisdiv>

                <refsection>
                    <title>Description</title>

                    <para>Return the convex hull geometry of the raster including the NoDataBandValue band pixels. For regular shaped and non-skewed
                    rasters, this gives more or less the same result as ST_Envelope
                    so only useful for irregularly shaped or skewed rasters.</para>

                    <note><para>ST_Envelope floors the coordinates and hence add a little buffer around the raster so the answer is subtly
                        different from ST_ConvexHull which does not floor.</para>
                    </note>
                </refsection>

                <refsection>
                    <title>Examples</title>
                    <para>See <filename>doc/development/internals/raster-affine.md</filename> for the scale, skew, and rotation terms that make the convex hull and envelope differ for skewed rasters.</para>
                    <para>For regular non-skewed rasters, the envelope and convex hull are more or less the same.</para>
                    <programlisting language="sql">
SELECT ST_ConvexHull(rast) As convhull, ST_Envelope(rast) As env
FROM dummy_rast WHERE rid=1;</programlisting>
<screen role="text-primary">                        convhull                        |                env
--------------------------------------------------------+------------------------------------
 POLYGON((0.5 0.5,20.5 0.5,20.5 60.5,0.5 60.5,0.5 0.5)) | POLYGON((0 0,20 0,20 60,0 60,0 0))</screen>
                <para>Now we skew the raster. Note how the convex hull and envelope are now different.</para>
                <programlisting language="sql">
SELECT ST_ConvexHull(rast) As convhull, ST_Envelope(rast) As env
FROM (SELECT ST_SetRotation(rast, 0.1, 0.1) As rast
    FROM dummy_rast WHERE rid=1) As foo;</programlisting>
<screen role="text-primary">                        convhull                        |                env
--------------------------------------------------------+------------------------------------
 POLYGON((0.5 0.5,20.5 1.5,22.5 61.5,2.5 60.5,0.5 0.5)) | POLYGON((0 0,22 0,22 61,0 61,0 0))</screen>
                </refsection>

                <!-- Optionally add a "See Also" section -->
                <refsection>
                    <title>See Also</title>
                    <para>
                        <xref linkend="RT_ST_Envelope"/>,
                        <xref linkend="RT_ST_MinConvexHull"/>,
                        <xref linkend="ST_ConvexHull"/>,
                        <xref linkend="ST_AsText"/>
                    </para>
                </refsection>
            </refentry>

            <refentry xml:id="RT_ST_DumpAsPolygons">
              <refnamediv>
                    <refname>ST_DumpAsPolygons</refname>
                    <refpurpose>Returns a set of geomval (geom,val) rows, from a given raster band.  If no band number is specified, band num defaults to 1.</refpurpose>
              </refnamediv>

              <refsynopsisdiv>
                    <funcsynopsis>
                      <funcprototype>
                            <funcdef>setof geomval <function>ST_DumpAsPolygons</function></funcdef>
                            <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                            <paramdef choice="opt"><type>integer </type> <parameter>band_num=1</parameter></paramdef>
                            <paramdef choice="opt"><type>boolean </type> <parameter>exclude_nodata_value=TRUE</parameter></paramdef>
                      </funcprototype>
                    </funcsynopsis>
              </refsynopsisdiv>

              <refsection>
                    <title>Description</title>
                    <para>This is a set-returning function (SRF). It returns a set of
                    geomval rows, formed by a geometry (geom) and a pixel band value (val).
                    Each polygon is the union of all pixels for that band that have the same pixel value denoted by val.</para>

                    <para>ST_DumpAsPolygon is useful for polygonizing rasters. It is the
                    reverse of a GROUP BY in that it creates new rows. For example it
                    can be used to expand a single raster into multiple POLYGONS/MULTIPOLYGONS.</para>

                    <para>Changed 3.3.0, validation and fixing is disabled to improve performance. May result invalid geometries.</para>
                    <para>Changed 3.7.0, the polygonization honours PostgreSQL interrupts so cancellations and statement timeouts halt processing promptly.</para>
                    <para role="availability" conformance="1.7">Availability: Requires GDAL 1.7 or higher.</para>
                    <note><para>If there is a no data value set for a band, pixels with that value will not be returned except in the case of exclude_nodata_value=false.</para></note>
                    <note><para>If you only care about count of pixels with a given value in a raster, it is faster to use <xref linkend="RT_ST_ValueCount"/>.</para></note>
                    <note>
                        <para>
                            This is different than ST_PixelAsPolygons where one geometry is returned for each pixel regardless of pixel value.
                        </para>
                    </note>
              </refsection>

              <refsection>
                    <title>Examples</title>
                    <para>This syntax uses a LATERAL join.</para>
                    <programlisting language="sql">
SELECT val,geom As geomwkt
FROM (
SELECT dp.*
FROM dummy_rast, LATERAL ST_DumpAsPolygons(rast) AS dp
WHERE rid = 2
) As foo
WHERE val BETWEEN 249 and 251
ORDER BY val;</programlisting>
<screen role="text-primary"> val |                                                       geomwkt
-----+--------------------------------------------------------------------------
 249 | POLYGON((3427927.95 5793243.95,3427927.95 5793243.85,3427928 5793243.85,
        3427928 5793243.95,3427927.95 5793243.95))
 250 | POLYGON((3427927.75 5793243.9,3427927.75 5793243.85,3427927.8 5793243.85,
        3427927.8 5793243.9,3427927.75 5793243.9))
 250 | POLYGON((3427927.8 5793243.8,3427927.8 5793243.75,3427927.85 5793243.75,
        3427927.85 5793243.8, 3427927.8 5793243.8))
 251 | POLYGON((3427927.75 5793243.85,3427927.75 5793243.8,3427927.8 5793243.8,
        3427927.8 5793243.85,3427927.75 5793243.85))</screen>
              </refsection>

                <refsection>
                    <title>See Also</title>
                    <para>
                        <xref linkend="geomval"/>,
                        <xref linkend="RT_ST_AsRasterAgg"/>,
                        <xref linkend="RT_ST_Value"/>,
                        <xref linkend="RT_ST_Polygon"/>,
                        <xref linkend="RT_ST_ValueCount"/>
                    </para>
                </refsection>
            </refentry>

            <refentry xml:id="RT_ST_Envelope">
                <refnamediv>
                    <refname>ST_Envelope</refname>
                    <refpurpose>Returns the polygon representation of the extent of the raster.</refpurpose>
                </refnamediv>

                <refsynopsisdiv>
                    <funcsynopsis>
                        <funcprototype>
                            <funcdef>geometry <function>ST_Envelope</function></funcdef>
                            <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                        </funcprototype>
                    </funcsynopsis>
                </refsynopsisdiv>

                <refsection>
                    <title>Description</title>

                    <para>Returns the polygon representation of the extent of the raster in spatial coordinate units defined by srid. It is a float8 minimum bounding box represented as a polygon. </para>

                    <para>The polygon is defined by the corner points of the bounding box
            ((<varname>MINX</varname>, <varname>MINY</varname>),
            (<varname>MINX</varname>, <varname>MAXY</varname>),
            (<varname>MAXX</varname>, <varname>MAXY</varname>),
            (<varname>MAXX</varname>, <varname>MINY</varname>),
            (<varname>MINX</varname>, <varname>MINY</varname>))
                    </para>
                </refsection>

                <refsection>
                    <title>Examples</title>

                    <programlisting language="sql">
SELECT rid, ST_Envelope(rast) As envgeomwkt
FROM dummy_rast;</programlisting>
<screen role="text-primary"> rid |                                         envgeomwkt
-----+--------------------------------------------------------------------
   1 | POLYGON((0 0,20 0,20 60,0 60,0 0))
   2 | POLYGON((3427927 5793243,3427928 5793243,
        3427928 5793244,3427927 5793244, 3427927 5793243))</screen>
                </refsection>

                <refsection>
                    <title>See Also</title>
                    <para>
                        <xref linkend="ST_Envelope"/>,
                        <xref linkend="ST_AsText"/>,
                        <xref linkend="RT_ST_SRID"/>
                    </para>
                </refsection>
            </refentry>

            <refentry xml:id="RT_ST_MinConvexHull">
                <refnamediv>
                    <refname>ST_MinConvexHull</refname>
                    <refpurpose>
                        Return the convex hull geometry of the raster excluding NODATA pixels.
                    </refpurpose>
                </refnamediv>

                <refsynopsisdiv>
                    <funcsynopsis>
                        <funcprototype>
                            <funcdef>geometry <function>ST_MinConvexHull</function></funcdef>
                            <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                            <paramdef choice="opt"><type>integer </type> <parameter>nband=NULL</parameter></paramdef>
                        </funcprototype>
                    </funcsynopsis>
                </refsynopsisdiv>

                <refsection>
                    <title>Description</title>

                    <para>
                        Return the convex hull geometry of the raster excluding NODATA pixels.  If <varname>nband</varname> is NULL, all bands of the raster are considered.
                    </para>

                    <para role="availability" conformance="2.1.0">Availability: 2.1.0 </para>
                </refsection>

                <refsection>
                    <title>Examples</title>
                    <programlisting language="sql">
WITH foo AS (
    SELECT
        ST_SetValues(ST_SetValues(ST_AddBand(ST_AddBand(ST_MakeEmptyRaster(9, 9, 0, 0, 1, -1, 0, 0, 0), 1, '8BUI', 0, 0), 2, '8BUI', 1, 0),
                1, 1, 1,
                ARRAY[
                    [0, 0, 0, 0, 0, 0, 0, 0, 0],
                    [0, 0, 0, 0, 0, 0, 0, 0, 0],
                    [0, 0, 0, 0, 0, 0, 0, 0, 0],
                    [0, 0, 0, 1, 0, 0, 0, 0, 1],
                    [0, 0, 0, 1, 1, 0, 0, 0, 0],
                    [0, 0, 0, 1, 0, 0, 0, 0, 0],
                    [0, 0, 0, 0, 0, 0, 0, 0, 0],
                    [0, 0, 0, 0, 0, 0, 0, 0, 0],
                    [0, 0, 0, 0, 0, 0, 0, 0, 0]
                ]::double precision[][]
            ),
            2, 1, 1,
            ARRAY[
                [0, 0, 0, 0, 0, 0, 0, 0, 0],
                [0, 0, 0, 0, 0, 0, 0, 0, 0],
                [0, 0, 0, 0, 0, 0, 0, 0, 0],
                [1, 0, 0, 0, 0, 1, 0, 0, 0],
                [0, 0, 0, 0, 1, 1, 0, 0, 0],
                [0, 0, 0, 0, 0, 1, 0, 0, 0],
                [0, 0, 0, 0, 0, 0, 0, 0, 0],
                [0, 0, 0, 0, 0, 0, 0, 0, 0],
                [0, 0, 1, 0, 0, 0, 0, 0, 0]
            ]::double precision[][]
        ) AS rast
)
SELECT title, geom AS geom
FROM foo
CROSS JOIN LATERAL (VALUES
    ('raster hull', ST_ConvexHull(rast)),
    ('all bands', ST_MinConvexHull(rast)),
    ('band 1', ST_MinConvexHull(rast, 1)),
    ('band 2', ST_MinConvexHull(rast, 2))
) AS variants(title, geom);</programlisting>
<screen role="text-primary">    title    |                 geom
-------------+---------------------------------------
 raster hull | POLYGON((0 0,9 0,9 -9,0 -9,0 0))
 all bands   | POLYGON((0 -3,9 -3,9 -9,0 -9,0 -3))
 band 1      | POLYGON((3 -3,9 -3,9 -6,3 -6,3 -3))
 band 2      | POLYGON((0 -3,6 -3,6 -9,0 -9,0 -3))</screen>
                </refsection>

                <refsection>
                    <title>See Also</title>
                    <para>
                        <xref linkend="RT_ST_Envelope"/>,
                        <xref linkend="RT_ST_ConvexHull"/>,
                        <xref linkend="ST_ConvexHull"/>,
                        <xref linkend="ST_AsText"/>
                    </para>
                </refsection>
            </refentry>

            <refentry xml:id="RT_ST_Polygon">
              <refnamediv>
                    <refname>ST_Polygon</refname>
                    <refpurpose>Returns a multipolygon geometry formed by the union of pixels that have a pixel value that is not no data value.  If no band number is specified, band num defaults to 1.</refpurpose>
              </refnamediv>

              <refsynopsisdiv>
                    <funcsynopsis>
                    <funcprototype>
                            <funcdef>geometry <function>ST_Polygon</function></funcdef>
                            <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                            <paramdef choice="opt"><type>integer </type> <parameter>band_num=1</parameter></paramdef>
                      </funcprototype>
                    </funcsynopsis>
              </refsynopsisdiv>

                <refsection>
                    <title>Description</title>
                    <para>Changed 3.3.0, validation and fixing is disabled to improve performance. May result invalid geometries.</para>
                    <para role="availability" conformance="0.1.6">Availability: 0.1.6 Requires GDAL 1.7 or higher.</para>
                    <para role="enhanced" conformance="2.1.0">Enhanced: 2.1.0 Improved Speed (fully C-Based) and the returning multipolygon is ensured to be valid.</para>
                    <para role="changed" conformance="2.1.0">Changed: 2.1.0 In prior versions would sometimes return a polygon, changed to always return multipolygon.</para>
                </refsection>

                <refsection>
                    <title>Examples</title>
                    <para>Compare polygonization of every pixel with
                    polygonization after zero is assigned as the NODATA value.
                    The latter preserves the gap formed by zero-valued cells.</para>
                    <programlisting language="sql">WITH source AS (
    SELECT ST_SetValues(
        ST_AddBand(
            ST_MakeEmptyRaster(4, 4, 0, 4, 1, -1, 0, 0, 0),
            1, '8BUI', 1, NULL
        ),
        1, 1, 1,
        ARRAY[
            [1, 1, 1, 1],
            [1, 0, 0, 1],
            [1, 1, 0, 1],
            [1, 1, 1, 1]
        ]::double precision[][]
    ) AS rast
), variants AS (
    SELECT 'all pixels' AS title, ST_Polygon(rast) AS geom
    FROM source
    UNION ALL
    SELECT
        'zero excluded',
        ST_Polygon(ST_SetBandNoDataValue(rast, 1, 0))
    FROM source
)
SELECT title, geom AS geom
FROM variants
ORDER BY CASE title
    WHEN 'all pixels' THEN 1
    ELSE 2
END;</programlisting>
                    <screen role="visual-primary visual-separate-output"> title         | geom
---------------+----------------------------------------------------------------------
 all pixels    | MULTIPOLYGON(((0 4,4 4,4 0,0 0,0 4)))
 zero excluded | MULTIPOLYGON(((0 4,0 0,4 0,4 4,0 4),(1 3,3 3,3 1,2 1,2 2,1 2,1 3)))
(2 rows)</screen>
                </refsection>

                <refsection>
                    <title>See Also</title>
                    <para>
                        <xref linkend="RT_ST_Value"/>,
                        <xref linkend="RT_ST_DumpAsPolygons"/>
                    </para>
                </refsection>
            </refentry>

            <refentry xml:id="RT_ST_IntersectionFractions">
              <refnamediv>
                    <refname>ST_IntersectionFractions</refname>
                    <refpurpose>Calculates the fraction of each raster cell that is covered by a given geometry.</refpurpose>
              </refnamediv>

              <refsynopsisdiv>
                    <funcsynopsis>
                    <funcprototype>
                            <funcdef>raster <function>ST_IntersectionFractions</function></funcdef>
                            <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
                            <paramdef><type>geometry </type> <parameter>geom</parameter></paramdef>
                      </funcprototype>
                    </funcsynopsis>
              </refsynopsisdiv>

                <refsection>
                    <title>Description</title>
                    <para>Calculates the fraction of each raster cell that is covered by a given geometry. The first argument is a raster, which defines the grid geometry to use for the calculation. The extent and cell size are read from the raster parameter. The second argument is a geometry, which is overlaid with the grid, and each grid populated based on overlaying the geometry on the grid. For polygons, the value returned for each cell is the proportion of its area that is covered by the geometry. For linestrings, the value returned for each cell is the length contained in the cell.</para>
                    <para role="availability" conformance="3.6.0">Availability: 3.6.0 Requires GEOS 3.14 or higher.</para>
                </refsection>

            <refsection>
                    <title>Examples</title>
                    <para>This rotated square polygon covers half of each cell in the raster.</para>
                    <programlisting language="sql">
CREATE TABLE raster_proportions_rast (
    name text,
    rast raster
);

INSERT INTO raster_proportions_rast (name, rast) VALUES (
  '2x2 raster covering 0,0 to 10,10',
  ST_MakeEmptyRaster(2, 2, -- raster width/height in pixels
    0, 10, -- upper-left corner x/y coordinates
    5, -5, -- pixel width/height in ground units
    0, 0, -- skew x/y
    0        -- SRID
  ));

SELECT name, ST_DumpValues(
    ST_IntersectionFractions(
        rast,
        'POLYGON((5 0,0 5,5 10,10 5,5 0))'::geometry),
    1)
FROM raster_proportions_rast;</programlisting>
<screen role="text-primary"> 2x2 raster covering 0,0 to 10,10
---------------------------------
 {{0.5,0.5},{0.5,0.5}}</screen>
                </refsection>

                <refsection>
                    <title>See Also</title>
                    <para>
                        <xref linkend="RT_ST_MakeEmptyRaster"/>
                    </para>
                </refsection>
            </refentry>


    </section> <!-- /misc -->

    <section xml:id="RT_Operators">
    <title>Raster Operators</title>
        <refentry xml:id="RT_Raster_Intersect">
          <refnamediv>
            <refname>&amp;&amp;</refname>

            <refpurpose>Returns <varname>TRUE</varname> if A's bounding box intersects B's bounding box.</refpurpose>
          </refnamediv>

          <refsynopsisdiv>
            <funcsynopsis>
                <funcprototype>
                <funcdef>boolean <function>&amp;&amp;</function></funcdef>
                    <paramdef>
                        <type>raster </type>
                        <parameter>A</parameter>
                    </paramdef>
                    <paramdef>
                        <type>raster </type>
                        <parameter>B</parameter>
                    </paramdef>
                </funcprototype>

                <funcprototype>
                <funcdef>boolean <function>&amp;&amp;</function></funcdef>
                    <paramdef>
                        <type>raster </type>
                        <parameter>A</parameter>
                    </paramdef>
                    <paramdef>
                        <type>geometry </type>
                        <parameter>B</parameter>
                    </paramdef>
                </funcprototype>

                <funcprototype>
                <funcdef>boolean <function>&amp;&amp;</function></funcdef>
                    <paramdef>
                        <type>geometry </type>
                        <parameter>B</parameter>
                    </paramdef>
                    <paramdef>
                        <type>raster </type>
                        <parameter>A</parameter>
                    </paramdef>
                </funcprototype>
            </funcsynopsis>
          </refsynopsisdiv>

          <refsection>
            <title>Description</title>

                <para>The <varname>&amp;&amp;</varname> operator returns <varname>TRUE</varname> if the bounding box of raster/geometr A intersects the bounding box of raster/geometr B.</para>

                <note><para>This operand will make use of any indexes that may be available on the
                rasters.</para></note>

                <para role="availability" conformance="2.0.0">Availability: 2.0.0</para>
          </refsection>

          <refsection>
            <title>Examples</title>

            <programlisting language="sql">SELECT A.rid As a_rid, B.rid As b_rid, A.rast &amp;&amp; B.rast As intersect
FROM dummy_rast AS A CROSS JOIN dummy_rast AS B LIMIT 3;</programlisting>
<screen role="text-primary"> a_rid | b_rid | intersect
-------+-------+---------
     2 |     2 | t
     2 |     3 | f
     2 |     1 | f</screen>
          </refsection>
         </refentry>

        <refentry xml:id="RT_Raster_OverLeft">
          <refnamediv>
            <refname>&amp;&lt;</refname>

            <refpurpose>Returns <varname>TRUE</varname> if A's bounding box is to the left of B's.</refpurpose>
          </refnamediv>

          <refsynopsisdiv>
            <funcsynopsis>
              <funcprototype>
                <funcdef>boolean <function>&amp;&lt;</function></funcdef>

                <paramdef>
                  <type>raster </type>

                  <parameter>A</parameter>
                </paramdef>

                <paramdef>
                  <type>raster </type>

                  <parameter>B</parameter>
                </paramdef>
              </funcprototype>
            </funcsynopsis>
          </refsynopsisdiv>

          <refsection>
            <title>Description</title>

            <para>The <varname>&amp;&lt;</varname> operator returns <varname>TRUE</varname> if the bounding box of raster A
            overlaps or is to the left of the bounding box of raster B, or more accurately, overlaps or is NOT to the right
            of the bounding box of raster B.</para>

            <note><para>This operand will make use of any indexes that may be available on the rasters.</para></note>
          </refsection>

          <refsection>
            <title>Examples</title>

            <programlisting language="sql"><![CDATA[
SELECT A.rid As a_rid, B.rid As b_rid, A.rast &< B.rast As overleft
 FROM dummy_rast AS A CROSS JOIN dummy_rast AS B;
]]></programlisting>
<screen role="text-primary"><![CDATA[a_rid | b_rid | overleft
------+-------+----------
    2 |     2 | t
    2 |     3 | f
    2 |     1 | f
    3 |     2 | t
    3 |     3 | t
    3 |     1 | f
    1 |     2 | t
    1 |     3 | t
    1 |     1 | t
]]></screen>
          </refsection>
         </refentry>

        <refentry xml:id="RT_Raster_OverRight">
          <refnamediv>
            <refname>&amp;&gt;</refname>

            <refpurpose>Returns <varname>TRUE</varname> if A's bounding box is to the right of B's.</refpurpose>
          </refnamediv>

          <refsynopsisdiv>
            <funcsynopsis>
              <funcprototype>
                <funcdef>boolean <function>&amp;&gt;</function></funcdef>

                <paramdef>
                  <type>raster </type>

                  <parameter>A</parameter>
                </paramdef>

                <paramdef>
                  <type>raster </type>

                  <parameter>B</parameter>
                </paramdef>
              </funcprototype>
            </funcsynopsis>
          </refsynopsisdiv>

          <refsection>
            <title>Description</title>

            <para>The <varname>&amp;&gt;</varname> operator returns <varname>TRUE</varname> if the bounding box of raster A
            overlaps or is to the right of the bounding box of raster B, or more accurately, overlaps or is NOT to the left
            of the bounding box of raster B.</para>

            <note><para>This operand will make use of any indexes that may be available on the
                geometries.</para></note>
          </refsection>

          <refsection>
            <title>Examples</title>

            <programlisting language="sql"><![CDATA[
SELECT A.rid As a_rid, B.rid As b_rid, A.rast &> B.rast As overright
 FROM dummy_rast AS A CROSS JOIN dummy_rast AS B;
]]></programlisting>
<screen role="text-primary"><![CDATA[ a_rid | b_rid | overright
-------+-------+----------
     2 |     2 | t
     2 |     3 | t
     2 |     1 | t
     3 |     2 | f
     3 |     3 | t
     3 |     1 | f
     1 |     2 | f
     1 |     3 | t
     1 |     1 | t
]]></screen>
          </refsection>
         </refentry>

        <refentry xml:id="RT_Raster_EQ">
          <refnamediv>
            <refname>&#61;</refname>

            <refpurpose>Returns <varname>TRUE</varname> if A's bounding box is the same as B's. Uses double precision bounding box.</refpurpose>
          </refnamediv>

          <refsynopsisdiv>
            <funcsynopsis>
              <funcprototype>
                <funcdef>boolean <function>&#61;</function></funcdef>

                <paramdef>
                  <type>raster </type>

                  <parameter>A</parameter>
                </paramdef>

                <paramdef>
                  <type>raster </type>

                  <parameter>B</parameter>
                </paramdef>
              </funcprototype>
            </funcsynopsis>
          </refsynopsisdiv>

          <refsection>
            <title>Description</title>

            <para>The <varname>&#61;</varname> operator returns <varname>TRUE</varname> if the bounding box of raster A
            is the same as the bounding box of raster B.  PostgreSQL uses the =, &lt;, and &gt; operators defined for rasters  to
            perform internal orderings and comparison of rasters (ie. in a GROUP BY or ORDER BY clause).</para>

            <caution><para>This operand will NOT make use of any indexes that may be available on the
                rasters. Use <xref linkend="RT_Raster_Same"/> instead.  This operator exists mostly so one can group by the raster column.</para></caution>

            <para role="availability" conformance="2.1.0">Availability:  2.1.0 </para>

          </refsection>

          <refsection>
            <title>See Also</title>

            <para><xref linkend="RT_Raster_Same"/></para>
          </refsection>
        </refentry>

        <refentry xml:id="RT_Raster_Contained">
          <refnamediv>
            <refname>@</refname>

            <refpurpose>Returns <varname>TRUE</varname> if A's bounding box is contained by B's. Uses double precision bounding box.</refpurpose>
          </refnamediv>

          <refsynopsisdiv>
            <funcsynopsis>
          <funcprototype>
            <funcdef>boolean <function>@</function></funcdef>
            <paramdef>
              <type>raster </type>
              <parameter>A</parameter>
            </paramdef>
            <paramdef>
              <type>raster </type>
              <parameter>B</parameter>
            </paramdef>
          </funcprototype>

          <funcprototype>
            <funcdef>boolean <function>@</function></funcdef>
            <paramdef>
              <type>geometry </type>
              <parameter>A</parameter>
            </paramdef>
            <paramdef>
              <type>raster </type>
              <parameter>B</parameter>
            </paramdef>
          </funcprototype>

          <funcprototype>
            <funcdef>boolean <function>@</function></funcdef>
            <paramdef>
              <type>raster </type>
              <parameter>B</parameter>
            </paramdef>
            <paramdef>
              <type>geometry </type>
              <parameter>A</parameter>
            </paramdef>

          </funcprototype>
            </funcsynopsis>
          </refsynopsisdiv>

          <refsection>
            <title>Description</title>

            <para>The <varname>@</varname> operator returns <varname>TRUE</varname> if the bounding box of raster/geometry A
            is contained by bounding box of raster/geometr B.  </para>

            <note><para>This operand will use spatial indexes on the rasters. </para></note>

            <para role="availability" conformance="2.0.0">Availability:  2.0.0 raster @ raster, raster @ geometry introduced</para>
            <para role="availability" conformance="2.0.5">Availability:  2.0.5 geometry @ raster introduced </para>

          </refsection>

          <refsection>
            <title>See Also</title>

            <para><xref linkend="RT_Raster_Contains"/></para>
          </refsection>
        </refentry>

        <refentry xml:id="RT_Raster_Same">
          <refnamediv>
            <refname>~=</refname>

            <refpurpose>Returns <varname>TRUE</varname> if A's bounding box is the same as B's.</refpurpose>
          </refnamediv>

          <refsynopsisdiv>
            <funcsynopsis>
              <funcprototype>
                <funcdef>boolean <function>~=</function></funcdef>

                <paramdef>
                  <type>raster </type>

                  <parameter>A</parameter>
                </paramdef>

                <paramdef>
                  <type>raster </type>

                  <parameter>B</parameter>
                </paramdef>
              </funcprototype>
            </funcsynopsis>
          </refsynopsisdiv>

          <refsection>
        <title>Description</title>

        <para>The <varname>~=</varname> operator returns <varname>TRUE</varname> if the bounding box of raster A
        is the same as the bounding box of raster B.</para>

        <note><para>This operand will make use of any indexes that may be available on the
          rasters.</para></note>

         <para role="availability" conformance="2.0.0">Availability: 2.0.0</para>

          </refsection>

          <refsection>
        <title>Examples</title>
        <para>Very useful usecase is for taking two sets of single band rasters that are of the same chunk but represent different themes and creating a multi-band raster</para>
  <programlisting language="sql">SELECT ST_AddBand(prec.rast, alt.rast) As new_rast
FROM prec INNER JOIN alt ON (prec.rast ~= alt.rast);
        </programlisting>
          </refsection>

          <refsection>
        <title>See Also</title>
        <para><xref linkend="RT_ST_AddBand"/>, <xref linkend="RT_Raster_EQ"/></para>
          </refsection>
        </refentry>

        <refentry xml:id="RT_Raster_Contains">
          <refnamediv>
            <refname>~</refname>

            <refpurpose>Returns <varname>TRUE</varname> if A's bounding box is contains B's. Uses double precision bounding box.</refpurpose>
          </refnamediv>

          <refsynopsisdiv>
            <funcsynopsis>
          <funcprototype>
            <funcdef>boolean <function>~</function></funcdef>
            <paramdef>
              <type>raster </type>
              <parameter>A</parameter>
            </paramdef>
            <paramdef>
              <type>raster </type>
              <parameter>B</parameter>
            </paramdef>
          </funcprototype>

          <funcprototype>
            <funcdef>boolean <function>~</function></funcdef>
            <paramdef>
              <type>geometry </type>
              <parameter>A</parameter>
            </paramdef>
            <paramdef>
              <type>raster </type>
              <parameter>B</parameter>
            </paramdef>
          </funcprototype>

          <funcprototype>
            <funcdef>boolean <function>~</function></funcdef>
            <paramdef>
              <type>raster </type>
              <parameter>B</parameter>
            </paramdef>
            <paramdef>
              <type>geometry </type>
              <parameter>A</parameter>
            </paramdef>

          </funcprototype>
            </funcsynopsis>
          </refsynopsisdiv>

          <refsection>
            <title>Description</title>

            <para>The <varname>~</varname> operator returns <varname>TRUE</varname> if the bounding box of raster/geometry A
            is contains bounding box of raster/geometr B.  </para>

            <note><para>This operand will use spatial indexes on the rasters. </para></note>

            <para role="availability" conformance="2.0.0">Availability:  2.0.0</para>

          </refsection>

          <refsection>
            <title>See Also</title>

            <para><xref linkend="RT_Raster_Contained"/></para>
          </refsection>
        </refentry>
    </section>

    <section xml:id="Raster_Relationships">
        <title>Raster and Raster Band Spatial Relationships</title>

    <refentry xml:id="RT_ST_Contains">
        <refnamediv>
            <refname>ST_Contains</refname>
            <refpurpose>
                Return true if no points of raster rastB lie in the exterior of raster rastA and at least one point of the interior of rastB lies in the interior of rastA.
            </refpurpose>
        </refnamediv>

        <refsynopsisdiv>
            <funcsynopsis>
                <funcprototype>
                    <funcdef>boolean <function>ST_Contains</function></funcdef>
                    <paramdef>
                        <type>raster </type>
                        <parameter>rastA</parameter>
                    </paramdef>
                    <paramdef>
                        <type>integer </type>
                        <parameter>nbandA</parameter>
                    </paramdef>
                    <paramdef>
                        <type>raster </type>
                        <parameter>rastB</parameter>
                    </paramdef>
                    <paramdef>
                        <type>integer </type>
                        <parameter>nbandB</parameter>
                    </paramdef>
                </funcprototype>

                <funcprototype>
                    <funcdef>boolean <function>ST_Contains</function></funcdef>
                    <paramdef>
                        <type>raster </type>
                        <parameter>rastA</parameter>
                    </paramdef>
                    <paramdef>
                        <type>raster </type>
                        <parameter>rastB</parameter>
                    </paramdef>
                </funcprototype>

            </funcsynopsis>
        </refsynopsisdiv>

        <refsection>
            <title>Description</title>

            <para>
                Raster rastA contains rastB if and only if no points of rastB lie in the exterior of rastA and at least one point of the interior of rastB lies in the interior of rastA. If the band number is not provided (or set to NULL), only the convex hull of the raster is considered in the test. If the band number is provided, only those pixels with value (not NODATA) are considered in the test.
            </para>

            <note>
                <para>
                    This function will make use of any indexes that may be available on the rasters.
                </para>
            </note>

            <note>
                <para>
                    To test the spatial relationship of a raster and a geometry, use ST_Polygon on the raster, e.g. ST_Contains(ST_Polygon(raster), geometry) or ST_Contains(geometry, ST_Polygon(raster)).
                </para>
            </note>

            <note>
                <para>
                    ST_Contains() is the inverse of ST_Within().  So, ST_Contains(rastA, rastB) implies ST_Within(rastB, rastA).
                </para>
            </note>

            <para role="availability" conformance="2.1.0">Availability: 2.1.0</para>
        </refsection>

        <refsection>
            <title>Examples</title>

            <para>Specified band numbers.</para>
            <programlisting language="sql">SELECT r1.rid, r2.rid, ST_Contains(r1.rast, 1, r2.rast, 1) FROM dummy_rast r1 CROSS JOIN dummy_rast r2 WHERE r1.rid = 1;</programlisting>
<screen role="text-primary">NOTICE:  The first raster provided has no bands
 rid | rid | st_contains
-----+-----+-------------
   1 |   1 |
   1 |   2 | f</screen>

            <para>No band numbers specified.</para>
            <programlisting language="sql">SELECT r1.rid, r2.rid, ST_Contains(r1.rast, r2.rast) FROM dummy_rast r1 CROSS JOIN dummy_rast r2 WHERE r1.rid = 1;</programlisting>
<screen role="text-primary"> rid | rid | st_contains
-----+-----+-------------
   1 |   1 | t
   1 |   2 | f</screen>
        </refsection>
        <refsection>
            <title>See Also</title>
            <para>
                <xref linkend="RT_ST_Intersects"/>,
                <xref linkend="RT_ST_Within"/>
            </para>
        </refsection>
    </refentry>

    <refentry xml:id="RT_ST_ContainsProperly">
        <refnamediv>
            <refname>ST_ContainsProperly</refname>
            <refpurpose>
                Return true if rastB intersects the interior of rastA but not the boundary or exterior of rastA.
            </refpurpose>
        </refnamediv>

        <refsynopsisdiv>
            <funcsynopsis>
                <funcprototype>
                    <funcdef>boolean <function>ST_ContainsProperly</function></funcdef>
                    <paramdef>
                        <type>raster </type>
                        <parameter>rastA</parameter>
                    </paramdef>
                    <paramdef>
                        <type>integer </type>
                        <parameter>nbandA</parameter>
                    </paramdef>
                    <paramdef>
                        <type>raster </type>
                        <parameter>rastB</parameter>
                    </paramdef>
                    <paramdef>
                        <type>integer </type>
                        <parameter>nbandB</parameter>
                    </paramdef>
                </funcprototype>

                <funcprototype>
                    <funcdef>boolean <function>ST_ContainsProperly</function></funcdef>
                    <paramdef>
                        <type>raster </type>
                        <parameter>rastA</parameter>
                    </paramdef>
                    <paramdef>
                        <type>raster </type>
                        <parameter>rastB</parameter>
                    </paramdef>
                </funcprototype>

            </funcsynopsis>
        </refsynopsisdiv>

        <refsection>
            <title>Description</title>

            <para>
                Raster rastA contains properly rastB if rastB intersects the interior of rastA but not the boundary or exterior of rastA. If the band number is not provided (or set to NULL), only the convex hull of the raster is considered in the test. If the band number is provided, only those pixels with value (not NODATA) are considered in the test.
            </para>

            <para>
                Raster rastA does not contain properly itself but does contain itself.
            </para>

            <note>
                <para>
                    This function will make use of any indexes that may be available on the rasters.
                </para>
            </note>

            <note>
                <para>
                    To test the spatial relationship of a raster and a geometry, use ST_Polygon on the raster, e.g. ST_ContainsProperly(ST_Polygon(raster), geometry) or ST_ContainsProperly(geometry, ST_Polygon(raster)).
                </para>
            </note>

            <para role="availability" conformance="2.1.0">Availability: 2.1.0</para>
        </refsection>

        <refsection>
            <title>Examples</title>

            <programlisting language="sql">SELECT r1.rid, r2.rid, ST_ContainsProperly(r1.rast, 1, r2.rast, 1) FROM dummy_rast r1 CROSS JOIN dummy_rast r2 WHERE r1.rid = 2;</programlisting>
<screen role="text-primary"> rid | rid | st_containsproperly
-----+-----+---------------------
   2 |   1 | f
   2 |   2 | f</screen>
        </refsection>
        <refsection>
            <title>See Also</title>
            <para>
                <xref linkend="RT_ST_Intersects"/>,
                <xref linkend="RT_ST_Contains"/>
            </para>
        </refsection>
    </refentry>

    <refentry xml:id="RT_ST_Covers">
        <refnamediv>
            <refname>ST_Covers</refname>
            <refpurpose>
                Return true if no points of raster rastB lie outside raster rastA.
            </refpurpose>
        </refnamediv>

        <refsynopsisdiv>
            <funcsynopsis>
                <funcprototype>
                    <funcdef>boolean <function>ST_Covers</function></funcdef>
                    <paramdef>
                        <type>raster </type>
                        <parameter>rastA</parameter>
                    </paramdef>
                    <paramdef>
                        <type>integer </type>
                        <parameter>nbandA</parameter>
                    </paramdef>
                    <paramdef>
                        <type>raster </type>
                        <parameter>rastB</parameter>
                    </paramdef>
                    <paramdef>
                        <type>integer </type>
                        <parameter>nbandB</parameter>
                    </paramdef>
                </funcprototype>

                <funcprototype>
                    <funcdef>boolean <function>ST_Covers</function></funcdef>
                    <paramdef>
                        <type>raster </type>
                        <parameter>rastA</parameter>
                    </paramdef>
                    <paramdef>
                        <type>raster </type>
                        <parameter>rastB</parameter>
                    </paramdef>
                </funcprototype>

            </funcsynopsis>
        </refsynopsisdiv>

        <refsection>
            <title>Description</title>

            <para>
                Raster rastA covers rastB if and only if no points of rastB lie in the exterior of rastA. If the band number is not provided (or set to NULL), only the convex hull of the raster is considered in the test. If the band number is provided, only those pixels with value (not NODATA) are considered in the test.
            </para>

            <note>
                <para>
                    This function will make use of any indexes that may be available on the rasters.
                </para>
            </note>

            <note>
                <para>
                    To test the spatial relationship of a raster and a geometry, use ST_Polygon on the raster, e.g. ST_Covers(ST_Polygon(raster), geometry) or ST_Covers(geometry, ST_Polygon(raster)).
                </para>
            </note>

            <para role="availability" conformance="2.1.0">Availability: 2.1.0</para>
        </refsection>

        <refsection>
            <title>Examples</title>

            <programlisting language="sql">SELECT r1.rid, r2.rid, ST_Covers(r1.rast, 1, r2.rast, 1) FROM dummy_rast r1 CROSS JOIN dummy_rast r2 WHERE r1.rid = 2;</programlisting>
<screen role="text-primary"> rid | rid | st_covers
-----+-----+-----------
   2 |   1 | f
   2 |   2 | t</screen>
        </refsection>
        <refsection>
            <title>See Also</title>
            <para>
                <xref linkend="RT_ST_Intersects"/>,
                <xref linkend="RT_ST_CoveredBy"/>
            </para>
        </refsection>
    </refentry>

    <refentry xml:id="RT_ST_CoveredBy">
        <refnamediv>
            <refname>ST_CoveredBy</refname>
            <refpurpose>
                Return true if no points of raster rastA lie outside raster rastB.
            </refpurpose>
        </refnamediv>

        <refsynopsisdiv>
            <funcsynopsis>
                <funcprototype>
                    <funcdef>boolean <function>ST_CoveredBy</function></funcdef>
                    <paramdef>
                        <type>raster </type>
                        <parameter>rastA</parameter>
                    </paramdef>
                    <paramdef>
                        <type>integer </type>
                        <parameter>nbandA</parameter>
                    </paramdef>
                    <paramdef>
                        <type>raster </type>
                        <parameter>rastB</parameter>
                    </paramdef>
                    <paramdef>
                        <type>integer </type>
                        <parameter>nbandB</parameter>
                    </paramdef>
                </funcprototype>

                <funcprototype>
                    <funcdef>boolean <function>ST_CoveredBy</function></funcdef>
                    <paramdef>
                        <type>raster </type>
                        <parameter>rastA</parameter>
                    </paramdef>
                    <paramdef>
                        <type>raster </type>
                        <parameter>rastB</parameter>
                    </paramdef>
                </funcprototype>

            </funcsynopsis>
        </refsynopsisdiv>

        <refsection>
            <title>Description</title>

            <para>
                Raster rastA is covered by rastB if and only if no points of rastA lie in the exterior of rastB. If the band number is not provided (or set to NULL), only the convex hull of the raster is considered in the test. If the band number is provided, only those pixels with value (not NODATA) are considered in the test.
            </para>

            <note>
                <para>
                    This function will make use of any indexes that may be available on the rasters.
                </para>
            </note>

            <note>
                <para>
                    To test the spatial relationship of a raster and a geometry, use ST_Polygon on the raster, e.g. ST_CoveredBy(ST_Polygon(raster), geometry) or ST_CoveredBy(geometry, ST_Polygon(raster)).
                </para>
            </note>

            <para role="availability" conformance="2.1.0">Availability: 2.1.0</para>
        </refsection>

        <refsection>
            <title>Examples</title>

            <programlisting language="sql">SELECT r1.rid, r2.rid, ST_CoveredBy(r1.rast, 1, r2.rast, 1) FROM dummy_rast r1 CROSS JOIN dummy_rast r2 WHERE r1.rid = 2;</programlisting>
<screen role="text-primary"> rid | rid | st_coveredby
-----+-----+--------------
   2 |   1 | f
   2 |   2 | t</screen>
        </refsection>
        <refsection>
            <title>See Also</title>
            <para>
                <xref linkend="RT_ST_Intersects"/>,
                <xref linkend="RT_ST_Covers"/>
            </para>
        </refsection>
    </refentry>

    <refentry xml:id="RT_ST_Disjoint">
        <refnamediv>
            <refname>ST_Disjoint</refname>
            <refpurpose>
                Return true if raster rastA does not spatially intersect rastB.
            </refpurpose>
        </refnamediv>

        <refsynopsisdiv>
            <funcsynopsis>
                <funcprototype>
                    <funcdef>boolean <function>ST_Disjoint</function></funcdef>
                    <paramdef>
                        <type>raster </type>
                        <parameter>rastA</parameter>
                    </paramdef>
                    <paramdef>
                        <type>integer </type>
                        <parameter>nbandA</parameter>
                    </paramdef>
                    <paramdef>
                        <type>raster </type>
                        <parameter>rastB</parameter>
                    </paramdef>
                    <paramdef>
                        <type>integer </type>
                        <parameter>nbandB</parameter>
                    </paramdef>
                </funcprototype>

                <funcprototype>
                    <funcdef>boolean <function>ST_Disjoint</function></funcdef>
                    <paramdef>
                        <type>raster </type>
                        <parameter>rastA</parameter>
                    </paramdef>
                    <paramdef>
                        <type>raster </type>
                        <parameter>rastB</parameter>
                    </paramdef>
                </funcprototype>

            </funcsynopsis>
        </refsynopsisdiv>

        <refsection>
            <title>Description</title>

            <para>
                Raster rastA and rastB are disjointed if they do not share any space together. If the band number is not provided (or set to NULL), only the convex hull of the raster is considered in the test. If the band number is provided, only those pixels with value (not NODATA) are considered in the test.
            </para>

            <note>
                <para>
                    This function does NOT use any indexes.
                </para>
            </note>

            <note>
                <para>
                    To test the spatial relationship of a raster and a geometry, use ST_Polygon on the raster, e.g. ST_Disjoint(ST_Polygon(raster), geometry).
                </para>
            </note>

            <para role="availability" conformance="2.1.0">Availability: 2.1.0</para>
        </refsection>

        <refsection>
            <title>Examples</title>

            <para>Rid = 1 has no bands, hence the NOTICE and the NULL value for st_disjoint.</para>
            <programlisting language="sql">SELECT r1.rid, r2.rid, ST_Disjoint(r1.rast, 1, r2.rast, 1) FROM dummy_rast r1 CROSS JOIN dummy_rast r2 WHERE r1.rid = 2;</programlisting>
<screen role="text-primary">NOTICE:  The second raster provided has no bands
 rid | rid | st_disjoint
-----+-----+-------------
   2 |   1 |
   2 |   2 | f</screen>

            <para>This time, without specifying band numbers.</para>
            <programlisting language="sql">SELECT r1.rid, r2.rid, ST_Disjoint(r1.rast, r2.rast) FROM dummy_rast r1 CROSS JOIN dummy_rast r2 WHERE r1.rid = 2;</programlisting>
<screen role="text-primary"> rid | rid | st_disjoint
-----+-----+-------------
   2 |   1 | t
   2 |   2 | f</screen>

        </refsection>
        <refsection>
            <title>See Also</title>
            <para>
                <xref linkend="RT_ST_Intersects"/>
            </para>
        </refsection>
    </refentry>

    <refentry xml:id="RT_ST_Intersects">
        <refnamediv>
            <refname>ST_Intersects</refname>
            <refpurpose>Return true if raster rastA spatially intersects raster rastB.</refpurpose>
        </refnamediv>

        <refsynopsisdiv>
            <funcsynopsis>
                <funcprototype>
                    <funcdef>boolean <function>ST_Intersects</function></funcdef>
                    <paramdef>
                        <type>raster </type>
                        <parameter>rastA</parameter>
                    </paramdef>
                    <paramdef>
                        <type>integer </type>
                        <parameter>nbandA</parameter>
                    </paramdef>
                    <paramdef>
                        <type>raster </type>
                        <parameter>rastB</parameter>
                    </paramdef>
                    <paramdef>
                        <type>integer </type>
                        <parameter>nbandB</parameter>
                    </paramdef>
                </funcprototype>

                <funcprototype>
                    <funcdef>boolean <function>ST_Intersects</function></funcdef>
                    <paramdef>
                        <type>raster </type>
                        <parameter>rastA</parameter>
                    </paramdef>
                    <paramdef>
                        <type>raster </type>
                        <parameter>rastB</parameter>
                    </paramdef>
                </funcprototype>

                <funcprototype>
                    <funcdef>boolean <function>ST_Intersects</function></funcdef>
                    <paramdef>
                        <type>raster </type>
                        <parameter>rast</parameter>
                    </paramdef>
                    <paramdef>
                        <type>integer </type>
                        <parameter>nband</parameter>
                    </paramdef>
                    <paramdef>
                        <type>geometry </type>
                        <parameter>geommin</parameter>
                    </paramdef>
                </funcprototype>

                <funcprototype>
                    <funcdef>boolean <function>ST_Intersects</function></funcdef>
                    <paramdef>
                        <type>raster </type>
                        <parameter>rast</parameter>
                    </paramdef>
                    <paramdef>
                        <type>geometry </type>
                        <parameter>geommin</parameter>
                    </paramdef>
                    <paramdef choice="opt">
                        <type>integer </type>
                        <parameter>nband=NULL</parameter>
                    </paramdef>
                </funcprototype>

                <funcprototype>
                    <funcdef>boolean <function>ST_Intersects</function></funcdef>
                    <paramdef>
                        <type>geometry </type>
                        <parameter>geommin</parameter>
                    </paramdef>
                    <paramdef>
                        <type>raster </type>
                        <parameter>rast</parameter>
                    </paramdef>
                    <paramdef choice="opt">
                        <type>integer </type>
                        <parameter>nband=NULL</parameter>
                    </paramdef>
                </funcprototype>

            </funcsynopsis>
        </refsynopsisdiv>

        <refsection>
            <title>Description</title>

            <para>
                Return true if raster rastA spatially intersects raster rastB. If the band number is not provided (or set to NULL), only the convex hull of the raster is considered in the test. If the band number is provided, only those pixels with value (not NODATA) are considered in the test.
            </para>

            <note>
                <para>
                    This function will make use of any indexes that may be available on the rasters.
                </para>
            </note>

            <para>
                Enhanced: 2.0.0 support raster/raster intersects was introduced.
            </para>

            <warning>
                <para>
                    Changed: 2.1.0 The behavior of the ST_Intersects(raster, geometry) variants changed to match that of ST_Intersects(geometry, raster).
                </para>
            </warning>

        </refsection>

        <refsection>
            <title>Examples</title>
            <para>Different bands of same raster.</para>
            <programlisting language="sql">SELECT ST_Intersects(rast, 2, rast, 3) FROM dummy_rast WHERE rid = 2;</programlisting>
<screen role="text-primary">t</screen>
        </refsection>

        <refsection>
            <title>See Also</title>
            <para>
                <xref linkend="RT_ST_Intersection"/>,
                <xref linkend="RT_ST_Disjoint"/>
            </para>
        </refsection>
    </refentry>

    <refentry xml:id="RT_ST_Overlaps">
        <refnamediv>
            <refname>ST_Overlaps</refname>
            <refpurpose>
                Return true if raster rastA and rastB intersect but one does not completely contain the other.
            </refpurpose>
        </refnamediv>

        <refsynopsisdiv>
            <funcsynopsis>
                <funcprototype>
                    <funcdef>boolean <function>ST_Overlaps</function></funcdef>
                    <paramdef>
                        <type>raster </type>
                        <parameter>rastA</parameter>
                    </paramdef>
                    <paramdef>
                        <type>integer </type>
                        <parameter>nbandA</parameter>
                    </paramdef>
                    <paramdef>
                        <type>raster </type>
                        <parameter>rastB</parameter>
                    </paramdef>
                    <paramdef>
                        <type>integer </type>
                        <parameter>nbandB</parameter>
                    </paramdef>
                </funcprototype>

                <funcprototype>
                    <funcdef>boolean <function>ST_Overlaps</function></funcdef>
                    <paramdef>
                        <type>raster </type>
                        <parameter>rastA</parameter>
                    </paramdef>
                    <paramdef>
                        <type>raster </type>
                        <parameter>rastB</parameter>
                    </paramdef>
                </funcprototype>

            </funcsynopsis>
        </refsynopsisdiv>

        <refsection>
            <title>Description</title>

            <para>
                Return true if raster rastA spatially overlaps raster rastB. This means that rastA and rastB intersect but one does not completely contain the other. If the band number is not provided (or set to NULL), only the convex hull of the raster is considered in the test. If the band number is provided, only those pixels with value (not NODATA) are considered in the test.
            </para>

            <note>
                <para>
                    This function will make use of any indexes that may be available on the rasters.
                </para>
            </note>

            <note>
                <para>
                    To test the spatial relationship of a raster and a geometry, use ST_Polygon on the raster, e.g. ST_Overlaps(ST_Polygon(raster), geometry).
                </para>
            </note>

            <para role="availability" conformance="2.1.0">Availability: 2.1.0</para>
        </refsection>

        <refsection>
            <title>Examples</title>

            <para>Comparing different bands of same raster.</para>
            <programlisting language="sql">SELECT ST_Overlaps(rast, 1, rast, 2) FROM dummy_rast WHERE rid = 2;</programlisting>
<screen role="text-primary">f</screen>
        </refsection>
        <refsection>
            <title>See Also</title>
            <para>
                <xref linkend="RT_ST_Intersects"/>
            </para>
        </refsection>
    </refentry>

    <refentry xml:id="RT_ST_Touches">
        <refnamediv>
            <refname>ST_Touches</refname>
            <refpurpose>
                Return true if raster rastA and rastB have at least one point in common but their interiors do not intersect.
            </refpurpose>
        </refnamediv>

        <refsynopsisdiv>
            <funcsynopsis>
                <funcprototype>
                    <funcdef>boolean <function>ST_Touches</function></funcdef>
                    <paramdef>
                        <type>raster </type>
                        <parameter>rastA</parameter>
                    </paramdef>
                    <paramdef>
                        <type>integer </type>
                        <parameter>nbandA</parameter>
                    </paramdef>
                    <paramdef>
                        <type>raster </type>
                        <parameter>rastB</parameter>
                    </paramdef>
                    <paramdef>
                        <type>integer </type>
                        <parameter>nbandB</parameter>
                    </paramdef>
                </funcprototype>

                <funcprototype>
                    <funcdef>boolean <function>ST_Touches</function></funcdef>
                    <paramdef>
                        <type>raster </type>
                        <parameter>rastA</parameter>
                    </paramdef>
                    <paramdef>
                        <type>raster </type>
                        <parameter>rastB</parameter>
                    </paramdef>
                </funcprototype>

            </funcsynopsis>
        </refsynopsisdiv>

        <refsection>
            <title>Description</title>

            <para>
                Return true if raster rastA spatially touches raster rastB. This means that rastA and rastB have at least one point in common but their interiors do not intersect. If the band number is not provided (or set to NULL), only the convex hull of the raster is considered in the test. If the band number is provided, only those pixels with value (not NODATA) are considered in the test.
            </para>

            <note>
                <para>
                    This function will make use of any indexes that may be available on the rasters.
                </para>
            </note>

            <note>
                <para>
                    To test the spatial relationship of a raster and a geometry, use ST_Polygon on the raster, e.g. ST_Touches(ST_Polygon(raster), geometry).
                </para>
            </note>

            <para role="availability" conformance="2.1.0">Availability: 2.1.0</para>
        </refsection>

        <refsection>
            <title>Examples</title>

            <programlisting language="sql">SELECT r1.rid, r2.rid, ST_Touches(r1.rast, 1, r2.rast, 1) FROM dummy_rast r1 CROSS JOIN dummy_rast r2 WHERE r1.rid = 2;</programlisting>
<screen role="text-primary"> rid | rid | st_touches
-----+-----+------------
   2 |   1 | f
   2 |   2 | f</screen>
        </refsection>
        <refsection>
            <title>See Also</title>
            <para>
                <xref linkend="RT_ST_Intersects"/>
            </para>
        </refsection>
    </refentry>

    <refentry xml:id="RT_ST_SameAlignment">
        <refnamediv>
            <refname>ST_SameAlignment</refname>

            <refpurpose>Returns true if rasters have same skew, scale, spatial ref, and offset (pixels can be put on same grid without cutting into pixels) and false if they don't with notice detailing issue.</refpurpose>
          </refnamediv>

          <refsynopsisdiv>
            <funcsynopsis>
              <funcprototype>
                <funcdef>boolean <function>ST_SameAlignment</function></funcdef>
                <paramdef>
                  <type>raster </type>
                  <parameter>rastA</parameter>
                </paramdef>
                <paramdef>
                  <type>raster </type>
                  <parameter>rastB</parameter>
                </paramdef>
              </funcprototype>

              <funcprototype>
                <funcdef>boolean <function>ST_SameAlignment</function></funcdef>
                <paramdef>
                  <type>double precision </type>
                  <parameter>ulx1</parameter>
                </paramdef>
                <paramdef>
                  <type>double precision </type>
                  <parameter>uly1</parameter>
                </paramdef>
                <paramdef>
                  <type>double precision </type>
                  <parameter>scalex1</parameter>
                </paramdef>
                <paramdef>
                  <type>double precision </type>
                  <parameter>scaley1</parameter>
                </paramdef>
                <paramdef>
                  <type>double precision </type>
                  <parameter>skewx1</parameter>
                </paramdef>
                <paramdef>
                  <type>double precision </type>
                  <parameter>skewy1</parameter>
                </paramdef>
                <paramdef>
                  <type>double precision </type>
                  <parameter>ulx2</parameter>
                </paramdef>
                <paramdef>
                  <type>double precision </type>
                  <parameter>uly2</parameter>
                </paramdef>
                <paramdef>
                  <type>double precision </type>
                  <parameter>scalex2</parameter>
                </paramdef>
                <paramdef>
                  <type>double precision </type>
                  <parameter>scaley2</parameter>
                </paramdef>
                <paramdef>
                  <type>double precision </type>
                  <parameter>skewx2</parameter>
                </paramdef>
                <paramdef>
                  <type>double precision </type>
                  <parameter>skewy2</parameter>
                </paramdef>
              </funcprototype>

              <funcprototype>
                    <funcdef>boolean <function>ST_SameAlignment</function></funcdef>
                    <paramdef>
                        <type>raster set </type>
                        <parameter>rastfield</parameter>
                    </paramdef>
              </funcprototype>

            </funcsynopsis>
          </refsynopsisdiv>

          <refsection>
            <title>Description</title>

            <para>
                Non-Aggregate version (Variants 1 and 2): Returns true if the two rasters (either provided directly or made using the values for upperleft, scale, skew and srid) have the same scale, skew, srid and at least one of any of the four corners of any pixel of one raster falls on any corner of the grid of the other raster. Returns false if they don't and a NOTICE detailing the alignment issue.
            </para>

            <para>
                Aggregate version (Variant 3): From a set of rasters, returns true if all rasters in the set are aligned. The ST_SameAlignment() function is an "aggregate" function in the terminology of PostgreSQL. That means that it operates on rows of data, in the same way the SUM() and AVG() functions do.
            </para>

            <para role="availability" conformance="2.0.0">Availability: 2.0.0</para>
            <para role="enhanced" conformance="2.1.0">Enhanced: 2.1.0 addition of Aggregate variant</para>
          </refsection>

          <refsection>
            <title>Examples: Rasters</title>

            <programlisting language="sql">SELECT ST_SameAlignment(ST_MakeEmptyRaster(1, 1, 0, 0, 1, 1, 0, 0),
    ST_MakeEmptyRaster(1, 1, 0, 0, 1, 1, 0, 0)
) as sm;</programlisting>
<screen role="text-primary">t</screen>
<programlisting language="sql">SELECT ST_SameAlignment(A.rast, b.rast)
FROM dummy_rast AS A CROSS JOIN dummy_rast AS B;</programlisting>
<screen role="text-primary">NOTICE:  The two rasters provided have different SRIDs
NOTICE:  The two rasters provided have different SRIDs
 t
 f
 f
 f</screen>
          </refsection>
            <refsection>
                <title>See Also</title>
                <para>
                    <xref linkend="RT_Loading_Rasters"/>,
                    <xref linkend="RT_ST_NotSameAlignmentReason"/>,
                    <xref linkend="RT_ST_MakeEmptyRaster"/>
                </para>
            </refsection>
        </refentry>

        <refentry xml:id="RT_ST_NotSameAlignmentReason">
            <refnamediv>
                <refname>ST_NotSameAlignmentReason</refname>
                <refpurpose>Returns text stating if rasters are aligned and if not aligned, a reason why.</refpurpose>
            </refnamediv>

            <refsynopsisdiv>
                <funcsynopsis>
                    <funcprototype>
                        <funcdef>text <function>ST_NotSameAlignmentReason</function></funcdef>
                        <paramdef><type>raster </type><parameter>rastA</parameter></paramdef>
                        <paramdef><type>raster </type><parameter>rastB</parameter></paramdef>
                    </funcprototype>
                </funcsynopsis>
            </refsynopsisdiv>

            <refsection>
                <title>Description</title>
                <para>Returns text stating if rasters are aligned and if not aligned, a reason why.</para>

                <note>
                    <para>
                        If there are several reasons why the rasters are not aligned, only one reason (the first test to fail) will be returned.
                    </para>
                </note>

                <para role="availability" conformance="2.1.0">Availability: 2.1.0</para>
            </refsection>

            <refsection>
                <title>Examples</title>
                <programlisting language="sql">
SELECT
    ST_SameAlignment(ST_MakeEmptyRaster(1, 1, 0, 0, 1, 1, 0, 0),
        ST_MakeEmptyRaster(1, 1, 0, 0, 1.1, 1.1, 0, 0)
    ),
    ST_NotSameAlignmentReason(ST_MakeEmptyRaster(1, 1, 0, 0, 1, 1, 0, 0),
        ST_MakeEmptyRaster(1, 1, 0, 0, 1.1, 1.1, 0, 0)
    )
;</programlisting>
<screen role="text-primary"> st_samealignment |            st_notsamealignmentreason
------------------+-------------------------------------------------
 f                | The rasters have different scales on the X axis
(1 row)</screen>
            </refsection>

            <refsection>
                <title>See Also</title>
                <para>
                    <xref linkend="RT_Loading_Rasters"/>,
                    <xref linkend="RT_ST_SameAlignment"/>
                </para>
            </refsection>
        </refentry>

    <refentry xml:id="RT_ST_Within">
        <refnamediv>
            <refname>ST_Within</refname>
            <refpurpose>
                Return true if no points of raster rastA lie in the exterior of raster rastB and at least one point of the interior of rastA lies in the interior of rastB.
            </refpurpose>
        </refnamediv>

        <refsynopsisdiv>
            <funcsynopsis>
                <funcprototype>
                    <funcdef>boolean <function>ST_Within</function></funcdef>
                    <paramdef>
                        <type>raster </type>
                        <parameter>rastA</parameter>
                    </paramdef>
                    <paramdef>
                        <type>integer </type>
                        <parameter>nbandA</parameter>
                    </paramdef>
                    <paramdef>
                        <type>raster </type>
                        <parameter>rastB</parameter>
                    </paramdef>
                    <paramdef>
                        <type>integer </type>
                        <parameter>nbandB</parameter>
                    </paramdef>
                </funcprototype>

                <funcprototype>
                    <funcdef>boolean <function>ST_Within</function></funcdef>
                    <paramdef>
                        <type>raster </type>
                        <parameter>rastA</parameter>
                    </paramdef>
                    <paramdef>
                        <type>raster </type>
                        <parameter>rastB</parameter>
                    </paramdef>
                </funcprototype>

            </funcsynopsis>
        </refsynopsisdiv>

        <refsection>
            <title>Description</title>

            <para>
                Raster rastA is within rastB if and only if no points of rastA lie in the exterior of rastB and at least one point of the interior of rastA lies in the interior of rastB. If the band number is not provided (or set to NULL), only the convex hull of the raster is considered in the test. If the band number is provided, only those pixels with value (not NODATA) are considered in the test.
            </para>

            <note>
                <para>
                    This operand will make use of any indexes that may be available on the rasters.
                </para>
            </note>

            <note>
                <para>
                    To test the spatial relationship of a raster and a geometry, use ST_Polygon on the raster, e.g. ST_Within(ST_Polygon(raster), geometry) or ST_Within(geometry, ST_Polygon(raster)).
                </para>
            </note>

            <note>
                <para>
                    ST_Within() is the inverse of ST_Contains().  So, ST_Within(rastA, rastB) implies ST_Contains(rastB, rastA).
                </para>
            </note>

            <para role="availability" conformance="2.1.0">Availability: 2.1.0</para>
        </refsection>

        <refsection>
            <title>Examples</title>

            <programlisting language="sql">SELECT r1.rid, r2.rid, ST_Within(r1.rast, 1, r2.rast, 1) FROM dummy_rast r1 CROSS JOIN dummy_rast r2 WHERE r1.rid = 2;</programlisting>
<screen role="text-primary"> rid | rid | st_within
-----+-----+-----------
   2 |   1 | f
   2 |   2 | t</screen>
        </refsection>
        <refsection>
            <title>See Also</title>
            <para>
                <xref linkend="RT_ST_Intersects"/>,
                <xref linkend="RT_ST_Contains"/>,
                <xref linkend="RT_ST_DWithin"/>,
                <xref linkend="RT_ST_DFullyWithin"/>
            </para>
        </refsection>
    </refentry>

    <refentry xml:id="RT_ST_DWithin">
        <refnamediv>
            <refname>ST_DWithin</refname>
            <refpurpose>
                Return true if rasters rastA and rastB are within the specified distance of each other.
            </refpurpose>
        </refnamediv>

        <refsynopsisdiv>
            <funcsynopsis>
                <funcprototype>
                    <funcdef>boolean <function>ST_DWithin</function></funcdef>
                    <paramdef>
                        <type>raster </type>
                        <parameter>rastA</parameter>
                    </paramdef>
                    <paramdef>
                        <type>integer </type>
                        <parameter>nbandA</parameter>
                    </paramdef>
                    <paramdef>
                        <type>raster </type>
                        <parameter>rastB</parameter>
                    </paramdef>
                    <paramdef>
                        <type>integer </type>
                        <parameter>nbandB</parameter>
                    </paramdef>
                    <paramdef>
                        <type>double precision </type>
                        <parameter>distance_of_srid</parameter>
                    </paramdef>
                </funcprototype>

                <funcprototype>
                    <funcdef>boolean <function>ST_DWithin</function></funcdef>
                    <paramdef>
                        <type>raster </type>
                        <parameter>rastA</parameter>
                    </paramdef>
                    <paramdef>
                        <type>raster </type>
                        <parameter>rastB</parameter>
                    </paramdef>
                    <paramdef>
                        <type>double precision </type>
                        <parameter>distance_of_srid</parameter>
                    </paramdef>
                </funcprototype>

            </funcsynopsis>
        </refsynopsisdiv>

        <refsection>
            <title>Description</title>

            <para>
                Return true if rasters rastA and rastB are within the specified distance of each other. If the band number is not provided (or set to NULL), only the convex hull of the raster is considered in the test. If the band number is provided, only those pixels with value (not NODATA) are considered in the test.
            </para>

            <para>
                The distance is specified in units defined by the spatial reference system of the rasters. For this function to make sense, the source rasters must both be of the same coordinate projection, having the same SRID.
            </para>

            <note>
                <para>
                    This operand will make use of any indexes that may be available on the rasters.
                </para>
            </note>

            <note>
                <para>
                    To test the spatial relationship of a raster and a geometry, use ST_Polygon on the raster, e.g. ST_DWithin(ST_Polygon(raster), geometry).
                </para>
            </note>

            <para role="availability" conformance="2.1.0">Availability: 2.1.0</para>
        </refsection>

        <refsection>
            <title>Examples</title>

            <programlisting language="sql">SELECT r1.rid, r2.rid, ST_DWithin(r1.rast, 1, r2.rast, 1, 3.14) FROM dummy_rast r1 CROSS JOIN dummy_rast r2 WHERE r1.rid = 2;</programlisting>
<screen role="text-primary"> rid | rid | st_dwithin
-----+-----+------------
   2 |   1 | f
   2 |   2 | t</screen>
        </refsection>
        <refsection>
            <title>See Also</title>
            <para>
                <xref linkend="RT_ST_Within"/>,
                <xref linkend="RT_ST_DFullyWithin"/>
            </para>
        </refsection>
    </refentry>

    <refentry xml:id="RT_ST_DFullyWithin">
        <refnamediv>
            <refname>ST_DFullyWithin</refname>
            <refpurpose>
                Return true if rasters rastA and rastB are fully within the specified distance of each other.
            </refpurpose>
        </refnamediv>

        <refsynopsisdiv>
            <funcsynopsis>
                <funcprototype>
                    <funcdef>boolean <function>ST_DFullyWithin</function></funcdef>
                    <paramdef>
                        <type>raster </type>
                        <parameter>rastA</parameter>
                    </paramdef>
                    <paramdef>
                        <type>integer </type>
                        <parameter>nbandA</parameter>
                    </paramdef>
                    <paramdef>
                        <type>raster </type>
                        <parameter>rastB</parameter>
                    </paramdef>
                    <paramdef>
                        <type>integer </type>
                        <parameter>nbandB</parameter>
                    </paramdef>
                    <paramdef>
                        <type>double precision </type>
                        <parameter>distance_of_srid</parameter>
                    </paramdef>
                </funcprototype>

                <funcprototype>
                    <funcdef>boolean <function>ST_DFullyWithin</function></funcdef>
                    <paramdef>
                        <type>raster </type>
                        <parameter>rastA</parameter>
                    </paramdef>
                    <paramdef>
                        <type>raster </type>
                        <parameter>rastB</parameter>
                    </paramdef>
                    <paramdef>
                        <type>double precision </type>
                        <parameter>distance_of_srid</parameter>
                    </paramdef>
                </funcprototype>

            </funcsynopsis>
        </refsynopsisdiv>

        <refsection>
            <title>Description</title>

            <para>
                Return true if rasters rastA and rastB are fully within the specified distance of each other. If the band number is not provided (or set to NULL), only the convex hull of the raster is considered in the test. If the band number is provided, only those pixels with value (not NODATA) are considered in the test.
            </para>

            <para>
                The distance is specified in units defined by the spatial reference system of the rasters. For this function to make sense, the source rasters must both be of the same coordinate projection, having the same SRID.
            </para>

            <note>
                <para>
                    This operand will make use of any indexes that may be available on the rasters.
                </para>
            </note>

            <note>
                <para>
                    To test the spatial relationship of a raster and a geometry, use ST_Polygon on the raster, e.g. ST_DFullyWithin(ST_Polygon(raster), geometry).
                </para>
            </note>

            <para role="availability" conformance="2.1.0">Availability: 2.1.0</para>
        </refsection>

        <refsection>
            <title>Examples</title>

            <programlisting language="sql">SELECT r1.rid, r2.rid, ST_DFullyWithin(r1.rast, 1, r2.rast, 1, 3.14) FROM dummy_rast r1 CROSS JOIN dummy_rast r2 WHERE r1.rid = 2;</programlisting>
<screen role="text-primary"> rid | rid | st_dfullywithin
-----+-----+-----------------
   2 |   1 | f
   2 |   2 | t</screen>
        </refsection>
        <refsection>
            <title>See Also</title>
            <para>
                <xref linkend="RT_ST_Within"/>,
                <xref linkend="RT_ST_DWithin"/>
            </para>
        </refsection>
    </refentry>

    </section>

  <section xml:id="Raster_Tips">
        <title>Raster Tips</title><info>
            <abstract>
                <para>This section documents various gotchas and tips related to PostGIS Raster.</para>
            </abstract>
        </info>


        <section xml:id="outdb">
            <title>Out-DB Rasters</title>

            <section xml:id="gdal_readdir">
                <title>Directory containing many files</title>
                <para>
                    When GDAL opens a file, GDAL eagerly scans the directory of that file to build a catalog of other files. If this directory contains many files (e.g. thousands, millions), opening that file becomes extremely slow (especially if that file happens to be on a network drive such as NFS).
                </para>
                <para>
                    To control this behavior, GDAL provides the following environment variable: <link xlink:href="https://gdal.org/user/configoptions.html#config-GDAL_DISABLE_READDIR_ON_OPEN">GDAL_DISABLE_READDIR_ON_OPEN</link>.  Set <varname>GDAL_DISABLE_READDIR_ON_OPEN</varname> to <varname>TRUE</varname> to disable directory scanning.
                </para>

                <para>
                    In Ubuntu (and assuming you are using PostgreSQL's packages for Ubuntu), <varname>GDAL_DISABLE_READDIR_ON_OPEN</varname> can be set in <emphasis>/etc/postgresql/POSTGRESQL_VERSION/CLUSTER_NAME/environment</emphasis> (where POSTGRESQL_VERSION is the version of PostgreSQL, e.g. 9.6 and CLUSTER_NAME is the name of the cluster, e.g. maindb). You can also set PostGIS environment variables here as well.

                    <programlisting language="bash" role="text-primary">
# environment variables for postmaster process
# This file has the same syntax as postgresql.conf:
#  VARIABLE = simple_value
#  VARIABLE2 = 'any value!'
# I. e. you need to enclose any value which does not only consist of letters,
# numbers, and '-', '_', '.' in single quotes. Shell commands are not
# evaluated.
POSTGIS_GDAL_ENABLED_DRIVERS = 'ENABLE_ALL'

POSTGIS_ENABLE_OUTDB_RASTERS = 1

<emphasis role="strong">GDAL_DISABLE_READDIR_ON_OPEN = 'TRUE'</emphasis>
                    </programlisting>
                </para>

            </section>

            <section xml:id="max_open_files">
                <title>Maximum Number of Open Files</title>

                <para>
                    The maximum number of open files permitted by Linux and PostgreSQL are typically conservative (typically 1024 open files per process) given the assumption that the system is consumed by human users. For Out-DB Rasters, a single valid query can easily exceed this limit (e.g. a dataset of 10 year's worth of rasters with one raster for each day containing minimum and maximum temperatures and we want to know the absolute min and max value for a pixel in that dataset).
                </para>

                <para>
                    The easiest change to make is the following PostgreSQL setting: <link xlink:href="https://www.postgresql.org/docs/current/static/runtime-config-resource.html#GUC-MAX-FILES-PER-PROCESS">max_files_per_process</link>. The default is set to 1000, which is far too low for Out-DB Rasters. A safe starting value could be 65536 but this really depends on your datasets and the queries run against those datasets. This setting can only be made on server start and probably only in the PostgreSQL configuration file (e.g. <emphasis>/etc/postgresql/POSTGRESQL_VERSION/CLUSTER_NAME/postgresql.conf</emphasis> in Ubuntu environments).

                    <programlisting language="bash" role="text-primary">
...
# - Kernel Resource Usage -

<emphasis role="strong">max_files_per_process = 65536</emphasis>           # min 25
                                        # (change requires restart)
...
                    </programlisting>
                </para>

                <para>
                    The major change to make is the Linux kernel's open files limits. There are two parts to this:
                    <itemizedlist>
                        <listitem>
                            <para>Maximum number of open files for the entire system</para>
                        </listitem>
                        <listitem>
                            <para>Maximum number of open files per process</para>
                        </listitem>
                    </itemizedlist>
                </para>

                <section xml:id="max_open_files_per_system">
                    <title>Maximum number of open files for the entire system</title>

                    <para>
                        You can inspect the current maximum number of open files for the entire system with the following example:
                    </para>

                    <programlisting language="bash" role="text-primary">
$ sysctl -a | grep fs.file-max
fs.file-max = 131072
                    </programlisting>

                    <para>
                        If the value returned is not large enough, add a file to <emphasis>/etc/sysctl.d/</emphasis> as per the following example:
                    </para>

                    <programlisting language="bash" role="text-primary">
$ echo "fs.file-max = 6145324" &gt;&gt; /etc/sysctl.d/fs.conf

$ cat /etc/sysctl.d/fs.conf
fs.file-max = 6145324

$ sysctl -p --system
* Applying /etc/sysctl.d/fs.conf ...
fs.file-max = 2097152
* Applying /etc/sysctl.conf ...

$ sysctl -a | grep fs.file-max
fs.file-max = 6145324
                    </programlisting>

                </section>
                <section xml:id="max_open_files_per_process">
                    <title>Maximum number of open files per process</title>

                    <para>
                        We need to increase the maximum number of open files per process for the PostgreSQL server processes.
                    </para>

                    <para>
                        To see what the current PostgreSQL service processes are using for maximum number of open files, do as per the following example (make sure to have PostgreSQL running):
                    </para>

                    <programlisting language="bash">$ ps aux | grep postgres</programlisting>
                    <screen role="text-primary">
postgres 31713  0.0  0.4 179012 17564 pts/0    S    Dec26   0:03 /home/dustymugs/devel/postgresql/sandbox/10/usr/local/bin/postgres -D /home/dustymugs/devel/postgresql/sandbox/10/pgdata
postgres 31716  0.0  0.8 179776 33632 ?        Ss   Dec26   0:01 postgres: checkpointer process
postgres 31717  0.0  0.2 179144  9416 ?        Ss   Dec26   0:05 postgres: writer process
postgres 31718  0.0  0.2 179012  8708 ?        Ss   Dec26   0:06 postgres: wal writer process
postgres 31719  0.0  0.1 179568  7252 ?        Ss   Dec26   0:03 postgres: autovacuum launcher process
postgres 31720  0.0  0.1  34228  4124 ?        Ss   Dec26   0:09 postgres: stats collector process
postgres 31721  0.0  0.1 179308  6052 ?        Ss   Dec26   0:00 postgres: bgworker: logical replication launcher</screen>
                    <programlisting language="bash">$ cat /proc/31718/limits</programlisting>
                    <screen role="text-primary">
Limit                     Soft Limit           Hard Limit           Units
Max cpu time              unlimited            unlimited            seconds
Max file size             unlimited            unlimited            bytes
Max data size             unlimited            unlimited            bytes
Max stack size            8388608              unlimited            bytes
Max core file size        0                    unlimited            bytes
Max resident set          unlimited            unlimited            bytes
Max processes             15738                15738                processes
<emphasis role="strong">Max open files            1024                 4096                 files</emphasis>
Max locked memory         65536                65536                bytes
Max address space         unlimited            unlimited            bytes
Max file locks            unlimited            unlimited            locks
Max pending signals       15738                15738                signals
Max msgqueue size         819200               819200               bytes
Max nice priority         0                    0
Max realtime priority     0                    0
Max realtime timeout      unlimited            unlimited            us
                    </screen>

                    <para>
                        In the example above, we inspected the open files limit for Process 31718. It doesn't matter which PostgreSQL process, any of them will do. The response we are interested in is <emphasis>Max open files</emphasis>.
                    </para>

                    <para>
                        We want to increase <emphasis>Soft Limit</emphasis> and <emphasis>Hard Limit</emphasis> of <emphasis>Max open files</emphasis> to be greater than the value we specified for the PostgreSQL setting <varname>max_files_per_process</varname>.  In our example, we set <varname>max_files_per_process</varname> to 65536.
                    </para>

                    <para>
                        In Ubuntu (and assuming you are using PostgreSQL's packages for Ubuntu), the easiest way to change the <emphasis>Soft Limit</emphasis> and <emphasis>Hard Limit</emphasis> is to edit <emphasis role="strong">/etc/init.d/postgresql</emphasis> (SysV) or <emphasis role="strong">/lib/systemd/system/postgresql*.service</emphasis> (systemd).
                    </para>

                    <para>
                        Let's first address the SysV Ubuntu case where we add <emphasis role="strong">ulimit -H -n 262144</emphasis> and <emphasis role="strong">ulimit -n 131072</emphasis> to <emphasis role="strong">/etc/init.d/postgresql</emphasis>.
                    </para>

                    <programlisting language="bash" role="text-primary">
...
case "$1" in
    start|stop|restart|reload)
        if [ "$1" = "start" ]; then
            create_socket_directory
        fi
    if [ -z "`pg_lsclusters -h`" ]; then
        log_warning_msg 'No PostgreSQL clusters exist; see "man pg_createcluster"'
        exit 0
    fi
<emphasis role="strong">
    ulimit -H -n 262144
    ulimit -n 131072
</emphasis>
    for v in $versions; do
        $1 $v || EXIT=$?
    done
    exit ${EXIT:-0}
        ;;
    status)
...
</programlisting>

                    <para>
                        Now to address the systemd Ubuntu case. We will add <emphasis role="strong">LimitNOFILE=131072</emphasis> to every <emphasis role="strong">/lib/systemd/system/postgresql*.service</emphasis> file in the <emphasis role="strong">[Service]</emphasis> section.
                    </para>

                    <programlisting language="bash" role="text-primary">
...
[Service]
<emphasis role="strong">
LimitNOFILE=131072
</emphasis>
...

[Install]
WantedBy=multi-user.target
...
</programlisting>

                    <para>
                        After making the necessary systemd changes, make sure to reload the daemon
                    </para>

                    <programlisting language="bash" role="text-primary">systemctl daemon-reload</programlisting>

                </section>

            </section>

        </section>

    </section>
</chapter>
