]> granicus.if.org Git - postgis/commitdiff
Add ST_MapAlgebraFct for 2 rasters. This is the sibling of 2-raster ST_MapAlgebraExp...
authorBborie Park <bkpark at ucdavis.edu>
Fri, 11 Nov 2011 15:41:32 +0000 (15:41 +0000)
committerBborie Park <bkpark at ucdavis.edu>
Fri, 11 Nov 2011 15:41:32 +0000 (15:41 +0000)
Associated ticket is #1281.

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

raster/rt_pg/rt_pg.c
raster/rt_pg/rtpostgis.sql.in.c
raster/test/regress/Makefile.in
raster/test/regress/rt_mapalgebraexpr_2raster.sql
raster/test/regress/rt_mapalgebraexpr_2raster_expected
raster/test/regress/rt_mapalgebrafct_2raster.sql [new file with mode: 0644]
raster/test/regress/rt_mapalgebrafct_2raster_expected [new file with mode: 0644]

index 662e3b874a42c39ce6945bb769e1c1fdade772f3..51f524a3d2cc0861e2c5b6dca3292b8e734d20d1 100644 (file)
@@ -244,7 +244,7 @@ Datum RASTER_intersects(PG_FUNCTION_ARGS);
 Datum RASTER_sameAlignment(PG_FUNCTION_ARGS);
 
 /* two-raster MapAlgebra */
-Datum RASTER_mapAlgebra2Expr(PG_FUNCTION_ARGS);
+Datum RASTER_mapAlgebra2(PG_FUNCTION_ARGS);
 /*
 Datum RASTER_mapAlgebra2Fct(PG_FUNCTION_ARGS);
 */
@@ -7882,10 +7882,10 @@ Datum RASTER_sameAlignment(PG_FUNCTION_ARGS)
 }
 
 /**
- * Two raster MapAlgebra
+ * Two raster MapAlgebra using expressions
  */
