36 #include <executor/spi.h> 37 #include <utils/lsyscache.h> 38 #include <utils/array.h> 39 #include <utils/builtins.h> 40 #include <catalog/pg_type.h> 41 #include <executor/executor.h> 43 #include "../../postgis_config.h" 44 #include "lwgeom_pg.h" 84 #if POSTGIS_PGSQL_VERSION < 120 89 FunctionCallInfoBaseData fcinfo;
90 char fcinfo_data[SizeForFunctionCallInfo(FUNC_MAX_ARGS)];
92 FunctionCallInfo ufc_info;
121 rtpg_nmapalgebra_arg arg = NULL;
125 elog(ERROR,
"rtpg_nmapalgebra_arg_init: Could not allocate memory for arguments");
149 #if POSTGIS_PGSQL_VERSION >= 120 161 if (arg->
raster != NULL) {
178 if( arg->
mask != NULL )
201 if (arg == NULL || array == NULL) {
202 elog(ERROR,
"rtpg_nmapalgebra_rastbandarg_process: NULL values not permitted for parameters");
206 etype = ARR_ELEMTYPE(array);
207 get_typlenbyvalalign(etype, &typlen, &typbyval, &typalign);
212 typlen, typbyval, typalign,
217 elog(ERROR,
"rtpg_nmapalgebra_rastbandarg_process: Invalid argument for rastbandarg");
235 arg->
nband == NULL ||
239 elog(ERROR,
"rtpg_nmapalgebra_rastbandarg_process: Could not allocate memory for processing rastbandarg");
248 for (i = 0; i < n; i++) {
263 tup = (HeapTupleHeader) DatumGetPointer(e[i]);
265 elog(ERROR,
"rtpg_nmapalgebra_rastbandarg_process: Invalid argument for rastbandarg at index %d", i);
271 tupv = GetAttributeByName(tup,
"rast", &isnull);
273 elog(NOTICE,
"First argument (nband) of rastbandarg at index %d is NULL. Assuming NULL raster", i);
287 for (j = 0; j < i; j++) {
299 if (arg->
raster[i] == NULL) {
300 elog(ERROR,
"rtpg_nmapalgebra_rastbandarg_process: Could not deserialize raster at index %d", i);
316 tupv = GetAttributeByName(tup,
"nband", &isnull);
319 elog(NOTICE,
"First argument (nband) of rastbandarg at index %d is NULL. Assuming nband = %d", i, nband);
322 nband = DatumGetInt32(tupv);
325 elog(ERROR,
"rtpg_nmapalgebra_rastbandarg_process: Band number provided for rastbandarg at index %d must be greater than zero (1-based)", i);
329 arg->
nband[i] = nband - 1;
349 arg->
nband == NULL ||
352 elog(ERROR,
"rtpg_nmapalgebra_rastbandarg_process: Could not reallocate memory for processed rastbandarg");
367 double *
value,
int *nodata
375 ArrayType *mdValues = NULL;
376 Datum *_values = NULL;
377 bool *_nodata = NULL;
379 ArrayType *mdPos = NULL;
388 int lbound[3] = {1, 1, 1};
389 Datum datum = (Datum) NULL;
403 if (_values == NULL || _nodata == NULL) {
404 elog(ERROR,
"rtpg_nmapalgebra_callback: Could not allocate memory for values array");
411 for (z = 0; z < arg->
rasters; z++) {
413 for (y = 0; y < arg->
rows; y++) {
415 for (x = 0; x < arg->
columns; x++) {
419 _nodata[i] = (bool) arg->
nodata[z][y][x];
421 _values[i] = Float8GetDatum(arg->
values[z][y][x]);
423 _values[i] = (Datum) NULL;
431 get_typlenbyvalalign(FLOAT8OID, &typlen, &typbyval, &typalign);
434 mdValues = construct_md_array(
438 typlen, typbyval, typalign
443 _pos = palloc(
sizeof(Datum) * (arg->
rasters + 1) * 2);
444 _null = palloc(
sizeof(
bool) * (arg->
rasters + 1) * 2);
445 if (_pos == NULL || _null == NULL) {
447 elog(ERROR,
"rtpg_nmapalgebra_callback: Could not allocate memory for position array");
450 memset(_null, 0,
sizeof(
bool) * (arg->
rasters + 1) * 2);
459 for (z = 0; z < arg->
rasters; z++) {
468 get_typlenbyvalalign(INT4OID, &typlen, &typbyval, &typalign);
476 mdPos = construct_md_array(
480 typlen, typbyval, typalign
485 #if POSTGIS_PGSQL_VERSION < 120 486 callback->
ufc_info.arg[0] = PointerGetDatum(mdValues);
487 callback->
ufc_info.arg[1] = PointerGetDatum(mdPos);
489 callback->
ufc_info->args[0].value = PointerGetDatum(mdValues);
490 callback->
ufc_info->args[1].value = PointerGetDatum(mdPos);
494 #if POSTGIS_PGSQL_VERSION < 120 495 datum = FunctionCallInvoke(&(callback->
ufc_info));
497 datum = FunctionCallInvoke(callback->
ufc_info);
503 #if POSTGIS_PGSQL_VERSION < 120 511 *value = DatumGetFloat8(datum);
514 *value = (double) DatumGetFloat4(datum);
517 *value = (double) DatumGetInt32(datum);
520 *value = (double) DatumGetInt16(datum);
536 rtpg_nmapalgebra_arg arg = NULL;
538 ArrayType *maskArray;
569 elog(ERROR,
"RASTER_nMapAlgebra: Could not initialize argument structure");
576 elog(ERROR,
"RASTER_nMapAlgebra: Could not process rastbandarg");
580 POSTGIS_RT_DEBUGF(4,
"allnull, allempty, noband = %d, %d, %d", allnull, allempty, noband);
584 elog(NOTICE,
"All input rasters are NULL. Returning NULL");
590 if (!PG_ARGISNULL(2)) {
591 char *pixtypename = text_to_cstring(PG_GETARG_TEXT_P(2));
597 elog(ERROR,
"RASTER_nMapAlgebra: Invalid pixel type: %s", pixtypename);
603 if (!PG_ARGISNULL(3)){
604 arg->
distance[0] = PG_GETARG_INT32(3);
609 if (!PG_ARGISNULL(4)){
610 arg->
distance[1] = PG_GETARG_INT32(4);
616 elog(ERROR,
"RASTER_nMapAlgebra: Distance for X and Y axis must be greater than or equal to zero");
621 if (!PG_ARGISNULL(5)) {
629 if (PG_ARGISNULL(6)) {
630 elog(NOTICE,
"Custom extent is NULL. Returning NULL");
641 elog(ERROR,
"RASTER_nMapAlgebra: Could not deserialize custom extent");
645 elog(NOTICE,
"Custom extent is an empty raster. Returning empty raster");
649 if (raster == NULL) {
650 elog(ERROR,
"RASTER_nMapAlgebra: Could not create empty raster");
656 if (!pgraster) PG_RETURN_NULL();
658 SET_VARSIZE(pgraster, pgraster->
size);
659 PG_RETURN_POINTER(pgraster);
665 if( PG_ARGISNULL(7) ){
670 maskArray = PG_GETARG_ARRAYTYPE_P(7);
671 etype = ARR_ELEMTYPE(maskArray);
672 get_typlenbyvalalign(etype,&typlen,&typbyval,&typalign);
680 elog(ERROR,
"RASTER_nMapAlgebra: Mask data type must be FLOAT8 or FLOAT4");
684 ndims = ARR_NDIM(maskArray);
687 elog(ERROR,
"RASTER_nMapAlgebra: Mask Must be a 2D array");
692 maskDims = ARR_DIMS(maskArray);
694 if (maskDims[0] % 2 == 0 || maskDims[1] % 2 == 0) {
695 elog(ERROR,
"RASTER_nMapAlgebra: Mask dimensions must be odd");
703 typlen, typbyval,typalign,
704 &maskElements,&maskNulls,&num
707 if (num < 1 || num != (maskDims[0] * maskDims[1])) {
712 elog(ERROR,
"RASTER_nMapAlgebra: Could not deconstruct new values array");
718 arg->
mask->
values = palloc(
sizeof(
double*)* maskDims[0]);
719 arg->
mask->
nodata = palloc(
sizeof(
int*)*maskDims[0]);
720 for (i = 0; i < maskDims[0]; i++) {
721 arg->
mask->
values[i] = (
double*) palloc(
sizeof(
double) * maskDims[1]);
722 arg->
mask->
nodata[i] = (
int*) palloc(
sizeof(
int) * maskDims[1]);
727 for (y = 0; y < maskDims[0]; y++) {
728 for (x = 0; x < maskDims[1]; x++) {
736 arg->
mask->
values[
y][
x] = (double) DatumGetFloat4(maskElements[i]);
740 arg->
mask->
values[
y][
x] = (double) DatumGetFloat8(maskElements[i]);
751 if (maskDims[0] == 1 && maskDims[1] == 1) {
762 if (PG_ARGISNULL(8) || !PG_GETARG_BOOL(8)) {
763 if (arg->
mask != NULL)
774 elog(NOTICE,
"All input rasters are empty. Returning empty raster");
779 elog(NOTICE,
"All input rasters do not have bands at indicated indexes. Returning empty raster");
786 if (raster == NULL) {
787 elog(ERROR,
"RASTER_nMapAlgebra: Could not create empty raster");
793 if (!pgraster) PG_RETURN_NULL();
795 SET_VARSIZE(pgraster, pgraster->
size);
796 PG_RETURN_POINTER(pgraster);
800 if (!PG_ARGISNULL(1) || get_fn_expr_argtype(fcinfo->flinfo, 1) == REGPROCEDUREOID) {
819 get_func_result_type(
846 elog(ERROR,
"RASTER_nMapAlgebra: Function provided must return a double precision, float, int or smallint");
849 elog(ERROR,
"RASTER_nMapAlgebra: Function provided must return scalar (double precision, float, int, smallint)");
852 elog(ERROR,
"RASTER_nMapAlgebra: Function provided must have three input parameters");
855 elog(ERROR,
"RASTER_nMapAlgebra: Function provided must return double precision, not resultset");
862 elog(NOTICE,
"Function provided is VOLATILE. Unless required and for best performance, function should be IMMUTABLE or STABLE");
865 #if POSTGIS_PGSQL_VERSION < 120 883 if (!PG_ARGISNULL(9))
884 #if POSTGIS_PGSQL_VERSION < 120 893 #if POSTGIS_PGSQL_VERSION < 120 895 construct_empty_array(TEXTOID)
899 arg->
callback.
ufc_info->args[2].value = PointerGetDatum(construct_empty_array(TEXTOID));
904 #if POSTGIS_PGSQL_VERSION < 120 916 elog(ERROR,
"RASTER_nMapAlgebra: callbackfunc must be provided");
961 if (itrset == NULL) {
963 elog(ERROR,
"RASTER_nMapAlgebra: Could not allocate memory for iterator arguments");
992 elog(ERROR,
"RASTER_nMapAlgebra: Could not run raster iterator function");
995 else if (raster == NULL)
1006 SET_VARSIZE(pgraster, pgraster->
size);
1007 PG_RETURN_POINTER(pgraster);
1046 rtpg_nmapalgebraexpr_arg arg = NULL;
1051 elog(ERROR,
"rtpg_nmapalgebraexpr_arg_init: Could not allocate memory for arguments");
1057 elog(ERROR,
"rtpg_nmapalgebraexpr_arg_init: Could not allocate memory for arg->bandarg");
1070 elog(ERROR,
"rtpg_nmapalgebraexpr_arg_init: Could not allocate memory for spi_argpos");
1101 double *value,
int *nodata
1104 SPIPlanPtr plan = NULL;
1124 else if (arg->
nodata[0][0][0] && !arg->
nodata[1][0][0]) {
1127 *value = callback->
expr[id].
val;
1134 else if (!arg->
nodata[0][0][0] && arg->
nodata[1][0][0]) {
1137 *value = callback->
expr[id].
val;
1147 *value = callback->
expr[id].
val;
1161 if (arg->
nodata[0][0][0]) {
1164 *value = callback->
expr[id].
val;
1174 *value = callback->
expr[id].
val;
1181 *value = callback->
expr[id].
val;
1197 SPITupleTable *tuptable = NULL;
1200 bool isnull =
false;
1205 memset(values, (Datum) NULL,
sizeof(Datum) * callback->
kw.
count);
1206 memset(nulls,
FALSE,
sizeof(
bool) * callback->
kw.
count);
1211 for (i = 0; i < callback->
kw.
count; i++) {
1213 if (idx < 1)
continue;
1219 values[idx] = Int32GetDatum(arg->
src_pixel[0][0] + 1);
1223 values[idx] = Int32GetDatum(arg->
src_pixel[0][1] + 1);
1229 if (!arg->
nodata[0][0][0])
1230 values[idx] = Float8GetDatum(arg->
values[0][0][0]);
1237 values[idx] = Int32GetDatum(arg->
src_pixel[0][0] + 1);
1241 values[idx] = Int32GetDatum(arg->
src_pixel[0][1] + 1);
1247 if (!arg->
nodata[0][0][0])
1248 values[idx] = Float8GetDatum(arg->
values[0][0][0]);
1255 values[idx] = Int32GetDatum(arg->
src_pixel[1][0] + 1);
1259 values[idx] = Int32GetDatum(arg->
src_pixel[1][1] + 1);
1265 if (!arg->
nodata[1][0][0])
1266 values[idx] = Float8GetDatum(arg->
values[1][0][0]);
1276 err = SPI_execute_plan(plan, values, nulls,
TRUE, 1);
1277 if (err != SPI_OK_SELECT || SPI_tuptable == NULL || SPI_processed != 1) {
1278 elog(ERROR,
"rtpg_nmapalgebraexpr_callback: Unexpected error when running prepared statement %d",
id);
1283 tupdesc = SPI_tuptable->tupdesc;
1284 tuptable = SPI_tuptable;
1285 tuple = tuptable->vals[0];
1287 datum = SPI_getbinval(tuple, tupdesc, 1, &isnull);
1288 if (SPI_result == SPI_ERROR_NOATTRIBUTE) {
1289 if (SPI_tuptable) SPI_freetuptable(tuptable);
1290 elog(ERROR,
"rtpg_nmapalgebraexpr_callback: Could not get result of prepared statement %d",
id);
1295 *value = DatumGetFloat8(datum);
1309 *value = callback->
expr[1].
val;
1315 if (SPI_tuptable) SPI_freetuptable(tuptable);
1325 MemoryContext mainMemCtx = CurrentMemoryContext;
1326 rtpg_nmapalgebraexpr_arg arg = NULL;
1328 uint16_t exprpos[3] = {1, 4, 5};
1342 SPITupleTable *tuptable = NULL;
1345 bool isnull =
FALSE;
1351 const int argkwcount = 12;
1367 if (PG_ARGISNULL(0))
1373 elog(ERROR,
"RASTER_nMapAlgebraExpr: Could not initialize argument structure");
1380 elog(ERROR,
"RASTER_nMapAlgebra: Could not process rastbandarg");
1384 POSTGIS_RT_DEBUGF(4,
"allnull, allempty, noband = %d, %d, %d", allnull, allempty, noband);
1388 elog(NOTICE,
"All input rasters are NULL. Returning NULL");
1400 if (!PG_ARGISNULL(2)) {
1401 char *pixtypename = text_to_cstring(PG_GETARG_TEXT_P(2));
1407 elog(ERROR,
"RASTER_nMapAlgebraExpr: Invalid pixel type: %s", pixtypename);
1414 if (!PG_ARGISNULL(3)) {
1420 if (numraster < 2) {
1421 elog(NOTICE,
"CUSTOM extent type not supported. Defaulting to FIRST");
1425 elog(NOTICE,
"CUSTOM extent type not supported. Defaulting to INTERSECTION");
1429 else if (numraster < 2)
1435 if (!PG_ARGISNULL(6)) {
1443 elog(NOTICE,
"All input rasters are empty. Returning empty raster");
1448 elog(NOTICE,
"All input rasters do not have bands at indicated indexes. Returning empty raster");
1455 if (raster == NULL) {
1456 elog(ERROR,
"RASTER_nMapAlgebraExpr: Could not create empty raster");
1462 if (!pgraster) PG_RETURN_NULL();
1464 SET_VARSIZE(pgraster, pgraster->
size);
1465 PG_RETURN_POINTER(pgraster);
1469 if (SPI_connect() != SPI_OK_CONNECT) {
1471 elog(ERROR,
"RASTER_nMapAlgebraExpr: Could not connect to the SPI manager");
1487 char place[5] =
"$1";
1489 if (PG_ARGISNULL(exprpos[i]))
1492 expr = text_to_cstring(PG_GETARG_TEXT_P(exprpos[i]));
1495 for (j = 0, k = 1; j < argkwcount; j++) {
1507 sprintf(place,
"$%d", k);
1513 len = strlen(
"SELECT (") + strlen(expr) + strlen(
")::double precision");
1514 sql = (
char *) palloc(len + 1);
1518 elog(ERROR,
"RASTER_nMapAlgebraExpr: Could not allocate memory for expression parameter %d", exprpos[i]);
1522 memcpy(sql,
"SELECT (", strlen(
"SELECT ("));
1523 memcpy(sql + strlen(
"SELECT ("), expr, strlen(expr));
1524 memcpy(sql + strlen(
"SELECT (") + strlen(expr),
")::double precision", strlen(
")::double precision"));
1533 if (argtype == NULL) {
1537 elog(ERROR,
"RASTER_nMapAlgebraExpr: Could not allocate memory for prepared plan argtypes of expression parameter %d", exprpos[i]);
1542 for (j = 0, k = 0; j < argkwcount; j++) {
1547 (strstr(argkw[j],
"[rast.x]") != NULL) ||
1548 (strstr(argkw[j],
"[rast.y]") != NULL) ||
1549 (strstr(argkw[j],
"[rast1.x]") != NULL) ||
1550 (strstr(argkw[j],
"[rast1.y]") != NULL) ||
1551 (strstr(argkw[j],
"[rast2.x]") != NULL) ||
1552 (strstr(argkw[j],
"[rast2.y]") != NULL)
1554 argtype[k] = INT4OID;
1557 argtype[k] = FLOAT8OID;
1569 elog(ERROR,
"RASTER_nMapAlgebraExpr: Could not create prepared plan of expression parameter %d", exprpos[i]);
1575 POSTGIS_RT_DEBUGF(3,
"expression parameter %d has no args, simply executing", exprpos[i]);
1576 err = SPI_execute(sql,
TRUE, 0);
1579 if (err != SPI_OK_SELECT || SPI_tuptable == NULL || SPI_processed != 1) {
1582 elog(ERROR,
"RASTER_nMapAlgebraExpr: Could not evaluate expression parameter %d", exprpos[i]);
1587 tupdesc = SPI_tuptable->tupdesc;
1588 tuptable = SPI_tuptable;
1589 tuple = tuptable->vals[0];
1591 datum = SPI_getbinval(tuple, tupdesc, 1, &isnull);
1592 if (SPI_result == SPI_ERROR_NOATTRIBUTE) {
1593 if (SPI_tuptable) SPI_freetuptable(tuptable);
1596 elog(ERROR,
"RASTER_nMapAlgebraExpr: Could not get result of expression parameter %d", exprpos[i]);
1605 if (SPI_tuptable) SPI_freetuptable(tuptable);
1625 for (i = 0; i < numraster; i++) {
1649 if (itrset == NULL) {
1652 elog(ERROR,
"RASTER_nMapAlgebra: Could not allocate memory for iterator arguments");
1657 for (i = 0; i < numraster; i++) {
1681 elog(ERROR,
"RASTER_nMapAlgebraExpr: Could not run raster iterator function");
1684 else if (raster == NULL) {
1690 MemoryContextSwitchTo(mainMemCtx);
1701 SET_VARSIZE(pgraster, pgraster->
size);
1702 PG_RETURN_POINTER(pgraster);
1722 assert(cutype && strlen(cutype) > 0);
1724 if (strcmp(cutype,
"LAST") == 0)
1726 else if (strcmp(cutype,
"FIRST") == 0)
1728 else if (strcmp(cutype,
"MIN") == 0)
1730 else if (strcmp(cutype,
"MAX") == 0)
1732 else if (strcmp(cutype,
"COUNT") == 0)
1734 else if (strcmp(cutype,
"SUM") == 0)
1736 else if (strcmp(cutype,
"MEAN") == 0)
1738 else if (strcmp(cutype,
"RANGE") == 0)
1765 for (i = 0; i < arg->
numband; i++) {
1789 double *value,
int *nodata
1791 rtpg_union_type *utype = (rtpg_union_type *) userarg;
1801 elog(ERROR,
"rtpg_union_callback: Invalid arguments passed to callback");
1817 else if (!arg->
nodata[0][0][0] && arg->
nodata[1][0][0]) {
1818 *value = arg->
values[0][0][0];
1823 else if (arg->
nodata[0][0][0] && !arg->
nodata[1][0][0]) {
1824 *value = arg->
values[1][0][0];
1832 *value = arg->
values[0][0][0];
1836 *value = arg->
values[0][0][0];
1838 *value = arg->
values[1][0][0];
1842 *value = arg->
values[0][0][0];
1844 *value = arg->
values[1][0][0];
1851 else if (!arg->
nodata[0][0][0] && arg->
nodata[1][0][0])
1852 *value = arg->
values[0][0][0];
1854 else if (arg->
nodata[0][0][0] && !arg->
nodata[1][0][0])
1858 *value = arg->
values[0][0][0] + 1;
1868 *value = arg->
values[1][0][0];
1880 double *value,
int *nodata
1890 elog(ERROR,
"rtpg_union_mean_callback: Invalid arguments passed to callback");
1916 double *value,
int *nodata
1926 elog(ERROR,
"rtpg_union_range_callback: Invalid arguments passed to callback");
1959 HeapTupleHeader tup;
1965 char *utypename = NULL;
1966 rtpg_union_type utype =
UT_LAST;
1968 etype = ARR_ELEMTYPE(array);
1969 get_typlenbyvalalign(etype, &typlen, &typbyval, &typalign);
1974 typlen, typbyval, typalign,
1979 elog(ERROR,
"rtpg_union_unionarg_process: Invalid argument for unionarg");
1987 elog(ERROR,
"rtpg_union_unionarg_process: Could not allocate memory for band information");
1992 for (i = 0; i < n; i++) {
2001 tup = (HeapTupleHeader) DatumGetPointer(e[i]);
2003 elog(ERROR,
"rtpg_union_unionarg_process: Invalid argument for unionarg");
2008 tupv = GetAttributeByName(tup,
"nband", &isnull);
2011 elog(NOTICE,
"First argument (nband) of unionarg is NULL. Assuming nband = %d", nband);
2014 nband = DatumGetInt32(tupv);
2017 elog(ERROR,
"rtpg_union_unionarg_process: Band number must be greater than zero (1-based)");
2022 tupv = GetAttributeByName(tup,
"uniontype", &isnull);
2024 elog(NOTICE,
"Second argument (uniontype) of unionarg is NULL. Assuming uniontype = LAST");
2028 utypename = text_to_cstring((text *) DatumGetPointer(tupv));
2049 elog(ERROR,
"rtpg_union_unionarg_process: Could not reallocate memory for band information");
2066 if (numbands <= arg->numband)
2076 elog(ERROR,
"rtpg_union_noarg: Could not reallocate memory for band information");
2082 for (; i < arg->
numband; i++) {
2090 elog(ERROR,
"rtpg_union_noarg: Could not allocate memory for working rasters");
2099 elog(ERROR,
"rtpg_union_noarg: Could not create working raster");
2112 MemoryContext aggcontext;
2113 MemoryContext oldcontext;
2114 rtpg_union_arg iwr = NULL;
2123 int isempty[2] = {0};
2124 int hasband[2] = {0};
2126 double _offset[4] = {0.};
2134 char *utypename = NULL;
2135 rtpg_union_type utype =
UT_LAST;
2138 double nodataval = 0;
2144 uint16_t _dim[2] = {0};
2151 if (!AggCheckCallContext(fcinfo, &aggcontext)) {
2152 elog(ERROR,
"RASTER_union_transfn: Cannot be called in a non-aggregate context");
2157 oldcontext = MemoryContextSwitchTo(aggcontext);
2159 if (PG_ARGISNULL(0)) {
2164 MemoryContextSwitchTo(oldcontext);
2165 elog(ERROR,
"RASTER_union_transfn: Could not allocate memory for state variable");
2181 if (!PG_ARGISNULL(1)) {
2183 pgraster = (
rt_pgraster *) PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
2187 if (raster == NULL) {
2190 PG_FREE_IF_COPY(pgraster, 1);
2192 MemoryContextSwitchTo(oldcontext);
2193 elog(ERROR,
"RASTER_union_transfn: Could not deserialize raster");
2206 if (!PG_ARGISNULL(2)) {
2207 Oid calltype = get_fn_expr_argtype(fcinfo->flinfo, 2);
2218 utypename = text_to_cstring(PG_GETARG_TEXT_P(2));
2242 if (numband > idx) {
2258 if (raster != NULL) {
2260 PG_FREE_IF_COPY(pgraster, 1);
2263 MemoryContextSwitchTo(oldcontext);
2264 elog(ERROR,
"RASTER_union_transfn: Could not allocate memory for band information");
2269 for (i = idx; i < iwr->
numband; i++) {
2293 nband = PG_GETARG_INT32(2);
2297 if (raster != NULL) {
2299 PG_FREE_IF_COPY(pgraster, 1);
2302 MemoryContextSwitchTo(oldcontext);
2303 elog(ERROR,
"RASTER_union_transfn: Band number must be greater than zero (1-based)");
2312 if (raster != NULL) {
2314 PG_FREE_IF_COPY(pgraster, 1);
2317 MemoryContextSwitchTo(oldcontext);
2318 elog(ERROR,
"RASTER_union_transfn: Could not allocate memory for band information");
2337 if (raster != NULL) {
2339 PG_FREE_IF_COPY(pgraster, 1);
2342 MemoryContextSwitchTo(oldcontext);
2343 elog(ERROR,
"RASTER_union_transfn: Could not process unionarg");
2352 if (nargs > 3 && !PG_ARGISNULL(3)) {
2353 utypename = text_to_cstring(PG_GETARG_TEXT_P(3));
2367 for (i = 0; i < iwr->
numband; i++) {
2380 if (raster != NULL) {
2382 PG_FREE_IF_COPY(pgraster, 1);
2385 MemoryContextSwitchTo(oldcontext);
2386 elog(ERROR,
"RASTER_union_transfn: Could not allocate memory for working raster(s)");
2399 if (raster != NULL) {
2401 PG_FREE_IF_COPY(pgraster, 1);
2404 MemoryContextSwitchTo(oldcontext);
2405 elog(ERROR,
"RASTER_union_transfn: Could not create working raster");
2420 if (raster != NULL) {
2422 PG_FREE_IF_COPY(pgraster, 1);
2425 MemoryContextSwitchTo(oldcontext);
2426 elog(ERROR,
"RASTER_union_transfn: Could not check and balance number of bands");
2433 if (itrset == NULL) {
2436 if (raster != NULL) {
2438 PG_FREE_IF_COPY(pgraster, 1);
2441 MemoryContextSwitchTo(oldcontext);
2442 elog(ERROR,
"RASTER_union_transfn: Could not allocate memory for iterator arguments");
2447 for (i = 0; i < iwr->
numband; i++) {
2467 if (!isempty[0] && hasband[0])
2469 else if (!isempty[1] && hasband[1])
2476 if (_band != NULL) {
2514 itrset[0].
nband = 0;
2530 if (!isempty[0] && !isempty[1] && hasband[0] && hasband[1]) {
2542 if (raster != NULL) {
2544 PG_FREE_IF_COPY(pgraster, 1);
2547 MemoryContextSwitchTo(oldcontext);
2548 elog(ERROR,
"RASTER_union_transfn: Could not create internal raster");
2552 _offset[0], _offset[1], _offset[2], _offset[3]);
2559 double igt[6] = {0};
2575 hasnodata, nodataval,
2582 if (raster != NULL) {
2584 PG_FREE_IF_COPY(pgraster, 1);
2587 MemoryContextSwitchTo(oldcontext);
2588 elog(ERROR,
"RASTER_union_transfn: Could not add new band to internal raster");
2596 for (y = 0; y < _dim[1]; y++) {
2597 POSTGIS_RT_DEBUGF(4,
"Getting pixel line of working raster at (x, y, length) = (0, %d, %d)", y, _dim[0]);
2609 if (raster != NULL) {
2611 PG_FREE_IF_COPY(pgraster, 1);
2614 MemoryContextSwitchTo(oldcontext);
2615 elog(ERROR,
"RASTER_union_transfn: Could not get pixel line from band of working raster");
2619 POSTGIS_RT_DEBUGF(4,
"Setting pixel line at (x, y, length) = (%d, %d, %d)", (
int) _offset[0], (
int) _offset[1] + y, nvals);
2622 (
int) _offset[0], (
int) _offset[1] + y,
2630 if (raster != NULL) {
2632 PG_FREE_IF_COPY(pgraster, 1);
2635 MemoryContextSwitchTo(oldcontext);
2636 elog(ERROR,
"RASTER_union_transfn: Could not set pixel line to band of internal raster");
2652 hasnodata, nodataval,
2667 if (raster != NULL) {
2669 PG_FREE_IF_COPY(pgraster, 1);
2672 MemoryContextSwitchTo(oldcontext);
2673 elog(ERROR,
"RASTER_union_transfn: Could not run raster iterator function");
2681 for (y = 0; y < _dim[1]; y++) {
2682 POSTGIS_RT_DEBUGF(4,
"Getting pixel line of iterator raster at (x, y, length) = (0, %d, %d)", y, _dim[0]);
2696 if (raster != NULL) {
2698 PG_FREE_IF_COPY(pgraster, 1);
2701 MemoryContextSwitchTo(oldcontext);
2702 elog(ERROR,
"RASTER_union_transfn: Could not get pixel line from band of working raster");
2706 POSTGIS_RT_DEBUGF(4,
"Setting pixel line at (x, y, length) = (%d, %d, %d)", (
int) _offset[2], (
int) _offset[3] + y, nvals);
2709 (
int) _offset[2], (
int) _offset[3] + y,
2719 if (raster != NULL) {
2721 PG_FREE_IF_COPY(pgraster, 1);
2724 MemoryContextSwitchTo(oldcontext);
2725 elog(ERROR,
"RASTER_union_transfn: Could not set pixel line to band of internal raster");
2745 hasnodata, nodataval,
2757 if (raster != NULL) {
2759 PG_FREE_IF_COPY(pgraster, 1);
2762 MemoryContextSwitchTo(oldcontext);
2763 elog(ERROR,
"RASTER_union_transfn: Could not run raster iterator function");
2780 if (raster != NULL) {
2782 PG_FREE_IF_COPY(pgraster, 1);
2786 MemoryContextSwitchTo(oldcontext);
2790 PG_RETURN_POINTER(iwr);
2810 double nodataval = 0;
2815 if (!AggCheckCallContext(fcinfo, NULL)) {
2816 elog(ERROR,
"RASTER_union_finalfn: Cannot be called in a non-aggregate context");
2821 if (PG_ARGISNULL(0))
2828 if (itrset == NULL) {
2830 elog(ERROR,
"RASTER_union_finalfn: Could not allocate memory for iterator arguments");
2834 for (i = 0; i < iwr->
numband; i++) {
2849 itrset[0].
nband = 0;
2851 itrset[1].
nband = 0;
2859 hasnodata, nodataval,
2872 hasnodata, nodataval,
2886 elog(ERROR,
"RASTER_union_finalfn: Could not run raster iterator function");
2897 status = (_rtn == NULL) ? -1 : 0;
2922 elog(ERROR,
"RASTER_union_finalfn: Could not add band to final raster");
2931 if (!_rtn) PG_RETURN_NULL();
2941 SET_VARSIZE(pgraster, pgraster->
size);
2942 PG_RETURN_POINTER(pgraster);
2967 rtpg_clip_arg arg = NULL;
2971 elog(ERROR,
"rtpg_clip_arg_init: Could not allocate memory for function arguments");
2985 if (arg->
band != NULL)
2990 if (arg->
mask != NULL)
2998 double *value,
int *nodata
3008 *value = arg->
values[0][0][0];
3026 unsigned char *wkb = NULL;
3041 rtpg_clip_arg arg = NULL;
3055 if (PG_ARGISNULL(0) || PG_ARGISNULL(2))
3061 elog(ERROR,
"RASTER_clip: Could not initialize argument structure");
3066 pgraster = (
rt_pgraster *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
3070 if (arg->
raster == NULL) {
3072 PG_FREE_IF_COPY(pgraster, 0);
3073 elog(ERROR,
"RASTER_clip: Could not deserialize raster");
3079 elog(NOTICE,
"Input raster is empty or has no bands. Returning empty raster");
3082 PG_FREE_IF_COPY(pgraster, 0);
3086 elog(ERROR,
"RASTER_clip: Could not create empty raster");
3095 SET_VARSIZE(pgrtn, pgrtn->
size);
3096 PG_RETURN_POINTER(pgrtn);
3104 gser = PG_GETARG_GSERIALIZED_P(2);
3116 elog(NOTICE,
"Geometry provided does not have the same SRID as the raster. Returning NULL");
3119 PG_FREE_IF_COPY(pgraster, 0);
3121 PG_FREE_IF_COPY(gser, 2);
3127 if (!PG_ARGISNULL(4) && !PG_GETARG_BOOL(4))
3134 PG_FREE_IF_COPY(pgraster, 0);
3136 PG_FREE_IF_COPY(gser, 2);
3138 elog(ERROR,
"RASTER_clip: Could not get convex hull of raster");
3145 PG_FREE_IF_COPY(gser, 2);
3150 elog(NOTICE,
"The input raster and input geometry do not intersect. Returning empty raster");
3153 PG_FREE_IF_COPY(pgraster, 0);
3158 elog(ERROR,
"RASTER_clip: Could not create empty raster");
3167 SET_VARSIZE(pgrtn, pgrtn->
size);
3168 PG_RETURN_POINTER(pgrtn);
3172 if (!PG_ARGISNULL(1)) {
3173 array = PG_GETARG_ARRAYTYPE_P(1);
3174 etype = ARR_ELEMTYPE(array);
3175 get_typlenbyvalalign(etype, &typlen, &typbyval, &typalign);
3183 PG_FREE_IF_COPY(pgraster, 0);
3185 elog(ERROR,
"RASTER_clip: Invalid data type for band indexes");
3192 typlen, typbyval, typalign,
3197 if (arg->
band == NULL) {
3199 PG_FREE_IF_COPY(pgraster, 0);
3201 elog(ERROR,
"RASTER_clip: Could not allocate memory for band arguments");
3205 for (i = 0, j = 0; i < arg->
numbands; i++) {
3206 if (nulls[i])
continue;
3210 arg->
band[j].
nband = DatumGetInt16(e[i]) - 1;
3213 arg->
band[j].
nband = DatumGetInt32(e[i]) - 1;
3220 if (j < arg->numbands) {
3222 if (arg->
band == NULL) {
3224 PG_FREE_IF_COPY(pgraster, 0);
3226 elog(ERROR,
"RASTER_clip: Could not reallocate memory for band arguments");
3234 for (i = 0; i < arg->
numbands; i++) {
3236 elog(NOTICE,
"Band at index %d not found in raster", arg->
band[i].
nband + 1);
3238 PG_FREE_IF_COPY(pgraster, 0);
3253 if (arg->
band == NULL) {
3256 PG_FREE_IF_COPY(pgraster, 0);
3259 elog(ERROR,
"RASTER_clip: Could not allocate memory for band arguments");
3263 for (i = 0; i < arg->
numbands; i++) {
3272 if (!PG_ARGISNULL(3)) {
3273 array = PG_GETARG_ARRAYTYPE_P(3);
3274 etype = ARR_ELEMTYPE(array);
3275 get_typlenbyvalalign(etype, &typlen, &typbyval, &typalign);
3283 PG_FREE_IF_COPY(pgraster, 0);
3285 elog(ERROR,
"RASTER_clip: Invalid data type for NODATA values");
3292 typlen, typbyval, typalign,
3297 for (i = 0, j = 0; i < arg->
numbands; i++, j++) {
3338 if (arg->
mask == NULL) {
3340 PG_FREE_IF_COPY(pgraster, 0);
3341 elog(ERROR,
"RASTER_clip: Could not rasterize intersection geometry");
3352 if (itrset == NULL) {
3354 PG_FREE_IF_COPY(pgraster, 0);
3355 elog(ERROR,
"RASTER_clip: Could not allocate memory for iterator arguments");
3360 for (i = 0; i < arg->
numbands; i++) {
3361 POSTGIS_RT_DEBUGF(4,
"band arg %d (nband, hasnodata, nodataval) = (%d, %d, %f)",
3389 PG_FREE_IF_COPY(pgraster, 0);
3390 elog(ERROR,
"RASTER_clip: Could not create output raster");
3399 PG_FREE_IF_COPY(pgraster, 0);
3400 elog(ERROR,
"RASTER_clip: Could not add NODATA band to output raster");
3414 itrset[1].
nband = 0;
3422 hasnodata, nodataval,
3434 PG_FREE_IF_COPY(pgraster, 0);
3435 elog(ERROR,
"RASTER_clip: Could not run raster iterator function");
3450 PG_FREE_IF_COPY(pgraster, 0);
3451 elog(NOTICE,
"RASTER_clip: Could not get band from working raster");
3460 PG_FREE_IF_COPY(pgraster, 0);
3461 elog(ERROR,
"RASTER_clip: Could not add new band to output raster");
3471 PG_FREE_IF_COPY(pgraster, 0);
3481 SET_VARSIZE(pgrtn, pgrtn->
size);
3482 PG_RETURN_POINTER(pgrtn);
3515 HeapTupleHeader tup;
3520 text *exprtext = NULL;
3525 char *pixeltype = NULL;
3526 text *pixeltypetext = NULL;
3528 double nodataval = 0;
3529 bool hasnodata =
FALSE;
3531 char **comma_set = NULL;
3533 char **colon_set = NULL;
3535 char **dash_set = NULL;
3541 if (PG_ARGISNULL(0))
3543 pgraster = (
rt_pgraster *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
3548 PG_FREE_IF_COPY(pgraster, 0);
3549 elog(ERROR,
"RASTER_reclass: Could not deserialize raster");
3553 POSTGIS_RT_DEBUGF(3,
"RASTER_reclass: %d possible bands to be reclassified", numBands);
3557 array = PG_GETARG_ARRAYTYPE_P(1);
3558 etype = ARR_ELEMTYPE(array);
3559 get_typlenbyvalalign(etype, &typlen, &typbyval, &typalign);
3561 deconstruct_array(array, etype, typlen, typbyval, typalign, &e,
3565 elog(NOTICE,
"Invalid argument for reclassargset. Returning original raster");
3569 PG_FREE_IF_COPY(pgraster, 0);
3573 SET_VARSIZE(pgrtn, pgrtn->
size);
3574 PG_RETURN_POINTER(pgrtn);
3582 for (i = 0; i < n; i++) {
3583 if (nulls[i])
continue;
3586 tup = (HeapTupleHeader) DatumGetPointer(e[i]);
3588 elog(NOTICE,
"Invalid argument for reclassargset. Returning original raster");
3592 PG_FREE_IF_COPY(pgraster, 0);
3596 SET_VARSIZE(pgrtn, pgrtn->
size);
3597 PG_RETURN_POINTER(pgrtn);
3601 tupv = GetAttributeByName(tup,
"nband", &isnull);
3603 elog(NOTICE,
"Invalid argument for reclassargset. Missing value of nband for reclassarg of index %d . Returning original raster", i);
3607 PG_FREE_IF_COPY(pgraster, 0);
3611 SET_VARSIZE(pgrtn, pgrtn->
size);
3612 PG_RETURN_POINTER(pgrtn);
3614 nband = DatumGetInt32(tupv);
3618 if (nband < 1 || nband > numBands) {
3619 elog(NOTICE,
"Invalid argument for reclassargset. Invalid band index (must use 1-based) for reclassarg of index %d . Returning original raster", i);
3623 PG_FREE_IF_COPY(pgraster, 0);
3627 SET_VARSIZE(pgrtn, pgrtn->
size);
3628 PG_RETURN_POINTER(pgrtn);
3632 tupv = GetAttributeByName(tup,
"reclassexpr", &isnull);
3634 elog(NOTICE,
"Invalid argument for reclassargset. Missing value of reclassexpr for reclassarg of index %d . Returning original raster", i);
3638 PG_FREE_IF_COPY(pgraster, 0);
3642 SET_VARSIZE(pgrtn, pgrtn->
size);
3643 PG_RETURN_POINTER(pgrtn);
3645 exprtext = (text *) DatumGetPointer(tupv);
3646 if (NULL == exprtext) {
3647 elog(NOTICE,
"Invalid argument for reclassargset. Missing value of reclassexpr for reclassarg of index %d . Returning original raster", i);
3651 PG_FREE_IF_COPY(pgraster, 0);
3655 SET_VARSIZE(pgrtn, pgrtn->
size);
3656 PG_RETURN_POINTER(pgrtn);
3658 expr = text_to_cstring(exprtext);
3667 elog(NOTICE,
"Invalid argument for reclassargset. Invalid expression of reclassexpr for reclassarg of index %d . Returning original raster", i);
3671 PG_FREE_IF_COPY(pgraster, 0);
3675 SET_VARSIZE(pgrtn, pgrtn->
size);
3676 PG_RETURN_POINTER(pgrtn);
3683 for (a = 0, j = 0; a < comma_n; a++) {
3689 elog(NOTICE,
"Invalid argument for reclassargset. Invalid expression of reclassexpr for reclassarg of index %d . Returning original raster", i);
3690 for (k = 0; k < j; k++) pfree(exprset[k]);
3695 PG_FREE_IF_COPY(pgraster, 0);
3699 SET_VARSIZE(pgrtn, pgrtn->
size);
3700 PG_RETURN_POINTER(pgrtn);
3706 for (b = 0; b < colon_n; b++) {
3711 if (dash_n < 1 || dash_n > 3) {
3712 elog(NOTICE,
"Invalid argument for reclassargset. Invalid expression of reclassexpr for reclassarg of index %d . Returning original raster", i);
3713 for (k = 0; k < j; k++) pfree(exprset[k]);
3718 PG_FREE_IF_COPY(pgraster, 0);
3722 SET_VARSIZE(pgrtn, pgrtn->
size);
3723 PG_RETURN_POINTER(pgrtn);
3726 for (c = 0; c < dash_n; c++) {
3730 strlen(dash_set[c]) == 1 && (
3731 strchr(dash_set[c],
'(') != NULL ||
3732 strchr(dash_set[c],
'[') != NULL ||
3733 strchr(dash_set[c],
')') != NULL ||
3734 strchr(dash_set[c],
']') != NULL
3737 junk = palloc(
sizeof(
char) * (strlen(dash_set[c + 1]) + 2));
3739 for (k = 0; k <= j; k++) pfree(exprset[k]);
3742 PG_FREE_IF_COPY(pgraster, 0);
3744 elog(ERROR,
"RASTER_reclass: Could not allocate memory");
3748 sprintf(junk,
"%s%s", dash_set[c], dash_set[c + 1]);
3750 dash_set[c] = repalloc(dash_set[c],
sizeof(
char) * (strlen(junk) + 1));
3751 strcpy(dash_set[c], junk);
3755 for (k = 1; k < dash_n; k++) {
3756 dash_set[k - 1] = repalloc(dash_set[k - 1], (strlen(dash_set[k]) + 1) *
sizeof(
char));
3757 strcpy(dash_set[k - 1], dash_set[k]);
3761 pfree(dash_set[dash_n]);
3762 dash_set = repalloc(dash_set,
sizeof(
char *) * dash_n);
3766 if (c < 1 && dash_n > 2) {
3767 elog(NOTICE,
"Invalid argument for reclassargset. Invalid expression of reclassexpr for reclassarg of index %d . Returning original raster", i);
3768 for (k = 0; k < j; k++) pfree(exprset[k]);
3773 PG_FREE_IF_COPY(pgraster, 0);
3777 SET_VARSIZE(pgrtn, pgrtn->
size);
3778 PG_RETURN_POINTER(pgrtn);
3789 strchr(dash_set[c],
')') != NULL ||
3790 strchr(dash_set[c],
']') != NULL
3795 else if (strchr(dash_set[c],
'(') != NULL){
3805 strrchr(dash_set[c],
'(') != NULL ||
3806 strrchr(dash_set[c],
'[') != NULL
3811 else if (strrchr(dash_set[c],
']') != NULL) {
3819 POSTGIS_RT_DEBUGF(4,
"RASTER_reclass: exc_val %d inc_val %d", exc_val, inc_val);
3827 val = strtod(dash_set[c], &junk);
3828 if (errno != 0 || dash_set[c] == junk) {
3829 elog(NOTICE,
"Invalid argument for reclassargset. Invalid expression of reclassexpr for reclassarg of index %d . Returning original raster", i);
3830 for (k = 0; k < j; k++) pfree(exprset[k]);
3835 PG_FREE_IF_COPY(pgraster, 0);
3839 SET_VARSIZE(pgrtn, pgrtn->
size);
3840 PG_RETURN_POINTER(pgrtn);
3846 junk = strstr(colon_set[b], dash_set[c]);
3851 "(colon_set[%d], dash_set[%d], junk) = (%s, %s, %s)",
3852 b, c, colon_set[b], dash_set[c], junk
3855 if (junk != colon_set[b]) {
3857 if (*(junk - 1) ==
'-') {
3860 ((junk - 1) == colon_set[b]) ||
3861 (*(junk - 2) ==
'-') ||
3862 (*(junk - 2) ==
'[') ||
3863 (*(junk - 2) ==
'(')
3883 exprset[j]->
src.
min = val;
3889 exprset[j]->
src.
max = val;
3899 exprset[j]->
dst.
min = val;
3902 exprset[j]->
dst.
max = val;
3910 , exprset[j]->src.min
3920 tupv = GetAttributeByName(tup,
"pixeltype", &isnull);
3922 elog(NOTICE,
"Invalid argument for reclassargset. Missing value of pixeltype for reclassarg of index %d . Returning original raster", i);
3926 PG_FREE_IF_COPY(pgraster, 0);
3930 SET_VARSIZE(pgrtn, pgrtn->
size);
3931 PG_RETURN_POINTER(pgrtn);
3933 pixeltypetext = (text *) DatumGetPointer(tupv);
3934 if (NULL == pixeltypetext) {
3935 elog(NOTICE,
"Invalid argument for reclassargset. Missing value of pixeltype for reclassarg of index %d . Returning original raster", i);
3939 PG_FREE_IF_COPY(pgraster, 0);
3943 SET_VARSIZE(pgrtn, pgrtn->
size);
3944 PG_RETURN_POINTER(pgrtn);
3946 pixeltype = text_to_cstring(pixeltypetext);
3951 tupv = GetAttributeByName(tup,
"nodataval", &isnull);
3957 nodataval = DatumGetFloat8(tupv);
3966 elog(NOTICE,
"Could not find raster band of index %d. Returning original raster", nband);
3967 for (k = 0; k < j; k++) pfree(exprset[k]);
3972 PG_FREE_IF_COPY(pgraster, 0);
3976 SET_VARSIZE(pgrtn, pgrtn->
size);
3977 PG_RETURN_POINTER(pgrtn);
3979 newband =
rt_band_reclass(band, pixtype, hasnodata, nodataval, exprset, j);
3981 for (k = 0; k < j; k++) pfree(exprset[k]);
3985 PG_FREE_IF_COPY(pgraster, 0);
3987 elog(ERROR,
"RASTER_reclass: Could not reclassify raster band of index %d", nband);
3993 for (k = 0; k < j; k++) pfree(exprset[k]);
3998 PG_FREE_IF_COPY(pgraster, 0);
4000 elog(ERROR,
"RASTER_reclass: Could not replace raster band of index %d with reclassified band", nband);
4008 for (k = 0; k < j; k++) pfree(exprset[k]);
4014 PG_FREE_IF_COPY(pgraster, 0);
4020 SET_VARSIZE(pgrtn, pgrtn->
size);
4021 PG_RETURN_POINTER(pgrtn);
4044 static rtpg_colormap_arg
4046 rtpg_colormap_arg arg = NULL;
4050 elog(ERROR,
"rtpg_colormap_arg: Could not allocate memory for function arguments");
4061 elog(ERROR,
"rtpg_colormap_arg: Could not allocate memory for function arguments");
4094 for (i = 0; i < arg->
nentry; i++) {
4095 if (arg->
entry[i] != NULL)
4096 pfree(arg->
entry[i]);
4102 for (i = 0; i < arg->
nelement; i++)
4115 rtpg_colormap_arg arg = NULL;
4122 if (PG_ARGISNULL(0))
4128 elog(ERROR,
"RASTER_colorMap: Could not initialize argument structure");
4133 pgraster = (
rt_pgraster *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
4139 PG_FREE_IF_COPY(pgraster, 0);
4140 elog(ERROR,
"RASTER_colorMap: Could not deserialize raster");
4145 if (!PG_ARGISNULL(1))
4146 arg->
nband = PG_GETARG_INT32(1);
4151 elog(NOTICE,
"Raster does not have band at index %d. Returning empty raster", arg->
nband);
4154 if (raster == NULL) {
4156 PG_FREE_IF_COPY(pgraster, 0);
4157 elog(ERROR,
"RASTER_colorMap: Could not create empty raster");
4162 PG_FREE_IF_COPY(pgraster, 0);
4166 if (pgraster == NULL)
4170 PG_RETURN_POINTER(pgraster);
4175 if (arg->
band == NULL) {
4178 PG_FREE_IF_COPY(pgraster, 0);
4179 elog(ERROR,
"RASTER_colorMap: Could not get band at index %d", nband);
4184 if (!PG_ARGISNULL(3)) {
4185 char *method = NULL;
4186 char *tmp = text_to_cstring(PG_GETARG_TEXT_P(3));
4193 if (strcmp(method,
"INTERPOLATE") == 0)
4195 else if (strcmp(method,
"EXACT") == 0)
4197 else if (strcmp(method,
"NEAREST") == 0)
4200 elog(NOTICE,
"Unknown value provided for method. Defaulting to INTERPOLATE");
4210 if (PG_ARGISNULL(2)) {
4212 PG_FREE_IF_COPY(pgraster, 0);
4213 elog(ERROR,
"RASTER_colorMap: Value must be provided for colormap");
4218 char *colormap = text_to_cstring(PG_GETARG_TEXT_P(2));
4227 if (!strlen(colormap)) {
4229 PG_FREE_IF_COPY(pgraster, 0);
4230 elog(ERROR,
"RASTER_colorMap: Value must be provided for colormap");
4238 PG_FREE_IF_COPY(pgraster, 0);
4239 elog(ERROR,
"RASTER_colorMap: Could not process the value provided for colormap");
4247 PG_FREE_IF_COPY(pgraster, 0);
4248 elog(ERROR,
"RASTER_colorMap: Could not allocate memory for colormap entries");
4254 for (i = 0; i < arg->
nentry; i++) {
4268 if (!strlen(_entry)) {
4278 PG_FREE_IF_COPY(pgraster, 0);
4279 elog(ERROR,
"RASTER_colorMap: Could not process colormap entry %d", i + 1);
4283 elog(NOTICE,
"More than five elements in colormap entry %d. Using at most five elements", i + 1);
4292 for (j = 0; j < arg->
nelement; j++) {
4301 char *percent = NULL;
4305 strcmp(_element,
"NV") == 0 ||
4306 strcmp(_element,
"NULL") == 0 ||
4307 strcmp(_element,
"NODATA") == 0
4312 elog(NOTICE,
"More than one NODATA entry found. Using only the first one");
4321 else if ((percent = strchr(_element,
'%')) != NULL) {
4333 PG_FREE_IF_COPY(pgraster, 0);
4334 elog(ERROR,
"RASTER_colorMap: Could not get band's summary stats to process percentages");
4340 tmp = palloc(
sizeof(
char) * (percent - _element + 1));
4344 PG_FREE_IF_COPY(pgraster, 0);
4345 elog(ERROR,
"RASTER_colorMap: Could not allocate memory for value of percentage");
4349 memcpy(tmp, _element, percent - _element);
4350 tmp[percent - _element] =
'\0';
4355 value = strtod(tmp, NULL);
4357 if (errno != 0 || _element == junk) {
4360 PG_FREE_IF_COPY(pgraster, 0);
4361 elog(ERROR,
"RASTER_colorMap: Could not process percent string to value");
4367 elog(NOTICE,
"Percentage values cannot be less than zero. Defaulting to zero");
4370 else if (value > 100.) {
4371 elog(NOTICE,
"Percentage values cannot be greater than 100. Defaulting to 100");
4383 if (errno != 0 || _element == junk) {
4386 PG_FREE_IF_COPY(pgraster, 0);
4387 elog(ERROR,
"RASTER_colorMap: Could not process string to value");
4398 value = (int) strtod(_element, &junk);
4399 if (errno != 0 || _element == junk) {
4402 PG_FREE_IF_COPY(pgraster, 0);
4403 elog(ERROR,
"RASTER_colorMap: Could not process string to value");
4408 elog(NOTICE,
"RGBA value cannot be greater than 255. Defaulting to 255");
4411 else if (value < 0) {
4412 elog(NOTICE,
"RGBA value cannot be less than zero. Defaulting to zero");
4421 POSTGIS_RT_DEBUGF(4,
"colormap->entry[%d] (isnodata, value, R, G, B, A) = (%d, %f, %d, %d, %d, %d)",
4440 if (raster == NULL) {
4442 PG_FREE_IF_COPY(pgraster, 0);
4443 elog(ERROR,
"RASTER_colorMap: Could not create new raster with applied colormap");
4448 PG_FREE_IF_COPY(pgraster, 0);
4454 if (pgraster == NULL)
4458 PG_RETURN_POINTER(pgraster);
4472 double newnodatavalue = 0.0;
4473 double newinitialvalue = 0.0;
4474 double newval = 0.0;
4475 char *newexpr = NULL;
4476 char *initexpr = NULL;
4477 char *expression = NULL;
4478 int hasnodataval = 0;
4479 double nodataval = 0.;
4481 int skipcomputation = 0;
4483 const int argkwcount = 3;
4484 enum KEYWORDS { kVAL=0, kX=1, kY=2 };
4485 char *argkw[] = {
"[rast]",
"[rast.x]",
"[rast.y]"};
4486 Oid argkwtypes[] = { FLOAT8OID, INT4OID, INT4OID };
4488 Oid argtype[] = { FLOAT8OID, INT4OID, INT4OID };
4494 SPIPlanPtr spi_plan = NULL;
4495 SPITupleTable * tuptable = NULL;
4497 char * strFromText = NULL;
4498 Datum *values = NULL;
4499 Datum datum = (Datum)NULL;
4501 bool isnull =
FALSE;
4508 if (PG_ARGISNULL(0)) {
4509 elog(NOTICE,
"Raster is NULL. Returning NULL");
4515 pgraster = (
rt_pgraster *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
4517 if (NULL == raster) {
4518 PG_FREE_IF_COPY(pgraster, 0);
4519 elog(ERROR,
"RASTER_mapAlgebraExpr: Could not deserialize raster");
4525 if (PG_ARGISNULL(1))
4528 nband = PG_GETARG_INT32(1);
4534 POSTGIS_RT_DEBUG(3,
"RASTER_mapAlgebraExpr: Creating new empty raster...");
4545 if ( NULL == newrast ) {
4546 PG_FREE_IF_COPY(pgraster, 0);
4547 elog(ERROR,
"RASTER_mapAlgebraExpr: Could not create a new raster");
4572 elog(NOTICE,
"Raster is empty. Returning an empty raster");
4574 PG_FREE_IF_COPY(pgraster, 0);
4578 if (NULL == pgrtn) {
4580 elog(ERROR,
"RASTER_mapAlgebraExpr: Could not serialize raster");
4584 SET_VARSIZE(pgrtn, pgrtn->
size);
4585 PG_RETURN_POINTER(pgrtn);
4589 POSTGIS_RT_DEBUGF(3,
"RASTER_mapAlgebraExpr: Getting raster band %d...", nband);
4596 elog(NOTICE,
"Raster does not have the required band. Returning a raster " 4599 PG_FREE_IF_COPY(pgraster, 0);
4603 if (NULL == pgrtn) {
4604 elog(ERROR,
"RASTER_mapAlgebraExpr: Could not serialize raster");
4608 SET_VARSIZE(pgrtn, pgrtn->
size);
4609 PG_RETURN_POINTER(pgrtn);
4614 if ( NULL == band ) {
4615 elog(NOTICE,
"Could not get the required band. Returning a raster " 4618 PG_FREE_IF_COPY(pgraster, 0);
4622 if (NULL == pgrtn) {
4623 elog(ERROR,
"RASTER_mapAlgebraExpr: Could not serialize raster");
4627 SET_VARSIZE(pgrtn, pgrtn->
size);
4628 PG_RETURN_POINTER(pgrtn);
4634 POSTGIS_RT_DEBUG(3,
"RASTER_mapAlgebraExpr: Getting NODATA value for band...");
4652 newinitialvalue = newnodatavalue;
4659 if (PG_ARGISNULL(2)) {
4664 strFromText = text_to_cstring(PG_GETARG_TEXT_P(2));
4667 if (newpixeltype ==
PT_END)
4671 if (newpixeltype ==
PT_END) {
4672 PG_FREE_IF_COPY(pgraster, 0);
4673 elog(ERROR,
"RASTER_mapAlgebraExpr: Invalid pixeltype");
4682 if (!PG_ARGISNULL(3)) {
4683 expression = text_to_cstring(PG_GETARG_TEXT_P(3));
4684 len = strlen(
"SELECT (") + strlen(expression) + strlen(
")::double precision");
4685 initexpr = (
char *)palloc(len + 1);
4687 strncpy(initexpr,
"SELECT (", strlen(
"SELECT ("));
4688 strncpy(initexpr + strlen(
"SELECT ("), expression, strlen(expression));
4689 strncpy(initexpr + strlen(
"SELECT (") + strlen(expression),
")::double precision", strlen(
")::double precision"));
4690 initexpr[len] =
'\0';
4708 if (!PG_ARGISNULL(4)) {
4710 nodataval = PG_GETARG_FLOAT8(4);
4711 newinitialvalue = nodataval;
4728 POSTGIS_RT_DEBUG(3,
"RASTER_mapAlgebraExpr: Band is a nodata band, returning " 4729 "a raster filled with nodata");
4732 newinitialvalue,
TRUE, newnodatavalue, 0);
4738 PG_FREE_IF_COPY(pgraster, 0);
4743 if (NULL == pgrtn) {
4744 elog(ERROR,
"RASTER_mapAlgebraExpr: Could not serialize raster");
4748 SET_VARSIZE(pgrtn, pgrtn->
size);
4749 PG_RETURN_POINTER(pgrtn);
4757 if (initexpr != NULL && ( !strcmp(initexpr,
"SELECT [rast]") || !strcmp(initexpr,
"SELECT [rast.val]") ) && !hasnodataval) {
4760 "Returning raster with band %d from original raster", nband);
4773 PG_FREE_IF_COPY(pgraster, 0);
4778 if (NULL == pgrtn) {
4779 elog(ERROR,
"RASTER_mapAlgebraExpr: Could not serialize raster");
4783 SET_VARSIZE(pgrtn, pgrtn->
size);
4784 PG_RETURN_POINTER(pgrtn);
4791 if (initexpr != NULL && strstr(initexpr,
"[rast") == NULL) {
4792 ret = SPI_connect();
4793 if (ret != SPI_OK_CONNECT) {
4794 PG_FREE_IF_COPY(pgraster, 0);
4795 elog(ERROR,
"RASTER_mapAlgebraExpr: Could not connect to the SPI manager");
4800 ret = SPI_execute(initexpr,
FALSE, 0);
4802 if (ret != SPI_OK_SELECT || SPI_tuptable == NULL || SPI_processed != 1) {
4806 SPI_freetuptable(tuptable);
4807 PG_FREE_IF_COPY(pgraster, 0);
4810 elog(ERROR,
"RASTER_mapAlgebraExpr: Invalid construction for expression");
4814 tupdesc = SPI_tuptable->tupdesc;
4815 tuptable = SPI_tuptable;
4817 tuple = tuptable->vals[0];
4818 newexpr = SPI_getvalue(tuple, tupdesc, 1);
4820 POSTGIS_RT_DEBUG(3,
"Constant expression evaluated to NULL, keeping initvalue");
4821 newval = newinitialvalue;
4823 newval = atof(newexpr);
4826 SPI_freetuptable(tuptable);
4833 skipcomputation = 1;
4839 if (!hasnodataval) {
4840 newinitialvalue = newval;
4841 skipcomputation = 2;
4845 else if (
FLT_NEQ(newval, newinitialvalue)) {
4846 skipcomputation = 2;
4855 newinitialvalue,
TRUE, newnodatavalue, 0);
4862 if (expression == NULL || skipcomputation == 2) {
4868 PG_FREE_IF_COPY(pgraster, 0);
4873 if (NULL == pgrtn) {
4874 elog(ERROR,
"RASTER_mapAlgebraExpr: Could not serialize raster");
4878 SET_VARSIZE(pgrtn, pgrtn->
size);
4879 PG_RETURN_POINTER(pgrtn);
4882 RASTER_DEBUG(3,
"RASTER_mapAlgebraExpr: Creating new raster band...");
4886 if ( NULL == newband ) {
4887 elog(NOTICE,
"Could not modify band for new raster. Returning new " 4888 "raster with the original band");
4893 PG_FREE_IF_COPY(pgraster, 0);
4898 if (NULL == pgrtn) {
4899 elog(ERROR,
"RASTER_mapAlgebraExpr: Could not serialize raster");
4903 SET_VARSIZE(pgrtn, pgrtn->
size);
4904 PG_RETURN_POINTER(pgrtn);
4910 if (initexpr != NULL) {
4913 pfree(initexpr); initexpr=newexpr;
4915 sprintf(place,
"$1");
4916 for (i = 0, j = 1; i < argkwcount; i++) {
4919 pfree(initexpr); initexpr=newexpr;
4921 argtype[argcount] = argkwtypes[i];
4925 sprintf(place,
"$%d", j);
4935 values = (Datum *) palloc(
sizeof(Datum) * argcount);
4936 if (values == NULL) {
4941 PG_FREE_IF_COPY(pgraster, 0);
4944 elog(ERROR,
"RASTER_mapAlgebraExpr: Could not allocate memory for value parameters of prepared statement");
4949 nulls = (
char *)palloc(argcount);
4950 if (nulls == NULL) {
4955 PG_FREE_IF_COPY(pgraster, 0);
4958 elog(ERROR,
"RASTER_mapAlgebraExpr: Could not allocate memory for null parameters of prepared statement");
4963 ret = SPI_connect();
4964 if (ret != SPI_OK_CONNECT) {
4969 PG_FREE_IF_COPY(pgraster, 0);
4972 elog(ERROR,
"RASTER_mapAlgebraExpr: Could not connect to the SPI manager");
4977 spi_plan = SPI_prepare(initexpr, argcount, argtype);
4979 if (spi_plan == NULL) {
4982 PG_FREE_IF_COPY(pgraster, 0);
4989 elog(ERROR,
"RASTER_mapAlgebraExpr: Could not prepare expression");
4994 for (x = 0; x <
width; x++) {
4995 for(y = 0; y <
height; y++) {
5003 if (skipcomputation == 0) {
5004 if (initexpr != NULL) {
5006 memset(nulls,
'n', argcount);
5008 for (i = 0; i < argkwcount; i++) {
5010 if (idx < 1)
continue;
5015 values[idx] = Int32GetDatum(x+1);
5020 values[idx] = Int32GetDatum(y+1);
5023 else if (i == kVAL ) {
5024 values[idx] = Float8GetDatum(r);
5030 ret = SPI_execute_plan(spi_plan, values, nulls,
FALSE, 0);
5031 if (ret != SPI_OK_SELECT || SPI_tuptable == NULL ||
5032 SPI_processed != 1) {
5034 SPI_freetuptable(tuptable);
5036 SPI_freeplan(spi_plan);
5044 PG_FREE_IF_COPY(pgraster, 0);
5047 elog(ERROR,
"RASTER_mapAlgebraExpr: Error executing prepared plan");
5052 tupdesc = SPI_tuptable->tupdesc;
5053 tuptable = SPI_tuptable;
5055 tuple = tuptable->vals[0];
5056 datum = SPI_getbinval(tuple, tupdesc, 1, &isnull);
5057 if ( SPI_result == SPI_ERROR_NOATTRIBUTE ) {
5058 POSTGIS_RT_DEBUGF(3,
"Expression for pixel %d,%d (value %g) errored, skip setting", x+1,y+1,r);
5059 newval = newinitialvalue;
5061 else if ( isnull ) {
5062 POSTGIS_RT_DEBUGF(3,
"Expression for pixel %d,%d (value %g) evaluated to NULL, skip setting", x+1,y+1,r);
5063 newval = newinitialvalue;
5065 newval = DatumGetFloat8(datum);
5068 SPI_freetuptable(tuptable);
5072 newval = newinitialvalue;
5085 if (initexpr != NULL) {
5086 SPI_freeplan(spi_plan);
5100 POSTGIS_RT_DEBUG(3,
"RASTER_mapAlgebraExpr: raster modified, serializing it.");
5104 PG_FREE_IF_COPY(pgraster, 0);
5111 SET_VARSIZE(pgrtn, pgrtn->
size);
5119 PG_RETURN_POINTER(pgrtn);
5136 double newnodatavalue = 0.0;
5137 double newinitialvalue = 0.0;
5138 double newval = 0.0;
5143 #if POSTGIS_PGSQL_VERSION < 120 5144 FunctionCallInfoData cbdata;
5146 LOCAL_FCINFO(cbdata, FUNC_MAX_ARGS);
5149 char * strFromText = NULL;
5155 if (PG_ARGISNULL(0)) {
5156 elog(WARNING,
"Raster is NULL. Returning NULL");
5162 pgraster = (
rt_pgraster *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
5164 if (NULL == raster) {
5165 PG_FREE_IF_COPY(pgraster, 0);
5166 elog(ERROR,
"RASTER_mapAlgebraFct: Could not deserialize raster");
5174 if (PG_ARGISNULL(1))
5177 nband = PG_GETARG_INT32(1);
5193 if ( NULL == newrast ) {
5196 PG_FREE_IF_COPY(pgraster, 0);
5198 elog(ERROR,
"RASTER_mapAlgebraFct: Could not create a new raster");
5223 elog(NOTICE,
"Raster is empty. Returning an empty raster");
5225 PG_FREE_IF_COPY(pgraster, 0);
5229 if (NULL == pgrtn) {
5230 elog(ERROR,
"RASTER_mapAlgebraFct: Could not serialize raster");
5234 SET_VARSIZE(pgrtn, pgrtn->
size);
5235 PG_RETURN_POINTER(pgrtn);
5245 elog(NOTICE,
"Raster does not have the required band. Returning a raster " 5248 PG_FREE_IF_COPY(pgraster, 0);
5252 if (NULL == pgrtn) {
5253 elog(ERROR,
"RASTER_mapAlgebraFct: Could not serialize raster");
5257 SET_VARSIZE(pgrtn, pgrtn->
size);
5258 PG_RETURN_POINTER(pgrtn);
5263 if ( NULL == band ) {
5264 elog(NOTICE,
"Could not get the required band. Returning a raster " 5267 PG_FREE_IF_COPY(pgraster, 0);
5271 if (NULL == pgrtn) {
5272 elog(ERROR,
"RASTER_mapAlgebraFct: Could not serialize raster");
5276 SET_VARSIZE(pgrtn, pgrtn->
size);
5277 PG_RETURN_POINTER(pgrtn);
5283 POSTGIS_RT_DEBUG(3,
"RASTER_mapAlgebraFct: Getting NODATA value for band...");
5300 newinitialvalue = newnodatavalue;
5307 if (PG_ARGISNULL(2)) {
5312 strFromText = text_to_cstring(PG_GETARG_TEXT_P(2));
5315 if (newpixeltype ==
PT_END)
5319 if (newpixeltype ==
PT_END) {
5322 PG_FREE_IF_COPY(pgraster, 0);
5325 elog(ERROR,
"RASTER_mapAlgebraFct: Invalid pixeltype");
5333 if (PG_ARGISNULL(3)) {
5336 PG_FREE_IF_COPY(pgraster, 0);
5339 elog(ERROR,
"RASTER_mapAlgebraFct: Required function is missing. Returning NULL");
5343 oid = PG_GETARG_OID(3);
5344 if (oid == InvalidOid) {
5347 PG_FREE_IF_COPY(pgraster, 0);
5350 elog(ERROR,
"RASTER_mapAlgebraFct: Got invalid function object id. Returning NULL");
5354 fmgr_info(oid, &cbinfo);
5357 if (cbinfo.fn_retset) {
5360 PG_FREE_IF_COPY(pgraster, 0);
5363 elog(ERROR,
"RASTER_mapAlgebraFct: Function provided must return double precision not resultset");
5367 else if (cbinfo.fn_nargs < 2 || cbinfo.fn_nargs > 3) {
5370 PG_FREE_IF_COPY(pgraster, 0);
5373 elog(ERROR,
"RASTER_mapAlgebraFct: Function does not have two or three input parameters");
5377 if (cbinfo.fn_nargs == 2)
5382 if (func_volatile(oid) ==
'v') {
5383 elog(NOTICE,
"Function provided is VOLATILE. Unless required and for best performance, function should be IMMUTABLE or STABLE");
5387 #if POSTGIS_PGSQL_VERSION < 120 5388 InitFunctionCallInfoData(cbdata, &cbinfo, 2, InvalidOid, NULL, NULL);
5390 cbdata.argnull[0] =
FALSE;
5391 cbdata.argnull[1] =
FALSE;
5392 cbdata.argnull[2] =
FALSE;
5394 InitFunctionCallInfoData(*cbdata, &cbinfo, 2, InvalidOid, NULL, NULL);
5396 cbdata->args[0].isnull =
FALSE;
5397 cbdata->args[1].isnull =
FALSE;
5398 cbdata->args[2].isnull =
FALSE;
5402 if (PG_ARGISNULL(4)) {
5403 if (cbinfo.fn_strict) {
5406 PG_FREE_IF_COPY(pgraster, 0);
5409 elog(ERROR,
"RASTER_mapAlgebraFct: Strict callback functions cannot have null parameters");
5413 #if POSTGIS_PGSQL_VERSION < 120 5414 cbdata.arg[k] = (Datum)NULL;
5415 cbdata.argnull[k] =
TRUE;
5417 cbdata->args[k].value = (Datum)NULL;
5418 cbdata->args[k].isnull =
TRUE;
5422 #if POSTGIS_PGSQL_VERSION < 120 5423 cbdata.arg[k] = PG_GETARG_DATUM(4);
5425 cbdata->args[k].value = PG_GETARG_DATUM(4);
5436 POSTGIS_RT_DEBUG(3,
"RASTER_mapAlgebraFct: Band is a nodata band, returning " 5437 "a raster filled with nodata");
5440 newinitialvalue,
TRUE, newnodatavalue, 0);
5443 PG_FREE_IF_COPY(pgraster, 0);
5448 if (NULL == pgrtn) {
5449 elog(ERROR,
"RASTER_mapAlgebraFct: Could not serialize raster");
5453 SET_VARSIZE(pgrtn, pgrtn->
size);
5454 PG_RETURN_POINTER(pgrtn);
5463 newinitialvalue,
TRUE, newnodatavalue, 0);
5467 if ( NULL == newband ) {
5468 elog(NOTICE,
"Could not modify band for new raster. Returning new " 5469 "raster with the original band");
5472 PG_FREE_IF_COPY(pgraster, 0);
5477 if (NULL == pgrtn) {
5478 elog(ERROR,
"RASTER_mapAlgebraFct: Could not serialize raster");
5482 SET_VARSIZE(pgrtn, pgrtn->
size);
5483 PG_RETURN_POINTER(pgrtn);
5489 for (x = 0; x <
width; x++) {
5490 for(y = 0; y <
height; y++) {
5498 if (
FLT_EQ(r, newnodatavalue)) {
5499 if (cbinfo.fn_strict) {
5500 POSTGIS_RT_DEBUG(3,
"RASTER_mapAlgebraFct: Strict callbacks cannot accept NULL arguments, skipping NODATA cell.");
5503 #if POSTGIS_PGSQL_VERSION < 120 5504 cbdata.argnull[0] =
TRUE;
5505 cbdata.arg[0] = (Datum)NULL;
5507 cbdata->args[0].isnull =
TRUE;
5508 cbdata->args[0].value = (Datum)NULL;
5512 #if POSTGIS_PGSQL_VERSION < 120 5513 cbdata.argnull[0] =
FALSE;
5514 cbdata.arg[0] = Float8GetDatum(r);
5516 cbdata->args[0].isnull =
FALSE;
5517 cbdata->args[0].value = Float8GetDatum(r);
5522 if (cbinfo.fn_nargs == 3) {
5526 d[0] = Int32GetDatum(x+1);
5527 d[1] = Int32GetDatum(y+1);
5529 a = construct_array(d, 2, INT4OID,
sizeof(
int32),
true,
'i');
5531 #if POSTGIS_PGSQL_VERSION < 120 5532 cbdata.argnull[1] =
FALSE;
5533 cbdata.arg[1] = PointerGetDatum(a);
5535 cbdata->args[1].isnull =
FALSE;
5536 cbdata->args[1].value = PointerGetDatum(a);
5543 #if POSTGIS_PGSQL_VERSION < 120 5544 tmpnewval = FunctionCallInvoke(&cbdata);
5546 if (cbdata.isnull) {
5547 newval = newnodatavalue;
5550 tmpnewval = FunctionCallInvoke(cbdata);
5554 newval = newnodatavalue;
5558 newval = DatumGetFloat8(tmpnewval);
5572 POSTGIS_RT_DEBUG(3,
"RASTER_mapAlgebraFct: raster modified, serializing it.");
5576 PG_FREE_IF_COPY(pgraster, 0);
5587 SET_VARSIZE(pgrtn, pgrtn->
size);
5588 PG_RETURN_POINTER(pgrtn);
5603 int x,
y,
nband,
width,
height, ngbwidth, ngbheight, winwidth, winheight, u, v, nIndex, nNullItems;
5605 double newnodatavalue = 0.0;
5606 double newinitialvalue = 0.0;
5607 double newval = 0.0;
5612 #if POSTGIS_PGSQL_VERSION < 120 5613 FunctionCallInfoData cbdata;
5615 LOCAL_FCINFO(cbdata, FUNC_MAX_ARGS);
5618 ArrayType * neighborDatum;
5619 char * strFromText = NULL;
5620 text * txtNodataMode = NULL;
5621 text * txtCallbackParam = NULL;
5623 float fltReplace = 0;
5624 bool valuereplace =
false, pixelreplace, nNodataOnly =
true, nNullSkip =
false;
5625 Datum * neighborData = NULL;
5626 bool * neighborNulls = NULL;
5627 int neighborDims[2];
5636 if (PG_ARGISNULL(0)) {
5637 elog(WARNING,
"Raster is NULL. Returning NULL");
5643 pgraster = (
rt_pgraster *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
5647 PG_FREE_IF_COPY(pgraster, 0);
5648 elog(ERROR,
"RASTER_mapAlgebraFctNgb: Could not deserialize raster");
5656 if (PG_ARGISNULL(1))
5659 nband = PG_GETARG_INT32(1);
5664 POSTGIS_RT_DEBUG(3,
"RASTER_mapAlgebraFctNgb: Creating new empty raster...");
5675 if ( NULL == newrast ) {
5677 PG_FREE_IF_COPY(pgraster, 0);
5678 elog(ERROR,
"RASTER_mapAlgebraFctNgb: Could not create a new raster");
5703 elog(NOTICE,
"Raster is empty. Returning an empty raster");
5705 PG_FREE_IF_COPY(pgraster, 0);
5709 if (NULL == pgrtn) {
5710 elog(ERROR,
"RASTER_mapAlgebraFctNgb: Could not serialize raster");
5714 SET_VARSIZE(pgrtn, pgrtn->
size);
5715 PG_RETURN_POINTER(pgrtn);
5718 POSTGIS_RT_DEBUGF(3,
"RASTER_mapAlgebraFctNgb: Getting raster band %d...", nband);
5725 elog(NOTICE,
"Raster does not have the required band. Returning a raster " 5728 PG_FREE_IF_COPY(pgraster, 0);
5732 if (NULL == pgrtn) {
5733 elog(ERROR,
"RASTER_mapAlgebraFctNgb: Could not serialize raster");
5737 SET_VARSIZE(pgrtn, pgrtn->
size);
5738 PG_RETURN_POINTER(pgrtn);
5743 if ( NULL == band ) {
5744 elog(NOTICE,
"Could not get the required band. Returning a raster " 5747 PG_FREE_IF_COPY(pgraster, 0);
5751 if (NULL == pgrtn) {
5752 elog(ERROR,
"RASTER_mapAlgebraFctNgb: Could not serialize raster");
5756 SET_VARSIZE(pgrtn, pgrtn->
size);
5757 PG_RETURN_POINTER(pgrtn);
5763 POSTGIS_RT_DEBUG(3,
"RASTER_mapAlgebraFctNgb: Getting NODATA value for band...");
5780 newinitialvalue = newnodatavalue;
5787 if (PG_ARGISNULL(2)) {
5792 strFromText = text_to_cstring(PG_GETARG_TEXT_P(2));
5793 POSTGIS_RT_DEBUGF(3,
"RASTER_mapAlgebraFctNgb: Pixeltype parameter: %s", strFromText);
5796 if (newpixeltype ==
PT_END)
5800 if (newpixeltype ==
PT_END) {
5803 PG_FREE_IF_COPY(pgraster, 0);
5806 elog(ERROR,
"RASTER_mapAlgebraFctNgb: Invalid pixeltype");
5814 if (PG_ARGISNULL(5)) {
5817 PG_FREE_IF_COPY(pgraster, 0);
5820 elog(ERROR,
"RASTER_mapAlgebraFctNgb: Required function is missing");
5824 oid = PG_GETARG_OID(5);
5825 if (oid == InvalidOid) {
5828 PG_FREE_IF_COPY(pgraster, 0);
5831 elog(ERROR,
"RASTER_mapAlgebraFctNgb: Got invalid function object id");
5835 fmgr_info(oid, &cbinfo);
5838 if (cbinfo.fn_retset) {
5841 PG_FREE_IF_COPY(pgraster, 0);
5844 elog(ERROR,
"RASTER_mapAlgebraFctNgb: Function provided must return double precision not resultset");
5848 else if (cbinfo.fn_nargs != 3) {
5851 PG_FREE_IF_COPY(pgraster, 0);
5854 elog(ERROR,
"RASTER_mapAlgebraFctNgb: Function does not have three input parameters");
5858 if (func_volatile(oid) ==
'v') {
5859 elog(NOTICE,
"Function provided is VOLATILE. Unless required and for best performance, function should be IMMUTABLE or STABLE");
5863 #if POSTGIS_PGSQL_VERSION < 120 5864 InitFunctionCallInfoData(cbdata, &cbinfo, 3, InvalidOid, NULL, NULL);
5865 memset(cbdata.argnull,
FALSE,
sizeof(
bool) * 3);
5867 InitFunctionCallInfoData(*cbdata, &cbinfo, 3, InvalidOid, NULL, NULL);
5868 cbdata->args[0].isnull =
FALSE;
5869 cbdata->args[1].isnull =
FALSE;
5870 cbdata->args[2].isnull =
FALSE;
5874 if (PG_ARGISNULL(7)) {
5875 if (cbinfo.fn_strict) {
5878 PG_FREE_IF_COPY(pgraster, 0);
5881 elog(ERROR,
"RASTER_mapAlgebraFctNgb: Strict callback functions cannot have NULL parameters");
5885 #if POSTGIS_PGSQL_VERSION < 120 5886 cbdata.arg[2] = (Datum)NULL;
5887 cbdata.argnull[2] =
TRUE;
5889 cbdata->args[2].value = (Datum)NULL;
5890 cbdata->args[2].isnull =
TRUE;
5894 #if POSTGIS_PGSQL_VERSION < 120 5895 cbdata.arg[2] = PG_GETARG_DATUM(7);
5897 cbdata->args[2].value = PG_GETARG_DATUM(7);
5908 POSTGIS_RT_DEBUG(3,
"RASTER_mapAlgebraFctNgb: Band is a nodata band, returning " 5909 "a raster filled with nodata");
5912 newinitialvalue,
TRUE, newnodatavalue, 0);
5915 PG_FREE_IF_COPY(pgraster, 0);
5920 if (NULL == pgrtn) {
5921 elog(ERROR,
"RASTER_mapAlgebraFctNgb: Could not serialize raster");
5925 SET_VARSIZE(pgrtn, pgrtn->
size);
5926 PG_RETURN_POINTER(pgrtn);
5935 newinitialvalue,
TRUE, newnodatavalue, 0);
5939 if ( NULL == newband ) {
5940 elog(NOTICE,
"Could not modify band for new raster. Returning new " 5941 "raster with the original band");
5944 PG_FREE_IF_COPY(pgraster, 0);
5949 if (NULL == pgrtn) {
5950 elog(ERROR,
"RASTER_mapAlgebraFctNgb: Could not serialize raster");
5954 SET_VARSIZE(pgrtn, pgrtn->
size);
5955 PG_RETURN_POINTER(pgrtn);
5959 if (PG_ARGISNULL(3) || PG_GETARG_INT32(3) <= 0) {
5960 elog(NOTICE,
"Neighborhood width is NULL or <= 0. Returning new " 5961 "raster with the original band");
5964 PG_FREE_IF_COPY(pgraster, 0);
5969 if (NULL == pgrtn) {
5970 elog(ERROR,
"RASTER_mapAlgebraFctNgb: Could not serialize raster");
5974 SET_VARSIZE(pgrtn, pgrtn->
size);
5975 PG_RETURN_POINTER(pgrtn);
5978 ngbwidth = PG_GETARG_INT32(3);
5979 winwidth = ngbwidth * 2 + 1;
5982 if (PG_ARGISNULL(4) || PG_GETARG_INT32(4) <= 0) {
5983 elog(NOTICE,
"Neighborhood height is NULL or <= 0. Returning new " 5984 "raster with the original band");
5987 PG_FREE_IF_COPY(pgraster, 0);
5992 if (NULL == pgrtn) {
5993 elog(ERROR,
"RASTER_mapAlgebraFctNgb: Could not serialize raster");
5997 SET_VARSIZE(pgrtn, pgrtn->
size);
5998 PG_RETURN_POINTER(pgrtn);
6001 ngbheight = PG_GETARG_INT32(4);
6002 winheight = ngbheight * 2 + 1;
6005 if (PG_ARGISNULL(6)) {
6006 elog(NOTICE,
"Neighborhood NODATA behavior defaulting to 'ignore'");
6007 txtNodataMode = cstring_to_text(
"ignore");
6010 txtNodataMode = PG_GETARG_TEXT_P(6);
6013 txtCallbackParam = (text*)palloc(VARSIZE(txtNodataMode));
6014 SET_VARSIZE(txtCallbackParam, VARSIZE(txtNodataMode));
6015 memcpy((
void *)VARDATA(txtCallbackParam), (
void *)VARDATA(txtNodataMode), VARSIZE(txtNodataMode) - VARHDRSZ);
6018 #if POSTGIS_PGSQL_VERSION < 120 6019 cbdata.arg[1] = CStringGetDatum(txtCallbackParam);
6021 cbdata->args[1].value = CStringGetDatum(txtCallbackParam);
6024 strFromText = text_to_cstring(txtNodataMode);
6027 if (strcmp(strFromText,
"VALUE") == 0)
6028 valuereplace =
true;
6029 else if (strcmp(strFromText,
"IGNORE") != 0 && strcmp(strFromText,
"NULL") != 0) {
6031 if (sscanf(strFromText,
"%d", &intReplace) <= 0 && sscanf(strFromText,
"%f", &fltReplace) <= 0) {
6033 elog(NOTICE,
"Neighborhood NODATA mode is not recognized. Must be one of 'value', 'ignore', " 6034 "'NULL', or a numeric value. Returning new raster with the original band");
6037 pfree(txtCallbackParam);
6041 PG_FREE_IF_COPY(pgraster, 0);
6046 if (NULL == pgrtn) {
6047 elog(ERROR,
"RASTER_mapAlgebraFctNgb: Could not serialize raster");
6051 SET_VARSIZE(pgrtn, pgrtn->
size);
6052 PG_RETURN_POINTER(pgrtn);
6055 else if (strcmp(strFromText,
"NULL") == 0) {
6064 neighborData = (Datum *)palloc(winwidth * winheight *
sizeof(Datum));
6065 neighborNulls = (
bool *)palloc(winwidth * winheight *
sizeof(
bool));
6068 neighborDims[0] = winwidth;
6069 neighborDims[1] = winheight;
6076 get_typlenbyvalalign(FLOAT8OID, &typlen, &typbyval, &typalign);
6078 for (x = 0 + ngbwidth; x < width - ngbwidth; x++) {
6079 for(y = 0 + ngbheight; y < height - ngbheight; y++) {
6084 pixelreplace =
false;
6088 pixelreplace =
true;
6091 for (u = x - ngbwidth; u <= x + ngbwidth; u++) {
6092 for (v = y - ngbheight; v <= y + ngbheight; v++) {
6095 if (
FLT_NEQ(r, newnodatavalue)) {
6097 neighborData[nIndex] = Float8GetDatum((
double)r);
6098 neighborNulls[nIndex] =
false;
6099 nNodataOnly =
false;
6103 if (valuereplace && pixelreplace) {
6105 neighborData[nIndex] = Float8GetDatum((
double)rpix);
6106 neighborNulls[nIndex] =
false;
6111 neighborData[nIndex] = PointerGetDatum(NULL);
6112 neighborNulls[nIndex] =
true;
6119 neighborData[nIndex] = PointerGetDatum(NULL);
6120 neighborNulls[nIndex] =
true;
6132 if (!(nNodataOnly ||
6133 (nNullSkip && nNullItems > 0) ||
6134 (valuereplace && nNullItems > 0))) {
6136 x, y, winwidth, winheight);
6138 neighborDatum = construct_md_array((
void *)neighborData, neighborNulls, 2, neighborDims, neighborLbs,
6139 FLOAT8OID, typlen, typbyval, typalign);
6141 #if POSTGIS_PGSQL_VERSION < 120 6143 cbdata.arg[0] = PointerGetDatum(neighborDatum);
6146 tmpnewval = FunctionCallInvoke(&cbdata);
6149 if (cbdata.isnull) {
6150 newval = newnodatavalue;
6154 cbdata->args[0].value = PointerGetDatum(neighborDatum);
6157 tmpnewval = FunctionCallInvoke(cbdata);
6162 newval = newnodatavalue;
6166 newval = DatumGetFloat8(tmpnewval);
6182 pfree(neighborNulls);
6183 pfree(neighborData);
6185 pfree(txtCallbackParam);
6188 PG_FREE_IF_COPY(pgraster, 0);
6192 POSTGIS_RT_DEBUG(3,
"RASTER_mapAlgebraFctNgb: raster modified, serializing it.");
6203 SET_VARSIZE(pgrtn, pgrtn->
size);
6204 PG_RETURN_POINTER(pgrtn);
6207 #define ARGKWCOUNT 8 6215 const int set_count = 2;
6217 int pgrastpos[2] = {-1, -1};
6220 int _isempty[2] = {0};
6224 int _hasnodata[2] = {0};
6225 double _nodataval[2] = {0};
6226 double _offset[4] = {0.};
6227 double _rastoffset[2][4] = {{0.}};
6228 int _haspixel[2] = {0};
6229 double _pixel[2] = {0};
6230 int _pos[2][2] = {{0}};
6231 uint16_t _dim[2][2] = {{0}};
6233 char *pixtypename = NULL;
6235 char *extenttypename = NULL;
6240 uint16_t dim[2] = {0};
6243 double nodataval = 0;
6244 double gt[6] = {0.};
6246 Oid calltype = InvalidOid;
6248 const int spi_count = 3;
6249 uint16_t spi_exprpos[3] = {4, 7, 8};
6253 SPIPlanPtr spi_plan[3] = {NULL};
6254 uint16_t spi_empty = 0;
6255 Oid *argtype = NULL;
6257 char *argkw[] = {
"[rast1.x]",
"[rast1.y]",
"[rast1.val]",
"[rast1]",
"[rast2.x]",
"[rast2.y]",
"[rast2.val]",
"[rast2]"};
6261 SPITupleTable *tuptable = NULL;
6264 bool isnull =
FALSE;
6265 int hasargval[3] = {0};
6266 double argval[3] = {0.};
6267 int hasnodatanodataval = 0;
6268 double nodatanodataval = 0;
6271 Oid ufc_noid = InvalidOid;
6273 #if POSTGIS_PGSQL_VERSION < 120 6274 FunctionCallInfoData ufc_info;
6276 LOCAL_FCINFO(ufc_info, FUNC_MAX_ARGS);
6278 int ufc_nullcount = 0;
6294 for (i = 0, j = 0; i < set_count; i++) {
6295 if (!PG_ARGISNULL(j)) {
6296 pgrast[i] = (
rt_pgraster *) PG_DETOAST_DATUM(PG_GETARG_DATUM(j));
6303 for (k = 0; k <= i; k++) {
6304 if (k < i && rast[k] != NULL)
6306 if (pgrastpos[k] != -1)
6307 PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6309 elog(ERROR,
"RASTER_mapAlgebra2: Could not deserialize the %s raster", i < 1 ?
"first" :
"second");
6317 if (!PG_ARGISNULL(j)) {
6318 bandindex[i] = PG_GETARG_INT32(j);
6331 if (rast[0] == NULL && rast[1] == NULL) {
6332 elog(NOTICE,
"The two rasters provided are NULL. Returning NULL");
6333 for (k = 0; k < set_count; k++) {
6334 if (pgrastpos[k] != -1)
6335 PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6341 if (_isempty[0] && _isempty[1]) {
6342 elog(NOTICE,
"The two rasters provided are empty. Returning empty raster");
6345 if (raster == NULL) {
6346 for (k = 0; k < set_count; k++) {
6347 if (rast[k] != NULL)
6349 if (pgrastpos[k] != -1)
6350 PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6352 elog(ERROR,
"RASTER_mapAlgebra2: Could not create empty raster");
6362 SET_VARSIZE(pgrtn, pgrtn->
size);
6363 PG_RETURN_POINTER(pgrtn);
6368 (rast[0] == NULL || _isempty[0]) ||
6369 (rast[1] == NULL || _isempty[1])
6372 if (rast[0] == NULL || _isempty[0]) {
6385 if (_rast[i] != NULL)
6397 if (_rast[i] == NULL) {
6399 for (k = 0; k < set_count; k++) {
6400 if (pgrastpos[k] != -1)
6401 PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6403 elog(ERROR,
"RASTER_mapAlgebra2: Could not create NODATA raster");
6437 for (k = 0; k < set_count; k++) {
6438 if (_rast[k] != NULL)
6440 if (pgrastpos[k] != -1)
6441 PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6443 elog(ERROR,
"RASTER_mapAlgebra2: Could not test for alignment on the two rasters");
6447 elog(NOTICE,
"The two rasters provided do not have the same alignment. Returning NULL");
6448 for (k = 0; k < set_count; k++) {
6449 if (_rast[k] != NULL)
6451 if (pgrastpos[k] != -1)
6452 PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6458 if (!PG_ARGISNULL(5)) {
6459 pixtypename = text_to_cstring(PG_GETARG_TEXT_P(5));
6462 if (pixtype ==
PT_END ) {
6463 for (k = 0; k < set_count; k++) {
6464 if (_rast[k] != NULL)
6466 if (pgrastpos[k] != -1)
6467 PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6469 elog(ERROR,
"RASTER_mapAlgebra2: Invalid pixel type: %s", pixtypename);
6475 if (!PG_ARGISNULL(6)) {
6488 for (k = 0; k < set_count; k++) {
6489 if (_rast[k] != NULL)
6491 if (pgrastpos[k] != -1)
6492 PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6494 elog(ERROR,
"RASTER_mapAlgebra2: Could not get output raster of correct extent");
6499 _rastoffset[0][0] = _offset[0];
6500 _rastoffset[0][1] = _offset[1];
6501 _rastoffset[1][0] = _offset[2];
6502 _rastoffset[1][1] = _offset[3];
6510 switch (extenttype) {
6520 (extenttype ==
ET_FIRST && i == 0) ||
6524 elog(NOTICE,
"The %s raster is NULL. Returning NULL", (i != 1 ?
"FIRST" :
"SECOND"));
6525 for (k = 0; k < set_count; k++) {
6526 if (_rast[k] != NULL)
6528 if (pgrastpos[k] != -1)
6529 PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6537 elog(NOTICE,
"The %s raster does not have the band at index %d. Returning no band raster of correct extent",
6538 (i != 1 ?
"FIRST" :
"SECOND"), bandindex[i]
6541 for (k = 0; k < set_count; k++) {
6542 if (_rast[k] != NULL)
6544 if (pgrastpos[k] != -1)
6545 PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6550 if (!pgrtn) PG_RETURN_NULL();
6552 SET_VARSIZE(pgrtn, pgrtn->
size);
6553 PG_RETURN_POINTER(pgrtn);
6561 _isempty[0] || _isempty[1] ||
6564 elog(NOTICE,
"The two rasters provided have no intersection. Returning no band raster");
6567 if (dim[0] || dim[1]) {
6571 if (raster == NULL) {
6572 for (k = 0; k < set_count; k++) {
6573 if (_rast[k] != NULL)
6575 if (pgrastpos[k] != -1)
6576 PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6578 elog(ERROR,
"RASTER_mapAlgebra2: Could not create no band raster");
6586 for (k = 0; k < set_count; k++) {
6587 if (_rast[k] != NULL)
6589 if (pgrastpos[k] != -1)
6590 PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6595 if (!pgrtn) PG_RETURN_NULL();
6597 SET_VARSIZE(pgrtn, pgrtn->
size);
6598 PG_RETURN_POINTER(pgrtn);
6603 for (k = 0; k < set_count; k++) {
6604 if (_rast[k] != NULL)
6606 if (pgrastpos[k] != -1)
6607 PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6609 elog(ERROR,
"RASTER_mapAlgebra2: ET_LAST and ET_CUSTOM are not implemented");
6619 elog(NOTICE,
"The two rasters provided do not have the respectively specified band indices. Returning no band raster of correct extent");
6621 for (k = 0; k < set_count; k++) {
6622 if (_rast[k] != NULL)
6624 if (pgrastpos[k] != -1)
6625 PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6630 if (!pgrtn) PG_RETURN_NULL();
6632 SET_VARSIZE(pgrtn, pgrtn->
size);
6633 PG_RETURN_POINTER(pgrtn);
6637 for (i = 0; i < set_count; i++) {
6646 if (_band[i] == NULL) {
6647 for (k = 0; k < set_count; k++) {
6648 if (_rast[k] != NULL)
6650 if (pgrastpos[k] != -1)
6651 PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6654 elog(ERROR,
"RASTER_mapAlgebra2: Could not get band %d of the %s raster",
6656 (i < 1 ?
"FIRST" :
"SECOND")
6668 if ((extenttype ==
ET_SECOND && !_isempty[1]) || _isempty[0])
6675 if (extenttype ==
ET_SECOND && !_isempty[1] && _hasnodata[1]) {
6676 nodataval = _nodataval[1];
6678 else if (!_isempty[0] && _hasnodata[0]) {
6679 nodataval = _nodataval[0];
6681 else if (!_isempty[1] && _hasnodata[1]) {
6682 nodataval = _nodataval[1];
6685 elog(NOTICE,
"Neither raster provided has a NODATA value for the specified band indices. NODATA value set to minimum possible for %s",
rt_pixtype_name(pixtype));
6697 for (k = 0; k < set_count; k++) {
6698 if (_rast[k] != NULL)
6700 if (pgrastpos[k] != -1)
6701 PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6704 elog(ERROR,
"RASTER_mapAlgebra2: Could not add new band to output raster");
6711 for (k = 0; k < set_count; k++) {
6712 if (_rast[k] != NULL)
6714 if (pgrastpos[k] != -1)
6715 PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6718 elog(ERROR,
"RASTER_mapAlgebra2: Could not get newly added band of output raster");
6723 (
int) _rastoffset[0][0],
6724 (
int) _rastoffset[0][1],
6725 (
int) _rastoffset[1][0],
6726 (
int) _rastoffset[1][1]
6729 POSTGIS_RT_DEBUGF(4,
"metadata = (%f, %f, %d, %d, %f, %f, %f, %f, %d)",
6746 calltype = get_fn_expr_argtype(fcinfo->flinfo, 4);
6753 if (SPI_connect() != SPI_OK_CONNECT) {
6754 for (k = 0; k < set_count; k++) {
6755 if (_rast[k] != NULL)
6757 if (pgrastpos[k] != -1)
6758 PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6761 elog(ERROR,
"RASTER_mapAlgebra2: Could not connect to the SPI manager");
6766 memset(hasargval, 0,
sizeof(
int) * spi_count);
6776 for (i = 0; i < spi_count; i++) {
6777 if (!PG_ARGISNULL(spi_exprpos[i])) {
6779 char place[5] =
"$1";
6780 expr = text_to_cstring(PG_GETARG_TEXT_P(spi_exprpos[i]));
6794 sprintf(place,
"$%d", k);
6800 len = strlen(
"SELECT (") + strlen(expr) + strlen(
")::double precision");
6801 sql = (
char *) palloc(len + 1);
6804 for (k = 0; k < spi_count; k++) SPI_freeplan(spi_plan[k]);
6807 for (k = 0; k < set_count; k++) {
6808 if (_rast[k] != NULL)
6810 if (pgrastpos[k] != -1)
6811 PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6815 elog(ERROR,
"RASTER_mapAlgebra2: Could not allocate memory for expression parameter %d", spi_exprpos[i]);
6819 strncpy(sql,
"SELECT (", strlen(
"SELECT ("));
6820 strncpy(sql + strlen(
"SELECT ("), expr, strlen(expr));
6821 strncpy(sql + strlen(
"SELECT (") + strlen(expr),
")::double precision", strlen(
")::double precision"));
6827 if (spi_argcount[i]) {
6828 argtype = (Oid *) palloc(spi_argcount[i] *
sizeof(Oid));
6829 if (argtype == NULL) {
6832 for (k = 0; k < spi_count; k++) SPI_freeplan(spi_plan[k]);
6835 for (k = 0; k < set_count; k++) {
6836 if (_rast[k] != NULL)
6838 if (pgrastpos[k] != -1)
6839 PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6843 elog(ERROR,
"RASTER_mapAlgebra2: Could not allocate memory for prepared plan argtypes of expression parameter %d", spi_exprpos[i]);
6849 if (argpos[i][j] < 1)
continue;
6853 (strstr(argkw[j],
"[rast1.x]") != NULL) ||
6854 (strstr(argkw[j],
"[rast1.y]") != NULL) ||
6855 (strstr(argkw[j],
"[rast2.x]") != NULL) ||
6856 (strstr(argkw[j],
"[rast2.y]") != NULL)
6858 argtype[k] = INT4OID;
6862 argtype[k] = FLOAT8OID;
6868 spi_plan[i] = SPI_prepare(sql, spi_argcount[i], argtype);
6871 if (spi_plan[i] == NULL) {
6874 for (k = 0; k < spi_count; k++) SPI_freeplan(spi_plan[k]);
6877 for (k = 0; k < set_count; k++) {
6878 if (_rast[k] != NULL)
6880 if (pgrastpos[k] != -1)
6881 PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6885 elog(ERROR,
"RASTER_mapAlgebra2: Could not create prepared plan of expression parameter %d", spi_exprpos[i]);
6891 err = SPI_execute(sql,
TRUE, 0);
6892 if (err != SPI_OK_SELECT || SPI_tuptable == NULL || SPI_processed != 1) {
6895 for (k = 0; k < spi_count; k++) SPI_freeplan(spi_plan[k]);
6898 for (k = 0; k < set_count; k++) {
6899 if (_rast[k] != NULL)
6901 if (pgrastpos[k] != -1)
6902 PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6906 elog(ERROR,
"RASTER_mapAlgebra2: Could not evaluate expression parameter %d", spi_exprpos[i]);
6911 tupdesc = SPI_tuptable->tupdesc;
6912 tuptable = SPI_tuptable;
6913 tuple = tuptable->vals[0];
6915 datum = SPI_getbinval(tuple, tupdesc, 1, &isnull);
6916 if (SPI_result == SPI_ERROR_NOATTRIBUTE) {
6919 if (SPI_tuptable) SPI_freetuptable(tuptable);
6920 for (k = 0; k < spi_count; k++) SPI_freeplan(spi_plan[k]);
6923 for (k = 0; k < set_count; k++) {
6924 if (_rast[k] != NULL)
6926 if (pgrastpos[k] != -1)
6927 PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6931 elog(ERROR,
"RASTER_mapAlgebra2: Could not get result of expression parameter %d", spi_exprpos[i]);
6937 argval[i] = DatumGetFloat8(datum);
6940 if (SPI_tuptable) SPI_freetuptable(tuptable);
6950 if (!PG_ARGISNULL(9)) {
6951 hasnodatanodataval = 1;
6952 nodatanodataval = PG_GETARG_FLOAT8(9);
6955 hasnodatanodataval = 0;
6958 case REGPROCEDUREOID: {
6960 if (!PG_ARGISNULL(4)) {
6963 ufc_noid = PG_GETARG_OID(4);
6966 fmgr_info(ufc_noid, &ufl_info);
6970 if (ufl_info.fn_retset) {
6974 else if (ufl_info.fn_nargs < 3 || ufl_info.fn_nargs > 4) {
6984 for (k = 0; k < set_count; k++) {
6985 if (_rast[k] != NULL)
6987 if (pgrastpos[k] != -1)
6988 PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
6993 elog(ERROR,
"RASTER_mapAlgebra2: Function provided must have three or four input parameters");
6995 elog(ERROR,
"RASTER_mapAlgebra2: Function provided must return double precision not resultset");
6999 if (func_volatile(ufc_noid) ==
'v') {
7000 elog(NOTICE,
"Function provided is VOLATILE. Unless required and for best performance, function should be IMMUTABLE or STABLE");
7004 #if POSTGIS_PGSQL_VERSION < 120 7005 InitFunctionCallInfoData(ufc_info, &ufl_info, ufl_info.fn_nargs, InvalidOid, NULL, NULL);
7006 memset(ufc_info.argnull,
FALSE,
sizeof(
bool) * ufl_info.fn_nargs);
7008 InitFunctionCallInfoData(
7009 *ufc_info, &ufl_info, ufl_info.fn_nargs, InvalidOid, NULL, NULL);
7010 ufc_info->args[0].isnull =
FALSE;
7011 ufc_info->args[1].isnull =
FALSE;
7012 ufc_info->args[2].isnull =
FALSE;
7013 if (ufl_info.fn_nargs == 4)
7014 ufc_info->args[3].isnull =
FALSE;
7017 if (ufl_info.fn_nargs != 4)
7021 #if POSTGIS_PGSQL_VERSION < 120 7022 if (!PG_ARGISNULL(7)) {
7023 ufc_info.arg[k] = PG_GETARG_DATUM(7);
7026 ufc_info.arg[k] = (Datum) NULL;
7027 ufc_info.argnull[k] =
TRUE;
7031 if (!PG_ARGISNULL(7))
7033 ufc_info->args[k].value = PG_GETARG_DATUM(7);
7037 ufc_info->args[k].value = (Datum)NULL;
7038 ufc_info->args[k].isnull =
TRUE;
7046 for (k = 0; k < set_count; k++) {
7047 if (_rast[k] != NULL)
7049 if (pgrastpos[k] != -1)
7050 PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
7053 elog(ERROR,
"RASTER_mapAlgebra2: Invalid data type for expression or userfunction");
7061 (calltype == TEXTOID) && (
7062 (spi_empty != spi_count) || hasnodatanodataval
7065 (calltype == REGPROCEDUREOID) && (ufc_noid != InvalidOid)
7067 for (x = 0; x < dim[0]; x++) {
7068 for (y = 0; y < dim[1]; y++) {
7071 for (i = 0; i < set_count; i++) {
7076 _x = x - (int) _rastoffset[i][0];
7077 _y = y - (int) _rastoffset[i][1];
7080 _pos[i][0] = _x + 1;
7081 _pos[i][1] = _y + 1;
7084 if (_band[i] == NULL) {
7085 if (!_hasnodata[i]) {
7087 _pixel[i] = _nodataval[i];
7092 (_x >= 0 && _x < _dim[i][0]) &&
7093 (_y >= 0 && _y < _dim[i][1])
7098 if (calltype == TEXTOID) {
7099 for (k = 0; k < spi_count; k++) SPI_freeplan(spi_plan[k]);
7103 for (k = 0; k < set_count; k++) {
7104 if (_rast[k] != NULL)
7106 if (pgrastpos[k] != -1)
7107 PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
7111 elog(ERROR,
"RASTER_mapAlgebra2: Could not get pixel of %s raster", (i < 1 ?
"FIRST" :
"SECOND"));
7115 if (!_hasnodata[i] || !isnodata)
7134 if (!_haspixel[0] && !_haspixel[1])
7138 else if (_haspixel[0] && !_haspixel[1])
7142 else if (!_haspixel[0] && _haspixel[1])
7151 if (hasnodatanodataval) {
7153 pixel = nodatanodataval;
7157 else if (hasargval[i]) {
7162 else if (spi_plan[i] != NULL) {
7166 if (spi_argcount[i]) {
7168 memset(values, (Datum) NULL,
sizeof(Datum) *
ARGKWCOUNT);
7170 memset(nulls,
FALSE,
sizeof(
bool) * ARGKWCOUNT);
7175 if (idx < 1)
continue;
7178 if (strstr(argkw[j],
"[rast1.x]") != NULL) {
7179 values[idx] = _pos[0][0];
7181 else if (strstr(argkw[j],
"[rast1.y]") != NULL) {
7182 values[idx] = _pos[0][1];
7185 (strstr(argkw[j],
"[rast1.val]") != NULL) ||
7186 (strstr(argkw[j],
"[rast1]") != NULL)
7188 if (_isempty[0] || !_haspixel[0])
7191 values[idx] = Float8GetDatum(_pixel[0]);
7193 else if (strstr(argkw[j],
"[rast2.x]") != NULL) {
7194 values[idx] = _pos[1][0];
7196 else if (strstr(argkw[j],
"[rast2.y]") != NULL) {
7197 values[idx] = _pos[1][1];
7200 (strstr(argkw[j],
"[rast2.val]") != NULL) ||
7201 (strstr(argkw[j],
"[rast2]") != NULL)
7203 if (_isempty[1] || !_haspixel[1])
7206 values[idx] = Float8GetDatum(_pixel[1]);
7212 err = SPI_execute_plan(spi_plan[i], values, nulls,
TRUE, 1);
7213 if (err != SPI_OK_SELECT || SPI_tuptable == NULL || SPI_processed != 1) {
7215 for (k = 0; k < spi_count; k++) SPI_freeplan(spi_plan[k]);
7218 for (k = 0; k < set_count; k++) {
7219 if (_rast[k] != NULL)
7221 if (pgrastpos[k] != -1)
7222 PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
7226 elog(ERROR,
"RASTER_mapAlgebra2: Unexpected error when running prepared statement %d", i);
7231 tupdesc = SPI_tuptable->tupdesc;
7232 tuptable = SPI_tuptable;
7233 tuple = tuptable->vals[0];
7235 datum = SPI_getbinval(tuple, tupdesc, 1, &isnull);
7236 if (SPI_result == SPI_ERROR_NOATTRIBUTE) {
7238 if (SPI_tuptable) SPI_freetuptable(tuptable);
7239 for (k = 0; k < spi_count; k++) SPI_freeplan(spi_plan[k]);
7242 for (k = 0; k < set_count; k++) {
7243 if (_rast[k] != NULL)
7245 if (pgrastpos[k] != -1)
7246 PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
7250 elog(ERROR,
"RASTER_mapAlgebra2: Could not get result of prepared statement %d", i);
7256 pixel = DatumGetFloat8(datum);
7259 if (SPI_tuptable) SPI_freetuptable(tuptable);
7262 case REGPROCEDUREOID: {
7267 for (i = 0; i < set_count; i++) {
7268 #if POSTGIS_PGSQL_VERSION < 120 7269 ufc_info.arg[i] = Float8GetDatum(_pixel[i]);
7271 ufc_info->args[i].value = Float8GetDatum(_pixel[i]);
7275 #if POSTGIS_PGSQL_VERSION < 120 7276 ufc_info.argnull[i] =
FALSE;
7278 ufc_info->args[i].isnull =
FALSE;
7283 #if POSTGIS_PGSQL_VERSION < 120 7284 ufc_info.argnull[i] =
TRUE;
7286 ufc_info->args[i].isnull =
TRUE;
7294 if (ufl_info.fn_strict && ufc_nullcount)
7298 if (ufl_info.fn_nargs == 4) {
7301 for (i = 0; i < set_count; i++) {
7303 d[0] = Int32GetDatum(_pos[i][0]);
7304 d[1] = Int32GetDatum(_pos[i][1]);
7307 d[2] = Int32GetDatum(_pos[i][0]);
7308 d[3] = Int32GetDatum(_pos[i][1]);
7312 a = construct_array(d, 4, INT4OID,
sizeof(
int32),
true,
'i');
7313 #if POSTGIS_PGSQL_VERSION < 120 7314 ufc_info.arg[2] = PointerGetDatum(a);
7315 ufc_info.argnull[2] =
FALSE;
7317 ufc_info->args[2].value = PointerGetDatum(a);
7318 ufc_info->args[2].isnull =
FALSE;
7322 #if POSTGIS_PGSQL_VERSION < 120 7323 datum = FunctionCallInvoke(&ufc_info);
7326 if (!ufc_info.isnull) {
7328 pixel = DatumGetFloat8(datum);
7331 datum = FunctionCallInvoke(ufc_info);
7334 if (!ufc_info->isnull)
7337 pixel = DatumGetFloat8(datum);
7347 if (calltype == TEXTOID) {
7348 for (k = 0; k < spi_count; k++) SPI_freeplan(spi_plan[k]);
7352 for (k = 0; k < set_count; k++) {
7353 if (_rast[k] != NULL)
7355 if (pgrastpos[k] != -1)
7356 PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
7360 elog(ERROR,
"RASTER_mapAlgebra2: Could not set pixel value of output raster");
7365 POSTGIS_RT_DEBUGF(5,
"(x, y, val) = (%d, %d, %f)", x, y, haspixel ? pixel : nodataval);
7372 if (calltype == TEXTOID) {
7373 for (i = 0; i < spi_count; i++) {
7374 if (spi_plan[i] != NULL) SPI_freeplan(spi_plan[i]);
7379 for (k = 0; k < set_count; k++) {
7380 if (_rast[k] != NULL)
7382 if (pgrastpos[k] != -1)
7383 PG_FREE_IF_COPY(pgrast[k], pgrastpos[k]);
7388 if (!pgrtn) PG_RETURN_NULL();
7392 SET_VARSIZE(pgrtn, pgrtn->
size);
7393 PG_RETURN_POINTER(pgrtn);
struct rtpg_colormap_arg_t * rtpg_colormap_arg
static int rtpg_union_range_callback(rt_iterator_arg arg, void *userarg, double *value, int *nodata)
int clamp_srid(int srid)
Return a valid SRID from an arbitrary integer Raises a notice if what comes out is different from wha...
char ** rtpg_strsplit(const char *str, const char *delimiter, int *n)
Datum RASTER_union_transfn(PG_FUNCTION_ARGS)
Datum RASTER_mapAlgebraFctNgb(PG_FUNCTION_ARGS)
Datum RASTER_colorMap(PG_FUNCTION_ARGS)
void * rt_raster_serialize(rt_raster raster)
Return this raster in serialized form.
double rt_raster_get_x_offset(rt_raster raster)
Get raster x offset, in projection units.
int rt_raster_get_num_bands(rt_raster raster)
Datum RASTER_nMapAlgebra(PG_FUNCTION_ARGS)
double rt_raster_get_y_skew(rt_raster raster)
Get skew about the Y axis.
static int rtpg_nmapalgebra_callback(rt_iterator_arg arg, void *userarg, double *value, int *nodata)
rt_errorstate rt_raster_same_alignment(rt_raster rast1, rt_raster rast2, int *aligned, char **reason)
static void rtpg_clip_arg_destroy(rtpg_clip_arg arg)
LWGEOM * lwgeom_from_gserialized(const GSERIALIZED *g)
Allocate a new LWGEOM from a GSERIALIZED.
rtpg_nmapalgebra_arg bandarg
raster
Be careful!! Zeros function's input parameter can be a (height x width) array, not (width x height): ...
rt_raster rt_raster_from_band(rt_raster raster, uint32_t *bandNums, int count)
Construct a new rt_raster from an existing rt_raster and an array of band numbers.
struct rt_reclassexpr_t::rt_reclassrange dst
rtpg_union_band_arg bandarg
void rt_raster_set_geotransform_matrix(rt_raster raster, double *gt)
Set raster's geotransform using 6-element array.
void rt_raster_get_geotransform_matrix(rt_raster raster, double *gt)
Get 6-element array of raster geotransform matrix.
void rt_raster_set_skews(rt_raster raster, double skewX, double skewY)
Set skews about the X and Y axis.
char * rtpg_strreplace(const char *str, const char *oldstr, const char *newstr, int *count)
struct rtpg_nmapalgebra_arg_t * rtpg_nmapalgebra_arg
void lwgeom_free(LWGEOM *geom)
static int rtpg_union_unionarg_process(rtpg_union_arg arg, ArrayType *array)
struct rtpg_nmapalgebraexpr_callback_arg::@18 kw
rt_errorstate rt_raster_from_two_rasters(rt_raster rast1, rt_raster rast2, rt_extenttype extenttype, rt_raster *rtnraster, double *offset)
static int rtpg_nmapalgebraexpr_callback(rt_iterator_arg arg, void *userarg, double *value, int *nodata)
rt_raster rt_raster_gdal_rasterize(const unsigned char *wkb, uint32_t wkb_len, const char *srs, uint32_t num_bands, rt_pixtype *pixtype, double *init, double *value, double *nodata, uint8_t *hasnodata, int *width, int *height, double *scale_x, double *scale_y, double *ul_xw, double *ul_yw, double *grid_xw, double *grid_yw, double *skew_x, double *skew_y, char **options)
Return a raster of the provided geometry.
static void rtpg_colormap_arg_destroy(rtpg_colormap_arg arg)
int rt_util_same_geotransform_matrix(double *gt1, double *gt2)
void rt_band_destroy(rt_band band)
Destroy a raster band.
static int rtpg_clip_callback(rt_iterator_arg arg, void *userarg, double *value, int *nodata)
int lwgeom_ndims(const LWGEOM *geom)
Return the number of dimensions (2, 3, 4) in a geometry.
int rt_raster_is_empty(rt_raster raster)
Return TRUE if the raster is empty.
#define POSTGIS_RT_DEBUGF(level, msg,...)
rt_errorstate rt_band_get_nodata(rt_band band, double *nodata)
Get NODATA value.
struct rtpg_clip_band_t * rtpg_clip_band
rt_errorstate rt_raster_get_convex_hull(rt_raster raster, LWGEOM **hull)
Get raster's convex hull.
struct rtpg_union_band_arg_t * rtpg_union_band_arg
struct rtpg_nmapalgebraexpr_callback_arg::@17 nodatanodata
Datum RASTER_mapAlgebraExpr(PG_FUNCTION_ARGS)
PG_FUNCTION_INFO_V1(RASTER_nMapAlgebra)
static void rtpg_nmapalgebra_arg_destroy(rtpg_nmapalgebra_arg arg)
struct rt_reclassexpr_t::rt_reclassrange src
static int rtpg_union_mean_callback(rt_iterator_arg arg, void *userarg, double *value, int *nodata)
uint8_t * lwgeom_to_wkb(const LWGEOM *geom, uint8_t variant, size_t *size_out)
Convert LWGEOM to a char* in WKB format.
rtpg_nmapalgebra_callback_arg callback
rt_errorstate rt_band_get_pixel(rt_band band, int x, int y, double *value, int *nodata)
Get pixel value.
enum rt_colormap_t::@7 method
rt_extenttype rt_util_extent_type(const char *name)
void rt_raster_set_scale(rt_raster raster, double scaleX, double scaleY)
Set scale in projection units.
int rt_raster_generate_new_band(rt_raster raster, rt_pixtype pixtype, double initialvalue, uint32_t hasnodata, double nodatavalue, int index)
Generate a new inline band and add it to a raster.
rt_pixtype rt_pixtype_index_from_name(const char *pixname)
static rtpg_nmapalgebraexpr_arg rtpg_nmapalgebraexpr_arg_init(int cnt, char **kw)
rt_errorstate rt_band_get_pixel_line(rt_band band, int x, int y, uint16_t len, void **vals, uint16_t *nvals)
Get values of multiple pixels.
rt_raster rt_raster_clone(rt_raster raster, uint8_t deep)
Clone an existing raster.
void rt_raster_set_offsets(rt_raster raster, double x, double y)
Set insertion points in projection units.
#define SRID_UNKNOWN
Unknown SRID value.
LWGEOM * lwgeom_intersection(const LWGEOM *geom1, const LWGEOM *geom2)
LWGEOM * lwgeom_force_2d(const LWGEOM *geom)
Strip out the Z/M components of an LWGEOM.
rt_band rt_raster_get_band(rt_raster raster, int bandNum)
Return Nth band, or NULL if unavailable.
int rt_raster_copy_band(rt_raster torast, rt_raster fromrast, int fromindex, int toindex)
Copy one band from one raster to another.
static int rtpg_nmapalgebra_rastbandarg_process(rtpg_nmapalgebra_arg arg, ArrayType *array, int *allnull, int *allempty, int *noband)
int rt_band_get_hasnodata_flag(rt_band band)
Get hasnodata flag value.
struct rtpg_clip_arg_t * rtpg_clip_arg
static int rtpg_union_callback(rt_iterator_arg arg, void *userarg, double *value, int *nodata)
double rt_raster_get_x_scale(rt_raster raster)
Get scale X in projection units.
char * rtpg_trim(const char *input)
int rt_raster_has_band(rt_raster raster, int nband)
Return TRUE if the raster has a band of this number.
struct rtpg_nmapalgebraexpr_arg_t * rtpg_nmapalgebraexpr_arg
double rt_pixtype_get_min_value(rt_pixtype pixtype)
Return minimum value possible for pixel type.
static rtpg_colormap_arg rtpg_colormap_arg_init()
void rt_raster_set_srid(rt_raster raster, int32_t srid)
Set raster's SRID.
int32_t rt_raster_get_srid(rt_raster raster)
Get raster's SRID.
struct rtpg_nmapalgebraexpr_callback_arg::@16 expr[3]
void rt_raster_destroy(rt_raster raster)
Release memory associated to a raster.
rt_band rt_raster_replace_band(rt_raster raster, rt_band band, int index)
Replace band at provided index with new band.
rt_bandstats rt_band_get_summary_stats(rt_band band, int exclude_nodata_value, double sample, int inc_vals, uint64_t *cK, double *cM, double *cQ)
Compute summary statistics for a band.
static void rtpg_nmapalgebraexpr_arg_destroy(rtpg_nmapalgebraexpr_arg arg)
static int rtpg_union_noarg(rtpg_union_arg arg, rt_raster raster)
double rt_raster_get_y_scale(rt_raster raster)
Get scale Y in projection units.
rt_raster rt_raster_new(uint32_t width, uint32_t height)
Construct a raster with given dimensions.
double rt_raster_get_x_skew(rt_raster raster)
Get skew about the X axis.
Datum distance(PG_FUNCTION_ARGS)
static void rtpg_union_arg_destroy(rtpg_union_arg arg)
static rtpg_union_type rtpg_uniontype_index_from_name(const char *cutype)
char * rtpg_chartrim(const char *input, char *remove)
uint16_t rt_raster_get_width(rt_raster raster)
#define RASTER_DEBUG(level, msg)
Datum RASTER_mapAlgebraFct(PG_FUNCTION_ARGS)
char * rtpg_removespaces(char *str)
double rt_band_get_min_value(rt_band band)
Returns the minimal possible value for the band according to the pixel type.
const char * rt_pixtype_name(rt_pixtype pixtype)
rt_errorstate rt_raster_iterator(rt_iterator itrset, uint16_t itrcount, rt_extenttype extenttype, rt_raster customextent, rt_pixtype pixtype, uint8_t hasnodata, double nodataval, uint16_t distancex, uint16_t distancey, rt_mask mask, void *userarg, int(*callback)(rt_iterator_arg arg, void *userarg, double *value, int *nodata), rt_raster *rtnraster)
n-raster iterator.
static rtpg_clip_arg rtpg_clip_arg_init()
rt_pixtype rt_band_get_pixtype(rt_band band)
Return pixeltype of this band.
rt_errorstate rt_band_set_pixel_line(rt_band band, int x, int y, void *vals, uint32_t len)
Set values of multiple pixels.
struct rtpg_union_arg_t * rtpg_union_arg
int rt_raster_add_band(rt_raster raster, rt_band band, int index)
Add band data to a raster.
Datum RASTER_union_finalfn(PG_FUNCTION_ARGS)
Datum RASTER_mapAlgebra2(PG_FUNCTION_ARGS)
rtpg_nmapalgebraexpr_callback_arg callback
rtpg_union_type uniontype
int rt_band_get_isnodata_flag(rt_band band)
Get isnodata flag value.
rt_errorstate rt_band_set_pixel(rt_band band, int x, int y, double val, int *converted)
Set single pixel's value.
rt_band rt_band_reclass(rt_band srcband, rt_pixtype pixtype, uint32_t hasnodata, double nodataval, rt_reclassexpr *exprset, int exprcount)
Returns new band with values reclassified.
uint16_t rt_raster_get_height(rt_raster raster)
#define POSTGIS_RT_DEBUG(level, msg)
char * rtpg_strrstr(const char *s1, const char *s2)
int lwgeom_is_empty(const LWGEOM *geom)
Return true or false depending on whether a geometry is an "empty" geometry (no vertices members) ...
Datum RASTER_nMapAlgebraExpr(PG_FUNCTION_ARGS)
static rtpg_nmapalgebra_arg rtpg_nmapalgebra_arg_init()
rt_raster rt_raster_colormap(rt_raster raster, int nband, rt_colormap colormap)
Returns a new raster with up to four 8BUI bands (RGBA) from applying a colormap to the user-specified...
rt_raster rt_raster_deserialize(void *serialized, int header_only)
Return a raster from a serialized form.
double rt_raster_get_y_offset(rt_raster raster)
Get raster y offset, in projection units.
int32_t gserialized_get_srid(const GSERIALIZED *s)
Extract the SRID from the serialized form (it is packed into three bytes so this is a handy function)...
char * rtpg_strtoupper(char *str)
Datum RASTER_clip(PG_FUNCTION_ARGS)
FunctionCallInfoData ufc_info
Datum RASTER_reclass(PG_FUNCTION_ARGS)