mirror of
https://git.osgeo.org/gitea/postgis/postgis
synced 2024-10-24 00:52:40 +00:00
Added support to pass pixel positions of both rasters to user function in 2-raster ST_MapAlgebraFct. This provides similar functionality to the keywords described in #1525.
git-svn-id: http://svn.osgeo.org/postgis/trunk@9052 b70326c6-7e19-0410-871a-916f4a2858ee
This commit is contained in:
parent
86d8c4aeae
commit
90ece61b86
|
@ -8438,10 +8438,10 @@ Datum RASTER_mapAlgebra2(PG_FUNCTION_ARGS)
|
|||
int hasnodatanodataval = 0;
|
||||
double nodatanodataval = 0;
|
||||
|
||||
Oid ufcnoid = InvalidOid;
|
||||
FmgrInfo uflinfo;
|
||||
FunctionCallInfoData ufcinfo;
|
||||
int ufcnullcount = 0;
|
||||
Oid ufc_noid = InvalidOid;
|
||||
FmgrInfo ufl_info;
|
||||
FunctionCallInfoData ufc_info;
|
||||
int ufc_nullcount = 0;
|
||||
|
||||
int idx = 0;
|
||||
uint32_t i = 0;
|
||||
|
@ -8983,24 +8983,29 @@ Datum RASTER_mapAlgebra2(PG_FUNCTION_ARGS)
|
|||
case REGPROCEDUREOID: {
|
||||
POSTGIS_RT_DEBUG(3, "arg 4 is \"userfunction\"!");
|
||||
if (!PG_ARGISNULL(4)) {
|
||||
ufcnullcount = 0;
|
||||
ufcnoid = PG_GETARG_OID(4);
|
||||
ufc_nullcount = 0;
|
||||
ufc_noid = PG_GETARG_OID(4);
|
||||
|
||||
/* get function info */
|
||||
fmgr_info(ufcnoid, &uflinfo);
|
||||
fmgr_info(ufc_noid, &ufl_info);
|
||||
|
||||
/* function cannot return set */
|
||||
err = 0;
|
||||
if (uflinfo.fn_retset) {
|
||||
if (ufl_info.fn_retset) {
|
||||
elog(ERROR, "RASTER_mapAlgebra2: Function provided must return double precision not resultset");
|
||||
err = 1;
|
||||
}
|
||||
/* function should have correct # of args */
|
||||
else if (uflinfo.fn_nargs != 3) {
|
||||
elog(ERROR, "RASTER_mapAlgebra2: Function does not have three input parameters");
|
||||
else if (ufl_info.fn_nargs < 3 || ufl_info.fn_nargs > 4) {
|
||||
elog(ERROR, "RASTER_mapAlgebra2: Function provided must have three or four input parameters");
|
||||
err = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
TODO: consider adding checks of the userfunction parameters
|
||||
should be able to use get_fn_expr_argtype() of fmgr.c
|
||||
*/
|
||||
|
||||
if (err) {
|
||||
for (k = 0; k < set_count; k++) rt_raster_destroy(_rast[k]);
|
||||
rt_raster_destroy(raster);
|
||||
|
@ -9008,25 +9013,29 @@ Datum RASTER_mapAlgebra2(PG_FUNCTION_ARGS)
|
|||
PG_RETURN_NULL();
|
||||
}
|
||||
|
||||
if (func_volatile(ufcnoid) == 'v') {
|
||||
if (func_volatile(ufc_noid) == 'v') {
|
||||
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
|
||||
InitFunctionCallInfoData(ufcinfo, &uflinfo, 3, InvalidOid, NULL);
|
||||
InitFunctionCallInfoData(ufc_info, &ufl_info, ufl_info.fn_nargs, InvalidOid, NULL);
|
||||
#else
|
||||
InitFunctionCallInfoData(ufcinfo, &uflinfo, 3, InvalidOid, NULL, NULL);
|
||||
InitFunctionCallInfoData(ufc_info, &ufl_info, ufl_info.fn_nargs, InvalidOid, NULL, NULL);
|
||||
#endif
|
||||
memset(ufcinfo.argnull, FALSE, 3);
|
||||
memset(ufc_info.argnull, FALSE, ufl_info.fn_nargs);
|
||||
|
||||
if (ufl_info.fn_nargs != 4)
|
||||
k = 2;
|
||||
else
|
||||
k = 3;
|
||||
if (!PG_ARGISNULL(7)) {
|
||||
ufcinfo.arg[2] = PG_GETARG_DATUM(7);
|
||||
ufc_info.arg[k] = PG_GETARG_DATUM(7);
|
||||
}
|
||||
else {
|
||||
ufcinfo.arg[2] = (Datum) NULL;
|
||||
ufcinfo.argnull[2] = TRUE;
|
||||
ufcnullcount++;
|
||||
ufc_info.arg[k] = (Datum) NULL;
|
||||
ufc_info.argnull[k] = TRUE;
|
||||
ufc_nullcount++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -9046,7 +9055,7 @@ Datum RASTER_mapAlgebra2(PG_FUNCTION_ARGS)
|
|||
(spi_empty != spi_count) || hasnodatanodataval
|
||||
)
|
||||
) || (
|
||||
(calltype == REGPROCEDUREOID) && (ufcnoid != InvalidOid)
|
||||
(calltype == REGPROCEDUREOID) && (ufc_noid != InvalidOid)
|
||||
)) {
|
||||
for (x = 0; x < dim[0]; x++) {
|
||||
for (y = 0; y < dim[1]; y++) {
|
||||
|
@ -9258,29 +9267,52 @@ Datum RASTER_mapAlgebra2(PG_FUNCTION_ARGS)
|
|||
}
|
||||
} break;
|
||||
case REGPROCEDUREOID: {
|
||||
Datum d[4];
|
||||
ArrayType *a;
|
||||
|
||||
/* build fcnarg */
|
||||
for (i = 0; i < set_count; i++) {
|
||||
ufcinfo.arg[i] = Float8GetDatum(_pixel[i]);
|
||||
ufc_info.arg[i] = Float8GetDatum(_pixel[i]);
|
||||
|
||||
if (_haspixel[i]) {
|
||||
ufcinfo.argnull[i] = FALSE;
|
||||
ufcnullcount--;
|
||||
ufc_info.argnull[i] = FALSE;
|
||||
ufc_nullcount--;
|
||||
}
|
||||
else {
|
||||
ufcinfo.argnull[i] = TRUE;
|
||||
ufcnullcount++;
|
||||
ufc_info.argnull[i] = TRUE;
|
||||
ufc_nullcount++;
|
||||
}
|
||||
}
|
||||
|
||||
/* function is strict and null parameter is passed */
|
||||
/* http://archives.postgresql.org/pgsql-general/2011-11/msg00424.php */
|
||||
if (uflinfo.fn_strict && ufcnullcount)
|
||||
if (ufl_info.fn_strict && ufc_nullcount)
|
||||
break;
|
||||
|
||||
datum = FunctionCallInvoke(&ufcinfo);
|
||||
/* 4 parameters, add position */
|
||||
if (ufl_info.fn_nargs == 4) {
|
||||
/* Datum of 4 element array */
|
||||
/* array is (x1, y1, x2, y2) */
|
||||
for (i = 0; i < set_count; i++) {
|
||||
if (i < 1) {
|
||||
d[0] = Int32GetDatum(_pos[i][0]);
|
||||
d[1] = Int32GetDatum(_pos[i][1]);
|
||||
}
|
||||
else {
|
||||
d[2] = Int32GetDatum(_pos[i][0]);
|
||||
d[3] = Int32GetDatum(_pos[i][1]);
|
||||
}
|
||||
}
|
||||
|
||||
a = construct_array(d, 4, INT4OID, sizeof(int4), true, 'i');
|
||||
ufc_info.arg[2] = PointerGetDatum(a);
|
||||
ufc_info.argnull[2] = FALSE;
|
||||
}
|
||||
|
||||
datum = FunctionCallInvoke(&ufc_info);
|
||||
|
||||
/* result is not null*/
|
||||
if (!ufcinfo.isnull) {
|
||||
if (!ufc_info.isnull) {
|
||||
haspixel = 1;
|
||||
pixel = DatumGetFloat8(datum);
|
||||
}
|
||||
|
|
|
@ -55,6 +55,7 @@ DROP FUNCTION IF EXISTS make_test_raster(integer, integer, integer, double preci
|
|||
CREATE OR REPLACE FUNCTION raster_mapalgebra_intersection(
|
||||
rast1 double precision,
|
||||
rast2 double precision,
|
||||
xy int[],
|
||||
VARIADIC userargs text[]
|
||||
)
|
||||
RETURNS double precision
|
||||
|
@ -142,7 +143,7 @@ CREATE OR REPLACE FUNCTION raster_mapalgebra_second(
|
|||
-- 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'
|
||||
r1.rast, r2.rast, 'raster_mapalgebra_intersection(double precision, double precision, int[], text[])'::regprocedure, '32BF', 'INTERSECTION'
|
||||
)
|
||||
FROM raster_mapalgebra r1
|
||||
JOIN raster_mapalgebra r2
|
||||
|
@ -151,7 +152,7 @@ INSERT INTO raster_mapalgebra_out
|
|||
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'
|
||||
r1.rast, r2.rast, 'raster_mapalgebra_intersection(double precision, double precision, int[], text[])'::regprocedure, '32BF', 'INTERSECTION'
|
||||
)
|
||||
FROM raster_mapalgebra r1
|
||||
JOIN raster_mapalgebra r2
|
||||
|
@ -162,21 +163,21 @@ INSERT INTO raster_mapalgebra_out
|
|||
|
||||
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'
|
||||
NULL::raster, rast, 'raster_mapalgebra_intersection(double precision, double precision, int[], 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'
|
||||
rast, NULL::raster, 'raster_mapalgebra_intersection(double precision, double precision, int[], 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'
|
||||
NULL::raster, NULL::raster, 'raster_mapalgebra_intersection(double precision, double precision, int[], text[])'::regprocedure, '32BF', 'INTERSECTION'
|
||||
)
|
||||
;
|
||||
|
||||
|
@ -335,7 +336,7 @@ FROM (
|
|||
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_intersection(double precision, double precision, int[], 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[]);
|
||||
|
|
Loading…
Reference in a new issue