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"
80 #if defined(__clang__)
81 # pragma clang diagnostic push
82 # pragma clang diagnostic ignored "-Wgnu-variable-sized-type-not-at-end"
89 #if POSTGIS_PGSQL_VERSION < 120
94 FunctionCallInfoBaseData fcinfo;
95 char fcinfo_data[SizeForFunctionCallInfo(FUNC_MAX_ARGS)];
97 FunctionCallInfo ufc_info;
101 #if defined(__clang__)
102 # pragma clang diagnostic pop
134 elog(ERROR,
"rtpg_nmapalgebra_arg_init: Could not allocate memory for arguments");
158 #if POSTGIS_PGSQL_VERSION >= 120
170 if (arg->
raster != NULL) {
187 if( arg->
mask != NULL )
210 if (arg == NULL || array == NULL) {
211 elog(ERROR,
"rtpg_nmapalgebra_rastbandarg_process: NULL values not permitted for parameters");
215 etype = ARR_ELEMTYPE(array);
216 get_typlenbyvalalign(etype, &typlen, &typbyval, &typalign);
221 typlen, typbyval, typalign,
226 elog(ERROR,
"rtpg_nmapalgebra_rastbandarg_process: Invalid argument for rastbandarg");
244 arg->
nband == NULL ||
248 elog(ERROR,
"rtpg_nmapalgebra_rastbandarg_process: Could not allocate memory for processing rastbandarg");
257 for (i = 0; i < n; i++) {
272 tup = (HeapTupleHeader) DatumGetPointer(e[i]);
274 elog(ERROR,
"rtpg_nmapalgebra_rastbandarg_process: Invalid argument for rastbandarg at index %d", i);
280 tupv = GetAttributeByName(tup,
"rast", &isnull);
282 elog(NOTICE,
"First argument (nband) of rastbandarg at index %d is NULL. Assuming NULL raster", i);
296 for (j = 0; j < i; j++) {
308 if (arg->
raster[i] == NULL) {
309 elog(ERROR,
"rtpg_nmapalgebra_rastbandarg_process: Could not deserialize raster at index %d", i);
325 tupv = GetAttributeByName(tup,
"nband", &isnull);
328 elog(NOTICE,
"First argument (nband) of rastbandarg at index %d is NULL. Assuming nband = %d", i,
nband);
331 nband = DatumGetInt32(tupv);
334 elog(ERROR,
"rtpg_nmapalgebra_rastbandarg_process: Band number provided for rastbandarg at index %d must be greater than zero (1-based)", i);
358 arg->
nband == NULL ||
361 elog(ERROR,
"rtpg_nmapalgebra_rastbandarg_process: Could not reallocate memory for processed rastbandarg");
376 double *
value,
int *nodata
384 ArrayType *mdValues = NULL;
385 Datum *_values = NULL;
386 bool *_nodata = NULL;
388 ArrayType *mdPos = NULL;
397 int lbound[3] = {1, 1, 1};
398 Datum datum = (Datum) NULL;
412 if (_values == NULL || _nodata == NULL) {
413 elog(ERROR,
"rtpg_nmapalgebra_callback: Could not allocate memory for values array");
420 for (z = 0; z < arg->
rasters; z++) {
422 for (
y = 0;
y < arg->
rows;
y++) {
428 _nodata[i] = (bool) arg->
nodata[z][
y][
x];
430 _values[i] = Float8GetDatum(arg->
values[z][
y][
x]);
432 _values[i] = (Datum) NULL;
440 get_typlenbyvalalign(FLOAT8OID, &typlen, &typbyval, &typalign);
443 mdValues = construct_md_array(
447 typlen, typbyval, typalign
452 _pos = palloc(
sizeof(Datum) * (arg->
rasters + 1) * 2);
453 _null = palloc(
sizeof(
bool) * (arg->
rasters + 1) * 2);
454 if (_pos == NULL || _null == NULL) {
456 elog(ERROR,
"rtpg_nmapalgebra_callback: Could not allocate memory for position array");
459 memset(_null, 0,
sizeof(
bool) * (arg->
rasters + 1) * 2);
468 for (z = 0; z < arg->
rasters; z++) {
477 get_typlenbyvalalign(INT4OID, &typlen, &typbyval, &typalign);
485 mdPos = construct_md_array(
489 typlen, typbyval, typalign
494 #if POSTGIS_PGSQL_VERSION < 120
495 callback->
ufc_info.arg[0] = PointerGetDatum(mdValues);
496 callback->
ufc_info.arg[1] = PointerGetDatum(mdPos);
498 callback->
ufc_info->args[0].value = PointerGetDatum(mdValues);
499 callback->
ufc_info->args[1].value = PointerGetDatum(mdPos);
503 #if POSTGIS_PGSQL_VERSION < 120
504 datum = FunctionCallInvoke(&(callback->
ufc_info));
506 datum = FunctionCallInvoke(callback->
ufc_info);
512 #if POSTGIS_PGSQL_VERSION < 120
520 *
value = DatumGetFloat8(datum);
523 *
value = (double) DatumGetFloat4(datum);
526 *
value = (double) DatumGetInt32(datum);
529 *
value = (double) DatumGetInt16(datum);
547 ArrayType *maskArray;
578 elog(ERROR,
"RASTER_nMapAlgebra: Could not initialize argument structure");
585 elog(ERROR,
"RASTER_nMapAlgebra: Could not process rastbandarg");
589 POSTGIS_RT_DEBUGF(4,
"allnull, allempty, noband = %d, %d, %d", allnull, allempty, noband);
593 elog(NOTICE,
"All input rasters are NULL. Returning NULL");
599 if (!PG_ARGISNULL(2)) {
606 elog(ERROR,
"RASTER_nMapAlgebra: Invalid pixel type: %s", pixtypename);
612 if (!PG_ARGISNULL(3)){
613 arg->
distance[0] = PG_GETARG_INT32(3);
618 if (!PG_ARGISNULL(4)){
619 arg->
distance[1] = PG_GETARG_INT32(4);
625 elog(ERROR,
"RASTER_nMapAlgebra: Distance for X and Y axis must be greater than or equal to zero");
630 if (!PG_ARGISNULL(5)) {
638 if (PG_ARGISNULL(6)) {
639 elog(NOTICE,
"Custom extent is NULL. Returning NULL");
650 elog(ERROR,
"RASTER_nMapAlgebra: Could not deserialize custom extent");
654 elog(NOTICE,
"Custom extent is an empty raster. Returning empty raster");
659 elog(ERROR,
"RASTER_nMapAlgebra: Could not create empty raster");
665 if (!pgraster) PG_RETURN_NULL();
667 SET_VARSIZE(pgraster, pgraster->
size);
668 PG_RETURN_POINTER(pgraster);
674 if( PG_ARGISNULL(7) ){
679 maskArray = PG_GETARG_ARRAYTYPE_P(7);
680 etype = ARR_ELEMTYPE(maskArray);
681 get_typlenbyvalalign(etype,&typlen,&typbyval,&typalign);
689 elog(ERROR,
"RASTER_nMapAlgebra: Mask data type must be FLOAT8 or FLOAT4");
693 ndims = ARR_NDIM(maskArray);
696 elog(ERROR,
"RASTER_nMapAlgebra: Mask Must be a 2D array");
701 maskDims = ARR_DIMS(maskArray);
703 if (maskDims[0] % 2 == 0 || maskDims[1] % 2 == 0) {
704 elog(ERROR,
"RASTER_nMapAlgebra: Mask dimensions must be odd");
712 typlen, typbyval,typalign,
713 &maskElements,&maskNulls,&num
716 if (num < 1 || num != (maskDims[0] * maskDims[1])) {
721 elog(ERROR,
"RASTER_nMapAlgebra: Could not deconstruct new values array");
727 arg->
mask->
values = palloc(
sizeof(
double*)* maskDims[0]);
728 arg->
mask->
nodata = palloc(
sizeof(
int*)*maskDims[0]);
729 for (i = 0; i < maskDims[0]; i++) {
730 arg->
mask->
values[i] = (
double*) palloc(
sizeof(
double) * maskDims[1]);
731 arg->
mask->
nodata[i] = (
int*) palloc(
sizeof(
int) * maskDims[1]);
736 for (
y = 0;
y < maskDims[0];
y++) {
737 for (
x = 0;
x < maskDims[1];
x++) {
745 arg->
mask->
values[
y][
x] = (double) DatumGetFloat4(maskElements[i]);
749 arg->
mask->
values[
y][
x] = (double) DatumGetFloat8(maskElements[i]);
760 if (maskDims[0] == 1 && maskDims[1] == 1) {
771 if (PG_ARGISNULL(8) || !PG_GETARG_BOOL(8)) {
772 if (arg->
mask != NULL)
783 elog(NOTICE,
"All input rasters are empty. Returning empty raster");
788 elog(NOTICE,
"All input rasters do not have bands at indicated indexes. Returning empty raster");
796 elog(ERROR,
"RASTER_nMapAlgebra: Could not create empty raster");
802 if (!pgraster) PG_RETURN_NULL();
804 SET_VARSIZE(pgraster, pgraster->
size);
805 PG_RETURN_POINTER(pgraster);
809 if (!PG_ARGISNULL(1) || get_fn_expr_argtype(fcinfo->flinfo, 1) == REGPROCEDUREOID) {
828 get_func_result_type(
855 elog(ERROR,
"RASTER_nMapAlgebra: Function provided must return a double precision, float, int or smallint");
858 elog(ERROR,
"RASTER_nMapAlgebra: Function provided must return scalar (double precision, float, int, smallint)");
861 elog(ERROR,
"RASTER_nMapAlgebra: Function provided must have three input parameters");
864 elog(ERROR,
"RASTER_nMapAlgebra: Function provided must return double precision, not resultset");
871 elog(NOTICE,
"Function provided is VOLATILE. Unless required and for best performance, function should be IMMUTABLE or STABLE");
874 #if POSTGIS_PGSQL_VERSION < 120
892 if (!PG_ARGISNULL(9))
893 #if POSTGIS_PGSQL_VERSION < 120
902 #if POSTGIS_PGSQL_VERSION < 120
904 construct_empty_array(TEXTOID)
908 arg->
callback.
ufc_info->args[2].value = PointerGetDatum(construct_empty_array(TEXTOID));
913 #if POSTGIS_PGSQL_VERSION < 120
925 elog(ERROR,
"RASTER_nMapAlgebra: callbackfunc must be provided");
970 if (itrset == NULL) {
972 elog(ERROR,
"RASTER_nMapAlgebra: Could not allocate memory for iterator arguments");
1001 elog(ERROR,
"RASTER_nMapAlgebra: Could not run raster iterator function");
1015 SET_VARSIZE(pgraster, pgraster->
size);
1016 PG_RETURN_POINTER(pgraster);
1060 elog(ERROR,
"rtpg_nmapalgebraexpr_arg_init: Could not allocate memory for arguments");
1066 elog(ERROR,
"rtpg_nmapalgebraexpr_arg_init: Could not allocate memory for arg->bandarg");
1079 elog(ERROR,
"rtpg_nmapalgebraexpr_arg_init: Could not allocate memory for spi_argpos");
1110 double *
value,
int *nodata
1113 SPIPlanPtr plan = NULL;
1133 else if (arg->
nodata[0][0][0] && !arg->
nodata[1][0][0]) {
1143 else if (!arg->
nodata[0][0][0] && arg->
nodata[1][0][0]) {
1170 if (arg->
nodata[0][0][0]) {
1206 SPITupleTable *tuptable = NULL;
1209 bool isnull =
FALSE;
1214 memset(values, (Datum) NULL,
sizeof(Datum) * callback->
kw.
count);
1215 memset(nulls,
FALSE,
sizeof(
char) * callback->
kw.
count);
1220 for (i = 0; i < callback->
kw.
count; i++) {
1222 if (idx < 1)
continue;
1228 values[idx] = Int32GetDatum(arg->
src_pixel[0][0] + 1);
1232 values[idx] = Int32GetDatum(arg->
src_pixel[0][1] + 1);
1238 if (!arg->
nodata[0][0][0])
1239 values[idx] = Float8GetDatum(arg->
values[0][0][0]);
1246 values[idx] = Int32GetDatum(arg->
src_pixel[0][0] + 1);
1250 values[idx] = Int32GetDatum(arg->
src_pixel[0][1] + 1);
1256 if (!arg->
nodata[0][0][0])
1257 values[idx] = Float8GetDatum(arg->
values[0][0][0]);
1264 values[idx] = Int32GetDatum(arg->
src_pixel[1][0] + 1);
1268 values[idx] = Int32GetDatum(arg->
src_pixel[1][1] + 1);
1274 if (!arg->
nodata[1][0][0])
1275 values[idx] = Float8GetDatum(arg->
values[1][0][0]);
1285 err = SPI_execute_plan(plan, values, nulls,
TRUE, 1);
1286 if (err != SPI_OK_SELECT || SPI_tuptable == NULL || SPI_processed != 1) {
1287 elog(ERROR,
"rtpg_nmapalgebraexpr_callback: Unexpected error when running prepared statement %d",
id);
1292 tupdesc = SPI_tuptable->tupdesc;
1293 tuptable = SPI_tuptable;
1294 tuple = tuptable->vals[0];
1296 datum = SPI_getbinval(tuple, tupdesc, 1, &isnull);
1297 if (SPI_result == SPI_ERROR_NOATTRIBUTE) {
1298 if (SPI_tuptable) SPI_freetuptable(tuptable);
1299 elog(ERROR,
"rtpg_nmapalgebraexpr_callback: Could not get result of prepared statement %d",
id);
1304 *
value = DatumGetFloat8(datum);
1324 if (SPI_tuptable) SPI_freetuptable(tuptable);
1334 MemoryContext mainMemCtx = CurrentMemoryContext;
1337 uint16_t exprpos[3] = {1, 4, 5};
1351 SPITupleTable *tuptable = NULL;
1354 bool isnull =
FALSE;
1360 const int argkwcount = 12;
1376 if (PG_ARGISNULL(0))
1382 elog(ERROR,
"RASTER_nMapAlgebraExpr: Could not initialize argument structure");
1389 elog(ERROR,
"RASTER_nMapAlgebra: Could not process rastbandarg");
1393 POSTGIS_RT_DEBUGF(4,
"allnull, allempty, noband = %d, %d, %d", allnull, allempty, noband);
1397 elog(NOTICE,
"All input rasters are NULL. Returning NULL");
1409 if (!PG_ARGISNULL(2)) {
1416 elog(ERROR,
"RASTER_nMapAlgebraExpr: Invalid pixel type: %s", pixtypename);
1423 if (!PG_ARGISNULL(3)) {
1429 if (numraster < 2) {
1430 elog(NOTICE,
"CUSTOM extent type not supported. Defaulting to FIRST");
1434 elog(NOTICE,
"CUSTOM extent type not supported. Defaulting to INTERSECTION");
1438 else if (numraster < 2)
1444 if (!PG_ARGISNULL(6)) {
1452 elog(NOTICE,
"All input rasters are empty. Returning empty raster");
1457 elog(NOTICE,
"All input rasters do not have bands at indicated indexes. Returning empty raster");
1465 elog(ERROR,
"RASTER_nMapAlgebraExpr: Could not create empty raster");
1471 if (!pgraster) PG_RETURN_NULL();
1473 SET_VARSIZE(pgraster, pgraster->
size);
1474 PG_RETURN_POINTER(pgraster);
1478 if (SPI_connect() != SPI_OK_CONNECT) {
1480 elog(ERROR,
"RASTER_nMapAlgebraExpr: Could not connect to the SPI manager");
1496 char place[12] =
"$1";
1498 if (PG_ARGISNULL(exprpos[i]))
1504 for (j = 0, k = 1; j < argkwcount; j++) {
1516 sprintf(place,
"$%d", k);
1522 len = strlen(
"SELECT (") + strlen(expr) + strlen(
")::double precision");
1523 sql = (
char *) palloc(len + 1);
1527 elog(ERROR,
"RASTER_nMapAlgebraExpr: Could not allocate memory for expression parameter %d", exprpos[i]);
1531 memcpy(
sql,
"SELECT (", strlen(
"SELECT ("));
1532 memcpy(
sql + strlen(
"SELECT ("), expr, strlen(expr));
1533 memcpy(
sql + strlen(
"SELECT (") + strlen(expr),
")::double precision", strlen(
")::double precision"));
1542 if (argtype == NULL) {
1546 elog(ERROR,
"RASTER_nMapAlgebraExpr: Could not allocate memory for prepared plan argtypes of expression parameter %d", exprpos[i]);
1551 for (j = 0, k = 0; j < argkwcount; j++) {
1556 (strstr(argkw[j],
"[rast.x]") != NULL) ||
1557 (strstr(argkw[j],
"[rast.y]") != NULL) ||
1558 (strstr(argkw[j],
"[rast1.x]") != NULL) ||
1559 (strstr(argkw[j],
"[rast1.y]") != NULL) ||
1560 (strstr(argkw[j],
"[rast2.x]") != NULL) ||
1561 (strstr(argkw[j],
"[rast2.y]") != NULL)
1563 argtype[k] = INT4OID;
1566 argtype[k] = FLOAT8OID;
1578 elog(ERROR,
"RASTER_nMapAlgebraExpr: Could not create prepared plan of expression parameter %d", exprpos[i]);
1584 POSTGIS_RT_DEBUGF(3,
"expression parameter %d has no args, simply executing", exprpos[i]);
1585 err = SPI_execute(
sql,
TRUE, 0);
1588 if (err != SPI_OK_SELECT || SPI_tuptable == NULL || SPI_processed != 1) {
1591 elog(ERROR,
"RASTER_nMapAlgebraExpr: Could not evaluate expression parameter %d", exprpos[i]);
1596 tupdesc = SPI_tuptable->tupdesc;
1597 tuptable = SPI_tuptable;
1598 tuple = tuptable->vals[0];
1600 datum = SPI_getbinval(tuple, tupdesc, 1, &isnull);
1601 if (SPI_result == SPI_ERROR_NOATTRIBUTE) {
1602 if (SPI_tuptable) SPI_freetuptable(tuptable);
1605 elog(ERROR,
"RASTER_nMapAlgebraExpr: Could not get result of expression parameter %d", exprpos[i]);
1614 if (SPI_tuptable) SPI_freetuptable(tuptable);
1634 for (i = 0; i < numraster; i++) {
1658 if (itrset == NULL) {
1661 elog(ERROR,
"RASTER_nMapAlgebra: Could not allocate memory for iterator arguments");
1666 for (i = 0; i < numraster; i++) {
1690 elog(ERROR,
"RASTER_nMapAlgebraExpr: Could not run raster iterator function");
1693 else if (
raster == NULL) {
1699 MemoryContextSwitchTo(mainMemCtx);
1710 SET_VARSIZE(pgraster, pgraster->
size);
1711 PG_RETURN_POINTER(pgraster);
1731 assert(cutype && strlen(cutype) > 0);
1733 if (strcmp(cutype,
"LAST") == 0)
1735 else if (strcmp(cutype,
"FIRST") == 0)
1737 else if (strcmp(cutype,
"MIN") == 0)
1739 else if (strcmp(cutype,
"MAX") == 0)
1741 else if (strcmp(cutype,
"COUNT") == 0)
1743 else if (strcmp(cutype,
"SUM") == 0)
1745 else if (strcmp(cutype,
"MEAN") == 0)
1747 else if (strcmp(cutype,
"RANGE") == 0)
1774 for (i = 0; i < arg->
numband; i++) {
1798 double *
value,
int *nodata
1810 elog(ERROR,
"rtpg_union_callback: Invalid arguments passed to callback");
1826 else if (!arg->
nodata[0][0][0] && arg->
nodata[1][0][0]) {
1832 else if (arg->
nodata[0][0][0] && !arg->
nodata[1][0][0]) {
1860 else if (!arg->
nodata[0][0][0] && arg->
nodata[1][0][0])
1863 else if (arg->
nodata[0][0][0] && !arg->
nodata[1][0][0])
1889 double *
value,
int *nodata
1899 elog(ERROR,
"rtpg_union_mean_callback: Invalid arguments passed to callback");
1925 double *
value,
int *nodata
1935 elog(ERROR,
"rtpg_union_range_callback: Invalid arguments passed to callback");
1968 HeapTupleHeader tup;
1974 char *utypename = NULL;
1977 etype = ARR_ELEMTYPE(array);
1978 get_typlenbyvalalign(etype, &typlen, &typbyval, &typalign);
1983 typlen, typbyval, typalign,
1988 elog(ERROR,
"rtpg_union_unionarg_process: Invalid argument for unionarg");
1996 elog(ERROR,
"rtpg_union_unionarg_process: Could not allocate memory for band information");
2001 for (i = 0; i < n; i++) {
2010 tup = (HeapTupleHeader) DatumGetPointer(e[i]);
2012 elog(ERROR,
"rtpg_union_unionarg_process: Invalid argument for unionarg");
2017 tupv = GetAttributeByName(tup,
"nband", &isnull);
2020 elog(NOTICE,
"First argument (nband) of unionarg is NULL. Assuming nband = %d",
nband);
2023 nband = DatumGetInt32(tupv);
2026 elog(ERROR,
"rtpg_union_unionarg_process: Band number must be greater than zero (1-based)");
2031 tupv = GetAttributeByName(tup,
"uniontype", &isnull);
2033 elog(NOTICE,
"Second argument (uniontype) of unionarg is NULL. Assuming uniontype = LAST");
2058 elog(ERROR,
"rtpg_union_unionarg_process: Could not reallocate memory for band information");
2075 if (numbands <= arg->numband)
2085 elog(ERROR,
"rtpg_union_noarg: Could not reallocate memory for band information");
2091 for (; i < arg->
numband; i++) {
2099 elog(ERROR,
"rtpg_union_noarg: Could not allocate memory for working rasters");
2108 elog(ERROR,
"rtpg_union_noarg: Could not create working raster");
2121 MemoryContext aggcontext;
2122 MemoryContext oldcontext;
2132 int isempty[2] = {0};
2133 int hasband[2] = {0};
2135 double _offset[4] = {0.};
2143 char *utypename = NULL;
2147 double nodataval = 0;
2153 uint16_t _dim[2] = {0};
2160 if (!AggCheckCallContext(fcinfo, &aggcontext)) {
2161 elog(ERROR,
"RASTER_union_transfn: Cannot be called in a non-aggregate context");
2166 oldcontext = MemoryContextSwitchTo(aggcontext);
2168 if (PG_ARGISNULL(0)) {
2173 MemoryContextSwitchTo(oldcontext);
2174 elog(ERROR,
"RASTER_union_transfn: Could not allocate memory for state variable");
2190 if (!PG_ARGISNULL(1)) {
2192 pgraster = (
rt_pgraster *) PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
2199 PG_FREE_IF_COPY(pgraster, 1);
2201 MemoryContextSwitchTo(oldcontext);
2202 elog(ERROR,
"RASTER_union_transfn: Could not deserialize raster");
2215 if (!PG_ARGISNULL(2)) {
2216 Oid calltype = get_fn_expr_argtype(fcinfo->flinfo, 2);
2251 if (numband > idx) {
2269 PG_FREE_IF_COPY(pgraster, 1);
2272 MemoryContextSwitchTo(oldcontext);
2273 elog(ERROR,
"RASTER_union_transfn: Could not allocate memory for band information");
2278 for (i = idx; i < iwr->
numband; i++) {
2302 nband = PG_GETARG_INT32(2);
2308 PG_FREE_IF_COPY(pgraster, 1);
2311 MemoryContextSwitchTo(oldcontext);
2312 elog(ERROR,
"RASTER_union_transfn: Band number must be greater than zero (1-based)");
2323 PG_FREE_IF_COPY(pgraster, 1);
2326 MemoryContextSwitchTo(oldcontext);
2327 elog(ERROR,
"RASTER_union_transfn: Could not allocate memory for band information");
2348 PG_FREE_IF_COPY(pgraster, 1);
2351 MemoryContextSwitchTo(oldcontext);
2352 elog(ERROR,
"RASTER_union_transfn: Could not process unionarg");
2361 if (nargs > 3 && !PG_ARGISNULL(3)) {
2376 for (i = 0; i < iwr->
numband; i++) {
2391 PG_FREE_IF_COPY(pgraster, 1);
2394 MemoryContextSwitchTo(oldcontext);
2395 elog(ERROR,
"RASTER_union_transfn: Could not allocate memory for working raster(s)");
2410 PG_FREE_IF_COPY(pgraster, 1);
2413 MemoryContextSwitchTo(oldcontext);
2414 elog(ERROR,
"RASTER_union_transfn: Could not create working raster");
2431 PG_FREE_IF_COPY(pgraster, 1);
2434 MemoryContextSwitchTo(oldcontext);
2435 elog(ERROR,
"RASTER_union_transfn: Could not check and balance number of bands");
2442 if (itrset == NULL) {
2447 PG_FREE_IF_COPY(pgraster, 1);
2450 MemoryContextSwitchTo(oldcontext);
2451 elog(ERROR,
"RASTER_union_transfn: Could not allocate memory for iterator arguments");
2456 for (i = 0; i < iwr->
numband; i++) {
2476 if (!isempty[0] && hasband[0])
2478 else if (!isempty[1] && hasband[1])
2485 if (_band != NULL) {
2523 itrset[0].
nband = 0;
2539 if (!isempty[0] && !isempty[1] && hasband[0] && hasband[1]) {
2553 PG_FREE_IF_COPY(pgraster, 1);
2556 MemoryContextSwitchTo(oldcontext);
2557 elog(ERROR,
"RASTER_union_transfn: Could not create internal raster");
2561 _offset[0], _offset[1], _offset[2], _offset[3]);
2568 double igt[6] = {0};
2584 hasnodata, nodataval,
2593 PG_FREE_IF_COPY(pgraster, 1);
2596 MemoryContextSwitchTo(oldcontext);
2597 elog(ERROR,
"RASTER_union_transfn: Could not add new band to internal raster");
2605 for (
y = 0;
y < _dim[1];
y++) {
2606 POSTGIS_RT_DEBUGF(4,
"Getting pixel line of working raster at (x, y, length) = (0, %d, %d)",
y, _dim[0]);
2620 PG_FREE_IF_COPY(pgraster, 1);
2623 MemoryContextSwitchTo(oldcontext);
2624 elog(ERROR,
"RASTER_union_transfn: Could not get pixel line from band of working raster");
2628 POSTGIS_RT_DEBUGF(4,
"Setting pixel line at (x, y, length) = (%d, %d, %d)", (
int) _offset[0], (
int) _offset[1] +
y, nvals);
2631 (
int) _offset[0], (
int) _offset[1] +
y,
2641 PG_FREE_IF_COPY(pgraster, 1);
2644 MemoryContextSwitchTo(oldcontext);
2645 elog(ERROR,
"RASTER_union_transfn: Could not set pixel line to band of internal raster");
2661 hasnodata, nodataval,
2678 PG_FREE_IF_COPY(pgraster, 1);
2681 MemoryContextSwitchTo(oldcontext);
2682 elog(ERROR,
"RASTER_union_transfn: Could not run raster iterator function");
2690 for (
y = 0;
y < _dim[1];
y++) {
2691 POSTGIS_RT_DEBUGF(4,
"Getting pixel line of iterator raster at (x, y, length) = (0, %d, %d)",
y, _dim[0]);
2707 PG_FREE_IF_COPY(pgraster, 1);
2710 MemoryContextSwitchTo(oldcontext);
2711 elog(ERROR,
"RASTER_union_transfn: Could not get pixel line from band of working raster");
2715 POSTGIS_RT_DEBUGF(4,
"Setting pixel line at (x, y, length) = (%d, %d, %d)", (
int) _offset[2], (
int) _offset[3] +
y, nvals);
2718 (
int) _offset[2], (
int) _offset[3] +
y,
2730 PG_FREE_IF_COPY(pgraster, 1);
2733 MemoryContextSwitchTo(oldcontext);
2734 elog(ERROR,
"RASTER_union_transfn: Could not set pixel line to band of internal raster");
2754 hasnodata, nodataval,
2768 PG_FREE_IF_COPY(pgraster, 1);
2771 MemoryContextSwitchTo(oldcontext);
2772 elog(ERROR,
"RASTER_union_transfn: Could not run raster iterator function");
2791 PG_FREE_IF_COPY(pgraster, 1);
2795 MemoryContextSwitchTo(oldcontext);
2799 PG_RETURN_POINTER(iwr);
2819 double nodataval = 0;
2824 if (!AggCheckCallContext(fcinfo, NULL)) {
2825 elog(ERROR,
"RASTER_union_finalfn: Cannot be called in a non-aggregate context");
2830 if (PG_ARGISNULL(0))
2837 if (itrset == NULL) {
2839 elog(ERROR,
"RASTER_union_finalfn: Could not allocate memory for iterator arguments");
2843 for (i = 0; i < iwr->
numband; i++) {
2858 itrset[0].
nband = 0;
2860 itrset[1].
nband = 0;
2868 hasnodata, nodataval,
2881 hasnodata, nodataval,
2895 elog(ERROR,
"RASTER_union_finalfn: Could not run raster iterator function");
2901 if (_raster == NULL)
2909 status = (_rtn == NULL) ? -1 : 0;
2934 elog(ERROR,
"RASTER_union_finalfn: Could not add band to final raster");
2943 if (!_rtn) PG_RETURN_NULL();
2953 SET_VARSIZE(pgraster, pgraster->
size);
2954 PG_RETURN_POINTER(pgraster);
2983 elog(ERROR,
"rtpg_clip_arg_init: Could not allocate memory for function arguments");
2997 if (arg->
band != NULL)
3002 if (arg->
mask != NULL)
3010 double *
value,
int *nodata
3038 unsigned char *wkb = NULL;
3067 if (PG_ARGISNULL(0) || PG_ARGISNULL(2))
3073 elog(ERROR,
"RASTER_clip: Could not initialize argument structure");
3078 pgraster = (
rt_pgraster *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
3082 if (arg->
raster == NULL) {
3084 PG_FREE_IF_COPY(pgraster, 0);
3085 elog(ERROR,
"RASTER_clip: Could not deserialize raster");
3091 elog(NOTICE,
"Input raster is empty or has no bands. Returning empty raster");
3094 PG_FREE_IF_COPY(pgraster, 0);
3098 elog(ERROR,
"RASTER_clip: Could not create empty raster");
3107 SET_VARSIZE(pgrtn, pgrtn->
size);
3108 PG_RETURN_POINTER(pgrtn);
3116 gser = PG_GETARG_GSERIALIZED_P(2);
3128 elog(NOTICE,
"Geometry provided does not have the same SRID as the raster. Returning NULL");
3131 PG_FREE_IF_COPY(pgraster, 0);
3133 PG_FREE_IF_COPY(gser, 2);
3139 if (!PG_ARGISNULL(4) && !PG_GETARG_BOOL(4))
3146 PG_FREE_IF_COPY(pgraster, 0);
3148 PG_FREE_IF_COPY(gser, 2);
3150 elog(ERROR,
"RASTER_clip: Could not get convex hull of raster");
3157 PG_FREE_IF_COPY(gser, 2);
3162 elog(NOTICE,
"The input raster and input geometry do not intersect. Returning empty raster");
3165 PG_FREE_IF_COPY(pgraster, 0);
3170 elog(ERROR,
"RASTER_clip: Could not create empty raster");
3179 SET_VARSIZE(pgrtn, pgrtn->
size);
3180 PG_RETURN_POINTER(pgrtn);
3184 if (!PG_ARGISNULL(1)) {
3185 array = PG_GETARG_ARRAYTYPE_P(1);
3186 etype = ARR_ELEMTYPE(array);
3187 get_typlenbyvalalign(etype, &typlen, &typbyval, &typalign);
3195 PG_FREE_IF_COPY(pgraster, 0);
3197 elog(ERROR,
"RASTER_clip: Invalid data type for band indexes");
3204 typlen, typbyval, typalign,
3209 if (arg->
band == NULL) {
3211 PG_FREE_IF_COPY(pgraster, 0);
3213 elog(ERROR,
"RASTER_clip: Could not allocate memory for band arguments");
3217 for (i = 0, j = 0; i < arg->
numbands; i++) {
3218 if (nulls[i])
continue;
3222 arg->
band[j].
nband = DatumGetInt16(e[i]) - 1;
3225 arg->
band[j].
nband = DatumGetInt32(e[i]) - 1;
3232 if (j < arg->numbands) {
3234 if (arg->
band == NULL) {
3236 PG_FREE_IF_COPY(pgraster, 0);
3238 elog(ERROR,
"RASTER_clip: Could not reallocate memory for band arguments");
3246 for (i = 0; i < arg->
numbands; i++) {
3248 elog(NOTICE,
"Band at index %d not found in raster", arg->
band[i].
nband + 1);
3250 PG_FREE_IF_COPY(pgraster, 0);
3265 if (arg->
band == NULL) {
3268 PG_FREE_IF_COPY(pgraster, 0);
3271 elog(ERROR,
"RASTER_clip: Could not allocate memory for band arguments");
3275 for (i = 0; i < arg->
numbands; i++) {
3284 if (!PG_ARGISNULL(3)) {
3285 array = PG_GETARG_ARRAYTYPE_P(3);
3286 etype = ARR_ELEMTYPE(array);
3287 get_typlenbyvalalign(etype, &typlen, &typbyval, &typalign);
3295 PG_FREE_IF_COPY(pgraster, 0);
3297 elog(ERROR,
"RASTER_clip: Invalid data type for NODATA values");
3304 typlen, typbyval, typalign,
3309 for (i = 0, j = 0; i < arg->
numbands; i++, j++) {
3350 if (arg->
mask == NULL) {
3352 PG_FREE_IF_COPY(pgraster, 0);
3353 elog(ERROR,
"RASTER_clip: Could not rasterize intersection geometry");
3364 if (itrset == NULL) {
3366 PG_FREE_IF_COPY(pgraster, 0);
3367 elog(ERROR,
"RASTER_clip: Could not allocate memory for iterator arguments");
3372 for (i = 0; i < arg->
numbands; i++) {
3373 POSTGIS_RT_DEBUGF(4,
"band arg %d (nband, hasnodata, nodataval) = (%d, %d, %f)",
3401 PG_FREE_IF_COPY(pgraster, 0);
3402 elog(ERROR,
"RASTER_clip: Could not create output raster");
3411 PG_FREE_IF_COPY(pgraster, 0);
3412 elog(ERROR,
"RASTER_clip: Could not add NODATA band to output raster");
3426 itrset[1].
nband = 0;
3434 hasnodata, nodataval,
3446 PG_FREE_IF_COPY(pgraster, 0);
3447 elog(ERROR,
"RASTER_clip: Could not run raster iterator function");
3462 PG_FREE_IF_COPY(pgraster, 0);
3463 elog(NOTICE,
"RASTER_clip: Could not get band from working raster");
3472 PG_FREE_IF_COPY(pgraster, 0);
3473 elog(ERROR,
"RASTER_clip: Could not add new band to output raster");
3483 PG_FREE_IF_COPY(pgraster, 0);
3493 SET_VARSIZE(pgrtn, pgrtn->
size);
3494 PG_RETURN_POINTER(pgrtn);
3527 HeapTupleHeader tup;
3532 text *exprtext = NULL;
3537 char *pixeltype = NULL;
3538 text *pixeltypetext = NULL;
3540 double nodataval = 0;
3541 bool hasnodata =
FALSE;
3543 char **comma_set = NULL;
3545 char **colon_set = NULL;
3547 char **dash_set = NULL;
3553 if (PG_ARGISNULL(0))
3555 pgraster = (
rt_pgraster *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
3560 PG_FREE_IF_COPY(pgraster, 0);
3561 elog(ERROR,
"RASTER_reclass: Could not deserialize raster");
3565 POSTGIS_RT_DEBUGF(3,
"RASTER_reclass: %d possible bands to be reclassified", numBands);
3569 array = PG_GETARG_ARRAYTYPE_P(1);
3570 etype = ARR_ELEMTYPE(array);
3571 get_typlenbyvalalign(etype, &typlen, &typbyval, &typalign);
3573 deconstruct_array(array, etype, typlen, typbyval, typalign, &e,
3577 elog(NOTICE,
"Invalid argument for reclassargset. Returning original raster");
3581 PG_FREE_IF_COPY(pgraster, 0);
3585 SET_VARSIZE(pgrtn, pgrtn->
size);
3586 PG_RETURN_POINTER(pgrtn);
3594 for (i = 0; i < n; i++) {
3595 if (nulls[i])
continue;
3598 tup = (HeapTupleHeader) DatumGetPointer(e[i]);
3600 elog(NOTICE,
"Invalid argument for reclassargset. Returning original raster");
3604 PG_FREE_IF_COPY(pgraster, 0);
3608 SET_VARSIZE(pgrtn, pgrtn->
size);
3609 PG_RETURN_POINTER(pgrtn);
3613 tupv = GetAttributeByName(tup,
"nband", &isnull);
3615 elog(NOTICE,
"Invalid argument for reclassargset. Missing value of nband for reclassarg of index %d . Returning original raster", i);
3619 PG_FREE_IF_COPY(pgraster, 0);
3623 SET_VARSIZE(pgrtn, pgrtn->
size);
3624 PG_RETURN_POINTER(pgrtn);
3626 nband = DatumGetInt32(tupv);
3630 if (nband < 1 || nband > numBands) {
3631 elog(NOTICE,
"Invalid argument for reclassargset. Invalid band index (must use 1-based) for reclassarg of index %d . Returning original raster", i);
3635 PG_FREE_IF_COPY(pgraster, 0);
3639 SET_VARSIZE(pgrtn, pgrtn->
size);
3640 PG_RETURN_POINTER(pgrtn);
3644 tupv = GetAttributeByName(tup,
"reclassexpr", &isnull);
3646 elog(NOTICE,
"Invalid argument for reclassargset. Missing value of reclassexpr for reclassarg of index %d . Returning original raster", i);
3650 PG_FREE_IF_COPY(pgraster, 0);
3654 SET_VARSIZE(pgrtn, pgrtn->
size);
3655 PG_RETURN_POINTER(pgrtn);
3657 exprtext = (text *) DatumGetPointer(tupv);
3658 if (NULL == exprtext) {
3659 elog(NOTICE,
"Invalid argument for reclassargset. Missing value of reclassexpr for reclassarg of index %d . Returning original raster", i);
3663 PG_FREE_IF_COPY(pgraster, 0);
3667 SET_VARSIZE(pgrtn, pgrtn->
size);
3668 PG_RETURN_POINTER(pgrtn);
3679 elog(NOTICE,
"Invalid argument for reclassargset. Invalid expression of reclassexpr for reclassarg of index %d . Returning original raster", i);
3683 PG_FREE_IF_COPY(pgraster, 0);
3687 SET_VARSIZE(pgrtn, pgrtn->
size);
3688 PG_RETURN_POINTER(pgrtn);
3695 for (a = 0, j = 0; a < comma_n; a++) {
3701 elog(NOTICE,
"Invalid argument for reclassargset. Invalid expression of reclassexpr for reclassarg of index %d . Returning original raster", i);
3702 for (k = 0; k < j; k++) pfree(exprset[k]);
3707 PG_FREE_IF_COPY(pgraster, 0);
3711 SET_VARSIZE(pgrtn, pgrtn->
size);
3712 PG_RETURN_POINTER(pgrtn);
3718 for (b = 0; b < colon_n; b++) {
3723 if (dash_n < 1 || dash_n > 3) {
3724 elog(NOTICE,
"Invalid argument for reclassargset. Invalid expression of reclassexpr for reclassarg of index %d . Returning original raster", i);
3725 for (k = 0; k < j; k++) pfree(exprset[k]);
3730 PG_FREE_IF_COPY(pgraster, 0);
3734 SET_VARSIZE(pgrtn, pgrtn->
size);
3735 PG_RETURN_POINTER(pgrtn);
3738 for (c = 0; c < dash_n; c++) {
3742 strlen(dash_set[c]) == 1 && (
3743 strchr(dash_set[c],
'(') != NULL ||
3744 strchr(dash_set[c],
'[') != NULL ||
3745 strchr(dash_set[c],
')') != NULL ||
3746 strchr(dash_set[c],
']') != NULL
3750 junk = palloc(
sizeof(
char) * (strlen(dash_set[c + 1]) + 2));
3752 for (k = 0; k <= j; k++) pfree(exprset[k]);
3755 PG_FREE_IF_COPY(pgraster, 0);
3757 elog(ERROR,
"RASTER_reclass: Could not allocate memory");
3761 sprintf(junk,
"%s%s", dash_set[c], dash_set[c + 1]);
3763 dash_set[c] = repalloc(dash_set[c],
sizeof(
char) * (strlen(junk) + 1));
3764 strcpy(dash_set[c], junk);
3768 for (dash_it = 1; dash_it < dash_n; dash_it++) {
3769 dash_set[dash_it - 1] = repalloc(dash_set[dash_it - 1], (strlen(dash_set[dash_it]) + 1) *
sizeof(
char));
3770 strcpy(dash_set[dash_it - 1], dash_set[dash_it]);
3774 pfree(dash_set[dash_n]);
3775 dash_set = repalloc(dash_set,
sizeof(
char *) * dash_n);
3779 if (c < 1 && dash_n > 2) {
3780 elog(NOTICE,
"Invalid argument for reclassargset. Invalid expression of reclassexpr for reclassarg of index %d . Returning original raster", i);
3781 for (k = 0; k < j; k++) pfree(exprset[k]);
3786 PG_FREE_IF_COPY(pgraster, 0);
3790 SET_VARSIZE(pgrtn, pgrtn->
size);
3791 PG_RETURN_POINTER(pgrtn);
3802 strchr(dash_set[c],
')') != NULL ||
3803 strchr(dash_set[c],
']') != NULL
3808 else if (strchr(dash_set[c],
'(') != NULL){
3818 strrchr(dash_set[c],
'(') != NULL ||
3819 strrchr(dash_set[c],
'[') != NULL
3824 else if (strrchr(dash_set[c],
']') != NULL) {
3832 POSTGIS_RT_DEBUGF(4,
"RASTER_reclass: exc_val %d inc_val %d", exc_val, inc_val);
3840 val = strtod(dash_set[c], &junk);
3841 if (errno != 0 || dash_set[c] == junk) {
3842 elog(NOTICE,
"Invalid argument for reclassargset. Invalid expression of reclassexpr for reclassarg of index %d . Returning original raster", i);
3843 for (k = 0; k < j; k++) pfree(exprset[k]);
3848 PG_FREE_IF_COPY(pgraster, 0);
3852 SET_VARSIZE(pgrtn, pgrtn->
size);
3853 PG_RETURN_POINTER(pgrtn);
3859 junk = strstr(colon_set[b], dash_set[c]);
3864 "(colon_set[%d], dash_set[%d], junk) = (%s, %s, %s)",
3865 b, c, colon_set[b], dash_set[c], junk
3868 if (junk != colon_set[b]) {
3870 if (*(junk - 1) ==
'-') {
3873 ((junk - 1) == colon_set[b]) ||
3874 (*(junk - 2) ==
'-') ||
3875 (*(junk - 2) ==
'[') ||
3876 (*(junk - 2) ==
'(')
3896 exprset[j]->
src.
min = val;
3902 exprset[j]->
src.
max = val;
3912 exprset[j]->
dst.
min = val;
3915 exprset[j]->
dst.
max = val;
3923 , exprset[j]->src.min
3933 tupv = GetAttributeByName(tup,
"pixeltype", &isnull);
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 pixeltypetext = (text *) DatumGetPointer(tupv);
3947 if (NULL == pixeltypetext) {
3948 elog(NOTICE,
"Invalid argument for reclassargset. Missing value of pixeltype for reclassarg of index %d . Returning original raster", i);
3952 PG_FREE_IF_COPY(pgraster, 0);
3956 SET_VARSIZE(pgrtn, pgrtn->
size);
3957 PG_RETURN_POINTER(pgrtn);
3964 tupv = GetAttributeByName(tup,
"nodataval", &isnull);
3970 nodataval = DatumGetFloat8(tupv);
3979 elog(NOTICE,
"Could not find raster band of index %d. Returning original raster",
nband);
3980 for (k = 0; k < j; k++) pfree(exprset[k]);
3985 PG_FREE_IF_COPY(pgraster, 0);
3989 SET_VARSIZE(pgrtn, pgrtn->
size);
3990 PG_RETURN_POINTER(pgrtn);
3994 for (k = 0; k < j; k++) pfree(exprset[k]);
3998 PG_FREE_IF_COPY(pgraster, 0);
4000 elog(ERROR,
"RASTER_reclass: Could not reclassify raster band of index %d",
nband);
4006 for (k = 0; k < j; k++) pfree(exprset[k]);
4011 PG_FREE_IF_COPY(pgraster, 0);
4013 elog(ERROR,
"RASTER_reclass: Could not replace raster band of index %d with reclassified band",
nband);
4021 for (k = 0; k < j; k++) pfree(exprset[k]);
4027 PG_FREE_IF_COPY(pgraster, 0);
4033 SET_VARSIZE(pgrtn, pgrtn->
size);
4034 PG_RETURN_POINTER(pgrtn);
4063 elog(ERROR,
"rtpg_colormap_arg: Could not allocate memory for function arguments");
4074 elog(ERROR,
"rtpg_colormap_arg: Could not allocate memory for function arguments");
4107 for (i = 0; i < arg->
nentry; i++) {
4108 if (arg->
entry[i] != NULL)
4109 pfree(arg->
entry[i]);
4115 for (i = 0; i < arg->
nelement; i++)
4135 if (PG_ARGISNULL(0))
4141 elog(ERROR,
"RASTER_colorMap: Could not initialize argument structure");
4146 pgraster = (
rt_pgraster *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
4152 PG_FREE_IF_COPY(pgraster, 0);
4153 elog(ERROR,
"RASTER_colorMap: Could not deserialize raster");
4158 if (!PG_ARGISNULL(1))
4159 arg->
nband = PG_GETARG_INT32(1);
4164 elog(NOTICE,
"Raster does not have band at index %d. Returning empty raster", arg->
nband);
4169 PG_FREE_IF_COPY(pgraster, 0);
4170 elog(ERROR,
"RASTER_colorMap: Could not create empty raster");
4175 PG_FREE_IF_COPY(pgraster, 0);
4179 if (pgraster == NULL)
4182 SET_VARSIZE(pgraster, ((
rt_pgraster*) pgraster)->size);
4183 PG_RETURN_POINTER(pgraster);
4188 if (arg->
band == NULL) {
4191 PG_FREE_IF_COPY(pgraster, 0);
4192 elog(ERROR,
"RASTER_colorMap: Could not get band at index %d",
nband);
4197 if (!PG_ARGISNULL(3)) {
4198 char *method = NULL;
4206 if (strcmp(method,
"INTERPOLATE") == 0)
4208 else if (strcmp(method,
"EXACT") == 0)
4210 else if (strcmp(method,
"NEAREST") == 0)
4213 elog(NOTICE,
"Unknown value provided for method. Defaulting to INTERPOLATE");
4223 if (PG_ARGISNULL(2)) {
4225 PG_FREE_IF_COPY(pgraster, 0);
4226 elog(ERROR,
"RASTER_colorMap: Value must be provided for colormap");
4240 if (!strlen(colormap)) {
4242 PG_FREE_IF_COPY(pgraster, 0);
4243 elog(ERROR,
"RASTER_colorMap: Value must be provided for colormap");
4251 PG_FREE_IF_COPY(pgraster, 0);
4252 elog(ERROR,
"RASTER_colorMap: Could not process the value provided for colormap");
4260 PG_FREE_IF_COPY(pgraster, 0);
4261 elog(ERROR,
"RASTER_colorMap: Could not allocate memory for colormap entries");
4267 for (i = 0; i < arg->
nentry; i++) {
4281 if (!strlen(_entry)) {
4291 PG_FREE_IF_COPY(pgraster, 0);
4292 elog(ERROR,
"RASTER_colorMap: Could not process colormap entry %d", i + 1);
4296 elog(NOTICE,
"More than five elements in colormap entry %d. Using at most five elements", i + 1);
4305 for (j = 0; j < arg->
nelement; j++) {
4314 char *percent = NULL;
4318 strcmp(_element,
"NV") == 0 ||
4319 strcmp(_element,
"NULL") == 0 ||
4320 strcmp(_element,
"NODATA") == 0
4325 elog(NOTICE,
"More than one NODATA entry found. Using only the first one");
4334 else if ((percent = strchr(_element,
'%')) != NULL) {
4346 PG_FREE_IF_COPY(pgraster, 0);
4347 elog(ERROR,
"RASTER_colorMap: Could not get band's summary stats to process percentages");
4353 tmp = palloc(
sizeof(
char) * (percent - _element + 1));
4357 PG_FREE_IF_COPY(pgraster, 0);
4358 elog(ERROR,
"RASTER_colorMap: Could not allocate memory for value of percentage");
4362 memcpy(tmp, _element, percent - _element);
4363 tmp[percent - _element] =
'\0';
4368 value = strtod(tmp, NULL);
4370 if (errno != 0 || _element == junk) {
4373 PG_FREE_IF_COPY(pgraster, 0);
4374 elog(ERROR,
"RASTER_colorMap: Could not process percent string to value");
4380 elog(NOTICE,
"Percentage values cannot be less than zero. Defaulting to zero");
4383 else if (
value > 100.) {
4384 elog(NOTICE,
"Percentage values cannot be greater than 100. Defaulting to 100");
4396 if (errno != 0 || _element == junk) {
4399 PG_FREE_IF_COPY(pgraster, 0);
4400 elog(ERROR,
"RASTER_colorMap: Could not process string to value");
4411 value = (int) strtod(_element, &junk);
4412 if (errno != 0 || _element == junk) {
4415 PG_FREE_IF_COPY(pgraster, 0);
4416 elog(ERROR,
"RASTER_colorMap: Could not process string to value");
4421 elog(NOTICE,
"RGBA value cannot be greater than 255. Defaulting to 255");
4424 else if (
value < 0) {
4425 elog(NOTICE,
"RGBA value cannot be less than zero. Defaulting to zero");
4434 POSTGIS_RT_DEBUGF(4,
"colormap->entry[%d] (isnodata, value, R, G, B, A) = (%d, %f, %d, %d, %d, %d)",
4455 PG_FREE_IF_COPY(pgraster, 0);
4456 elog(ERROR,
"RASTER_colorMap: Could not create new raster with applied colormap");
4461 PG_FREE_IF_COPY(pgraster, 0);
4467 if (pgraster == NULL)
4470 SET_VARSIZE(pgraster, ((
rt_pgraster*) pgraster)->size);
4471 PG_RETURN_POINTER(pgraster);
4483 int x,
y,
nband, width, height;
4485 double newnodatavalue = 0.0;
4486 double newinitialvalue = 0.0;
4487 double newval = 0.0;
4488 char *newexpr = NULL;
4489 char *initexpr = NULL;
4490 char *expression = NULL;
4491 int hasnodataval = 0;
4492 double nodataval = 0.;
4494 int skipcomputation = 0;
4496 const int argkwcount = 3;
4497 enum KEYWORDS { kVAL=0, kX=1, kY=2 };
4498 char *argkw[] = {
"[rast]",
"[rast.x]",
"[rast.y]"};
4499 Oid argkwtypes[] = { FLOAT8OID, INT4OID, INT4OID };
4501 Oid argtype[] = { FLOAT8OID, INT4OID, INT4OID };
4507 SPIPlanPtr spi_plan = NULL;
4508 SPITupleTable * tuptable = NULL;
4510 char * strFromText = NULL;
4511 Datum *values = NULL;
4512 Datum datum = (Datum)NULL;
4514 bool isnull =
FALSE;
4521 if (PG_ARGISNULL(0)) {
4522 elog(NOTICE,
"Raster is NULL. Returning NULL");
4528 pgraster = (
rt_pgraster *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
4531 PG_FREE_IF_COPY(pgraster, 0);
4532 elog(ERROR,
"RASTER_mapAlgebraExpr: Could not deserialize raster");
4538 if (PG_ARGISNULL(1))
4541 nband = PG_GETARG_INT32(1);
4547 POSTGIS_RT_DEBUG(3,
"RASTER_mapAlgebraExpr: Creating new empty raster...");
4558 if ( NULL == newrast ) {
4559 PG_FREE_IF_COPY(pgraster, 0);
4560 elog(ERROR,
"RASTER_mapAlgebraExpr: Could not create a new raster");
4585 elog(NOTICE,
"Raster is empty. Returning an empty raster");
4587 PG_FREE_IF_COPY(pgraster, 0);
4591 if (NULL == pgrtn) {
4593 elog(ERROR,
"RASTER_mapAlgebraExpr: Could not serialize raster");
4597 SET_VARSIZE(pgrtn, pgrtn->
size);
4598 PG_RETURN_POINTER(pgrtn);
4609 elog(NOTICE,
"Raster does not have the required band. Returning a raster "
4612 PG_FREE_IF_COPY(pgraster, 0);
4616 if (NULL == pgrtn) {
4617 elog(ERROR,
"RASTER_mapAlgebraExpr: Could not serialize raster");
4621 SET_VARSIZE(pgrtn, pgrtn->
size);
4622 PG_RETURN_POINTER(pgrtn);
4627 if ( NULL ==
band ) {
4628 elog(NOTICE,
"Could not get the required band. Returning a raster "
4631 PG_FREE_IF_COPY(pgraster, 0);
4635 if (NULL == pgrtn) {
4636 elog(ERROR,
"RASTER_mapAlgebraExpr: Could not serialize raster");
4640 SET_VARSIZE(pgrtn, pgrtn->
size);
4641 PG_RETURN_POINTER(pgrtn);
4647 POSTGIS_RT_DEBUG(3,
"RASTER_mapAlgebraExpr: Getting NODATA value for band...");
4665 newinitialvalue = newnodatavalue;
4672 if (PG_ARGISNULL(2)) {
4680 if (newpixeltype ==
PT_END)
4684 if (newpixeltype ==
PT_END) {
4685 PG_FREE_IF_COPY(pgraster, 0);
4686 elog(ERROR,
"RASTER_mapAlgebraExpr: Invalid pixeltype");
4695 if (!PG_ARGISNULL(3)) {
4697 len = strlen(
"SELECT (") + strlen(expression) + strlen(
")::double precision");
4698 initexpr = (
char *)palloc(len + 1);
4700 strncpy(initexpr,
"SELECT (", strlen(
"SELECT ("));
4701 strncpy(initexpr + strlen(
"SELECT ("), expression, strlen(expression));
4702 strncpy(initexpr + strlen(
"SELECT (") + strlen(expression),
")::double precision", strlen(
")::double precision"));
4703 initexpr[len] =
'\0';
4721 if (!PG_ARGISNULL(4)) {
4723 nodataval = PG_GETARG_FLOAT8(4);
4724 newinitialvalue = nodataval;
4741 POSTGIS_RT_DEBUG(3,
"RASTER_mapAlgebraExpr: Band is a nodata band, returning "
4742 "a raster filled with nodata");
4745 newinitialvalue,
TRUE, newnodatavalue, 0);
4751 PG_FREE_IF_COPY(pgraster, 0);
4756 if (NULL == pgrtn) {
4757 elog(ERROR,
"RASTER_mapAlgebraExpr: Could not serialize raster");
4761 SET_VARSIZE(pgrtn, pgrtn->
size);
4762 PG_RETURN_POINTER(pgrtn);
4770 if (initexpr != NULL && ( !strcmp(initexpr,
"SELECT [rast]") || !strcmp(initexpr,
"SELECT [rast.val]") ) && !hasnodataval) {
4773 "Returning raster with band %d from original raster",
nband);
4785 PG_FREE_IF_COPY(pgraster, 0);
4790 if (NULL == pgrtn) {
4791 elog(ERROR,
"RASTER_mapAlgebraExpr: Could not serialize raster");
4795 SET_VARSIZE(pgrtn, pgrtn->
size);
4796 PG_RETURN_POINTER(pgrtn);
4803 if (initexpr != NULL && strstr(initexpr,
"[rast") == NULL) {
4804 ret = SPI_connect();
4805 if (ret != SPI_OK_CONNECT) {
4806 PG_FREE_IF_COPY(pgraster, 0);
4807 elog(ERROR,
"RASTER_mapAlgebraExpr: Could not connect to the SPI manager");
4812 ret = SPI_execute(initexpr,
FALSE, 0);
4814 if (ret != SPI_OK_SELECT || SPI_tuptable == NULL || SPI_processed != 1) {
4818 SPI_freetuptable(tuptable);
4819 PG_FREE_IF_COPY(pgraster, 0);
4822 elog(ERROR,
"RASTER_mapAlgebraExpr: Invalid construction for expression");
4826 tupdesc = SPI_tuptable->tupdesc;
4827 tuptable = SPI_tuptable;
4829 tuple = tuptable->vals[0];
4830 newexpr = SPI_getvalue(tuple, tupdesc, 1);
4832 POSTGIS_RT_DEBUG(3,
"Constant expression evaluated to NULL, keeping initvalue");
4833 newval = newinitialvalue;
4835 newval = atof(newexpr);
4838 SPI_freetuptable(tuptable);
4845 skipcomputation = 1;
4851 if (!hasnodataval) {
4852 newinitialvalue = newval;
4853 skipcomputation = 2;
4857 else if (
FLT_NEQ(newval, newinitialvalue)) {
4858 skipcomputation = 2;
4867 newinitialvalue,
TRUE, newnodatavalue, 0);
4874 if (expression == NULL || skipcomputation == 2) {
4880 PG_FREE_IF_COPY(pgraster, 0);
4885 if (NULL == pgrtn) {
4886 elog(ERROR,
"RASTER_mapAlgebraExpr: Could not serialize raster");
4890 SET_VARSIZE(pgrtn, pgrtn->
size);
4891 PG_RETURN_POINTER(pgrtn);
4894 RASTER_DEBUG(3,
"RASTER_mapAlgebraExpr: Creating new raster band...");
4898 if ( NULL == newband ) {
4899 elog(NOTICE,
"Could not modify band for new raster. Returning new "
4900 "raster with the original band");
4905 PG_FREE_IF_COPY(pgraster, 0);