]> granicus.if.org Git - postgis/commitdiff
Added 2-raster expression variant of ST_MapAlgebra() and regression
authorBborie Park <bkpark at ucdavis.edu>
Tue, 16 Oct 2012 19:55:50 +0000 (19:55 +0000)
committerBborie Park <bkpark at ucdavis.edu>
Tue, 16 Oct 2012 19:55:50 +0000 (19:55 +0000)
tests.

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

raster/rt_pg/rt_pg.c
raster/rt_pg/rtpostgis.sql.in.c
raster/test/regress/rt_mapalgebra_expr.sql
raster/test/regress/rt_mapalgebra_expr_expected

index 44670aefaa0950e97ae37a9d3ec5275c49375a99..2c8c4efde13590021b7b6ee891a4fb5029bc1852 100644 (file)
@@ -14146,13 +14146,12 @@ Datum RASTER_nMapAlgebra(PG_FUNCTION_ARGS)
                        elog(NOTICE, "Function provided is VOLATILE. Unless required and for best performance, function should be IMMUTABLE or STABLE");
 
                /* prep function call data */
-#if POSTGIS_PGSQL_VERSION > 90 
+#if POSTGIS_PGSQL_VERSION > 90
                InitFunctionCallInfoData(arg->callback.ufc_info, &(arg->callback.ufl_info), arg->callback.ufl_info.fn_nargs, InvalidOid, NULL, NULL);
-#else  
+#else
                InitFunctionCallInfoData(arg->callback.ufc_info, &(arg->callback.ufl_info), arg->callback.ufl_info.fn_nargs, NULL, NULL);
 #endif
                memset(arg->callback.ufc_info.argnull, FALSE, arg->callback.ufl_info.fn_nargs);
-               
 
                /* userargs (7) */
                if (!PG_ARGISNULL(7))