-PG_FUNCTION_INFO_V1(RASTER_mapAlgebra2Expr);
-Datum RASTER_mapAlgebra2Expr(PG_FUNCTION_ARGS)
+PG_FUNCTION_INFO_V1(RASTER_mapAlgebra2);
+Datum RASTER_mapAlgebra2(PG_FUNCTION_ARGS)
 {
        const int set_count = 2;
        rt_pgraster *pgrast;
@@ -7894,17 +7894,28 @@ Datum RASTER_mapAlgebra2Expr(PG_FUNCTION_ARGS)
        uint32_t bandindex[2] = {0};
        rt_raster _rast[2] = {NULL};
        rt_band _band[2] = {NULL};
+       int _hasnodata[2] = {0};
+       double _nodataval[2] = {0};
+       double _offset[4] = {0.};
+       double _rastoffset[2][4] = {{0.}};
+       int _haspixel[2] = {0};
+       double _pixel[2] = {0};
+       uint16_t _dim[2][2] = {{0}};
 
        char *pixtypename = NULL;
        rt_pixtype pixtype = PT_END;
        char *extenttypename = NULL;
        rt_extenttype extenttype = ET_INTERSECTION;
+
+       rt_raster raster = NULL;
+       rt_band band = NULL;
+       uint16_t dim[2] = {0};
+       int haspixel = 0;
+       double pixel = 0.;
        double nodataval = 0;
-       int _hasnodata[2] = {0};
-       double _nodataval[2] = {0};
+       double gt[6] = {0.};
 
-       int hasnodatanodataval = 0;
-       double nodatanodataval = 0;
+       Oid calltype = InvalidOid;
 
        int spicount = 3;
        uint16_t exprpos[3] = {4, 7, 8};
@@ -7924,18 +7935,13 @@ Datum RASTER_mapAlgebra2Expr(PG_FUNCTION_ARGS)
        bool isnull = FALSE;
        int hasargval[3] = {0};
        double argval[3] = {0.};
+       int hasnodatanodataval = 0;
+       double nodatanodataval = 0;
 
-       double _offset[4] = {0.};
-       double _rastoffset[2][4] = {{0.}};
-       int _haspixel[2] = {0};
-       double _pixel[2] = {0};
-       uint16_t _dim[2][2] = {{0}};
-
-       rt_raster raster = NULL;
-       rt_band band = NULL;
-       uint16_t dim[2] = {0};
-       int haspixel = 0;
-       double pixel = 0.;
+       Oid ufcnoid = InvalidOid;
+       FmgrInfo uflinfo;
+       FunctionCallInfoData ufcinfo;
+       int ufcnullcount = 0;
 
        uint32_t i = 0;
        uint32_t j = 0;
@@ -7945,11 +7951,10 @@ Datum RASTER_mapAlgebra2Expr(PG_FUNCTION_ARGS)
        int _x = 0;
        int _y = 0;
        int err;
-       double gt[6] = {0.};
        int aligned = 0;
        int len = 0;
 
-       POSTGIS_RT_DEBUG(3, "Starting RASTER_mapAlgebra2Expr");
+       POSTGIS_RT_DEBUG(3, "Starting RASTER_mapAlgebra2");
 
        for (i = 0, j = 0; i < set_count; i++) {
                if (!PG_ARGISNULL(j)) {
@@ -7959,7 +7964,7 @@ Datum RASTER_mapAlgebra2Expr(PG_FUNCTION_ARGS)
                        /* raster */
                        rast[i] = rt_raster_deserialize(pgrast, FALSE);
                        if (!rast[i]) {
-                               elog(ERROR, "RASTER_mapAlgebra2Expr: Could not deserialize the %s raster", i < 1 ? "first" : "second");
+                               elog(ERROR, "RASTER_mapAlgebra2: Could not deserialize the %s raster", i < 1 ? "first" : "second");
                                for (k = 0; k < i; k++) {
                                        if (rast[k] != NULL) rt_raster_destroy(rast[k]);
                                }
@@ -7995,7 +8000,7 @@ Datum RASTER_mapAlgebra2Expr(PG_FUNCTION_ARGS)
 
                raster = rt_raster_new(0, 0);
                if (raster == NULL) {
-                       elog(ERROR, "RASTER_mapAlgebra2Expr: Unable to create empty raster");
+                       elog(ERROR, "RASTER_mapAlgebra2: Unable to create empty raster");
                        for (k = 0; k < i; k++) {
                                if (rast[k] != NULL) rt_raster_destroy(rast[k]);
                        }
@@ -8041,7 +8046,7 @@ Datum RASTER_mapAlgebra2Expr(PG_FUNCTION_ARGS)
                        _dim[j][1]
                );
                if (_rast[i] == NULL) {
-                       elog(ERROR, "RASTER_mapAlgebra2Expr: Unable to create nodata raster");
+                       elog(ERROR, "RASTER_mapAlgebra2: Unable to create nodata raster");
                        rt_raster_destroy(_rast[j]);
                        PG_RETURN_NULL();
                }
@@ -8069,7 +8074,7 @@ Datum RASTER_mapAlgebra2Expr(PG_FUNCTION_ARGS)
 
        /* same alignment */
        if (!rt_raster_same_alignment(_rast[0], _rast[1], &aligned)) {
-               elog(ERROR, "RASTER_mapAlgebra2Expr: Unable to test for alignment on the two rasters");
+               elog(ERROR, "RASTER_mapAlgebra2: Unable to test for alignment on the two rasters");
                for (k = 0; k < set_count; k++) rt_raster_destroy(_rast[k]);
                PG_RETURN_NULL();
        }
@@ -8085,7 +8090,7 @@ Datum RASTER_mapAlgebra2Expr(PG_FUNCTION_ARGS)
                /* Get the pixel type index */
                pixtype = rt_pixtype_index_from_name(pixtypename);
                if (pixtype == PT_END ) {
-                       elog(ERROR, "RASTER_mapAlgebra2Expr: Invalid pixel type: %s", pixtypename);
+                       elog(ERROR, "RASTER_mapAlgebra2: Invalid pixel type: %s", pixtypename);
                        for (k = 0; k < set_count; k++) rt_raster_destroy(_rast[k]);
                        PG_RETURN_NULL();
                }
@@ -8105,7 +8110,7 @@ Datum RASTER_mapAlgebra2Expr(PG_FUNCTION_ARGS)
                &err, _offset
        );
        if (!err) {
-               elog(ERROR, "RASTER_mapAlgebra2Expr: Unable to get output raster of correct extent");
+               elog(ERROR, "RASTER_mapAlgebra2: Unable to get output raster of correct extent");
                for (k = 0; k < set_count; k++) rt_raster_destroy(_rast[k]);
                PG_RETURN_NULL();
        }
@@ -8121,6 +8126,7 @@ Datum RASTER_mapAlgebra2Expr(PG_FUNCTION_ARGS)
        dim[1] = rt_raster_get_height(raster);
 
        i = 2;
+       /* handle special cases for extent */
        switch (extenttype) {
                case ET_FIRST:
                        i = 0;
@@ -8172,7 +8178,7 @@ Datum RASTER_mapAlgebra2Expr(PG_FUNCTION_ARGS)
 
                                        raster = rt_raster_new(0, 0);
                                        if (raster == NULL) {
-                                               elog(ERROR, "RASTER_mapAlgebra2Expr: Unable to create no band raster");
+                                               elog(ERROR, "RASTER_mapAlgebra2: Unable to create no band raster");
                                                for (k = 0; k < set_count; k++) rt_raster_destroy(_rast[k]);
                                                PG_RETURN_NULL();
                                        }
@@ -8220,7 +8226,7 @@ Datum RASTER_mapAlgebra2Expr(PG_FUNCTION_ARGS)
 
                _band[i] = rt_raster_get_band(_rast[i], bandindex[i] - 1);
                if (_band[i] == NULL) {
-                       elog(ERROR, "RASTER_mapAlgebra2Expr: Unable to get band %d of the %s raster",
+                       elog(ERROR, "RASTER_mapAlgebra2: Unable to get band %d of the %s raster",
                                bandindex[i],
                                (i < 1 ? "FIRST" : "SECOND")
                        );
@@ -8264,7 +8270,7 @@ Datum RASTER_mapAlgebra2Expr(PG_FUNCTION_ARGS)
                1, nodataval,
                0
        ) < 0) {
-               elog(ERROR, "RASTER_mapAlgebra2Expr: Unable to add new band to output raster");
+               elog(ERROR, "RASTER_mapAlgebra2: Unable to add new band to output raster");
                for (k = 0; k < set_count; k++) rt_raster_destroy(_rast[k]);
                rt_raster_destroy(raster);
                PG_RETURN_NULL();
@@ -8273,7 +8279,7 @@ Datum RASTER_mapAlgebra2Expr(PG_FUNCTION_ARGS)
        /* get output band */
        band = rt_raster_get_band(raster, 0);
        if (band == NULL) {
-               elog(ERROR, "RASTER_mapAlgebra2Expr: Unable to get newly added band of output raster");
+               elog(ERROR, "RASTER_mapAlgebra2: Unable to get newly added band of output raster");
                for (k = 0; k < set_count; k++) rt_raster_destroy(_rast[k]);
                rt_raster_destroy(raster);
                PG_RETURN_NULL();
@@ -8304,154 +8310,209 @@ Datum RASTER_mapAlgebra2Expr(PG_FUNCTION_ARGS)
                rt_band_get_nodata(band)
        );
 
-       /* connect SPI */
-       if (SPI_connect() != SPI_OK_CONNECT) {
-               elog(ERROR, "RASTER_mapAlgebra2Expr: Unable to connect to the SPI manager");
-               for (k = 0; k < set_count; k++) rt_raster_destroy(_rast[k]);
-               rt_raster_destroy(raster);
-               PG_RETURN_NULL();
-       }
-
        /*
-               process expressions
-
-               exprpos elements are:
-                       4 - expression => spiplan[0]
-                       7 - nodata1expr => spiplan[1]
-                       8 - nodata2expr => spiplan[2]
+               determine who called this function
+               Arg 4 will either be text or regprocedure
        */
-       for (i = 0; i < spicount; i++) {
-               if (!PG_ARGISNULL(exprpos[i])) {
-                       expr = strtoupper(text_to_cstring(PG_GETARG_TEXT_P(exprpos[i])));
-                       POSTGIS_RT_DEBUGF(3, "raw expr #%d: %s", i, expr);
-                       expr = replace(expr, "RAST1", "$1", &len);
-                       if (len) {
-                               argcount[i]++;
-                               argexists[i][0] = 1;
-                       }
-                       expr = replace(expr, "RAST2", (argexists[i][0] ? "$2" : "$1"), &len);
-                       if (len) {
-                               argcount[i]++;
-                               argexists[i][1] = 1;
-                       }
+       POSTGIS_RT_DEBUG(3, "checking parameter type for arg 4");
+       calltype = get_fn_expr_argtype(fcinfo->flinfo, 4);
+
+       switch(calltype) {
+               case TEXTOID: {
+                       POSTGIS_RT_DEBUG(3, "arg 4 is \"expression\"!");
 
-                       len = strlen("SELECT (") + strlen(expr) + strlen(")::double precision");
-                       sql = (char *) palloc(len + 1);
-                       if (sql == NULL) {
-                               elog(ERROR, "RASTER_mapAlgebra2Expr: Unable to allocate memory for expression parameter %d", exprpos[i]);
+                       /* connect SPI */
+                       if (SPI_connect() != SPI_OK_CONNECT) {
+                               elog(ERROR, "RASTER_mapAlgebra2: Unable to connect to the SPI manager");
                                for (k = 0; k < set_count; k++) rt_raster_destroy(_rast[k]);
                                rt_raster_destroy(raster);
-                               for (k = 0; k < spicount; k++) SPI_freeplan(spiplan[k]);
-                               SPI_finish();
                                PG_RETURN_NULL();
                        }
 
-                       strncpy(sql, "SELECT (", strlen("SELECT ("));
-                       strncpy(sql + strlen("SELECT ("), expr, strlen(expr));
-                       strncpy(sql + strlen("SELECT (") + strlen(expr), ")::double precision", strlen(")::double precision"));
-                       sql[len] = '\0';
+                       /* reset hasargval */
+                       memset(hasargval, 0, spicount);
+
+                       /*
+                               process expressions
+
+                               exprpos elements are:
+                                       4 - expression => spiplan[0]
+                                       7 - nodata1expr => spiplan[1]
+                                       8 - nodata2expr => spiplan[2]
+                       */
+                       for (i = 0; i < spicount; i++) {
+                               if (!PG_ARGISNULL(exprpos[i])) {
+                                       expr = strtoupper(text_to_cstring(PG_GETARG_TEXT_P(exprpos[i])));
+                                       POSTGIS_RT_DEBUGF(3, "raw expr #%d: %s", i, expr);
+                                       expr = replace(expr, "RAST1", "$1", &len);
+                                       if (len) {
+                                               argcount[i]++;
+                                               argexists[i][0] = 1;
+                                       }
+                                       expr = replace(expr, "RAST2", (argexists[i][0] ? "$2" : "$1"), &len);
+                                       if (len) {
+                                               argcount[i]++;
+                                               argexists[i][1] = 1;
+                                       }
 
-                       POSTGIS_RT_DEBUGF(3, "sql #%d: %s", i, sql);
+                                       len = strlen("SELECT (") + strlen(expr) + strlen(")::double precision");
+                                       sql = (char *) palloc(len + 1);
+                                       if (sql == NULL) {
+                                               elog(ERROR, "RASTER_mapAlgebra2: Unable to allocate memory for expression parameter %d", exprpos[i]);
+                                               for (k = 0; k < set_count; k++) rt_raster_destroy(_rast[k]);
+                                               rt_raster_destroy(raster);
+                                               for (k = 0; k < spicount; k++) SPI_freeplan(spiplan[k]);
+                                               SPI_finish();
+                                               PG_RETURN_NULL();
+                                       }
 
-                       /* create prepared plan */
-                       if (argcount[i]) {
-                               argtype = (Oid *) palloc(argcount[i] * sizeof(Oid));
-                               if (argtype == NULL) {
-                                       elog(ERROR, "RASTER_mapAlgebra2Expr: Unable to allocate memory for prepared plan argtypes of expression parameter %d", exprpos[i]);
+                                       strncpy(sql, "SELECT (", strlen("SELECT ("));
+                                       strncpy(sql + strlen("SELECT ("), expr, strlen(expr));
+                                       strncpy(sql + strlen("SELECT (") + strlen(expr), ")::double precision", strlen(")::double precision"));
+                                       sql[len] = '\0';
 
-                                       for (k = 0; k < set_count; k++) rt_raster_destroy(_rast[k]);
-                                       rt_raster_destroy(raster);
+                                       POSTGIS_RT_DEBUGF(3, "sql #%d: %s", i, sql);
 
-                                       for (k = 0; k < spicount; k++) SPI_freeplan(spiplan[k]);
-                                       SPI_finish();
+                                       /* create prepared plan */
+                                       if (argcount[i]) {
+                                               argtype = (Oid *) palloc(argcount[i] * sizeof(Oid));
+                                               if (argtype == NULL) {
+                                                       elog(ERROR, "RASTER_mapAlgebra2: Unable to allocate memory for prepared plan argtypes of expression parameter %d", exprpos[i]);
 
-                                       pfree(sql);
+                                                       for (k = 0; k < set_count; k++) rt_raster_destroy(_rast[k]);
+                                                       rt_raster_destroy(raster);
 
-                                       PG_RETURN_NULL();
-                               }
-                               for (j = 0; j < argcount[i]; j++) argtype[j] = FLOAT8OID;
+                                                       for (k = 0; k < spicount; k++) SPI_freeplan(spiplan[k]);
+                                                       SPI_finish();
 
-                               spiplan[i] = SPI_prepare(sql, argcount[i], argtype);
-                               if (spiplan[i] == NULL) {
-                                       elog(ERROR, "RASTER_mapAlgebra2Expr: Unable to create prepared plan of expression parameter %d", exprpos[i]);
+                                                       pfree(sql);
 
-                                       for (k = 0; k < set_count; k++) rt_raster_destroy(_rast[k]);
-                                       rt_raster_destroy(raster);
+                                                       PG_RETURN_NULL();
+                                               }
+                                               for (j = 0; j < argcount[i]; j++) argtype[j] = FLOAT8OID;
 
-                                       for (k = 0; k < spicount; k++) SPI_freeplan(spiplan[k]);
-                                       SPI_finish();
+                                               spiplan[i] = SPI_prepare(sql, argcount[i], argtype);
+                                               if (spiplan[i] == NULL) {
+                                                       elog(ERROR, "RASTER_mapAlgebra2: Unable to create prepared plan of expression parameter %d", exprpos[i]);
 
-                                       pfree(sql);
-                                       pfree(argtype);
+                                                       for (k = 0; k < set_count; k++) rt_raster_destroy(_rast[k]);
+                                                       rt_raster_destroy(raster);
 
-                                       PG_RETURN_NULL();
-                               }
+                                                       for (k = 0; k < spicount; k++) SPI_freeplan(spiplan[k]);
+                                                       SPI_finish();
 
-                               pfree(argtype);
-                       }
-                       /* no args, just execute query */
-                       else {
-                               err = SPI_execute(sql, TRUE, 0);
-                               if (err != SPI_OK_SELECT || SPI_tuptable == NULL || SPI_processed != 1) {
-                                       elog(ERROR, "RASTER_mapAlgebra2Expr: Unable to evaluate expression parameter %d", exprpos[i]);
+                                                       pfree(sql);
+                                                       pfree(argtype);
 
-                                       for (k = 0; k < set_count; k++) rt_raster_destroy(_rast[k]);
-                                       rt_raster_destroy(raster);
+                                                       PG_RETURN_NULL();
+                                               }
 
-                                       for (k = 0; k < spicount; k++) SPI_freeplan(spiplan[k]);
-                                       SPI_finish();
+                                               pfree(argtype);
+                                       }
+                                       /* no args, just execute query */
+                                       else {
+                                               err = SPI_execute(sql, TRUE, 0);
+                                               if (err != SPI_OK_SELECT || SPI_tuptable == NULL || SPI_processed != 1) {
+                                                       elog(ERROR, "RASTER_mapAlgebra2: Unable to evaluate expression parameter %d", exprpos[i]);
 
-                                       pfree(sql);
+                                                       for (k = 0; k < set_count; k++) rt_raster_destroy(_rast[k]);
+                                                       rt_raster_destroy(raster);
 
-                                       PG_RETURN_NULL();
-                               }
+                                                       for (k = 0; k < spicount; k++) SPI_freeplan(spiplan[k]);
+                                                       SPI_finish();
 
-                               /* get output of prepared plan */
-                               tupdesc = SPI_tuptable->tupdesc;
-                               tuptable = SPI_tuptable;
-                               tuple = tuptable->vals[0];
+                                                       pfree(sql);
 
-                               datum = SPI_getbinval(tuple, tupdesc, 1, &isnull);
-                               if (SPI_result == SPI_ERROR_NOATTRIBUTE) {
-                                       elog(ERROR, "RASTER_mapAlgebra2Expr: Unable to get result of expression parameter %d", exprpos[i]);
+                                                       PG_RETURN_NULL();
+                                               }
 
-                                       for (k = 0; k < set_count; k++) rt_raster_destroy(_rast[k]);
-                                       rt_raster_destroy(raster);
+                                               /* get output of prepared plan */
+                                               tupdesc = SPI_tuptable->tupdesc;
+                                               tuptable = SPI_tuptable;
+                                               tuple = tuptable->vals[0];
 
-                                       if (SPI_tuptable) SPI_freetuptable(tuptable);
-                                       for (k = 0; k < spicount; k++) SPI_freeplan(spiplan[k]);
-                                       SPI_finish();
+                                               datum = SPI_getbinval(tuple, tupdesc, 1, &isnull);
+                                               if (SPI_result == SPI_ERROR_NOATTRIBUTE) {
+                                                       elog(ERROR, "RASTER_mapAlgebra2: Unable to get result of expression parameter %d", exprpos[i]);
 
-                                       pfree(sql);
+                                                       for (k = 0; k < set_count; k++) rt_raster_destroy(_rast[k]);
+                                                       rt_raster_destroy(raster);
 
-                                       PG_RETURN_NULL();
-                               }
+                                                       if (SPI_tuptable) SPI_freetuptable(tuptable);
+                                                       for (k = 0; k < spicount; k++) SPI_freeplan(spiplan[k]);
+                                                       SPI_finish();
 
-                               if (!isnull) {
-                                       hasargval[i] = 1;
-                                       argval[i] = DatumGetFloat8(datum);
-                               }
+                                                       pfree(sql);
 
-                               if (SPI_tuptable) SPI_freetuptable(tuptable);
+                                                       PG_RETURN_NULL();
+                                               }
+
+                                               if (!isnull) {
+                                                       hasargval[i] = 1;
+                                                       argval[i] = DatumGetFloat8(datum);
+                                               }
+
+                                               if (SPI_tuptable) SPI_freetuptable(tuptable);
+                                       }
+
+                                       pfree(sql);
+                               }
+                               else
+                                       spiempty++;
                        }
 
-                       pfree(sql);
-               }
-               else
-                       spiempty++;
-       }
+                       /* nodatanodataval */
+                       if (!PG_ARGISNULL(9)) {
+                               hasnodatanodataval = 1;
+                               nodatanodataval = PG_GETARG_FLOAT8(9);
+                       }
+                       else
+                               hasnodatanodataval = 0;
+               }       break;
+               case REGPROCEDUREOID: {
+                       POSTGIS_RT_DEBUG(3, "arg 4 is \"userfunction\"!");
+                       if (!PG_ARGISNULL(4)) {
+                               ufcnullcount = 0;
+                               ufcnoid = PG_GETARG_OID(4);
+
+                               /* get function info */
+                               fmgr_info(ufcnoid, &uflinfo);
+
+                               /* prep function call data */
+#if POSTGIS_PGSQL_VERSION <= 90
+                               InitFunctionCallInfoData(ufcinfo, &uflinfo, 3, InvalidOid, NULL);
+#else
+                               InitFunctionCallInfoData(ufcinfo, &uflinfo, 3, InvalidOid, NULL, NULL);
+#endif
+                               memset(ufcinfo.argnull, FALSE, 3);
 
-       /* nodatanodataval */
-       if (!PG_ARGISNULL(9)) {
-               hasnodatanodataval = 1;
-               nodatanodataval = PG_GETARG_FLOAT8(9);
+                               if (!PG_ARGISNULL(7)) {
+                                ufcinfo.arg[2] = PG_GETARG_DATUM(7);
+                               }
+                               else {
+                                ufcinfo.arg[2] = (Datum) NULL;
+                                ufcinfo.argnull[2] = TRUE;
+                                ufcnullcount++;
+                               }
+                       }
+               }       break;
+               default:
+                       elog(ERROR, "RASTER_mapAlgebra2: Invalid data type for expression or userfunction");
+                       for (k = 0; k < set_count; k++) rt_raster_destroy(_rast[k]);
+                       rt_raster_destroy(raster);
+                       PG_RETURN_NULL();
+                       break;
        }
-       else
-               hasnodatanodataval = 0;
 
        /* loop over pixels */
        /* if any expression present, run */
-       if (spiempty != spicount || hasnodatanodataval) {
+       if ((
+               (calltype == TEXTOID) && (
+                       (spiempty != spicount) || hasnodatanodataval
+               )
+       ) || (
+               (calltype == REGPROCEDUREOID) && (ufcnoid != InvalidOid)
+       )) {
                for (x = 0; x < dim[0]; x++) {
                        for (y = 0; y < dim[1]; y++) {
 
@@ -8472,13 +8533,15 @@ Datum RASTER_mapAlgebra2Expr(PG_FUNCTION_ARGS)
                                        ) {
                                                err = rt_band_get_pixel(_band[i], _x, _y, &(_pixel[i]));
                                                if (err < 0) {
-                                                       elog(ERROR, "RASTER_mapAlgebra2Expr: Unable to get pixel of %s raster", (i < 1 ? "FIRST" : "SECOND"));
+                                                       elog(ERROR, "RASTER_mapAlgebra2: Unable to get pixel of %s raster", (i < 1 ? "FIRST" : "SECOND"));
 
                                                        for (k = 0; k < set_count; k++) rt_raster_destroy(_rast[k]);
                                                        rt_raster_destroy(raster);
 
-                                                       for (k = 0; k < spicount; k++) SPI_freeplan(spiplan[k]);
-                                                       SPI_finish();
+                                                       if (calltype == TEXTOID) {
+                                                               for (k = 0; k < spicount; k++) SPI_freeplan(spiplan[k]);
+                                                               SPI_finish();
+                                                       }
 
                                                        PG_RETURN_NULL();
                                                }
@@ -8497,166 +8560,203 @@ Datum RASTER_mapAlgebra2Expr(PG_FUNCTION_ARGS)
 
                                haspixel = 0;
 
-                               /* which prepared plan to use? */
-                               /* !pixel0 && !pixel1 */
-                               /* use nodatanodataval */
-                               if (!_haspixel[0] && !_haspixel[1])
-                                       i = 3;
-                               /* pixel0 && !pixel1 */
-                               /* run spiplan[2] (nodata2expr) */
-                               else if (_haspixel[0] && !_haspixel[1])
-                                       i = 2;
-                               /* !pixel0 && pixel1 */
-                               /* run spiplan[1] (nodata1expr) */
-                               else if (!_haspixel[0] && _haspixel[1])
-                                       i = 1;
-                               /* pixel0 && pixel1 */
-                               /* run spiplan[0] (expression) */
-                               else
-                                       i = 0;
+                               switch (calltype) {
+                                       case TEXTOID: {
+                                               /* which prepared plan to use? */
+                                               /* !pixel0 && !pixel1 */
+                                               /* use nodatanodataval */
+                                               if (!_haspixel[0] && !_haspixel[1])
+                                                       i = 3;
+                                               /* pixel0 && !pixel1 */
+                                               /* run spiplan[2] (nodata2expr) */
+                                               else if (_haspixel[0] && !_haspixel[1])
+                                                       i = 2;
+                                               /* !pixel0 && pixel1 */
+                                               /* run spiplan[1] (nodata1expr) */
+                                               else if (!_haspixel[0] && _haspixel[1])
+                                                       i = 1;
+                                               /* pixel0 && pixel1 */
+                                               /* run spiplan[0] (expression) */
+                                               else
+                                                       i = 0;
 
-                               /* process values */
-                               if (i == 3) {
-                                       if (hasnodatanodataval) {
-                                               haspixel = 1;
-                                               pixel = nodatanodataval;
-                                       }
-                               }
-                               /* prepared plan exists */
-                               else if (spiplan[i] != NULL) {
-                                       POSTGIS_RT_DEBUGF(5, "Using prepared plan: %d", i);
+                                               /* process values */
+                                               if (i == 3) {
+                                                       if (hasnodatanodataval) {
+                                                               haspixel = 1;
+                                                               pixel = nodatanodataval;
+                                                       }
+                                               }
+                                               /* has an evaluated value */
+                                               else if (hasargval[i]) {
+                                                       haspixel = 1;
+                                                       pixel = argval[i];
+                                               }
+                                               /* prepared plan exists */
+                                               else if (spiplan[i] != NULL) {
+                                                       POSTGIS_RT_DEBUGF(5, "Using prepared plan: %d", i);
+
+                                                       /* expression has argument(s) */
+                                                       if (argcount[i]) {
+                                                               values = (Datum *) palloc(sizeof(Datum) * argcount[i]);
+                                                               if (values == NULL) {
+                                                                       elog(ERROR, "RASTER_mapAlgebra2: Unable to allocate memory for value parameters of prepared statement %d", i);
+
+                                                                       for (k = 0; k < set_count; k++) rt_raster_destroy(_rast[k]);
+                                                                       rt_raster_destroy(raster);
+
+                                                                       for (k = 0; k < spicount; k++) SPI_freeplan(spiplan[k]);
+                                                                       SPI_finish();
+
+                                                                       PG_RETURN_NULL();
+                                                               }
+
+                                                               nulls = (bool *) palloc(sizeof(bool) * argcount[i]);
+                                                               if (nulls == NULL) {
+                                                                       elog(ERROR, "RASTER_mapAlgebra2: Unable to allocate memory for NULL parameters of prepared statement %d", i);
+
+                                                                       pfree(values);
+
+                                                                       for (k = 0; k < set_count; k++) rt_raster_destroy(_rast[k]);
+                                                                       rt_raster_destroy(raster);
+
+                                                                       for (k = 0; k < spicount; k++) SPI_freeplan(spiplan[k]);
+                                                                       SPI_finish();
+
+                                                                       PG_RETURN_NULL();
+                                                               }
+                                                               memset(nulls, FALSE, argcount[i]);
+
+                                                               /* two arguments */
+                                                               if (argcount[i] > 1) {
+                                                                       for (j = 0; j < argcount[i]; j++) {
+                                                                               if (_isempty[j] || !_haspixel[j])
+                                                                                       nulls[j] = TRUE;
+                                                                               else
+                                                                                       values[j] = Float8GetDatum(_pixel[j]);
+                                                                       }
+                                                               }
+                                                               /* only one argument */
+                                                               else {
+                                                                       if (argexists[i][0])
+                                                                               j = 0;
+                                                                       else
+                                                                               j = 1;
+
+                                                                       if (_isempty[j] || !_haspixel[j]) {
+                                                                               POSTGIS_RT_DEBUG(5, "using null");
+                                                                               nulls[0] = TRUE;
+                                                                       }
+                                                                       else {
+                                                                               POSTGIS_RT_DEBUGF(5, "using value %f", _pixel[j]);
+                                                                               values[0] = Float8GetDatum(_pixel[j]);
+                                                                       }
+                                                               }
+                                                       }
 
-                                       /* expression has argument(s) */
-                                       if (argcount[i]) {
-                                               values = (Datum *) palloc(sizeof(Datum) * argcount[i]);
-                                               if (values == NULL) {
-                                                       elog(ERROR, "RASTER_mapAlgebra2Expr: Unable to allocate memory for value parameters of prepared statement %d", i);
+                                                       /* run prepared plan */
+                                                       err = SPI_execute_plan(spiplan[i], values, nulls, TRUE, 1);
+                                                       if (values != NULL) pfree(values);
+                                                       if (nulls != NULL) pfree(nulls);
+                                                       if (err != SPI_OK_SELECT || SPI_tuptable == NULL || SPI_processed != 1) {
+                                                               elog(ERROR, "RASTER_mapAlgebra2: Unexpected error when running prepared statement %d", i);
 
-                                                       for (k = 0; k < set_count; k++) rt_raster_destroy(_rast[k]);
-                                                       rt_raster_destroy(raster);
+                                                               for (k = 0; k < set_count; k++) rt_raster_destroy(_rast[k]);
+                                                               rt_raster_destroy(raster);
 
-                                                       for (k = 0; k < spicount; k++) SPI_freeplan(spiplan[k]);
-                                                       SPI_finish();
+                                                               for (k = 0; k < spicount; k++) SPI_freeplan(spiplan[k]);
+                                                               SPI_finish();
 
-                                                       PG_RETURN_NULL();
-                                               }
+                                                               PG_RETURN_NULL();
+                                                       }
 
-                                               nulls = (bool *) palloc(sizeof(bool) * argcount[i]);
-                                               if (nulls == NULL) {
-                                                       elog(ERROR, "RASTER_mapAlgebra2Expr: Unable to allocate memory for NULL parameters of prepared statement %d", i);
+                                                       /* get output of prepared plan */
+                                                       tupdesc = SPI_tuptable->tupdesc;
+                                                       tuptable = SPI_tuptable;
+                                                       tuple = tuptable->vals[0];
 
-                                                       pfree(values);
+                                                       datum = SPI_getbinval(tuple, tupdesc, 1, &isnull);
+                                                       if (SPI_result == SPI_ERROR_NOATTRIBUTE) {
+                                                               elog(ERROR, "RASTER_mapAlgebra2: Unable to get result of prepared statement %d", i);
 
-                                                       for (k = 0; k < set_count; k++) rt_raster_destroy(_rast[k]);
-                                                       rt_raster_destroy(raster);
+                                                               for (k = 0; k < set_count; k++) rt_raster_destroy(_rast[k]);
+                                                               rt_raster_destroy(raster);
 
-                                                       for (k = 0; k < spicount; k++) SPI_freeplan(spiplan[k]);
-                                                       SPI_finish();
+                                                               if (SPI_tuptable) SPI_freetuptable(tuptable);
+                                                               for (k = 0; k < spicount; k++) SPI_freeplan(spiplan[k]);
+                                                               SPI_finish();
 
-                                                       PG_RETURN_NULL();
-                                               }
-                                               memset(nulls, FALSE, argcount[i]);
-
-                                               /* two arguments */
-                                               if (argcount[i] > 1) {
-                                                       for (j = 0; j < argcount[i]; j++) {
-                                                               if (_isempty[j] || !_haspixel[j])
-                                                                       nulls[j] = TRUE;
-                                                               else
-                                                                       values[j] = Float8GetDatum(_pixel[j]);
+                                                               PG_RETURN_NULL();
+                                                       }
+
+                                                       if (!isnull) {
+                                                               haspixel = 1;
+                                                               pixel = DatumGetFloat8(datum);
                                                        }
+
+                                                       if (SPI_tuptable) SPI_freetuptable(tuptable);
                                                }
-                                               /* only one argument */
-                                               else {
-                                                       if (argexists[i][0])
-                                                               j = 0;
-                                                       else
-                                                               j = 1;
-
-                                                       if (_isempty[j] || !_haspixel[j]) {
-                                                               POSTGIS_RT_DEBUG(5, "using null");
-                                                               nulls[0] = TRUE;
+                                       }       break;
+                                       case REGPROCEDUREOID: {
+                                               /* build fcnarg */
+                                               for (i = 0; i < set_count; i++) {
+                                                       ufcinfo.arg[i] = Float8GetDatum(_pixel[i]);
+
+                                                       if (_haspixel[i]) {
+                                                               ufcinfo.argnull[i] = FALSE;
+                                                               ufcnullcount--;
                                                        }
                                                        else {
-                                                               POSTGIS_RT_DEBUGF(5, "using value %f", _pixel[j]);
-                                                               values[0] = Float8GetDatum(_pixel[j]);
+                                                               ufcinfo.argnull[i] = TRUE;
+                                                               ufcnullcount++;
                                                        }
                                                }
-                                       }
-
-                                       /* run prepared plan */
-                                       err = SPI_execute_plan(spiplan[i], values, nulls, TRUE, 1);
-                                       if (values != NULL) pfree(values);
-                                       if (nulls != NULL) pfree(nulls);
-                                       if (err != SPI_OK_SELECT || SPI_tuptable == NULL || SPI_processed != 1) {
-                                               elog(ERROR, "RASTER_mapAlgebra2Expr: Unexpected error when running prepared statement %d", i);
-
-                                               for (k = 0; k < set_count; k++) rt_raster_destroy(_rast[k]);
-                                               rt_raster_destroy(raster);
-
-                                               for (k = 0; k < spicount; k++) SPI_freeplan(spiplan[k]);
-                                               SPI_finish();
-
-                                               PG_RETURN_NULL();
-                                       }
-
-                                       /* get output of prepared plan */
-                                       tupdesc = SPI_tuptable->tupdesc;
-                                       tuptable = SPI_tuptable;
-                                       tuple = tuptable->vals[0];
-
-                                       datum = SPI_getbinval(tuple, tupdesc, 1, &isnull);
-                                       if (SPI_result == SPI_ERROR_NOATTRIBUTE) {
-                                               elog(ERROR, "RASTER_mapAlgebra2Expr: Unable to get result of prepared statement %d", i);
-
-                                               for (k = 0; k < set_count; k++) rt_raster_destroy(_rast[k]);
-                                               rt_raster_destroy(raster);
-
-                                               if (SPI_tuptable) SPI_freetuptable(tuptable);
-                                               for (k = 0; k < spicount; k++) SPI_freeplan(spiplan[k]);
-                                               SPI_finish();
 
-                                               PG_RETURN_NULL();
-                                       }
+                                               /* function is strict and null parameter is passed */
+                                               /* http://archives.postgresql.org/pgsql-general/2011-11/msg00424.php */
+                                               if (uflinfo.fn_strict && ufcnullcount)
+                                                       break;
 
-                                       if (!isnull) {
-                                               haspixel = 1;
-                                               pixel = DatumGetFloat8(datum);
-                                       }
+                                               datum = FunctionCallInvoke(&ufcinfo);
 
-                                       if (SPI_tuptable) SPI_freetuptable(tuptable);
-                               }
-                               /* has an evaluated value */
-                               else if (hasargval[i]) {
-                                       haspixel = 1;
-                                       pixel = argval[i];
+                                               /* result is not null*/
+                                               if (!ufcinfo.isnull) {
+                                                       haspixel = 1;
+                                                       pixel = DatumGetFloat8(datum);
+                                               }
+                                       }       break;
                                }
 
                                /* burn pixel if haspixel != 0 */
                                if (haspixel) {
                                        if (rt_band_set_pixel(band, x, y, pixel) < 0) {
-                                               elog(ERROR, "RASTER_mapAlgebra2Expr: Unable to set pixel value of output raster");
+                                               elog(ERROR, "RASTER_mapAlgebra2: Unable to set pixel value of output raster");
 
                                                for (k = 0; k < set_count; k++) rt_raster_destroy(_rast[k]);
                                                rt_raster_destroy(raster);
 
-                                               for (k = 0; k < spicount; k++) SPI_freeplan(spiplan[k]);
-                                               SPI_finish();
+                                               if (calltype == TEXTOID) {
+                                                       for (k = 0; k < spicount; k++) SPI_freeplan(spiplan[k]);
+                                                       SPI_finish();
+                                               }
 
                                                PG_RETURN_NULL();
                                        }
                                }
 
                                POSTGIS_RT_DEBUGF(5, "(x, y, val) = (%d, %d, %f)", x, y, haspixel ? pixel : nodataval);
-                       }
-               }
+
+                       } /* y: height */
+               } /* x: width */
        }
 
        /* CLEANUP */
-       for (i = 0; i < spicount; i++) {
-               if (spiplan[i] != NULL) SPI_freeplan(spiplan[i]);
+       if (calltype == TEXTOID) {
+               for (i = 0; i < spicount; i++) {
+                       if (spiplan[i] != NULL) SPI_freeplan(spiplan[i]);
+               }
+               SPI_finish();
        }
-       SPI_finish();
 
        for (k = 0; k < set_count; k++) {
                if (_rast[k] != NULL) rt_raster_destroy(_rast[k]);
@@ -8666,10 +8766,23 @@ Datum RASTER_mapAlgebra2Expr(PG_FUNCTION_ARGS)
        rt_raster_destroy(raster);
        if (!pgrast) PG_RETURN_NULL();
 
+       POSTGIS_RT_DEBUG(3, "Finished RASTER_mapAlgebra2");
+
        SET_VARSIZE(pgrast, pgrast->size);
        PG_RETURN_POINTER(pgrast);
 }
 
+/**
+ * Two raster MapAlgebra using user function
+ */
+ /*
+PG_FUNCTION_INFO_V1(RASTER_mapAlgebra2Fct);
+Datum RASTER_mapAlgebra2Fct(PG_FUNCTION_ARGS)
+{
+       PG_RETURN_NULL();
+}
+*/
+
 /* ---------------------------------------------------------------- */
 /*  Memory allocation / error reporting hooks                       */
 /* ---------------------------------------------------------------- */
index 1368f306cd522f7640db91772e9dff2dd77cd40b..683e555182490e5d9638de0946214c5dc5ef6be1 100644 (file)
@@ -1668,22 +1668,56 @@ CREATE OR REPLACE FUNCTION st_mapalgebraexpr(
        rast2 raster, band2 integer,
        expression text,
        pixeltype text DEFAULT NULL, extenttype text DEFAULT 'INTERSECTION',
-       nodata1expr text DEFAULT NULL, nodata2expr text DEFAULT NULL, nodatanodataval double precision DEFAULT NULL
+       nodata1expr text DEFAULT NULL, nodata2expr text DEFAULT NULL,
+       nodatanodataval double precision DEFAULT NULL
 )
        RETURNS raster
-       AS 'MODULE_PATHNAME', 'RASTER_mapAlgebra2Expr'
-       LANGUAGE 'C' IMMUTABLE;
+       AS 'MODULE_PATHNAME', 'RASTER_mapAlgebra2'
+       LANGUAGE 'C' STABLE;
 
 CREATE OR REPLACE FUNCTION st_mapalgebraexpr(
        rast1 raster,
        rast2 raster,
        expression text,
        pixeltype text DEFAULT NULL, extenttype text DEFAULT 'INTERSECTION',
-       nodata1expr text DEFAULT NULL, nodata2expr text DEFAULT NULL, nodatanodataval double precision DEFAULT NULL
+       nodata1expr text DEFAULT NULL, nodata2expr text DEFAULT NULL,
+       nodatanodataval double precision DEFAULT NULL
 )
        RETURNS raster
        AS $$ SELECT st_mapalgebraexpr($1, 1, $2, 1, $3, $4, $5, $6, $7, $8) $$
-       LANGUAGE 'SQL' IMMUTABLE;
+       LANGUAGE 'SQL' STABLE;
+
+CREATE OR REPLACE FUNCTION st_mapalgebrafct(
+       rast1 raster, band1 integer,
+       rast2 raster, band2 integer,
+       userfunction regprocedure,
+       pixeltype text DEFAULT NULL, extenttype text DEFAULT 'INTERSECTION',
+       VARIADIC userargs text[] DEFAULT NULL
+)
+       RETURNS raster
+       AS 'MODULE_PATHNAME', 'RASTER_mapAlgebra2'
+       LANGUAGE 'C' STABLE;
+
+CREATE OR REPLACE FUNCTION st_mapalgebrafct(
+       rast1 raster,
+       rast2 raster,
+       userfunction regprocedure,
+       pixeltype text DEFAULT NULL, extenttype text DEFAULT 'INTERSECTION',
+       VARIADIC userargs text[] DEFAULT NULL
+)
+       RETURNS raster
+       AS $$ SELECT st_mapalgebrafct($1, 1, $2, 1, $3, $4, $5, VARIADIC $6) $$
+       LANGUAGE 'SQL' STABLE;
+
+CREATE OR REPLACE FUNCTION st_mapalgebrafct(
+       rast1 raster,
+       rast2 raster,
+       userfunction regprocedure,
+       VARIADIC userargs text[]
+)
+       RETURNS raster
+       AS $$ SELECT st_mapalgebrafct($1, 1, $2, 1, $3, NULL, 'INTERSECTION', VARIADIC $4) $$
+       LANGUAGE 'SQL' STABLE;
 
 -----------------------------------------------------------------------
 -- Get information about the raster
index 09f1ec24a2e80115550ab187a4a10a0bd77f218d..1c422cbcc79af734ea1285ddf9e855b6d241b3e4 100644 (file)
@@ -89,6 +89,7 @@ TEST_UTILITY = \
        rt_mapalgebraexpr.sql \
        rt_mapalgebrafct.sql \
        rt_mapalgebraexpr_2raster.sql \
+       rt_mapalgebrafct_2raster.sql \
        rt_reclass.sql \
        rt_resample.sql \
        rt_asraster.sql \
index adb190da0d7bf882e09bc10e4c7e598490f0e287..454ff6e7923ea71fbe4c5f9a42e74710175f6dd2 100644 (file)
@@ -167,7 +167,7 @@ INSERT INTO raster_mapalgebra_out
                AND r2.rid BETWEEN 1 AND 9
        ) UNION ALL (
        SELECT r1.rid, r2.rid, 'FIRST', st_mapalgebraexpr(
-               r1.rast, r2.rast, '((rast1 + rast2)/2.)::numeric', '32BF', 'UNION', 'rast2', 'rast1', NULL
+               r1.rast, r2.rast, 'CASE WHEN rast2 IS NOT NULL THEN NULL ELSE rast1 END', '32BF', 'FIRST', NULL, 'rast1', NULL
        )
        FROM raster_mapalgebra r1
        JOIN raster_mapalgebra r2
@@ -178,7 +178,7 @@ INSERT INTO raster_mapalgebra_out
 
 INSERT INTO raster_mapalgebra_out
        SELECT NULL AS rid, rid, 'FIRST', st_mapalgebraexpr(
-               NULL::raster, rast, 'CASE WHEN rast1 IS NOT NULL THEN NULL ELSE rast2 END', '32BF', 'SECOND', 'rast2', NULL, NULL
+               NULL::raster, rast, 'CASE WHEN rast1 IS NOT NULL THEN NULL ELSE rast2 END', '32BF', 'FIRST', 'rast2', NULL, NULL
        )
        FROM raster_mapalgebra
 ;
index 59182be8b8f4bf9c22eb338e5b24db7f9ca4416f..2d3f6d56639d48786c86e1c15cf7d4de00d1705b 100644 (file)
@@ -24,6 +24,16 @@ NOTICE:  The two rasters provided have no intersection.  Returning no band raste
 NOTICE:  The two rasters provided have no intersection.  Returning no band raster
 NOTICE:  The two rasters provided are NULL.  Returning NULL
 NOTICE:  The two rasters provided are NULL.  Returning NULL
+NOTICE:  The FIRST raster is NULL.  Returning NULL
+NOTICE:  The FIRST raster is NULL.  Returning NULL
+NOTICE:  The FIRST raster is NULL.  Returning NULL
+NOTICE:  The FIRST raster is NULL.  Returning NULL
+NOTICE:  The FIRST raster is NULL.  Returning NULL
+NOTICE:  The FIRST raster is NULL.  Returning NULL
+NOTICE:  The FIRST raster is NULL.  Returning NULL
+NOTICE:  The FIRST raster is NULL.  Returning NULL
+NOTICE:  The FIRST raster is NULL.  Returning NULL
+NOTICE:  The FIRST raster is NULL.  Returning NULL
 NOTICE:  The two rasters provided are NULL.  Returning NULL
 NOTICE:  The SECOND raster is NULL.  Returning NULL
 NOTICE:  The SECOND raster is NULL.  Returning NULL
@@ -218,18 +228,18 @@ NOTICE:  Could not find raster band of index 1 when getting pixel value. Returni
 0|4|FIRST|-2.000|-2.000|4|4|1.000|1.000|0.000|0.000|0|1|32BF|t|0.000|1.000|1.000
 10|11|FIRST|-2.000|-2.000|4|4|1.000|1.000|1.000|-1.000|0|1|32BF|t|0.000|1.000|1.000
 10|12|FIRST|-2.000|-2.000|4|4|1.000|1.000|1.000|-1.000|0|1|32BF|t|0.000|1.000|1.000
-10|13|FIRST|-2.000|-2.000|4|5|1.000|1.000|1.000|-1.000|0|1|32BF|t|0.000|1.000|
-10|14|FIRST|-2.000|-2.000|4|6|1.000|1.000|1.000|-1.000|0|1|32BF|t|0.000|1.000|
-|0|FIRST|-2.000|-2.000|4|4|1.000|1.000|0.000|0.000|0|1|32BF|t|0.000|1.000|1.000
-|1|FIRST|0.000|0.000|2|2|1.000|1.000|0.000|0.000|0|1|32BF|t|0.000|2.000|2.000
-|2|FIRST|1.000|-1.000|2|2|1.000|1.000|0.000|0.000|0|1|32BF|t|0.000|3.000|3.000
-|3|FIRST|1.000|1.000|2|2|1.000|1.000|0.000|0.000|0|1|32BF|t|0.000|4.000|4.000
-|4|FIRST|2.000|2.000|2|2|1.000|1.000|0.000|0.000|0|1|32BF|t|0.000|5.000|5.000
-|10|FIRST|-2.000|-2.000|4|4|1.000|1.000|1.000|-1.000|0|1|32BF|t|0.000|1.000|1.000
-|11|FIRST|0.000|0.000|2|2|1.000|1.000|1.000|-1.000|0|1|32BF|t|0.000|2.000|2.000
-|12|FIRST|1.000|-1.000|2|2|1.000|1.000|1.000|-1.000|0|1|32BF|t|0.000|3.000|3.000
-|13|FIRST|1.000|1.000|2|2|1.000|1.000|1.000|-1.000|0|1|32BF|t|0.000|4.000|4.000
-|14|FIRST|2.000|2.000|2|2|1.000|1.000|1.000|-1.000|0|1|32BF|t|0.000|5.000|5.000
+10|13|FIRST|-2.000|-2.000|4|4|1.000|1.000|1.000|-1.000|0|1|32BF|t|0.000|1.000|1.000
+10|14|FIRST|-2.000|-2.000|4|4|1.000|1.000|1.000|-1.000|0|1|32BF|t|0.000|1.000|1.000
+|0|FIRST|||||||||||||||
+|1|FIRST|||||||||||||||
+|2|FIRST|||||||||||||||
+|3|FIRST|||||||||||||||
+|4|FIRST|||||||||||||||
+|10|FIRST|||||||||||||||
+|11|FIRST|||||||||||||||
+|12|FIRST|||||||||||||||
+|13|FIRST|||||||||||||||
+|14|FIRST|||||||||||||||
 0||FIRST|-2.000|-2.000|4|4|1.000|1.000|0.000|0.000|0|1|32BF|t|0.000|1.000|1.000
 1||FIRST|0.000|0.000|2|2|1.000|1.000|0.000|0.000|0|1|32BF|t|0.000|2.000|2.000
 2||FIRST|1.000|-1.000|2|2|1.000|1.000|0.000|0.000|0|1|32BF|t|0.000|3.000|3.000
diff --git a/raster/test/regress/rt_mapalgebrafct_2raster.sql b/raster/test/regress/rt_mapalgebrafct_2raster.sql
new file mode 100644 (file)
index 0000000..00ee8d9
--- /dev/null
@@ -0,0 +1,344 @@
+DROP TABLE IF EXISTS raster_mapalgebra;
+CREATE TABLE raster_mapalgebra (
+       rid integer,
+       rast raster
+);
+DROP TABLE IF EXISTS raster_mapalgebra_out;
+CREATE TABLE raster_mapalgebra_out (
+       rid1 integer,
+       rid2 integer,
+       extent varchar,
+       rast raster
+);
+CREATE OR REPLACE FUNCTION make_test_raster(
+       rid integer,
+       width integer DEFAULT 2,
+       height integer DEFAULT 2,
+       ul_x double precision DEFAULT 0,
+       ul_y double precision DEFAULT 0,
+       skew_x double precision DEFAULT 0,
+       skew_y double precision DEFAULT 0,
+       initvalue double precision DEFAULT 1,
+       nodataval double precision DEFAULT 0
+)
+       RETURNS void
+       AS $$
+       DECLARE
+               x int;
+               y int;
+               rast raster;
+       BEGIN
+               rast := ST_MakeEmptyRaster(width, height, ul_x, ul_y, 1, 1, skew_x, skew_y, 0);
+               rast := ST_AddBand(rast, 1, '8BUI', initvalue, nodataval);
+
+               INSERT INTO raster_mapalgebra VALUES (rid, rast);
+
+               RETURN;
+       END;
+       $$ LANGUAGE 'plpgsql';
+-- no skew
+SELECT make_test_raster(0, 4, 4, -2, -2);
+SELECT make_test_raster(1, 2, 2, 0, 0, 0, 0, 2);
+SELECT make_test_raster(2, 2, 2, 1, -1, 0, 0, 3);
+SELECT make_test_raster(3, 2, 2, 1, 1, 0, 0, 4);
+SELECT make_test_raster(4, 2, 2, 2, 2, 0, 0, 5);
+
+-- skew
+SELECT make_test_raster(10, 4, 4, -2, -2, 1, -1);
+SELECT make_test_raster(11, 2, 2, 0, 0, 1, -1, 2);
+SELECT make_test_raster(12, 2, 2, 1, -1, 1, -1, 3);
+SELECT make_test_raster(13, 2, 2, 1, 1, 1, -1, 4);
+SELECT make_test_raster(14, 2, 2, 2, 2, 1, -1, 5);
+
+DROP FUNCTION IF EXISTS make_test_raster(integer, integer, integer, double precision, double precision, double precision, double precision, double precision, double precision);
+
+CREATE OR REPLACE FUNCTION raster_mapalgebra_intersection(
+       rast1 double precision,
+       rast2 double precision,
+       VARIADIC userargs text[]
+)
+       RETURNS double precision
+       AS $$
+       DECLARE
+       BEGIN
+               IF rast1 IS NOT NULL AND rast2 IS NOT NULL THEN
+                       RETURN rast1;
+               ELSE
+                       RETURN NULL;
+               END IF;
+
+               RETURN NULL;
+       END;
+       $$ LANGUAGE 'plpgsql';
+
+CREATE OR REPLACE FUNCTION raster_mapalgebra_union(
+       rast1 double precision,
+       rast2 double precision,
+       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';
+
+CREATE OR REPLACE FUNCTION raster_mapalgebra_first(
+       rast1 double precision,
+       rast2 double precision,
+       VARIADIC userargs text[]
+)
+       RETURNS double precision
+       AS $$
+       DECLARE
+       BEGIN
+               CASE
+                       WHEN rast1 IS NOT NULL AND rast2 IS NOT NULL THEN
+                               RETURN NULL;
+                       WHEN rast1 IS NOT NULL THEN
+                               RETURN rast1;
+                       ELSE
+                               RETURN NULL;
+               END CASE;
+
+               RETURN NULL;
+       END;
+       $$ LANGUAGE 'plpgsql';
+
+CREATE OR REPLACE FUNCTION raster_mapalgebra_second(
+       rast1 double precision,
+       rast2 double precision,
+       VARIADIC userargs text[]
+)
+       RETURNS double precision
+       AS $$
+       DECLARE
+       BEGIN
+               CASE
+                       WHEN rast1 IS NOT NULL AND rast2 IS NOT NULL THEN
+                               RETURN NULL;
+                       WHEN rast2 IS NOT NULL THEN
+                               RETURN rast2;
+                       ELSE
+                               RETURN NULL;
+               END CASE;
+
+               RETURN NULL;
+       END;
+       $$ LANGUAGE 'plpgsql';
+
+-- INTERSECTION
+INSERT INTO raster_mapalgebra_out
+       (SELECT r1.rid, r2.rid, 'INTERSECTION', st_mapalgebrafct(
+               r1.rast, r2.rast, 'raster_mapalgebra_intersection(double precision, double precision, text[])'::regprocedure, '32BF', 'INTERSECTION'
+       )
+       FROM raster_mapalgebra r1
+       JOIN raster_mapalgebra r2
+               ON r1.rid != r2.rid
+       WHERE r1.rid = 0
+               AND r2.rid BETWEEN 1 AND 9
+       ) UNION ALL (
+       SELECT r1.rid, r2.rid, 'INTERSECTION', st_mapalgebrafct(
+               r1.rast, r2.rast, 'raster_mapalgebra_intersection(double precision, double precision, text[])'::regprocedure, '32BF', 'INTERSECTION'
+       )
+       FROM raster_mapalgebra r1
+       JOIN raster_mapalgebra r2
+               ON r1.rid != r2.rid
+       WHERE r1.rid = 10
+               AND r2.rid BETWEEN 11 AND 19)
+;
+
+INSERT INTO raster_mapalgebra_out
+       SELECT NULL AS rid, rid, 'INTERSECTION', st_mapalgebrafct(
+               NULL::raster, rast, 'raster_mapalgebra_intersection(double precision, double precision, text[])'::regprocedure, '32BF', 'INTERSECTION'
+       )
+       FROM raster_mapalgebra
+;
+
+INSERT INTO raster_mapalgebra_out
+       SELECT rid, NULL AS rid, 'INTERSECTION', st_mapalgebrafct(
+               rast, NULL::raster, 'raster_mapalgebra_intersection(double precision, double precision, text[])'::regprocedure, '32BF', 'INTERSECTION'
+       )
+       FROM raster_mapalgebra
+;
+
+INSERT INTO raster_mapalgebra_out
+       SELECT NULL AS rid, NULL AS rid, 'INTERSECTION', st_mapalgebrafct(
+               NULL::raster, NULL::raster, 'raster_mapalgebra_intersection(double precision, double precision, text[])'::regprocedure, '32BF', 'INTERSECTION'
+       )
+;
+
+-- UNION
+INSERT INTO raster_mapalgebra_out
+       (SELECT r1.rid, r2.rid, 'UNION', st_mapalgebrafct(
+               r1.rast, r2.rast, 'raster_mapalgebra_union(double precision, double precision, text[])'::regprocedure, '32BF', 'UNION'
+       )
+       FROM raster_mapalgebra r1
+       JOIN raster_mapalgebra r2
+               ON r1.rid != r2.rid
+       WHERE r1.rid = 0
+               AND r2.rid BETWEEN 1 AND 9
+       ) UNION ALL (
+       SELECT r1.rid, r2.rid, 'UNION', st_mapalgebrafct(
+               r1.rast, r2.rast, 'raster_mapalgebra_union(double precision, double precision, text[])'::regprocedure, '32BF', 'UNION'
+       )
+       FROM raster_mapalgebra r1
+       JOIN raster_mapalgebra r2
+               ON r1.rid != r2.rid
+       WHERE r1.rid = 10
+               AND r2.rid BETWEEN 11 AND 19)
+;
+
+INSERT INTO raster_mapalgebra_out
+       SELECT NULL AS rid, rid, 'UNION', st_mapalgebrafct(
+               NULL::raster, rast, 'raster_mapalgebra_union(double precision, double precision, text[])'::regprocedure, '32BF', 'UNION'
+       )
+       FROM raster_mapalgebra
+;
+
+INSERT INTO raster_mapalgebra_out
+       SELECT rid, NULL AS rid, 'UNION', st_mapalgebrafct(
+               rast, NULL::raster, 'raster_mapalgebra_union(double precision, double precision, text[])'::regprocedure, '32BF', 'UNION'
+       )
+       FROM raster_mapalgebra
+;
+
+INSERT INTO raster_mapalgebra_out
+       SELECT NULL AS rid, NULL AS rid, 'UNION', st_mapalgebrafct(
+               NULL::raster, NULL::raster, 'raster_mapalgebra_union(double precision, double precision, text[])'::regprocedure, '32BF', 'UNION'
+       )
+;
+
+-- FIRST
+INSERT INTO raster_mapalgebra_out
+       (SELECT r1.rid, r2.rid, 'FIRST', st_mapalgebrafct(
+               r1.rast, r2.rast, 'raster_mapalgebra_first(double precision, double precision, text[])'::regprocedure, '32BF', 'FIRST'
+       )
+       FROM raster_mapalgebra r1
+       JOIN raster_mapalgebra r2
+               ON r1.rid != r2.rid
+       WHERE r1.rid = 0
+               AND r2.rid BETWEEN 1 AND 9
+       ) UNION ALL (
+       SELECT r1.rid, r2.rid, 'FIRST', st_mapalgebrafct(
+               r1.rast, r2.rast, 'raster_mapalgebra_first(double precision, double precision, text[])'::regprocedure, '32BF', 'FIRST'
+       )
+       FROM raster_mapalgebra r1
+       JOIN raster_mapalgebra r2
+               ON r1.rid != r2.rid
+       WHERE r1.rid = 10
+               AND r2.rid BETWEEN 11 AND 19)
+;
+
+INSERT INTO raster_mapalgebra_out
+       SELECT NULL AS rid, rid, 'FIRST', st_mapalgebrafct(
+               NULL::raster, rast, 'raster_mapalgebra_first(double precision, double precision, text[])'::regprocedure, '32BF', 'FIRST'
+       )
+       FROM raster_mapalgebra
+;
+
+INSERT INTO raster_mapalgebra_out
+       SELECT rid, NULL AS rid, 'FIRST', st_mapalgebrafct(
+               rast, NULL::raster, 'raster_mapalgebra_first(double precision, double precision, text[])'::regprocedure, '32BF', 'FIRST'
+       )
+       FROM raster_mapalgebra
+;
+
+INSERT INTO raster_mapalgebra_out
+       SELECT NULL AS rid, NULL AS rid, 'FIRST', st_mapalgebrafct(
+               NULL::raster, NULL::raster, 'raster_mapalgebra_first(double precision, double precision, text[])'::regprocedure, '32BF', 'FIRST'
+       )
+;
+
+-- SECOND
+INSERT INTO raster_mapalgebra_out
+       (SELECT r1.rid, r2.rid, 'SECOND', st_mapalgebrafct(
+               r1.rast, r2.rast, 'raster_mapalgebra_second(double precision, double precision, text[])'::regprocedure, '32BF', 'SECOND'
+       )
+       FROM raster_mapalgebra r1
+       JOIN raster_mapalgebra r2
+               ON r1.rid != r2.rid
+       WHERE r1.rid = 0
+               AND r2.rid BETWEEN 1 AND 9
+       ) UNION ALL (
+       SELECT r1.rid, r2.rid, 'SECOND', st_mapalgebrafct(
+               r1.rast, r2.rast, 'raster_mapalgebra_second(double precision, double precision, text[])'::regprocedure, '32BF', 'SECOND'
+       )
+       FROM raster_mapalgebra r1
+       JOIN raster_mapalgebra r2
+               ON r1.rid != r2.rid
+       WHERE r1.rid = 10
+               AND r2.rid BETWEEN 11 AND 19)
+;
+
+INSERT INTO raster_mapalgebra_out
+       SELECT NULL AS rid, rid, 'SECOND', st_mapalgebrafct(
+               NULL::raster, rast, 'raster_mapalgebra_second(double precision, double precision, text[])'::regprocedure, '32BF', 'SECOND'
+       )
+       FROM raster_mapalgebra
+;
+
+INSERT INTO raster_mapalgebra_out
+       SELECT rid, NULL AS rid, 'SECOND', st_mapalgebrafct(
+               rast, NULL::raster, 'raster_mapalgebra_second(double precision, double precision, text[])'::regprocedure, '32BF', 'SECOND'
+       )
+       FROM raster_mapalgebra
+;
+
+INSERT INTO raster_mapalgebra_out
+       SELECT NULL AS rid, NULL AS rid, 'SECOND', st_mapalgebrafct(
+               NULL::raster, NULL::raster, 'raster_mapalgebra_second(double precision, double precision, text[])'::regprocedure, '32BF', 'SECOND'
+       )
+;
+
+-- output
+SELECT
+       rid1,
+       rid2,
+       extent,
+       round(upperleftx::numeric, 3) AS upperleftx,
+       round(upperlefty::numeric, 3) AS upperlefty,
+       width,
+       height,
+       round(scalex::numeric, 3) AS scalex,
+       round(scaley::numeric, 3) AS scaley,
+       round(skewx::numeric, 3) AS skewx,
+       round(skewy::numeric, 3) AS skewy,
+       srid,
+       numbands,
+       pixeltype,
+       hasnodata,
+       round(nodatavalue::numeric, 3) AS nodatavalue,
+       round(firstvalue::numeric, 3) AS firstvalue,
+       round(lastvalue::numeric, 3) AS lastvalue
+FROM (
+       SELECT
+               rid1,
+               rid2,
+               extent,
+               (ST_Metadata(rast)).*,
+               (ST_BandMetadata(rast, 1)).*,
+               ST_Value(rast, 1, 1, 1) AS firstvalue,
+               ST_Value(rast, 1, ST_Width(rast), ST_Height(rast)) AS lastvalue
+       FROM raster_mapalgebra_out
+) AS r;
+
+DROP FUNCTION IF EXISTS raster_mapalgebra_intersection(double precision, double precision, VARIADIC text[]);
+DROP FUNCTION IF EXISTS raster_mapalgebra_union(double precision, double precision, VARIADIC text[]);
+DROP FUNCTION IF EXISTS raster_mapalgebra_first(double precision, double precision, VARIADIC text[]);
+DROP FUNCTION IF EXISTS raster_mapalgebra_second(double precision, double precision, VARIADIC text[]);
+
+DROP TABLE IF EXISTS raster_mapalgebra;
+DROP TABLE IF EXISTS raster_mapalgebra_out;
diff --git a/raster/test/regress/rt_mapalgebrafct_2raster_expected b/raster/test/regress/rt_mapalgebrafct_2raster_expected
new file mode 100644 (file)
index 0000000..199f099
--- /dev/null
@@ -0,0 +1,274 @@
+NOTICE:  table "raster_mapalgebra" does not exist, skipping
+NOTICE:  table "raster_mapalgebra_out" does not exist, skipping
+NOTICE:  The two rasters provided have no intersection.  Returning no band raster
+NOTICE:  The two rasters provided have no intersection.  Returning no band raster
+NOTICE:  The two rasters provided have no intersection.  Returning no band raster
+NOTICE:  The two rasters provided have no intersection.  Returning no band raster
+NOTICE:  The two rasters provided have no intersection.  Returning no band raster
+NOTICE:  The two rasters provided have no intersection.  Returning no band raster
+NOTICE:  The two rasters provided have no intersection.  Returning no band raster
+NOTICE:  The two rasters provided have no intersection.  Returning no band raster
+NOTICE:  The two rasters provided have no intersection.  Returning no band raster
+NOTICE:  The two rasters provided have no intersection.  Returning no band raster
+NOTICE:  The two rasters provided have no intersection.  Returning no band raster
+NOTICE:  The two rasters provided have no intersection.  Returning no band raster
+NOTICE:  The two rasters provided have no intersection.  Returning no band raster
+NOTICE:  The two rasters provided have no intersection.  Returning no band raster
+NOTICE:  The two rasters provided have no intersection.  Returning no band raster
+NOTICE:  The two rasters provided have no intersection.  Returning no band raster
+NOTICE:  The two rasters provided have no intersection.  Returning no band raster
+NOTICE:  The two rasters provided have no intersection.  Returning no band raster
+NOTICE:  The two rasters provided have no intersection.  Returning no band raster
+NOTICE:  The two rasters provided have no intersection.  Returning no band raster
+NOTICE:  The two rasters provided have no intersection.  Returning no band raster
+NOTICE:  The two rasters provided have no intersection.  Returning no band raster
+NOTICE:  The two rasters provided are NULL.  Returning NULL
+NOTICE:  The two rasters provided are NULL.  Returning NULL
+NOTICE:  The FIRST raster is NULL.  Returning NULL
+NOTICE:  The FIRST raster is NULL.  Returning NULL
+NOTICE:  The FIRST raster is NULL.  Returning NULL
+NOTICE:  The FIRST raster is NULL.  Returning NULL
+NOTICE:  The FIRST raster is NULL.  Returning NULL
+NOTICE:  The FIRST raster is NULL.  Returning NULL
+NOTICE:  The FIRST raster is NULL.  Returning NULL
+NOTICE:  The FIRST raster is NULL.  Returning NULL
+NOTICE:  The FIRST raster is NULL.  Returning NULL
+NOTICE:  The FIRST raster is NULL.  Returning NULL
+NOTICE:  The two rasters provided are NULL.  Returning NULL
+NOTICE:  The SECOND raster is NULL.  Returning NULL
+NOTICE:  The SECOND raster is NULL.  Returning NULL
+NOTICE:  The SECOND raster is NULL.  Returning NULL
+NOTICE:  The SECOND raster is NULL.  Returning NULL
+NOTICE:  The SECOND raster is NULL.  Returning NULL
+NOTICE:  The SECOND raster is NULL.  Returning NULL
+NOTICE:  The SECOND raster is NULL.  Returning NULL
+NOTICE:  The SECOND raster is NULL.  Returning NULL
+NOTICE:  The SECOND raster is NULL.  Returning NULL
+NOTICE:  The SECOND raster is NULL.  Returning NULL
+NOTICE:  The two rasters provided are NULL.  Returning NULL
+NOTICE:  Raster provided has no bands
+NOTICE:  Raster provided has no bands
+NOTICE:  Raster provided has no bands
+NOTICE:  Could not find raster band of index 1 when getting pixel value. Returning NULL
+NOTICE:  Could not find raster band of index 1 when getting pixel value. Returning NULL
+NOTICE:  Raster provided has no bands
+NOTICE:  Raster provided has no bands
+NOTICE:  Raster provided has no bands
+NOTICE:  Could not find raster band of index 1 when getting pixel value. Returning NULL
+NOTICE:  Could not find raster band of index 1 when getting pixel value. Returning NULL
+NOTICE:  Raster provided has no bands
+NOTICE:  Raster provided has no bands
+NOTICE:  Raster provided has no bands
+NOTICE:  Could not find raster band of index 1 when getting pixel value. Returning NULL
+NOTICE:  Could not find raster band of index 1 when getting pixel value. Returning NULL
+NOTICE:  Raster provided has no bands
+NOTICE:  Raster provided has no bands
+NOTICE:  Raster provided has no bands
+NOTICE:  Could not find raster band of index 1 when getting pixel value. Returning NULL
+NOTICE:  Could not find raster band of index 1 when getting pixel value. Returning NULL
+NOTICE:  Raster provided has no bands
+NOTICE:  Raster provided has no bands
+NOTICE:  Raster provided has no bands
+NOTICE:  Could not find raster band of index 1 when getting pixel value. Returning NULL
+NOTICE:  Could not find raster band of index 1 when getting pixel value. Returning NULL
+NOTICE:  Raster provided has no bands
+NOTICE:  Raster provided has no bands
+NOTICE:  Raster provided has no bands
+NOTICE:  Could not find raster band of index 1 when getting pixel value. Returning NULL
+NOTICE:  Could not find raster band of index 1 when getting pixel value. Returning NULL
+NOTICE:  Raster provided has no bands
+NOTICE:  Raster provided has no bands
+NOTICE:  Raster provided has no bands
+NOTICE:  Could not find raster band of index 1 when getting pixel value. Returning NULL
+NOTICE:  Could not find raster band of index 1 when getting pixel value. Returning NULL
+NOTICE:  Raster provided has no bands
+NOTICE:  Raster provided has no bands
+NOTICE:  Raster provided has no bands
+NOTICE:  Could not find raster band of index 1 when getting pixel value. Returning NULL
+NOTICE:  Could not find raster band of index 1 when getting pixel value. Returning NULL
+NOTICE:  Raster provided has no bands
+NOTICE:  Raster provided has no bands
+NOTICE:  Raster provided has no bands
+NOTICE:  Could not find raster band of index 1 when getting pixel value. Returning NULL
+NOTICE:  Could not find raster band of index 1 when getting pixel value. Returning NULL
+NOTICE:  Raster provided has no bands
+NOTICE:  Raster provided has no bands
+NOTICE:  Raster provided has no bands
+NOTICE:  Could not find raster band of index 1 when getting pixel value. Returning NULL
+NOTICE:  Could not find raster band of index 1 when getting pixel value. Returning NULL
+NOTICE:  Raster provided has no bands
+NOTICE:  Raster provided has no bands
+NOTICE:  Raster provided has no bands
+NOTICE:  Could not find raster band of index 1 when getting pixel value. Returning NULL
+NOTICE:  Could not find raster band of index 1 when getting pixel value. Returning NULL
+NOTICE:  Raster provided has no bands
+NOTICE:  Raster provided has no bands
+NOTICE:  Raster provided has no bands
+NOTICE:  Could not find raster band of index 1 when getting pixel value. Returning NULL
+NOTICE:  Could not find raster band of index 1 when getting pixel value. Returning NULL
+NOTICE:  Raster provided has no bands
+NOTICE:  Raster provided has no bands
+NOTICE:  Raster provided has no bands
+NOTICE:  Could not find raster band of index 1 when getting pixel value. Returning NULL
+NOTICE:  Could not find raster band of index 1 when getting pixel value. Returning NULL
+NOTICE:  Raster provided has no bands
+NOTICE:  Raster provided has no bands
+NOTICE:  Raster provided has no bands
+NOTICE:  Could not find raster band of index 1 when getting pixel value. Returning NULL
+NOTICE:  Could not find raster band of index 1 when getting pixel value. Returning NULL
+NOTICE:  Raster provided has no bands
+NOTICE:  Raster provided has no bands
+NOTICE:  Raster provided has no bands
+NOTICE:  Could not find raster band of index 1 when getting pixel value. Returning NULL
+NOTICE:  Could not find raster band of index 1 when getting pixel value. Returning NULL
+NOTICE:  Raster provided has no bands
+NOTICE:  Raster provided has no bands
+NOTICE:  Raster provided has no bands
+NOTICE:  Could not find raster band of index 1 when getting pixel value. Returning NULL
+NOTICE:  Could not find raster band of index 1 when getting pixel value. Returning NULL
+NOTICE:  Raster provided has no bands
+NOTICE:  Raster provided has no bands
+NOTICE:  Raster provided has no bands
+NOTICE:  Could not find raster band of index 1 when getting pixel value. Returning NULL
+NOTICE:  Could not find raster band of index 1 when getting pixel value. Returning NULL
+NOTICE:  Raster provided has no bands
+NOTICE:  Raster provided has no bands
+NOTICE:  Raster provided has no bands
+NOTICE:  Could not find raster band of index 1 when getting pixel value. Returning NULL
+NOTICE:  Could not find raster band of index 1 when getting pixel value. Returning NULL
+NOTICE:  Raster provided has no bands
+NOTICE:  Raster provided has no bands
+NOTICE:  Raster provided has no bands
+NOTICE:  Could not find raster band of index 1 when getting pixel value. Returning NULL
+NOTICE:  Could not find raster band of index 1 when getting pixel value. Returning NULL
+NOTICE:  Raster provided has no bands
+NOTICE:  Raster provided has no bands
+NOTICE:  Raster provided has no bands
+NOTICE:  Could not find raster band of index 1 when getting pixel value. Returning NULL
+NOTICE:  Could not find raster band of index 1 when getting pixel value. Returning NULL
+NOTICE:  Raster provided has no bands
+NOTICE:  Raster provided has no bands
+NOTICE:  Raster provided has no bands
+NOTICE:  Could not find raster band of index 1 when getting pixel value. Returning NULL
+NOTICE:  Could not find raster band of index 1 when getting pixel value. Returning NULL
+NOTICE:  Raster provided has no bands
+NOTICE:  Raster provided has no bands
+NOTICE:  Raster provided has no bands
+NOTICE:  Could not find raster band of index 1 when getting pixel value. Returning NULL
+NOTICE:  Could not find raster band of index 1 when getting pixel value. Returning NULL
+0|1|INTERSECTION|0.000|0.000|2|2|1.000|1.000|0.000|0.000|0|1|32BF|t|0.000|1.000|1.000
+0|2|INTERSECTION|1.000|-1.000|1|2|1.000|1.000|0.000|0.000|0|1|32BF|t|0.000|1.000|1.000
+0|3|INTERSECTION|1.000|1.000|1|1|1.000|1.000|0.000|0.000|0|1|32BF|t|0.000|1.000|1.000
+0|4|INTERSECTION|0.000|0.000|0|0|0.000|0.000|0.000|0.000|0|0|||||
+10|11|INTERSECTION|0.000|0.000|2|2|1.000|1.000|1.000|-1.000|0|1|32BF|t|0.000|1.000|1.000
+10|12|INTERSECTION|1.000|-1.000|2|2|1.000|1.000|1.000|-1.000|0|1|32BF|t|0.000|1.000|1.000
+10|13|INTERSECTION|1.000|1.000|2|1|1.000|1.000|1.000|-1.000|0|1|32BF|t|0.000|1.000|1.000
+10|14|INTERSECTION|0.000|0.000|0|0|0.000|0.000|0.000|0.000|0|0|||||
+|0|INTERSECTION|0.000|0.000|0|0|0.000|0.000|0.000|0.000|0|0|||||
+|1|INTERSECTION|0.000|0.000|0|0|0.000|0.000|0.000|0.000|0|0|||||
+|2|INTERSECTION|0.000|0.000|0|0|0.000|0.000|0.000|0.000|0|0|||||
+|3|INTERSECTION|0.000|0.000|0|0|0.000|0.000|0.000|0.000|0|0|||||
+|4|INTERSECTION|0.000|0.000|0|0|0.000|0.000|0.000|0.000|0|0|||||
+|10|INTERSECTION|0.000|0.000|0|0|0.000|0.000|0.000|0.000|0|0|||||
+|11|INTERSECTION|0.000|0.000|0|0|0.000|0.000|0.000|0.000|0|0|||||
+|12|INTERSECTION|0.000|0.000|0|0|0.000|0.000|0.000|0.000|0|0|||||
+|13|INTERSECTION|0.000|0.000|0|0|0.000|0.000|0.000|0.000|0|0|||||
+|14|INTERSECTION|0.000|0.000|0|0|0.000|0.000|0.000|0.000|0|0|||||
+0||INTERSECTION|0.000|0.000|0|0|0.000|0.000|0.000|0.000|0|0|||||
+1||INTERSECTION|0.000|0.000|0|0|0.000|0.000|0.000|0.000|0|0|||||
+2||INTERSECTION|0.000|0.000|0|0|0.000|0.000|0.000|0.000|0|0|||||
+3||INTERSECTION|0.000|0.000|0|0|0.000|0.000|0.000|0.000|0|0|||||
+4||INTERSECTION|0.000|0.000|0|0|0.000|0.000|0.000|0.000|0|0|||||
+10||INTERSECTION|0.000|0.000|0|0|0.000|0.000|0.000|0.000|0|0|||||
+11||INTERSECTION|0.000|0.000|0|0|0.000|0.000|0.000|0.000|0|0|||||
+12||INTERSECTION|0.000|0.000|0|0|0.000|0.000|0.000|0.000|0|0|||||
+13||INTERSECTION|0.000|0.000|0|0|0.000|0.000|0.000|0.000|0|0|||||
+14||INTERSECTION|0.000|0.000|0|0|0.000|0.000|0.000|0.000|0|0|||||
+||INTERSECTION|||||||||||||||
+0|1|UNION|-2.000|-2.000|4|4|1.000|1.000|0.000|0.000|0|1|32BF|t|0.000|1.000|1.500
+0|2|UNION|-2.000|-2.000|5|4|1.000|1.000|0.000|0.000|0|1|32BF|t|0.000|1.000|
+0|3|UNION|-2.000|-2.000|5|5|1.000|1.000|0.000|0.000|0|1|32BF|t|0.000|1.000|4.000
+0|4|UNION|-2.000|-2.000|6|6|1.000|1.000|0.000|0.000|0|1|32BF|t|0.000|1.000|5.000
+10|11|UNION|-2.000|-2.000|4|4|1.000|1.000|1.000|-1.000|0|1|32BF|t|0.000|1.000|1.000
+10|12|UNION|-2.000|-2.000|4|4|1.000|1.000|1.000|-1.000|0|1|32BF|t|0.000|1.000|1.000
+10|13|UNION|-2.000|-2.000|4|5|1.000|1.000|1.000|-1.000|0|1|32BF|t|0.000|1.000|
+10|14|UNION|-2.000|-2.000|4|6|1.000|1.000|1.000|-1.000|0|1|32BF|t|0.000|1.000|
+|0|UNION|-2.000|-2.000|4|4|1.000|1.000|0.000|0.000|0|1|32BF|t|0.000|1.000|1.000
+|1|UNION|0.000|0.000|2|2|1.000|1.000|0.000|0.000|0|1|32BF|t|0.000|2.000|2.000
+|2|UNION|1.000|-1.000|2|2|1.000|1.000|0.000|0.000|0|1|32BF|t|0.000|3.000|3.000
+|3|UNION|1.000|1.000|2|2|1.000|1.000|0.000|0.000|0|1|32BF|t|0.000|4.000|4.000
+|4|UNION|2.000|2.000|2|2|1.000|1.000|0.000|0.000|0|1|32BF|t|0.000|5.000|5.000
+|10|UNION|-2.000|-2.000|4|4|1.000|1.000|1.000|-1.000|0|1|32BF|t|0.000|1.000|1.000
+|11|UNION|0.000|0.000|2|2|1.000|1.000|1.000|-1.000|0|1|32BF|t|0.000|2.000|2.000
+|12|UNION|1.000|-1.000|2|2|1.000|1.000|1.000|-1.000|0|1|32BF|t|0.000|3.000|3.000
+|13|UNION|1.000|1.000|2|2|1.000|1.000|1.000|-1.000|0|1|32BF|t|0.000|4.000|4.000
+|14|UNION|2.000|2.000|2|2|1.000|1.000|1.000|-1.000|0|1|32BF|t|0.000|5.000|5.000
+0||UNION|-2.000|-2.000|4|4|1.000|1.000|0.000|0.000|0|1|32BF|t|0.000|1.000|1.000
+1||UNION|0.000|0.000|2|2|1.000|1.000|0.000|0.000|0|1|32BF|t|0.000|2.000|2.000
+2||UNION|1.000|-1.000|2|2|1.000|1.000|0.000|0.000|0|1|32BF|t|0.000|3.000|3.000
+3||UNION|1.000|1.000|2|2|1.000|1.000|0.000|0.000|0|1|32BF|t|0.000|4.000|4.000
+4||UNION|2.000|2.000|2|2|1.000|1.000|0.000|0.000|0|1|32BF|t|0.000|5.000|5.000
+10||UNION|-2.000|-2.000|4|4|1.000|1.000|1.000|-1.000|0|1|32BF|t|0.000|1.000|1.000
+11||UNION|0.000|0.000|2|2|1.000|1.000|1.000|-1.000|0|1|32BF|t|0.000|2.000|2.000
+12||UNION|1.000|-1.000|2|2|1.000|1.000|1.000|-1.000|0|1|32BF|t|0.000|3.000|3.000
+13||UNION|1.000|1.000|2|2|1.000|1.000|1.000|-1.000|0|1|32BF|t|0.000|4.000|4.000
+14||UNION|2.000|2.000|2|2|1.000|1.000|1.000|-1.000|0|1|32BF|t|0.000|5.000|5.000
+||UNION|||||||||||||||
+0|1|FIRST|-2.000|-2.000|4|4|1.000|1.000|0.000|0.000|0|1|32BF|t|0.000|1.000|
+0|2|FIRST|-2.000|-2.000|4|4|1.000|1.000|0.000|0.000|0|1|32BF|t|0.000|1.000|1.000
+0|3|FIRST|-2.000|-2.000|4|4|1.000|1.000|0.000|0.000|0|1|32BF|t|0.000|1.000|
+0|4|FIRST|-2.000|-2.000|4|4|1.000|1.000|0.000|0.000|0|1|32BF|t|0.000|1.000|1.000
+10|11|FIRST|-2.000|-2.000|4|4|1.000|1.000|1.000|-1.000|0|1|32BF|t|0.000|1.000|1.000
+10|12|FIRST|-2.000|-2.000|4|4|1.000|1.000|1.000|-1.000|0|1|32BF|t|0.000|1.000|1.000
+10|13|FIRST|-2.000|-2.000|4|4|1.000|1.000|1.000|-1.000|0|1|32BF|t|0.000|1.000|1.000
+10|14|FIRST|-2.000|-2.000|4|4|1.000|1.000|1.000|-1.000|0|1|32BF|t|0.000|1.000|1.000
+|0|FIRST|||||||||||||||
+|1|FIRST|||||||||||||||
+|2|FIRST|||||||||||||||
+|3|FIRST|||||||||||||||
+|4|FIRST|||||||||||||||
+|10|FIRST|||||||||||||||
+|11|FIRST|||||||||||||||
+|12|FIRST|||||||||||||||
+|13|FIRST|||||||||||||||
+|14|FIRST|||||||||||||||
+0||FIRST|-2.000|-2.000|4|4|1.000|1.000|0.000|0.000|0|1|32BF|t|0.000|1.000|1.000
+1||FIRST|0.000|0.000|2|2|1.000|1.000|0.000|0.000|0|1|32BF|t|0.000|2.000|2.000
+2||FIRST|1.000|-1.000|2|2|1.000|1.000|0.000|0.000|0|1|32BF|t|0.000|3.000|3.000
+3||FIRST|1.000|1.000|2|2|1.000|1.000|0.000|0.000|0|1|32BF|t|0.000|4.000|4.000
+4||FIRST|2.000|2.000|2|2|1.000|1.000|0.000|0.000|0|1|32BF|t|0.000|5.000|5.000
+10||FIRST|-2.000|-2.000|4|4|1.000|1.000|1.000|-1.000|0|1|32BF|t|0.000|1.000|1.000
+11||FIRST|0.000|0.000|2|2|1.000|1.000|1.000|-1.000|0|1|32BF|t|0.000|2.000|2.000
+12||FIRST|1.000|-1.000|2|2|1.000|1.000|1.000|-1.000|0|1|32BF|t|0.000|3.000|3.000
+13||FIRST|1.000|1.000|2|2|1.000|1.000|1.000|-1.000|0|1|32BF|t|0.000|4.000|4.000
+14||FIRST|2.000|2.000|2|2|1.000|1.000|1.000|-1.000|0|1|32BF|t|0.000|5.000|5.000
+||FIRST|||||||||||||||
+0|1|SECOND|0.000|0.000|2|2|1.000|1.000|0.000|0.000|0|1|32BF|t|0.000||
+0|2|SECOND|1.000|-1.000|2|2|1.000|1.000|0.000|0.000|0|1|32BF|t|0.000||3.000
+0|3|SECOND|1.000|1.000|2|2|1.000|1.000|0.000|0.000|0|1|32BF|t|0.000||4.000
+0|4|SECOND|2.000|2.000|2|2|1.000|1.000|0.000|0.000|0|1|32BF|t|0.000|5.000|5.000
+10|11|SECOND|0.000|0.000|2|2|1.000|1.000|1.000|-1.000|0|1|32BF|t|0.000||
+10|12|SECOND|1.000|-1.000|2|2|1.000|1.000|1.000|-1.000|0|1|32BF|t|0.000||
+10|13|SECOND|1.000|1.000|2|2|1.000|1.000|1.000|-1.000|0|1|32BF|t|0.000||4.000
+10|14|SECOND|2.000|2.000|2|2|1.000|1.000|1.000|-1.000|0|1|32BF|t|0.000|5.000|5.000
+|0|SECOND|-2.000|-2.000|4|4|1.000|1.000|0.000|0.000|0|1|32BF|t|0.000|1.000|1.000
+|1|SECOND|0.000|0.000|2|2|1.000|1.000|0.000|0.000|0|1|32BF|t|0.000|2.000|2.000
+|2|SECOND|1.000|-1.000|2|2|1.000|1.000|0.000|0.000|0|1|32BF|t|0.000|3.000|3.000
+|3|SECOND|1.000|1.000|2|2|1.000|1.000|0.000|0.000|0|1|32BF|t|0.000|4.000|4.000
+|4|SECOND|2.000|2.000|2|2|1.000|1.000|0.000|0.000|0|1|32BF|t|0.000|5.000|5.000
+|10|SECOND|-2.000|-2.000|4|4|1.000|1.000|1.000|-1.000|0|1|32BF|t|0.000|1.000|1.000
+|11|SECOND|0.000|0.000|2|2|1.000|1.000|1.000|-1.000|0|1|32BF|t|0.000|2.000|2.000
+|12|SECOND|1.000|-1.000|2|2|1.000|1.000|1.000|-1.000|0|1|32BF|t|0.000|3.000|3.000
+|13|SECOND|1.000|1.000|2|2|1.000|1.000|1.000|-1.000|0|1|32BF|t|0.000|4.000|4.000
+|14|SECOND|2.000|2.000|2|2|1.000|1.000|1.000|-1.000|0|1|32BF|t|0.000|5.000|5.000
+0||SECOND|||||||||||||||
+1||SECOND|||||||||||||||
+2||SECOND|||||||||||||||
+3||SECOND|||||||||||||||
+4||SECOND|||||||||||||||
+10||SECOND|||||||||||||||
+11||SECOND|||||||||||||||
+12||SECOND|||||||||||||||
+13||SECOND|||||||||||||||
+14||SECOND|||||||||||||||
+||SECOND|||||||||||||||