]> granicus.if.org Git - postgis/commitdiff
Add ST_SetBandPath (#4007) and ST_SetBandIndex (#4008). Update signature
authorBborie Park <dustymugs@gmail.com>
Wed, 7 Feb 2018 07:47:55 +0000 (07:47 +0000)
committerBborie Park <dustymugs@gmail.com>
Wed, 7 Feb 2018 07:47:55 +0000 (07:47 +0000)
of ST_BandMetaData to include external raster band index

git-svn-id: http://svn.osgeo.org/postgis/trunk@16373 b70326c6-7e19-0410-871a-916f4a2858ee

15 files changed:
doc/reference_raster.xml
raster/rt_core/librtcore.h
raster/rt_core/rt_band.c
raster/rt_pg/rtpg_band_properties.c
raster/rt_pg/rtpg_create.c
raster/rt_pg/rtpostgis.sql.in
raster/rt_pg/rtpostgis_upgrade_cleanup.sql.in
raster/test/cunit/cu_band_basics.c
raster/test/regress/Makefile.in
raster/test/regress/rt_addband_expected
raster/test/regress/rt_bandmetadata.sql
raster/test/regress/rt_bandmetadata_expected
raster/test/regress/rt_mapalgebra_expected
raster/test/regress/rt_setbandpath.sql [new file with mode: 0644]
raster/test/regress/rt_setbandpath_expected [new file with mode: 0644]

index 5c8c77e07f76b707b004d97e881c2b56c5ad1c72..d6078df2b3fca314ff4ae600b1299d27f1295b8f 100644 (file)
@@ -3745,9 +3745,14 @@ FROM dummy_rast;
                        <refsynopsisdiv>
                                <funcsynopsis>
                                  <funcprototype>
-                                       <funcdef>record <function>ST_BandMetaData</function></funcdef>
-                                       <paramdef><type>raster </type><parameter>rast</parameter></paramdef>
-                                       <paramdef choice="opt"><type>integer </type><parameter>bandnum=1</parameter></paramdef>
+                                               <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>
@@ -3755,32 +3760,70 @@ FROM dummy_rast;
                        <refsection>
                                <title>Description</title>
 
-                               <para>Returns basic meta data about a raster band. Columns returned
-                                        pixeltype | nodatavalue | isoutdb | path.
+                               <para>Returns basic meta data about a raster band. Columns returned: pixeltype, nodatavalue, isoutdb, path, outdbbandnum.
                                </para>
                                <note>
-                                  <para>
-                                       If raster contains no bands then an error is thrown.
-                                  </para>
+                                       <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 band has no NODATA value, nodatavalue will be NULL.
-                                  </para>
+                                       <para>
+                                               If isoutdb is False, path and outdbbandnum are NULL.
+                                       </para>
                                </note>
                        </refsection>
 
                        <refsection>
-                               <title>Examples</title>
+                               <title>Examples: Variant 1</title>
 
-                               <programlisting>SELECT rid, (foo.md).*
- FROM (SELECT rid, ST_BandMetaData(rast,1) As md
-FROM dummy_rast WHERE rid=2) As foo;
+                               <programlisting>
+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
+       *
+FROM ST_BandMetadata(
+       (SELECT rast FROM foo),
+       ARRAY[1,3,2]::int[]
+);
 
- rid | pixeltype | nodatavalue | isoutdb | path
------+-----------+----------------+-------------+---------+------
-   2 | 8BUI      |           0 | f       |
+ bandnum | pixeltype | nodatavalue | isoutdb |                                      path                                      | outdbbandnum 
+---------+-----------+-------------+---------+--------------------------------------------------------------------------------+--------------
+       1 | 8BUI      |             | t       | /home/pele/devel/geo/postgis-git/raster/test/regress/loader/Projected.tif      |            1
+       3 | 8BUI      |             | t       | /home/pele/devel/geo/postgis-git/raster/test/regress/loader/Projected.tif      |            3
+       2 | 8BUI      |             | t       | /home/pele/devel/geo/postgis-git/raster/test/regress/loader/Projected.tif      |            2
                                </programlisting>
+
+                       </refsection>
+
+                       <refsection>
+                               <title>Examples: Variant 2</title>
+
+                               <programlisting>
+SELECT
+       rid,
+       (foo.md).*
+FROM (
+       SELECT
+               rid,
+               ST_BandMetaData(rast, 1) AS md
+       FROM dummy_rast
+       WHERE rid=2
+) As foo;
+
+ rid | pixeltype | nodatavalue | isoutdb | path | outdbbandnum
+-----+-----------+---- --------+---------+------+--------------
+   2 | 8BUI      |           0 | f       |      |
+                               </programlisting>
+
                        </refsection>
 
                        <!-- Optionally add a "See Also" section -->
@@ -7088,6 +7131,191 @@ select st_bandisnodata(rast, 1) from dummy_rast where rid = 1; -- Expected true
                 linkend="RT_ST_BandIsNoData"/></para>
                        </refsection>
                </refentry>
+
+               <refentry 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>
+
+                               <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>Availability: 2.5.0</para>
+                       </refsection>
+
+                       <refsection>
+                               <title>Examples</title>
+                               <programlisting>
+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,
+       *
+FROM ST_BandMetadata(
+       (SELECT rast FROM foo),
+       ARRAY[1,3,2]::int[]
+)
+UNION ALL
+SELECT
+       2,
+       *
+FROM ST_BandMetadata(
+       (
+               SELECT
+                       <emphasis role="strong">ST_SetBandPath(
+                               rast,
+                               2,
+                               '/home/pele/devel/geo/postgis-git/raster/test/regress/loader/Projected2.tif',
+                               1
+                       )</emphasis> AS rast
+               FROM foo
+       ),
+       ARRAY[1,3,2]::int[]
+)
+ORDER BY 1, 2;
+
+ query | bandnum | pixeltype | nodatavalue | isoutdb |                                      path                                       | outdbbandnum 
+-------+---------+-----------+-------------+---------+---------------------------------------------------------------------------------+--------------
+     1 |       1 | 8BUI      |             | t       | /home/pele/devel/geo/postgis-git/raster/test/regress/loader/Projected.tif       |            1
+     1 |       2 | 8BUI      |             | t       | /home/pele/devel/geo/postgis-git/raster/test/regress/loader/Projected.tif       |            2
+     1 |       3 | 8BUI      |             | t       | /home/pele/devel/geo/postgis-git/raster/test/regress/loader/Projected.tif       |            3
+     2 |       1 | 8BUI      |             | t       | /home/pele/devel/geo/postgis-git/raster/test/regress/loader/Projected.tif       |            1
+<emphasis role="strong">     2 |       2 | 8BUI      |             | t       | /home/pele/devel/geo/postgis-git/raster/test/regress/loader/Projected2.tif      |            1</emphasis>
+     2 |       3 | 8BUI      |             | t       | /home/pele/devel/geo/postgis-git/raster/test/regress/loader/Projected.tif       |            3
+                               </programlisting>
+                       </refsection>
+
+                       <refsection>
+                               <title>See Also</title>
+                               <para>
+                                       <xref linkend="RT_ST_BandMetaData" />,
+                                       <xref linkend="RT_ST_SetBandIndex" />
+                               </para>
+                       </refsection>
+
+               </refentry>
+
+               <refentry 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>Availability: 2.5.0</para>
+                       </refsection>
+
+                       <refsection>
+                               <title>Examples</title>
+                               <programlisting>
+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,
+       *
+FROM ST_BandMetadata(
+       (SELECT rast FROM foo),
+       ARRAY[1,3,2]::int[]
+)
+UNION ALL
+SELECT
+       2,
+       *
+FROM ST_BandMetadata(
+       (
+               SELECT
+                       <emphasis role="strong">ST_SetBandIndex(
+                               rast,
+                               2,
+                               1
+                       )</emphasis> AS rast
+               FROM foo
+       ),
+       ARRAY[1,3,2]::int[]
+)
+ORDER BY 1, 2;
+
+ query | bandnum | pixeltype | nodatavalue | isoutdb |                                      path                                       | outdbbandnum 
+-------+---------+-----------+-------------+---------+---------------------------------------------------------------------------------+--------------
+     1 |       1 | 8BUI      |             | t       | /home/pele/devel/geo/postgis-git/raster/test/regress/loader/Projected.tif       |            1
+     1 |       2 | 8BUI      |             | t       | /home/pele/devel/geo/postgis-git/raster/test/regress/loader/Projected.tif       |            2
+     1 |       3 | 8BUI      |             | t       | /home/pele/devel/geo/postgis-git/raster/test/regress/loader/Projected.tif       |            3
+     2 |       1 | 8BUI      |             | t       | /home/pele/devel/geo/postgis-git/raster/test/regress/loader/Projected.tif       |            1
+<emphasis role="strong">     2 |       2 | 8BUI      |             | t       | /home/pele/devel/geo/postgis-git/raster/test/regress/loader/Projected.tif       |            1</emphasis>
+     2 |       3 | 8BUI      |             | t       | /home/pele/devel/geo/postgis-git/raster/test/regress/loader/Projected.tif       |            3
+                               </programlisting>
+                       </refsection>
+
+                       <refsection>
+                               <title>See Also</title>
+                               <para>
+                                       <xref linkend="RT_ST_BandMetaData" />,
+                                       <xref linkend="RT_ST_SetBandPath" />
+                               </para>
+                       </refsection>
+
+               </refentry>
+
        </sect1>
 
        <sect1 id="RasterBand_Stats">
index d1437db2f188575371782a9a7da3d6454a12bb78..99bb7c9f0fa4335f9aef2f699864d2767fc26f8c 100644 (file)
@@ -450,6 +450,35 @@ rt_band rt_band_new_offline(
        uint8_t bandNum, const char* path
 );
 
+/**
+ * Create an out-db rt_band from path
+ *
+ * @param width     : number of pixel columns
+ * @param height    : number of pixel rows
+ * @param hasnodata : indicates if the band has nodata value
+ * @param nodataval : the nodata value, will be appropriately
+ * @param bandNum   : 1-based band number in the external file
+ *                    to associate this band with.
+ * @param path      : NULL-terminated path string pointing to the file
+ *                    containing band data. The string will NOT be
+ *                    copied, ownership is left to caller which is
+ *                    responsible to keep it allocated for the whole
+ *                    lifetime of the returned rt_band.
+ * @param force     : if True, ignore all validation checks
+ *
+ * @return an rt_band, or 0 on failure
+ */
+rt_band
+rt_band_new_offline_from_path(
+       uint16_t width,
+       uint16_t height,
+       int hasnodata,
+       double nodataval,
+       uint8_t bandNum,
+       const char* path,
+       int force
+);
+
 /**
  * Create a new band duplicated from source band.  Memory is allocated
  * for band path (if band is offline) or band data (if band is online).
index 4dbf64bd9f0c335392780fd9d05cbbc296c5c7ac..8ec84f74685d730032b0676b995eb19f984738c6 100644 (file)
@@ -3,6 +3,7 @@
  * WKTRaster - Raster Types for PostGIS
  * http://trac.osgeo.org/postgis/wiki/WKTRaster
  *
+ * Copyright (C) 2018 Bborie Park <dustymugs@gmail.com>
  * Copyright (C) 2011-2013 Regents of the University of California
  *   <bkpark@ucdavis.edu>
  * Copyright (C) 2010-2011 Jorge Arevalo <jorge.arevalo@deimos-space.com>
@@ -172,6 +173,102 @@ rt_band_new_offline(
        return band;
 }
 
+/**
+ * Create an out-db rt_band from path
+ *
+ * @param width     : number of pixel columns
+ * @param height    : number of pixel rows
+ * @param hasnodata : indicates if the band has nodata value
+ * @param nodataval : the nodata value, will be appropriately
+ * @param bandNum   : 1-based band number in the external file
+ *                    to associate this band with.
+ * @param path      : NULL-terminated path string pointing to the file
+ *                    containing band data. The string will NOT be
+ *                    copied, ownership is left to caller which is
+ *                    responsible to keep it allocated for the whole
+ *                    lifetime of the returned rt_band.
+ * @param force     : if True, ignore all validation checks
+ *
+ * @return an rt_band, or 0 on failure
+ */
+rt_band
+rt_band_new_offline_from_path(
+       uint16_t width,
+       uint16_t height,
+       int hasnodata,
+       double nodataval,
+       uint8_t bandNum,
+       const char* path,
+       int force
+) {
+       GDALDatasetH hdsSrc = NULL;
+       int nband = 0;
+       GDALRasterBandH hbandSrc = NULL;
+
+       GDALDataType gdpixtype;
+       rt_pixtype pt = PT_END;
+
+       /* open outdb raster file */
+       rt_util_gdal_register_all(0);
+       hdsSrc = rt_util_gdal_open(path, GA_ReadOnly, 1);
+       if (hdsSrc == NULL && !force) {
+               rterror("rt_band_new_offline_from_path: Cannot open offline raster: %s", path);
+               return NULL;
+       }
+
+       nband = GDALGetRasterCount(hdsSrc);
+       if (!nband && !force) {
+               rterror("rt_band_new_offline_from_path: No bands found in offline raster: %s", path);
+               GDALClose(hdsSrc);
+               return NULL;
+       }
+       /* bandNum is 1-based */
+       else if (bandNum > nband && !force) {
+               rterror(
+                       "rt_band_new_offline_from_path: Specified band %d not found in offline raster: %s",
+                       bandNum,
+                       path
+               );
+               GDALClose(hdsSrc);
+               return NULL;
+       }
+
+       hbandSrc = GDALGetRasterBand(hdsSrc, bandNum);
+       if (hbandSrc == NULL && !force) {
+               rterror(
+                       "rt_band_new_offline_from_path: Cannot get band %d from GDAL dataset",
+                       bandNum
+               );
+               GDALClose(hdsSrc);
+               return NULL;
+       }
+
+       gdpixtype = GDALGetRasterDataType(hbandSrc);
+       pt = rt_util_gdal_datatype_to_pixtype(gdpixtype);
+       if (pt == PT_END && !force) {
+               rterror(
+                       "rt_band_new_offline_from_path: Unsupported pixel type %s of band %d from GDAL dataset",
+                       GDALGetDataTypeName(gdpixtype),
+                       bandNum
+               );
+               GDALClose(hdsSrc);
+               return NULL;
+       }
+
+       /* use out-db band's nodata value if nodataval not already set */
+       if (!hasnodata)
+               nodataval = GDALGetRasterNoDataValue(hbandSrc, &hasnodata);
+
+       GDALClose(hdsSrc);
+
+       return rt_band_new_offline(
+               width, height,
+               pt,
+               hasnodata, nodataval,
+               bandNum - 1, path
+       );
+}
+
 /**
  * Create a new band duplicated from source band.  Memory is allocated
  * for band path (if band is offline) or band data (if band is online).
@@ -226,11 +323,8 @@ rt_band_duplicate(rt_band band) {
 
 int
 rt_band_is_offline(rt_band band) {
-
-    assert(NULL != band);
-
-
-    return band->offline ? 1 : 0;
+  assert(NULL != band);
+       return band->offline ? 1 : 0;
 }
 
 /**
@@ -333,7 +427,6 @@ rt_band_load_offline_data(rt_band band) {
        int nband = 0;
        VRTDatasetH hdsDst = NULL;
        VRTSourcedRasterBandH hbandDst = NULL;
-       double gt[6] = {0.};
        double ogt[6] = {0};
        double offset[2] = {0};
 
@@ -362,9 +455,6 @@ rt_band_load_offline_data(rt_band band) {
 
        rt_util_gdal_register_all(0);
        hdsSrc = rt_util_gdal_open(band->data.offline.path, GA_ReadOnly, 1);
-       /*
-       hdsSrc = rt_util_gdal_open(band->data.offline.path, GA_ReadOnly, 0);
-       */
        if (hdsSrc == NULL) {
                rterror("rt_band_load_offline_data: Cannot open offline raster: %s", band->data.offline.path);
                return ES_ERROR;
@@ -384,11 +474,6 @@ rt_band_load_offline_data(rt_band band) {
                return ES_ERROR;
        }
 
-       /* get raster's geotransform */
-       rt_raster_get_geotransform_matrix(band->raster, gt);
-       RASTER_DEBUGF(3, "Raster geotransform (%f, %f, %f, %f, %f, %f)",
-               gt[0], gt[1], gt[2], gt[3], gt[4], gt[5]);
-
        /* get offline raster's geotransform */
        if (GDALGetGeoTransform(hdsSrc, ogt) != CE_None) {
                RASTER_DEBUG(4, "Using default geotransform matrix (0, 1, 0, 0, 0, -1)");
@@ -430,7 +515,7 @@ rt_band_load_offline_data(rt_band band) {
 
        /* create VRT dataset */
        hdsDst = VRTCreate(band->width, band->height);
-       GDALSetGeoTransform(hdsDst, gt);
+       GDALSetGeoTransform(hdsDst, ogt);
        /*
        GDALSetDescription(hdsDst, "/tmp/offline.vrt");
        */
index d1cb038eae46d08e249fa64f7e8a62e35dc2bed4..7b5f49538a0d582261323f7e10a0ddc53eab3789 100644 (file)
@@ -30,7 +30,7 @@
 #include <postgres.h>
 #include <fmgr.h>
 #include <funcapi.h>
-#include <utils/builtins.h>
+#include <utils/builtins.h> /* for text_to_cstring() */
 #include "utils/lsyscache.h" /* for get_typlenbyvalalign */
 #include "utils/array.h" /* for ArrayType */
 #include "catalog/pg_type.h" /* for INT2OID, INT4OID, FLOAT4OID, FLOAT8OID and TEXTOID */
@@ -56,6 +56,8 @@ Datum RASTER_bandmetadata(PG_FUNCTION_ARGS);
 /* Set all the properties of a raster band */
 Datum RASTER_setBandIsNoData(PG_FUNCTION_ARGS);
 Datum RASTER_setBandNoDataValue(PG_FUNCTION_ARGS);
+Datum RASTER_setBandPath(PG_FUNCTION_ARGS);
+Datum RASTER_setBandIndex(PG_FUNCTION_ARGS);
 
 /**
  * Return pixel type of the specified band of raster.
@@ -358,6 +360,7 @@ Datum RASTER_bandmetadata(PG_FUNCTION_ARGS)
                double nodataval;
                bool isoutdb;
                char *bandpath;
+               uint8_t extbandnum;
        };
        struct bandmetadata *bmd = NULL;
        struct bandmetadata *bmd2 = NULL;
@@ -386,7 +389,9 @@ Datum RASTER_bandmetadata(PG_FUNCTION_ARGS)
                uint32_t numBands;
                uint32_t idx = 1;
                uint32_t *bandNums = NULL;
-               const char *tmp = NULL;
+               const char *chartmp = NULL;
+               size_t charlen;
+               uint8_t extbandnum;
 
                POSTGIS_RT_DEBUG(3, "RASTER_bandmetadata: Starting");
 
@@ -496,9 +501,10 @@ Datum RASTER_bandmetadata(PG_FUNCTION_ARGS)
                        bmd[i].bandnum = bandNums[i];
 
                        /* pixeltype */
-                       tmp = rt_pixtype_name(rt_band_get_pixtype(band));
-                       bmd[i].pixeltype = palloc(sizeof(char) * (strlen(tmp) + 1));
-                       strncpy(bmd[i].pixeltype, tmp, strlen(tmp) + 1);
+                       chartmp = rt_pixtype_name(rt_band_get_pixtype(band));
+                       charlen = strlen(chartmp) + 1;
+                       bmd[i].pixeltype = palloc(sizeof(char) * charlen);
+                       strncpy(bmd[i].pixeltype, chartmp, charlen);
 
                        /* hasnodatavalue */
                        if (rt_band_get_hasnodata_flag(band))
@@ -512,11 +518,12 @@ Datum RASTER_bandmetadata(PG_FUNCTION_ARGS)
                        else
                                bmd[i].nodataval = 0;
 
-                       /* path */
-                       tmp = rt_band_get_ext_path(band);
-                       if (tmp) {
-                               bmd[i].bandpath = palloc(sizeof(char) * (strlen(tmp) + 1));
-                               strncpy(bmd[i].bandpath, tmp, strlen(tmp) + 1);
+                       /* out-db path */
+                       chartmp = rt_band_get_ext_path(band);
+                       if (chartmp) {
+                               charlen = strlen(chartmp) + 1;
+                               bmd[i].bandpath = palloc(sizeof(char) * charlen);
+                               strncpy(bmd[i].bandpath, chartmp, charlen);
                        }
                        else
                                bmd[i].bandpath = NULL;
@@ -524,6 +531,12 @@ Datum RASTER_bandmetadata(PG_FUNCTION_ARGS)
                        /* isoutdb */
                        bmd[i].isoutdb = bmd[i].bandpath ? TRUE : FALSE;
 
+                       /* out-db bandnum */
+                       if (rt_band_get_ext_band_num(band, &extbandnum) == ES_NONE)
+                               bmd[i].extbandnum = extbandnum + 1;
+                       else
+                               bmd[i].extbandnum = 0;
+
                        rt_band_destroy(band);
                }
 
@@ -564,7 +577,7 @@ Datum RASTER_bandmetadata(PG_FUNCTION_ARGS)
 
        /* do when there is more left to send */
        if (call_cntr < max_calls) {
-               int values_length = 5;
+               int values_length = 6;
                Datum values[values_length];
                bool nulls[values_length];
 
@@ -579,10 +592,14 @@ Datum RASTER_bandmetadata(PG_FUNCTION_ARGS)
                        nulls[2] = TRUE;
 
                values[3] = BoolGetDatum(bmd2[call_cntr].isoutdb);
-               if (bmd2[call_cntr].bandpath && strlen(bmd2[call_cntr].bandpath))
+               if (bmd2[call_cntr].bandpath && strlen(bmd2[call_cntr].bandpath)) {
                        values[4] = CStringGetTextDatum(bmd2[call_cntr].bandpath);
-               else
+                       values[5] = UInt32GetDatum(bmd2[call_cntr].extbandnum);
+               }
+               else {
                        nulls[4] = TRUE;
+                       nulls[5] = TRUE;
+               }
 
                /* build a tuple */
                tuple = heap_form_tuple(tupdesc, values, nulls);
@@ -679,6 +696,9 @@ Datum RASTER_setBandNoDataValue(PG_FUNCTION_ARGS)
        PG_RETURN_POINTER(pgrtn);
 }
 
+/**
+ * Set flag indicating that the entire band is NODATA
+ */
 PG_FUNCTION_INFO_V1(RASTER_setBandIsNoData);
 Datum RASTER_setBandIsNoData(PG_FUNCTION_ARGS)
 {
@@ -734,3 +754,94 @@ Datum RASTER_setBandIsNoData(PG_FUNCTION_ARGS)
        PG_RETURN_POINTER(pgrtn);
 }
 
+/**
+ * Set the path value of an out-db band
+ */
+PG_FUNCTION_INFO_V1(RASTER_setBandPath);
+Datum RASTER_setBandPath(PG_FUNCTION_ARGS)
+{
+       rt_pgraster *pgraster = NULL;
+       rt_pgraster *pgrtn = NULL;
+       rt_raster raster = NULL;
+       rt_band band = NULL;
+       int32_t bandindex = 1;
+       const char *outdbpathchar = NULL;
+       int32_t outdbindex = 1;
+       bool forceset = FALSE;
+       rt_band newband = NULL;
+
+       int hasnodata;
+       double nodataval = 0.;
+
+       if (PG_ARGISNULL(0))
+               PG_RETURN_NULL();
+       pgraster = (rt_pgraster *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
+
+       raster = rt_raster_deserialize(pgraster, FALSE);
+       if (!raster) {
+               PG_FREE_IF_COPY(pgraster, 0);
+               elog(ERROR, "RASTER_setBandPath: Cannot deserialize raster");
+               PG_RETURN_NULL();
+       }
+
+       /* Check index is not NULL or smaller than 1 */
+       if (!PG_ARGISNULL(1))
+               bandindex = PG_GETARG_INT32(1);
+
+       if (bandindex < 1)
+               elog(NOTICE, "Invalid band index (must use 1-based). Returning original raster");
+       else {
+               /* Fetch requested band */
+               band = rt_raster_get_band(raster, bandindex - 1);
+
+               if (!band)
+                       elog(NOTICE, "Cannot find raster band of index %d. Returning original raster", bandindex);
+               else if (!rt_band_is_offline(band)) {
+                       elog(NOTICE, "Band of index %d is not out-db. Returning original raster", bandindex);
+               }
+               else {
+                       /* outdbpath */
+                       if (!PG_ARGISNULL(2))
+                               outdbpathchar = text_to_cstring(PG_GETARG_TEXT_P(2));
+                       else
+                               outdbpathchar = rt_band_get_ext_path(band);
+
+                       /* outdbindex, is 1-based */
+                       if (!PG_ARGISNULL(3))
+                       outdbindex = PG_GETARG_INT32(3);
+
+                       /* force */
+                       if (!PG_ARGISNULL(4))
+                               forceset = PG_GETARG_BOOL(4);
+
+                       hasnodata = rt_band_get_hasnodata_flag(band);
+                       if (hasnodata)
+                               rt_band_get_nodata(band, &nodataval);
+
+                       newband = rt_band_new_offline_from_path(
+                               rt_raster_get_width(raster),
+                               rt_raster_get_height(raster),
+                               hasnodata,
+                               nodataval,
+                               outdbindex,
+                               outdbpathchar,
+                               forceset
+                       );
+
+                       if (rt_raster_replace_band(raster, newband, bandindex - 1) == NULL)
+                               elog(NOTICE, "Cannot change path of band. Returning original raster");
+                       else
+                               /* old band is in the variable band */
+                               rt_band_destroy(band);
+               }
+       }
+
+       /* Serialize raster again */
+       pgrtn = rt_raster_serialize(raster);
+       rt_raster_destroy(raster);
+       PG_FREE_IF_COPY(pgraster, 0);
+       if (!pgrtn) PG_RETURN_NULL();
+
+       SET_VARSIZE(pgrtn, pgrtn->size);
+       PG_RETURN_POINTER(pgrtn);
+}
index d0a5be0abaa3c6f38f870b78bd8b8246003860cf..f8bedc3c5a8e53e9a5957624b220ecc56fa9a3a5 100644 (file)
@@ -568,11 +568,7 @@ Datum RASTER_addBandOutDB(PG_FUNCTION_ARGS)
        int j = 0;
 
        GDALDatasetH hdsOut;
-       GDALRasterBandH hbandOut;
-       GDALDataType gdpixtype;
 
-       rt_pixtype pt = PT_END;
-       double gt[6] = {0.};
        double ogt[6] = {0.};
        rt_raster _rast = NULL;
        int aligned = 0;
@@ -586,7 +582,7 @@ Datum RASTER_addBandOutDB(PG_FUNCTION_ARGS)
                raster = rt_raster_deserialize(pgraster, FALSE);
                if (!raster) {
                        PG_FREE_IF_COPY(pgraster, 0);
-                       elog(ERROR, "RASTER_addBandOutDB: Could not deserialize destination raster");
+                       elog(ERROR, "RASTER_addBandOutDB: Cannot deserialize destination raster");
                        PG_RETURN_NULL();
                }
 
@@ -661,7 +657,7 @@ Datum RASTER_addBandOutDB(PG_FUNCTION_ARGS)
                                rt_raster_destroy(raster);
                                PG_FREE_IF_COPY(pgraster, 0);
                        }
-                       elog(ERROR, "RASTER_addBandOutDB: Could not allocate memory for band indexes");
+                       elog(ERROR, "RASTER_addBandOutDB: Cannot allocate memory for band indexes");
                        PG_RETURN_NULL();
                }
 
@@ -686,7 +682,7 @@ Datum RASTER_addBandOutDB(PG_FUNCTION_ARGS)
                                        rt_raster_destroy(raster);
                                        PG_FREE_IF_COPY(pgraster, 0);
                                }
-                               elog(ERROR, "RASTER_addBandOutDB: Could not reallocate memory for band indexes");
+                               elog(ERROR, "RASTER_addBandOutDB: Cannot reallocate memory for band indexes");
                                PG_RETURN_NULL();
                        }
 
@@ -731,7 +727,7 @@ Datum RASTER_addBandOutDB(PG_FUNCTION_ARGS)
                        rt_raster_destroy(raster);
                        PG_FREE_IF_COPY(pgraster, 0);
                }