index fd57d56e8f973b84c246c3082df0fa690559825d..820e1567597cfc9b39feef8a7978cc1cfeded4bf 100644 (file)
@@ -2625,6 +2625,10 @@ CREATE OR REPLACE FUNCTION st_mapalgebra(
        AS $$ SELECT _ST_MapAlgebra(ARRAY[ROW($1, $2), ROW($3, $4)]::rastbandarg[], $5, $6, $9, $10, $7, $8, VARIADIC $11) $$
        LANGUAGE 'sql' STABLE;
 
+-----------------------------------------------------------------------
+-- n-Raster ST_MapAlgebra with expressions
+-----------------------------------------------------------------------
+
 CREATE OR REPLACE FUNCTION st_mapalgebra(
        rast raster, nband integer,
        pixeltype text,
@@ -2643,18 +2647,22 @@ CREATE OR REPLACE FUNCTION st_mapalgebra(
                funcname := 'pg_temp.callbackfunc' || (round(random() * 1000000))::text;
 
                -- substitute keywords
-               expr := replace(expression, '[rast]', ''' || value[1][1][1] || ''');
-               expr := replace(expr, '[rast.val]', ''' || value[1][1][1] || ''');
-               expr := replace(expr, '[rast.x]', ''' || pos[1][1] || ''');
-               expr := replace(expr, '[rast.y]', ''' || pos[1][2] || ''');
+               IF expression IS NOT NULL THEN
+                       expr := replace(expression, '[rast]', ''' || value[1][1][1] || ''');
+                       expr := replace(expr, '[rast.val]', ''' || value[1][1][1] || ''');
+                       expr := replace(expr, '[rast.x]', ''' || pos[1][1] || ''');
+                       expr := replace(expr, '[rast.y]', ''' || pos[1][2] || ''');
+               ELSE
+                       expr := NULL;
+               END IF;
 
                -- build callback function body
                funcbody := ' DECLARE val double precision; BEGIN';
                --funcbody := funcbody || ' RAISE NOTICE ''value = %'', value;';
                --funcbody := funcbody || ' RAISE NOTICE ''pos = %'', pos;';
-               funcbody := funcbody || ' IF value[1][1][1] IS NULL THEN';
 
                -- handle NODATA in callback function
+               funcbody := funcbody || ' IF value[1][1][1] IS NULL THEN';
                IF nodataval IS NOT NULL THEN
                        funcbody := funcbody || ' RETURN ' || nodataval::text || ';';
                ELSE
@@ -2663,7 +2671,11 @@ CREATE OR REPLACE FUNCTION st_mapalgebra(
                funcbody := funcbody || ' END IF;';
 
                -- handle value processing in callback function
-               funcbody := funcbody || ' EXECUTE ''SELECT (' || expr || ')::double precision'' INTO val;';
+               IF expr IS NOT NULL THEN
+                       funcbody := funcbody || ' EXECUTE ''SELECT (' || expr || ')::double precision'' INTO val;';
+               ELSE
+                       funcbody := funcbody || ' val := NULL;';
+               END IF;
 
                -- handle val is NULL
                IF nodataval IS NOT NULL THEN
@@ -2704,6 +2716,138 @@ CREATE OR REPLACE FUNCTION st_mapalgebra(
        AS $$ SELECT st_mapalgebra($1, 1, $2, $3, $4) $$
        LANGUAGE 'sql' VOLATILE;
 
+CREATE OR REPLACE FUNCTION st_mapalgebra(
+       rast1 raster, band1 integer,
+       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
+)
+       RETURNS raster
+       AS $$
+       DECLARE
+               rtn raster;
+               funcname text;
+               funcbody text;
+               funccmd text;
+               expr text;
+               nd1expr text;
+               nd2expr text;
+       BEGIN
+               -- set name of callback function
+               funcname := 'pg_temp.callbackfunc' || (round(random() * 1000000))::text;
+
+               -- substitute keywords
+               -- expression
+               IF expression IS NOT NULL THEN
+                       expr := replace(expression, '[rast1]', ''' || value[1][1][1] || ''');
+                       expr := replace(expr, '[rast1.val]', ''' || value[1][1][1] || ''');
+                       expr := replace(expr, '[rast1.x]', ''' || pos[1][1] || ''');
+                       expr := replace(expr, '[rast1.y]', ''' || pos[1][2] || ''');
+
+                       expr := replace(expr, '[rast2]', ''' || value[2][1][1] || ''');
+                       expr := replace(expr, '[rast2.val]', ''' || value[2][1][1] || ''');
+                       expr := replace(expr, '[rast2.x]', ''' || pos[2][1] || ''');
+                       expr := replace(expr, '[rast2.y]', ''' || pos[2][2] || ''');
+               ELSE
+                       expr := NULL;
+               END IF;
+
+               -- nodata1expr
+               IF nodata1expr IS NOT NULL THEN
+                       nd1expr := replace(nodata1expr, '[rast2]', ''' || value[2][1][1] || ''');
+                       nd1expr := replace(nd1expr, '[rast2.val]', ''' || value[2][1][1] || ''');
+                       nd1expr := replace(nd1expr, '[rast2.x]', ''' || pos[2][1] || ''');
+                       nd1expr := replace(nd1expr, '[rast2.y]', ''' || pos[2][2] || ''');
+               END IF;
+
+               -- nodata2expr
+               IF nodata2expr IS NOT NULL THEN
+                       nd2expr := replace(nodata2expr, '[rast1]', ''' || value[1][1][1] || ''');
+                       nd2expr := replace(nd2expr, '[rast1.val]', ''' || value[1][1][1] || ''');
+                       nd2expr := replace(nd2expr, '[rast1.x]', ''' || pos[1][1] || ''');
+                       nd2expr := replace(nd2expr, '[rast1.y]', ''' || pos[1][2] || ''');
+               END IF;
+
+               -- build callback function body
+               funcbody := ' DECLARE val double precision; BEGIN';
+               --funcbody := funcbody || ' RAISE NOTICE ''value = %'', value;';
+               --funcbody := funcbody || ' RAISE NOTICE ''pos = %'', pos;';
+
+               -- handle both NODATA in callback function
+               funcbody := funcbody || ' IF value[1][1][1] IS NULL AND value[2][1][1] IS NULL THEN';
+               IF nodatanodataval IS NOT NULL THEN
+                       funcbody := funcbody || ' RETURN ' || nodatanodataval::text || ';';
+               ELSE
+                       funcbody := funcbody || ' RETURN NULL;';
+               END IF;
+               funcbody := funcbody || ' END IF;';
+
+               -- handle first NODATA in callback function
+               funcbody := funcbody || ' IF value[1][1][1] IS NULL AND value[2][1][1] IS NOT NULL THEN';
+               IF nodata1expr IS NOT NULL THEN
+                       funcbody := funcbody || ' EXECUTE ''SELECT (' || nd1expr || ')::double precision'' INTO val;';
+                       funcbody := funcbody || ' RETURN val;';
+               ELSE
+                       funcbody := funcbody || ' RETURN NULL;';
+               END IF;
+               funcbody := funcbody || ' END IF;';
+
+               -- handle second NODATA in callback function
+               funcbody := funcbody || ' IF value[1][1][1] IS NOT NULL AND value[2][1][1] IS NULL THEN';
+               IF nodata2expr IS NOT NULL THEN
+                       funcbody := funcbody || ' EXECUTE ''SELECT (' || nd2expr || ')::double precision'' INTO val;';
+                       funcbody := funcbody || ' RETURN val;';
+               ELSE
+                       funcbody := funcbody || ' RETURN NULL;';
+               END IF;
+               funcbody := funcbody || ' END IF;';
+
+               -- handle value processing in callback function
+               IF expr IS NOT NULL THEN
+                       funcbody := funcbody || ' EXECUTE ''SELECT (' || expr || ')::double precision'' INTO val;';
+               ELSE
+                       funcbody := funcbody || ' val := NULL;';
+               END IF;
+
+               -- finish callback function
+               funcbody := funcbody || ' RETURN val; END;';
+
+               funccmd := 'CREATE OR REPLACE FUNCTION ' || funcname
+                       || '(value double precision[][][], pos integer[][], VARIADIC userargs text[] DEFAULT NULL)'
+                       || ' RETURNS double precision AS '
+                       || quote_literal(funcbody)
+                       || ' LANGUAGE ''plpgsql'' STABLE;';
+
+               --RAISE NOTICE 'funccmd = %', funccmd;
+
+               -- create callback function
+               EXECUTE funccmd;
+
+               -- call ST_MapAlgebra
+               rtn := ST_MapAlgebra(ARRAY[ROW($1, $2), ROW($3, $4)]::rastbandarg[], (funcname || '(double precision[][][], integer[][], text[])')::regprocedure, $6, $7);
+
+               -- drop callback function
+               EXECUTE 'DROP FUNCTION IF EXISTS ' || funcname
+                       || '(double precision[][][], integer[][], text[]);';
+
+               RETURN rtn;
+       END;
+       $$ LANGUAGE 'plpgsql' VOLATILE;
+
+CREATE OR REPLACE FUNCTION st_mapalgebra(
+       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
+)
+       RETURNS raster
+       AS $$ SELECT st_mapalgebra($1, 1, $2, 1, $3, $4, $5, $6, $7, $8) $$
+       LANGUAGE 'sql' VOLATILE;
+
 -----------------------------------------------------------------------
 -- ST_MapAlgebra callback functions
 -- Should be called with values for distancex and distancey
index 41fa4619017743cb3d3d78951b5940176b576a58..b12b975371f4a4744fffd639bd3e2380374192f6 100644 (file)
@@ -162,3 +162,276 @@ DROP FUNCTION raster_polynomial(pixel FLOAT, VARIADIC args TEXT[]);
 DROP FUNCTION raster_nullage(pixel FLOAT, VARIADIC args TEXT[]);
 DROP FUNCTION raster_x_plus_arg(pixel FLOAT, pos INT[], VARIADIC args TEXT[]);
 DROP FUNCTION raster_y_plus_arg(pixel FLOAT, pos INT[], VARIADIC args TEXT[]);
+
+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 make_test_raster(integer, integer, integer, double precision, double precision, double precision, double precision, double precision, double precision);
+
+-- INTERSECTION
+INSERT INTO raster_mapalgebra_out
+       (SELECT r1.rid, r2.rid, 'INTERSECTION', st_mapalgebra(
+               r1.rast, r2.rast, '[rast1.val]', '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_mapalgebra(
+               r1.rast, r2.rast, '[rast1.val]', '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_mapalgebra(
+               NULL::raster, rast, '[rast1.val]', '32BF', 'INTERSECTION'
+       )
+       FROM raster_mapalgebra
+;
+
+INSERT INTO raster_mapalgebra_out
+       SELECT rid, NULL AS rid, 'INTERSECTION', st_mapalgebra(
+               rast, NULL::raster, '[rast1.val]', '32BF', 'INTERSECTION'
+       )
+       FROM raster_mapalgebra
+;
+
+INSERT INTO raster_mapalgebra_out
+       SELECT NULL AS rid, NULL AS rid, 'INTERSECTION', st_mapalgebra(
+               NULL::raster, NULL::raster, '[rast1.val]', '32BF', 'INTERSECTION'
+       )
+;
+
+-- UNION
+INSERT INTO raster_mapalgebra_out
+       (SELECT r1.rid, r2.rid, 'UNION', st_mapalgebra(
+               r1.rast, r2.rast, '(([rast1.val] + [rast2.val])/2.)::numeric', '32BF', 'UNION', '[rast2.val]', '[rast1.val]', NULL
+       )
+       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_mapalgebra(
+               r1.rast, r2.rast, '(([rast1.val] + [rast2.val])/2.)::numeric', '32BF', 'UNION', '[rast2.val]', '[rast1.val]', NULL
+       )
+       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 r1.rid, r2.rid, 'UNION', st_mapalgebra(
+               r1.rast, r2.rast, '(([rast1.val] + [rast2.val])/2.)::numeric', '32BF', 'UNION', '100', '200', NULL
+       )
+       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_mapalgebra(
+               r1.rast, r2.rast, '(([rast1.val] + [rast2.val])/2.)::numeric', '32BF', 'UNION', '100', '200', NULL
+       )
+       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_mapalgebra(
+               NULL::raster, rast, '(([rast1.val] + [rast2.val])/2.)::numeric', '32BF', 'UNION', '[rast2.val]', '[rast1.val]', NULL
+       )
+       FROM raster_mapalgebra
+;
+
+INSERT INTO raster_mapalgebra_out
+       SELECT rid, NULL AS rid, 'UNION', st_mapalgebra(
+               rast, NULL::raster, '(([rast1.val] + [rast2.val])/2.)::numeric', '32BF', 'UNION', '[rast2.val]', '[rast1.val]', NULL
+       )
+       FROM raster_mapalgebra
+;
+
+INSERT INTO raster_mapalgebra_out
+       SELECT NULL AS rid, NULL AS rid, 'UNION', st_mapalgebra(
+               NULL::raster, NULL::raster, '(([rast1.val] + [rast2.val])/2.)::numeric', '32BF', 'UNION', '[rast2.val]', '[rast1.val]', NULL
+       )
+;
+
+-- FIRST
+INSERT INTO raster_mapalgebra_out
+       (SELECT r1.rid, r2.rid, 'FIRST', st_mapalgebra(
+               r1.rast, r2.rast, 'CASE WHEN [rast2.val] IS NOT NULL THEN NULL ELSE [rast1.val] END', '32BF', 'FIRST', NULL, '[rast1.val]', NULL
+       )
+       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_mapalgebra(
+               r1.rast, r2.rast, 'CASE WHEN [rast2.val] IS NOT NULL THEN NULL ELSE [rast1.val] END', '32BF', 'FIRST', NULL, '[rast1.val]', NULL
+       )
+       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_mapalgebra(
+               NULL::raster, rast, 'CASE WHEN [rast1.val] IS NOT NULL THEN NULL ELSE [rast2.val] END', '32BF', 'FIRST', '[rast2.val]', NULL, NULL
+       )
+       FROM raster_mapalgebra
+;
+
+INSERT INTO raster_mapalgebra_out
+       SELECT rid, NULL AS rid, 'FIRST', st_mapalgebra(
+               rast, NULL::raster, 'CASE WHEN [rast2.val] IS NOT NULL THEN NULL ELSE [rast1.val] END', '32BF', 'FIRST', NULL, '[rast1.val]', NULL
+       )
+       FROM raster_mapalgebra
+;
+
+INSERT INTO raster_mapalgebra_out
+       SELECT NULL AS rid, NULL AS rid, 'FIRST', st_mapalgebra(
+               NULL::raster, NULL::raster, 'CASE WHEN [rast2.val] IS NOT NULL THEN NULL ELSE [rast1.val] END', '32BF', 'FIRST', NULL, '[rast1.val]', NULL
+       )
+;
+
+-- SECOND
+INSERT INTO raster_mapalgebra_out
+       (SELECT r1.rid, r2.rid, 'SECOND', st_mapalgebra(
+               r1.rast, r2.rast, 'CASE WHEN [rast1.val] IS NOT NULL THEN NULL ELSE [rast2.val] END', '32BF', 'SECOND', '[rast2.val]', NULL, NULL
+       )
+       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_mapalgebra(
+               r1.rast, r2.rast, 'CASE WHEN [rast1.val] IS NOT NULL THEN NULL ELSE [rast2.val] END', '32BF', 'SECOND', '[rast2.val]', NULL, NULL
+       )
+       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_mapalgebra(
+               NULL::raster, rast, 'CASE WHEN [rast1.val] IS NOT NULL THEN NULL ELSE [rast2.val] END', '32BF', 'SECOND', '[rast2.val]', NULL, NULL
+       )
+       FROM raster_mapalgebra
+;
+
+INSERT INTO raster_mapalgebra_out
+       SELECT rid, NULL AS rid, 'SECOND', st_mapalgebra(
+               rast, NULL::raster, 'CASE WHEN [rast1.val] IS NOT NULL THEN NULL ELSE [rast2.val] END', '32BF', 'SECOND', '[rast2.val]', NULL, NULL
+       )
+       FROM raster_mapalgebra
+;
+
+INSERT INTO raster_mapalgebra_out
+       SELECT NULL AS rid, NULL AS rid, 'SECOND', st_mapalgebra(
+               NULL::raster, NULL::raster, 'CASE WHEN [rast1.val] IS NOT NULL THEN NULL ELSE [rast2.val] END', '32BF', 'SECOND', '[rast2.val]', NULL, NULL
+       )
+;
+
+-- 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,
+       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 TABLE IF EXISTS raster_mapalgebra;
+DROP TABLE IF EXISTS raster_mapalgebra_out;
index 9eb5fd3638090965b054f0c52e433ef08b5adf92..9e7a50ab1d278c21771adecaab179b645a94e487 100644 (file)
@@ -21,3 +21,127 @@ ERROR:  division by zero
 T11.1|10|2
 T11.2|10|2
 T12|t|t|t|t
+0|1|INTERSECTION|0.000|0.000|2|2|1.000|1.000|0.000|0.000|0|1|32BF|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|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|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|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|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|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|-2.000|-2.000|4|4|1.000|1.000|0.000|0.000|0|1|32BF|0.000||
+|1|INTERSECTION|0.000|0.000|2|2|1.000|1.000|0.000|0.000|0|1|32BF|0.000||
+|2|INTERSECTION|1.000|-1.000|2|2|1.000|1.000|0.000|0.000|0|1|32BF|0.000||
+|3|INTERSECTION|1.000|1.000|2|2|1.000|1.000|0.000|0.000|0|1|32BF|0.000||
+|4|INTERSECTION|2.000|2.000|2|2|1.000|1.000|0.000|0.000|0|1|32BF|0.000||
+|10|INTERSECTION|-2.000|-2.000|4|4|1.000|1.000|1.000|-1.000|0|1|32BF|0.000||
+|11|INTERSECTION|0.000|0.000|2|2|1.000|1.000|1.000|-1.000|0|1|32BF|0.000||
+|12|INTERSECTION|1.000|-1.000|2|2|1.000|1.000|1.000|-1.000|0|1|32BF|0.000||
+|13|INTERSECTION|1.000|1.000|2|2|1.000|1.000|1.000|-1.000|0|1|32BF|0.000||
+|14|INTERSECTION|2.000|2.000|2|2|1.000|1.000|1.000|-1.000|0|1|32BF|0.000||
+0||INTERSECTION|-2.000|-2.000|4|4|1.000|1.000|0.000|0.000|0|1|32BF|0.000||
+1||INTERSECTION|0.000|0.000|2|2|1.000|1.000|0.000|0.000|0|1|32BF|0.000||
+2||INTERSECTION|1.000|-1.000|2|2|1.000|1.000|0.000|0.000|0|1|32BF|0.000||
+3||INTERSECTION|1.000|1.000|2|2|1.000|1.000|0.000|0.000|0|1|32BF|0.000||
+4||INTERSECTION|2.000|2.000|2|2|1.000|1.000|0.000|0.000|0|1|32BF|0.000||
+10||INTERSECTION|-2.000|-2.000|4|4|1.000|1.000|1.000|-1.000|0|1|32BF|0.000||
+11||INTERSECTION|0.000|0.000|2|2|1.000|1.000|1.000|-1.000|0|1|32BF|0.000||
+12||INTERSECTION|1.000|-1.000|2|2|1.000|1.000|1.000|-1.000|0|1|32BF|0.000||
+13||INTERSECTION|1.000|1.000|2|2|1.000|1.000|1.000|-1.000|0|1|32BF|0.000||
+14||INTERSECTION|2.000|2.000|2|2|1.000|1.000|1.000|-1.000|0|1|32BF|0.000||
+||INTERSECTION||||||||||||||
+0|1|UNION|-2.000|-2.000|4|4|1.000|1.000|0.000|0.000|0|1|32BF|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|0.000|1.000|
+0|3|UNION|-2.000|-2.000|5|5|1.000|1.000|0.000|0.000|0|1|32BF|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|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|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|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|0.000|1.000|
+10|14|UNION|-2.000|-2.000|4|6|1.000|1.000|1.000|-1.000|0|1|32BF|0.000|1.000|
+0|1|UNION|-2.000|-2.000|4|4|1.000|1.000|0.000|0.000|0|1|32BF|0.000|200.000|1.500
+0|2|UNION|-2.000|-2.000|5|4|1.000|1.000|0.000|0.000|0|1|32BF|0.000|200.000|
+0|3|UNION|-2.000|-2.000|5|5|1.000|1.000|0.000|0.000|0|1|32BF|0.000|200.000|100.000
+0|4|UNION|-2.000|-2.000|6|6|1.000|1.000|0.000|0.000|0|1|32BF|0.000|200.000|100.000
+10|11|UNION|-2.000|-2.000|4|4|1.000|1.000|1.000|-1.000|0|1|32BF|0.000|200.000|200.000
+10|12|UNION|-2.000|-2.000|4|4|1.000|1.000|1.000|-1.000|0|1|32BF|0.000|200.000|200.000
+10|13|UNION|-2.000|-2.000|4|5|1.000|1.000|1.000|-1.000|0|1|32BF|0.000|200.000|
+10|14|UNION|-2.000|-2.000|4|6|1.000|1.000|1.000|-1.000|0|1|32BF|0.000|200.000|
+|0|UNION|-2.000|-2.000|4|4|1.000|1.000|0.000|0.000|0|1|32BF|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|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|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|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|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|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|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|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|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|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|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|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|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|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|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|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|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|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|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|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|0.000|1.000|
+0|2|FIRST|-2.000|-2.000|4|4|1.000|1.000|0.000|0.000|0|1|32BF|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|0.000|1.000|
+0|4|FIRST|-2.000|-2.000|4|4|1.000|1.000|0.000|0.000|0|1|32BF|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|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|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|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|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|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|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|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|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|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|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|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|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|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|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|0.000||
+0|2|SECOND|1.000|-1.000|2|2|1.000|1.000|0.000|0.000|0|1|32BF|0.000||3.000
+0|3|SECOND|1.000|1.000|2|2|1.000|1.000|0.000|0.000|0|1|32BF|0.000||4.000
+0|4|SECOND|2.000|2.000|2|2|1.000|1.000|0.000|0.000|0|1|32BF|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|0.000||
+10|12|SECOND|1.000|-1.000|2|2|1.000|1.000|1.000|-1.000|0|1|32BF|0.000||
+10|13|SECOND|1.000|1.000|2|2|1.000|1.000|1.000|-1.000|0|1|32BF|0.000||4.000
+10|14|SECOND|2.000|2.000|2|2|1.000|1.000|1.000|-1.000|0|1|32BF|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|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|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|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|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|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|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|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|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|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|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||||||||||||||