1325 MemoryContext mainMemCtx = CurrentMemoryContext;
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);
void * rt_raster_serialize(rt_raster raster)
Return this raster in serialized form.
rtpg_nmapalgebra_arg bandarg
raster
Be careful!! Zeros function's input parameter can be a (height x width) array, not (width x height): ...
char * rtpg_strreplace(const char *str, const char *oldstr, const char *newstr, int *count)
static int rtpg_nmapalgebraexpr_callback(rt_iterator_arg arg, void *userarg, double *value, int *nodata)
#define POSTGIS_RT_DEBUGF(level, msg,...)
rt_errorstate rt_band_get_nodata(rt_band band, double *nodata)
Get NODATA value.
struct rtpg_nmapalgebraexpr_callback_arg::@17 nodatanodata
rt_extenttype rt_util_extent_type(const char *name)
rt_pixtype rt_pixtype_index_from_name(const char *pixname)
static rtpg_nmapalgebraexpr_arg rtpg_nmapalgebraexpr_arg_init(int cnt, char **kw)
rt_band rt_raster_get_band(rt_raster raster, int bandNum)
Return Nth band, or NULL if unavailable.
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.
char * rtpg_trim(const char *input)
struct rtpg_nmapalgebraexpr_callback_arg::@16 expr[3]
void rt_raster_destroy(rt_raster raster)
Release memory associated to a raster.
static void rtpg_nmapalgebraexpr_arg_destroy(rtpg_nmapalgebraexpr_arg arg)
rt_raster rt_raster_new(uint32_t width, uint32_t height)
Construct a raster with given dimensions.
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.
rt_pixtype rt_band_get_pixtype(rt_band band)
Return pixeltype of this band.
rtpg_nmapalgebraexpr_callback_arg callback
char * rtpg_strtoupper(char *str)