-               elog(ERROR, "RASTER_addBandOutDB: Could not open out-db file with GDAL");
+               elog(ERROR, "RASTER_addBandOutDB: Cannot open out-db file with GDAL");
                PG_RETURN_NULL();
        }
 
@@ -749,11 +745,10 @@ Datum RASTER_addBandOutDB(PG_FUNCTION_ARGS)
        if (raster == NULL) {
                raster = rt_raster_new(GDALGetRasterXSize(hdsOut), GDALGetRasterYSize(hdsOut));
                if (rt_raster_is_empty(raster)) {
-                       elog(ERROR, "RASTER_addBandOutDB: Could not create new raster");
+                       elog(ERROR, "RASTER_addBandOutDB: Cannot create new raster");
                        PG_RETURN_NULL();
                }
                rt_raster_set_geotransform_matrix(raster, ogt);
-               rt_raster_get_geotransform_matrix(raster, gt);
 
                if (rt_util_gdal_sr_auth_info(hdsOut, &authname, &authcode) == ES_NONE) {
                        if (
@@ -767,7 +762,7 @@ Datum RASTER_addBandOutDB(PG_FUNCTION_ARGS)
                                elog(INFO, "Unknown SRS auth name and code from out-db file. Defaulting SRID of new raster to %d", SRID_UNKNOWN);
                }
                else
-                       elog(INFO, "Could not get SRS auth name and code from out-db file. Defaulting SRID of new raster to %d", SRID_UNKNOWN);
+                       elog(INFO, "Cannot get SRS auth name and code from out-db file. Defaulting SRID of new raster to %d", SRID_UNKNOWN);
        }
 
        /* some raster info */
@@ -787,101 +782,59 @@ Datum RASTER_addBandOutDB(PG_FUNCTION_ARGS)
                        rt_raster_destroy(raster);
                if (pgraster != NULL)
                        PG_FREE_IF_COPY(pgraster, 0);
-               elog(ERROR, "RASTER_addBandOutDB: Could not test alignment of out-db file");
+               elog(ERROR, "RASTER_addBandOutDB: Cannot test alignment of out-db file");
                return ES_ERROR;
        }
        else if (!aligned)
                elog(WARNING, "The in-db representation of the out-db raster is not aligned. Band data may be incorrect");
 
-       numbands = GDALGetRasterCount(hdsOut);
-
        /* build up srcnband */
        if (allbands) {
-               numsrcnband = numbands;
+               numsrcnband = GDALGetRasterCount(hdsOut);
+               GDALClose(hdsOut);
+
                srcnband = palloc(sizeof(int) * numsrcnband);
                if (srcnband == NULL) {
-                       GDALClose(hdsOut);
                        if (raster != NULL)
                                rt_raster_destroy(raster);
                        if (pgraster != NULL)
                                PG_FREE_IF_COPY(pgraster, 0);
-                       elog(ERROR, "RASTER_addBandOutDB: Could not allocate memory for band indexes");
+                       elog(ERROR, "RASTER_addBandOutDB: Cannot allocate memory for band indexes");
                        PG_RETURN_NULL();
                }
 
                for (i = 0, j = 1; i < numsrcnband; i++, j++)
                        srcnband[i] = j;
        }
+       else
+               GDALClose(hdsOut);
 
-       /* check band properties and add band */
+       /* add band */
        for (i = 0, j = dstnband - 1; i < numsrcnband; i++, j++) {
-               /* valid index? */
-               if (srcnband[i] < 1 || srcnband[i] > numbands) {
-                       elog(NOTICE, "Out-db file does not have a band at index %d. Returning original raster", srcnband[i]);
-                       GDALClose(hdsOut);
-                       if (raster != NULL)
-                               rt_raster_destroy(raster);
-                       if (pgraster != NULL)
-                               PG_RETURN_POINTER(pgraster);
-                       else
-                               PG_RETURN_NULL();
-               }
-
-               /* get outdb band */
-               hbandOut = NULL;
-               hbandOut = GDALGetRasterBand(hdsOut, srcnband[i]);
-               if (NULL == hbandOut) {
-                       GDALClose(hdsOut);
-                       if (raster != NULL)
-                               rt_raster_destroy(raster);
-                       if (pgraster != NULL)
-                               PG_FREE_IF_COPY(pgraster, 0);
-                       elog(ERROR, "RASTER_addBandOutDB: Could not get band %d from GDAL dataset", srcnband[i]);
-                       PG_RETURN_NULL();
-               }
 
-               /* supported pixel type */
-               gdpixtype = GDALGetRasterDataType(hbandOut);
-               pt = rt_util_gdal_datatype_to_pixtype(gdpixtype);
-               if (pt == PT_END) {
-                       elog(NOTICE, "Pixel type %s of band %d from GDAL dataset is not supported. Returning original raster", GDALGetDataTypeName(gdpixtype), srcnband[i]);
-                       GDALClose(hdsOut);
-                       if (raster != NULL)
-                               rt_raster_destroy(raster);
-                       if (pgraster != NULL)
-                               PG_RETURN_POINTER(pgraster);
-                       else
-                               PG_RETURN_NULL();
-               }
-
-               /* use out-db band's nodata value if nodataval not already set */
-               if (!hasnodata)
-                       nodataval = GDALGetRasterNoDataValue(hbandOut, &hasnodata);
-
-               /* add band */
-               band = rt_band_new_offline(
+               /* create band with path */
+               band = rt_band_new_offline_from_path(
                        width, height,
-                       pt,
                        hasnodata, nodataval,
-                       srcnband[i] - 1, outdbfile
+                       srcnband[i], outdbfile,
+                       FALSE
                );
                if (band == NULL) {
-                       GDALClose(hdsOut);
                        if (raster != NULL)
                                rt_raster_destroy(raster);
                        if (pgraster != NULL)
                                PG_FREE_IF_COPY(pgraster, 0);
-                       elog(ERROR, "RASTER_addBandOutDB: Could not create new out-db band");
+                       elog(ERROR, "RASTER_addBandOutDB: Cannot create new out-db band");
                        PG_RETURN_NULL();
                }
 
+               /* add band */
                if (rt_raster_add_band(raster, band, j) < 0) {
-                       GDALClose(hdsOut);
                        if (raster != NULL)
                                rt_raster_destroy(raster);
                        if (pgraster != NULL)
                                PG_FREE_IF_COPY(pgraster, 0);
-                       elog(ERROR, "RASTER_addBandOutDB: Could not add new out-db band to raster");
+                       elog(ERROR, "RASTER_addBandOutDB: Cannot add new out-db band to raster");
                        PG_RETURN_NULL();
                }
        }
index b80ebfcd22789bcef622d4e819a5c5bb20369dcf..68f34c25acf88db2346b3d745284c24553dfd79e 100644 (file)
@@ -4982,7 +4982,8 @@ CREATE OR REPLACE FUNCTION ST_BandMetaData(
        OUT pixeltype text,
        OUT nodatavalue double precision,
        OUT isoutdb boolean,
-       OUT path text
+       OUT path text,
+       OUT outdbbandnum integer
 )
        AS 'MODULE_PATHNAME','RASTER_bandmetadata'
        LANGUAGE 'c' IMMUTABLE STRICT _PARALLEL;
@@ -4993,9 +4994,10 @@ CREATE OR REPLACE FUNCTION ST_BandMetaData(
        OUT pixeltype text,
        OUT nodatavalue double precision,
        OUT isoutdb boolean,
-       OUT path text
+       OUT path text,
+       OUT outdbbandnum integer
 )
-       AS $$ SELECT pixeltype, nodatavalue, isoutdb, path FROM @extschema@.ST_BandMetaData($1, ARRAY[$2]::int[]) LIMIT 1 $$
+       AS $$ SELECT pixeltype, nodatavalue, isoutdb, path, outdbbandnum FROM @extschema@.ST_BandMetaData($1, ARRAY[$2]::int[]) LIMIT 1 $$
        LANGUAGE 'sql' IMMUTABLE STRICT _PARALLEL;
 
 -----------------------------------------------------------------------
@@ -5317,6 +5319,17 @@ CREATE OR REPLACE FUNCTION st_setbandisnodata(rast raster, band integer DEFAULT
     AS 'MODULE_PATHNAME', 'RASTER_setBandIsNoData'
     LANGUAGE 'c' IMMUTABLE STRICT _PARALLEL;
 
+-- This function can not be STRICT, because outdbpath can be NULL
+CREATE OR REPLACE FUNCTION st_setbandpath(rast raster, band integer, outdbpath text, outdbindex integer, force boolean DEFAULT FALSE)
+    RETURNS raster
+    AS 'MODULE_PATHNAME', 'RASTER_setBandPath'
+    LANGUAGE 'c' IMMUTABLE _PARALLEL;
+
+CREATE OR REPLACE FUNCTION st_setbandindex(rast raster, band integer, outdbindex integer, force boolean DEFAULT FALSE)
+    RETURNS raster
+               AS $$ SELECT @extschema@.ST_SetBandPath($1, $2, NULL, $3, $4) $$
+    LANGUAGE 'sql' IMMUTABLE STRICT _PARALLEL;
+
 -----------------------------------------------------------------------
 -- Raster Pixel Editors
 -----------------------------------------------------------------------
index dbb797f82ce27ba481652e893229dda5ee6c612d..0d6f3ba006191a43fb639564fb06a9db1634a58b 100644 (file)
@@ -599,3 +599,7 @@ BEGIN
        END IF;
 END;
 $$;
+
+-- 2.5.0 signature changed
+DROP FUNCTION IF EXISTS st_bandmetadata(raster, int[]);
+DROP FUNCTION IF EXISTS st_bandmetadata(raster, int);
index 18750f5ae0fbed46546ef8361235c43a62784ac9..7ebc269c64545a880dc492e5481c53f5f80194f0 100644 (file)
@@ -2,6 +2,7 @@
  * PostGIS Raster - Raster Types for PostGIS
  * http://trac.osgeo.org/postgis/wiki/WKTRaster
  *
+ * Copyright (C) 2018 Bborie Park <dustymugs@gmail.com>
  * Copyright (C) 2012 Regents of the University of California
  *   <bkpark@ucdavis.edu>
  *
@@ -1252,6 +1253,42 @@ static void test_band_get_pixel_line() {
        cu_free_raster(rast);
 }
 
+static void test_band_new_offline_from_path() {
+       rt_band band = NULL;
+       int width = 10;
+       int height = 10;
+       char *path = "../regress/loader/testraster.tif";
+       uint8_t extband = 0;
+
+       /* offline band */
+       band = rt_band_new_offline_from_path(
+               width, height,
+               0, 0,
+               2, path,
+               FALSE
+       );
+       CU_ASSERT(band != NULL);
+
+       /* isoffline */
+       CU_ASSERT(rt_band_is_offline(band));
+
+       /* ext path */
+       CU_ASSERT_STRING_EQUAL(rt_band_get_ext_path(band), path);
+
+       /* ext band number */
+       CU_ASSERT_EQUAL(rt_band_get_ext_band_num(band, &extband), ES_NONE);
+       CU_ASSERT_EQUAL(extband, 1);
+
+       /* test rt_band_check_is_nodata */
+       CU_ASSERT_EQUAL(rt_band_check_is_nodata(band), FALSE);
+
+       /* dimensions */
+       CU_ASSERT_EQUAL(rt_band_get_width(band), width);
+       CU_ASSERT_EQUAL(rt_band_get_height(band), height);
+
+       rt_band_destroy(band);
+}
+
 /* register tests */
 void band_basics_suite_setup(void);
 void band_basics_suite_setup(void)
@@ -1270,5 +1307,6 @@ void band_basics_suite_setup(void)
        PG_ADD_TEST(suite, test_band_pixtype_32BF);
        PG_ADD_TEST(suite, test_band_pixtype_64BF);
        PG_ADD_TEST(suite, test_band_get_pixel_line);
+       PG_ADD_TEST(suite, test_band_new_offline_from_path);
 }
 
index d560c1c36c905aa3bb9c25c1fe2834161191fd1d..71e4b02da5b500157943cc46878c22269057d24d 100644 (file)
@@ -96,7 +96,8 @@ TEST_BANDPROPS = \
        rt_neighborhood \
        rt_nearestvalue \
        rt_pixelofvalue \
-       rt_polygon
+       rt_polygon \
+       rt_setbandpath
 
 TEST_UTILITY = \
        rt_utility \
index 347fdf91cab802f227bd59559106912145d65d5e..3f7b559d43d6525dcc452b9a5f768e8174254193 100644 (file)
@@ -90,23 +90,23 @@ NOTICE:  rt_raster_copy_band: Second raster has no band
 NOTICE:  RASTER_copyBand: Could not add band to raster. Returning original raster.
 1234.5678
 1234.567|255
-1|4BUI|0|f|
-2|8BUI|0|f|
-3|16BUI|0|f|
-4|32BUI|0|f|
-5|64BF|0|f|
-1|2BUI|0|f|
-2|4BUI|0|f|
-3|8BUI|0|f|
-4|16BUI|0|f|
-5|32BUI|0|f|
-6|64BF|0|f|
-1|4BUI|0|f|
-2|8BUI|0|f|
-3|16BUI|0|f|
-4|32BUI|0|f|
-5|64BF|0|f|
-6|2BUI|0|f|
+1|4BUI|0|f||
+2|8BUI|0|f||
+3|16BUI|0|f||
+4|32BUI|0|f||
+5|64BF|0|f||
+1|2BUI|0|f||
+2|4BUI|0|f||
+3|8BUI|0|f||
+4|16BUI|0|f||
+5|32BUI|0|f||
+6|64BF|0|f||
+1|4BUI|0|f||
+2|8BUI|0|f||
+3|16BUI|0|f||
+4|32BUI|0|f||
+5|64BF|0|f||
+6|2BUI|0|f||
 90
 1|1|t|t
 1|2|t|t
index 62ad706fa4adb173f4da75fcdced264d4d7b25be..ed9b8525a5f6876a8d4233d93b5d8fd75d8c48aa 100644 (file)
@@ -37,7 +37,8 @@ SELECT
        pixeltype,
        round(nodatavalue::numeric, 3),
        isoutdb,
-       path
+       path,
+       outdbbandnum
 FROM ST_BandMetaData(
        ST_SetBandNoDataValue(make_test_raster(10, 10, 0, 0, 0, 0), NULL)
 );
@@ -46,7 +47,8 @@ SELECT
        pixeltype,
        round(nodatavalue::numeric, 3),
        isoutdb,
-       path
+       path,
+       outdbbandnum
 FROM ST_BandMetaData(
        make_test_raster(10, 10, 0, 0, 0, 0)
 );
@@ -55,7 +57,8 @@ SELECT
        pixeltype,
        round(nodatavalue::numeric, 3),
        isoutdb,
-       path
+       path,
+       outdbbandnum
 FROM ST_BandMetaData(
        make_test_raster(10, 10, 0, 0, 0, 0, 2),
        2
@@ -65,7 +68,8 @@ SELECT
        pixeltype,
        round(nodatavalue::numeric, 3),
        isoutdb,
-       path
+       path,
+       outdbbandnum
 FROM ST_BandMetaData(
        make_test_raster(10, 10, 0, 0, 0, 0, 3, TRUE),
        3
@@ -75,7 +79,8 @@ SELECT
        pixeltype,
        round(nodatavalue::numeric, 3),
        isoutdb,
-       path
+       path,
+       outdbbandnum
 FROM ST_BandMetaData(
        make_test_raster(10, 10, 0, 0, 0, 0, 5, TRUE),
        4
@@ -85,7 +90,8 @@ SELECT
        pixeltype,
        round(nodatavalue::numeric, 3),
        isoutdb,
-       path
+       path,
+       outdbbandnum
 FROM ST_BandMetaData(
        make_test_raster(10, 10, 0, 0, 0, 0, 5, TRUE),
        6
@@ -96,7 +102,8 @@ SELECT
        pixeltype,
        round(nodatavalue::numeric, 3),
        isoutdb,
-       path
+       path,
+       outdbbandnum
 FROM ST_BandMetaData(
        make_test_raster(10, 10, 0, 0, 0, 0, 5, TRUE),
        ARRAY[1,2,5]
@@ -107,7 +114,8 @@ SELECT
        pixeltype,
        round(nodatavalue::numeric, 3),
        isoutdb,
-       path
+       path,
+       outdbbandnum
 FROM ST_BandMetaData(
        make_test_raster(10, 10, 0, 0, 0, 0, 5, TRUE),
        ARRAY[]::int[]
index b4ae11982512ed6440d4ea0a7e7f0af7270d4027..8458aacf069b18e55fefeb5af73e4146299eddb4 100644 (file)
@@ -1,15 +1,15 @@
-8BUI||f|
-8BUI|1.000|f|
-8BUI|2.000|f|
-8BUI|3.000|f|
-8BUI|4.000|f|
+8BUI||f||
+8BUI|1.000|f||
+8BUI|2.000|f||
+8BUI|3.000|f||
+8BUI|4.000|f||
 NOTICE:  Invalid band index: 6. Indices must be 1-based. Returning NULL
-|||
-1|1.000|f|
-2|2.000|f|
-5|5.000|f|
-1|1.000|f|
-2|2.000|f|
-3|3.000|f|
-4|4.000|f|
-5|5.000|f|
+||||
+1|1.000|f||
+2|2.000|f||
+5|5.000|f||
+1|1.000|f||
+2|2.000|f||
+3|3.000|f||
+4|4.000|f||
+5|5.000|f||
index b7c103a112716972afde3a99fa323f6af666ac90..655b9205724da6a860ff40ed3cb7b2a319b06753 100644 (file)
@@ -84,8 +84,8 @@ NOTICE:  userargs = <NULL>
 NOTICE:  value = {{{200,200,NULL},{200,200,NULL},{NULL,NULL,NULL}}}
 NOTICE:  pos = [0:1][1:2]={{2,2},{2,2}}
 NOTICE:  userargs = <NULL>
-3|(0,0,0,0,1,-1,0,0,0,0)|(,,,)|
-4|(1,-1,2,2,1,-1,0,0,0,1)|(8BUI,0,f,)|255
+3|(0,0,0,0,1,-1,0,0,0,0)|(,,,,)|
+4|(1,-1,2,2,1,-1,0,0,0,1)|(8BUI,0,f,,)|255
 NOTICE:  value = {{{NULL,NULL,NULL},{NULL,1,1},{NULL,1,1}}}
 NOTICE:  pos = [0:1][1:2]={{1,1},{1,1}}
 NOTICE:  userargs = <NULL>
@@ -98,7 +98,7 @@ NOTICE:  userargs = <NULL>
 NOTICE:  value = {{{1,1,2},{1,1,2},{10,10,20}}}
 NOTICE:  pos = [0:1][1:2]={{2,2},{2,2}}
 NOTICE:  userargs = <NULL>
-NOTICE:  record = (10,"(0,0,2,2,1,-1,0,0,0,1)","(32BUI,0,f,)",255)
+NOTICE:  record = (10,"(0,0,2,2,1,-1,0,0,0,1)","(32BUI,0,f,,)",255)
 NOTICE:  value = {{{1,2,2},{10,20,20},{10,20,20}}}
 NOTICE:  pos = [0:1][1:2]={{1,1},{3,3}}
 NOTICE:  userargs = <NULL>
@@ -111,7 +111,7 @@ NOTICE:  userargs = <NULL>
 NOTICE:  value = {{{20,20,30},{20,20,30},{200,200,300}}}
 NOTICE:  pos = [0:1][1:2]={{2,2},{4,4}}
 NOTICE:  userargs = <NULL>
-NOTICE:  record = (14,"(2,-2,2,2,1,-1,0,0,0,1)","(32BUI,0,f,)",255)
+NOTICE:  record = (14,"(2,-2,2,2,1,-1,0,0,0,1)","(32BUI,0,f,,)",255)
 NOTICE:  value = {{{10,20,20},{100,200,200},{100,200,200}}}
 NOTICE:  pos = [0:1][1:2]={{1,1},{3,3}}
 NOTICE:  userargs = {1000}
@@ -124,17 +124,17 @@ NOTICE:  userargs = {1000}
 NOTICE:  value = {{{200,200,300},{200,200,300},{NULL,NULL,NULL}}}
 NOTICE:  pos = [0:1][1:2]={{2,2},{4,4}}
 NOTICE:  userargs = {1000}
-NOTICE:  record = (17,"(2,-4,2,2,1,-1,0,0,0,1)","(32BUI,0,f,)",1000)
+NOTICE:  record = (17,"(2,-4,2,2,1,-1,0,0,0,1)","(32BUI,0,f,,)",1000)
 NOTICE:  value = {{{1}},{{2}}}
 NOTICE:  pos = [0:2][1:2]={{1,1},{2,2},{1,1}}
 NOTICE:  userargs = <NULL>
-20|21|(1,-1,1,1,1,-1,0,0,0,1)|(16BUI,0,f,)
+20|21|(1,-1,1,1,1,-1,0,0,0,1)|(16BUI,0,f,,)
 NOTICE:  Raster provided has no bands
-20|22|(0,0,0,0,0,0,0,0,0,0)|(,,,)
+20|22|(0,0,0,0,0,0,0,0,0,0)|(,,,,)
 NOTICE:  value = {{{2}},{{3}}}
 NOTICE:  pos = [0:2][1:2]={{1,1},{1,2},{2,1}}
 NOTICE:  userargs = <NULL>
-21|22|(1,-2,1,1,1,-1,0,0,0,1)|(16BUI,0,f,)
+21|22|(1,-2,1,1,1,-1,0,0,0,1)|(16BUI,0,f,,)
 NOTICE:  value = {{{1}},{{NULL}}}
 NOTICE:  pos = [0:2][1:2]={{1,1},{1,1},{0,0}}
 NOTICE:  userargs = <NULL>
@@ -162,7 +162,7 @@ NOTICE:  userargs = <NULL>
 NOTICE:  value = {{{NULL}},{{2}}}
 NOTICE:  pos = [0:2][1:2]={{3,3},{3,3},{2,2}}
 NOTICE:  userargs = <NULL>
-20|21|(0,0,3,3,1,-1,0,0,0,1)|(16BUI,0,f,)
+20|21|(0,0,3,3,1,-1,0,0,0,1)|(16BUI,0,f,,)
 NOTICE:  value = {{{1}},{{NULL}}}
 NOTICE:  pos = [0:2][1:2]={{1,1},{1,1},{1,-1}}
 NOTICE:  userargs = <NULL>
@@ -187,7 +187,7 @@ NOTICE:  userargs = <NULL>
 NOTICE:  value = {{{NULL}},{{3}}}
 NOTICE:  pos = [0:2][1:2]={{2,4},{2,4},{2,2}}
 NOTICE:  userargs = <NULL>
-20|22|(0,0,2,4,1,-1,0,0,0,1)|(16BUI,0,f,)
+20|22|(0,0,2,4,1,-1,0,0,0,1)|(16BUI,0,f,,)
 NOTICE:  value = {{{1}},{{NULL}},{{NULL}}}
 NOTICE:  pos = [0:3][1:2]={{1,1},{1,1},{0,0},{1,-1}}
 NOTICE:  userargs = <NULL>
@@ -224,7 +224,7 @@ NOTICE:  userargs = <NULL>
 NOTICE:  value = {{{NULL}},{{NULL}},{{NULL}}}
 NOTICE:  pos = [0:3][1:2]={{3,4},{3,4},{2,3},{3,2}}
 NOTICE:  userargs = <NULL>
-20|21|22|(0,0,3,4,1,-1,0,0,0,1)|(16BUI,0,f,)
+20|21|22|(0,0,3,4,1,-1,0,0,0,1)|(16BUI,0,f,,)
 NOTICE:  value = {{{1}},{{NULL}},{{NULL}}}
 NOTICE:  pos = [0:3][1:2]={{1,1},{1,1},{0,0},{1,-1}}
 NOTICE:  userargs = <NULL>
@@ -237,7 +237,7 @@ NOTICE:  userargs = <NULL>
 NOTICE:  value = {{{1}},{{2}},{{NULL}}}
 NOTICE:  pos = [0:3][1:2]={{2,2},{2,2},{1,1},{2,0}}
 NOTICE:  userargs = <NULL>
-20|21|22|(0,0,2,2,1,-1,0,0,0,1)|(16BUI,0,f,)
+20|21|22|(0,0,2,2,1,-1,0,0,0,1)|(16BUI,0,f,,)
 NOTICE:  value = {{{1}},{{2}},{{NULL}}}
 NOTICE:  pos = [0:3][1:2]={{1,1},{2,2},{1,1},{2,0}}
 NOTICE:  userargs = <NULL>
@@ -250,7 +250,7 @@ NOTICE:  userargs = <NULL>
 NOTICE:  value = {{{NULL}},{{2}},{{NULL}}}
 NOTICE:  pos = [0:3][1:2]={{2,2},{3,3},{2,2},{3,1}}
 NOTICE:  userargs = <NULL>
-20|21|22|(1,-1,2,2,1,-1,0,0,0,1)|(16BUI,0,f,)
+20|21|22|(1,-1,2,2,1,-1,0,0,0,1)|(16BUI,0,f,,)
 NOTICE:  value = {{{NULL}},{{NULL}},{{3}}}
 NOTICE:  pos = [0:3][1:2]={{1,1},{1,3},{0,2},{1,1}}
 NOTICE:  userargs = <NULL>
@@ -263,9 +263,9 @@ NOTICE:  userargs = <NULL>
 NOTICE:  value = {{{NULL}},{{NULL}},{{3}}}
 NOTICE:  pos = [0:3][1:2]={{2,2},{2,4},{1,3},{2,2}}
 NOTICE:  userargs = <NULL>
-20|21|22|(0,-2,2,2,1,-1,0,0,0,1)|(16BUI,0,f,)
+20|21|22|(0,-2,2,2,1,-1,0,0,0,1)|(16BUI,0,f,,)
 NOTICE:  Raster provided has no bands
-20|21|22|(0,0,0,0,0,0,0,0,0,0)|(,,,)
+20|21|22|(0,0,0,0,0,0,0,0,0,0)|(,,,,)
 NOTICE:  value = {{{1}},{{10}},{{100}}}
 NOTICE:  pos = [0:3][1:2]={{1,1},{1,1},{1,1},{1,1}}
 NOTICE:  userargs = <NULL>
@@ -278,7 +278,7 @@ NOTICE:  userargs = <NULL>
 NOTICE:  value = {{{1}},{{10}},{{100}}}
 NOTICE:  pos = [0:3][1:2]={{2,2},{2,2},{2,2},{2,2}}
 NOTICE:  userargs = <NULL>
-30|(0,0,2,2,1,-1,0,0,0,1)|(16BUI,0,f,)
+30|(0,0,2,2,1,-1,0,0,0,1)|(16BUI,0,f,,)
 NOTICE:  value = {{{100}},{{1}},{{100}}}
 NOTICE:  pos = [0:3][1:2]={{1,1},{1,1},{1,1},{1,1}}
 NOTICE:  userargs = <NULL>
@@ -291,7 +291,7 @@ NOTICE:  userargs = <NULL>
 NOTICE:  value = {{{100}},{{1}},{{100}}}
 NOTICE:  pos = [0:3][1:2]={{2,2},{2,2},{2,2},{2,2}}
 NOTICE:  userargs = <NULL>
-30|(0,0,2,2,1,-1,0,0,0,1)|(32BUI,0,f,)
+30|(0,0,2,2,1,-1,0,0,0,1)|(32BUI,0,f,,)
 NOTICE:  value = {{{20}},{{20}}}
 NOTICE:  pos = [0:2][1:2]={{1,1},{1,1},{1,1}}
 NOTICE:  userargs = <NULL>
@@ -304,14 +304,14 @@ NOTICE:  userargs = <NULL>
 NOTICE:  value = {{{20}},{{20}}}
 NOTICE:  pos = [0:2][1:2]={{2,2},{2,2},{2,2}}
 NOTICE:  userargs = <NULL>
-31|(0,1,2,2,1,-1,0,0,0,1)|(16BUI,0,f,)
+31|(0,1,2,2,1,-1,0,0,0,1)|(16BUI,0,f,,)
 NOTICE:  value = {{{10}},{{2}},{{20}}}
 NOTICE:  pos = [0:3][1:2]={{1,1},{1,1},{1,2},{1,2}}
 NOTICE:  userargs = <NULL>
 NOTICE:  value = {{{10}},{{2}},{{20}}}
 NOTICE:  pos = [0:3][1:2]={{2,1},{2,1},{2,2},{2,2}}
 NOTICE:  userargs = <NULL>
-30|31|(0,0,2,1,1,-1,0,0,0,1)|(16BUI,0,f,)
+30|31|(0,0,2,1,1,-1,0,0,0,1)|(16BUI,0,f,,)
 NOTICE:  value = {{{100}},{{1}},{{100}}}
 NOTICE:  pos = [0:3][1:2]={{1,1},{1,1},{1,1},{1,1}}
 NOTICE:  userargs = <NULL>
@@ -324,7 +324,7 @@ NOTICE:  userargs = <NULL>
 NOTICE:  value = {{{100}},{{1}},{{100}}}
 NOTICE:  pos = [0:3][1:2]={{2,2},{2,2},{2,2},{2,2}}
 NOTICE:  userargs = <NULL>
-30|(0,0,2,2,1,-1,0,0,0,1)|(32BUI,0,f,)
+30|(0,0,2,2,1,-1,0,0,0,1)|(32BUI,0,f,,)
 NOTICE:  value = {{{10}}}
 NOTICE:  pos = [0:1][1:2]={{1,1},{1,1}}
 NOTICE:  userargs = <NULL>
@@ -337,7 +337,7 @@ NOTICE:  userargs = <NULL>
 NOTICE:  value = {{{10}}}
 NOTICE:  pos = [0:1][1:2]={{2,2},{2,2}}
 NOTICE:  userargs = <NULL>
-30|(0,0,2,2,1,-1,0,0,0,1)|(8BUI,0,f,)
+30|(0,0,2,2,1,-1,0,0,0,1)|(8BUI,0,f,,)
 NOTICE:  value = {{{1}}}
 NOTICE:  pos = [0:1][1:2]={{1,1},{1,1}}
 NOTICE:  userargs = {}
diff --git a/raster/test/regress/rt_setbandpath.sql b/raster/test/regress/rt_setbandpath.sql
new file mode 100644 (file)
index 0000000..3f94774
--- /dev/null
@@ -0,0 +1,29 @@
+SET postgis.gdal_enabled_drivers = 'GTiff';
+SET postgis.enable_outdb_rasters = true;
+
+(
+SELECT
+       1,
+       bandnum,
+       isoutdb,
+       CASE
+               WHEN isoutdb IS TRUE
+                       THEN strpos(path, 'testraster.tif') > 0
+               ELSE NULL
+       END,
+       outdbbandnum
+FROM ST_BandMetadata((SELECT rast FROM raster_outdb_template WHERE rid = 1), ARRAY[]::int[])
+UNION ALL
+SELECT
+       2,
+       bandnum,
+       isoutdb,
+       CASE
+               WHEN isoutdb IS TRUE
+                       THEN strpos(path, 'testraster.tif') > 0
+               ELSE NULL
+       END,
+       outdbbandnum
+FROM ST_BandMetadata((SELECT ST_SetBandIndex(rast, 1, 2) FROM raster_outdb_template WHERE rid = 1), ARRAY[]::int[])
+)
+ORDER BY 1, 2;
diff --git a/raster/test/regress/rt_setbandpath_expected b/raster/test/regress/rt_setbandpath_expected
new file mode 100644 (file)
index 0000000..74fd688
--- /dev/null
@@ -0,0 +1,6 @@
+1|1|t|t|1
+1|2|t|t|2
+1|3|t|t|3
+2|1|t|t|2
+2|2|t|t|2
+2|3|t|t|3