PostGIS  2.3.8dev-r@@SVN_REVISION@@

◆ rtpg_nmapalgebraexpr_callback()

static int rtpg_nmapalgebraexpr_callback ( rt_iterator_arg  arg,
void *  userarg,
double *  value,
int *  nodata 
)
static

Definition at line 1049 of file rtpg_mapalgebra.c.

References rtpg_nmapalgebraexpr_callback_arg::count, rtpg_nmapalgebraexpr_callback_arg::expr, FALSE, rtpg_nmapalgebraexpr_callback_arg::hasval, rtpg_nmapalgebraexpr_callback_arg::kw, rt_iterator_arg_t::nodata, rtpg_nmapalgebraexpr_callback_arg::nodatanodata, PG_FUNCTION_INFO_V1(), POSTGIS_RT_DEBUG, POSTGIS_RT_DEBUGF, RASTER_nMapAlgebraExpr(), rt_iterator_arg_t::rasters, rtpg_nmapalgebraexpr_callback_arg::spi_argcount, rtpg_nmapalgebraexpr_callback_arg::spi_argpos, rtpg_nmapalgebraexpr_callback_arg::spi_plan, rt_iterator_arg_t::src_pixel, TRUE, rtpg_nmapalgebraexpr_callback_arg::val, and rt_iterator_arg_t::values.

Referenced by RASTER_nMapAlgebraExpr().

1052  {
1054  SPIPlanPtr plan = NULL;
1055  int i = 0;
1056  int id = -1;
1057 
1058  if (arg == NULL)
1059  return 0;
1060 
1061  *value = 0;
1062  *nodata = 0;
1063 
1064  /* 2 raster */
1065  if (arg->rasters > 1) {
1066  /* nodata1 = 1 AND nodata2 = 1, nodatanodataval */
1067  if (arg->nodata[0][0][0] && arg->nodata[1][0][0]) {
1068  if (callback->nodatanodata.hasval)
1069  *value = callback->nodatanodata.val;
1070  else
1071  *nodata = 1;
1072  }
1073  /* nodata1 = 1 AND nodata2 != 1, nodata1expr */
1074  else if (arg->nodata[0][0][0] && !arg->nodata[1][0][0]) {
1075  id = 1;
1076  if (callback->expr[id].hasval)
1077  *value = callback->expr[id].val;
1078  else if (callback->expr[id].spi_plan)
1079  plan = callback->expr[id].spi_plan;
1080  else
1081  *nodata = 1;
1082  }
1083  /* nodata1 != 1 AND nodata2 = 1, nodata2expr */
1084  else if (!arg->nodata[0][0][0] && arg->nodata[1][0][0]) {
1085  id = 2;
1086  if (callback->expr[id].hasval)
1087  *value = callback->expr[id].val;
1088  else if (callback->expr[id].spi_plan)
1089  plan = callback->expr[id].spi_plan;
1090  else
1091  *nodata = 1;
1092  }
1093  /* expression */
1094  else {
1095  id = 0;
1096  if (callback->expr[id].hasval)
1097  *value = callback->expr[id].val;
1098  else if (callback->expr[id].spi_plan)
1099  plan = callback->expr[id].spi_plan;
1100  else {
1101  if (callback->nodatanodata.hasval)
1102  *value = callback->nodatanodata.val;
1103  else
1104  *nodata = 1;
1105  }
1106  }
1107  }
1108  /* 1 raster */
1109  else {
1110  /* nodata = 1, nodata1expr */
1111  if (arg->nodata[0][0][0]) {
1112  id = 1;
1113  if (callback->expr[id].hasval)
1114  *value = callback->expr[id].val;
1115  else if (callback->expr[id].spi_plan)
1116  plan = callback->expr[id].spi_plan;
1117  else
1118  *nodata = 1;
1119  }
1120  /* expression */
1121  else {
1122  id = 0;
1123  if (callback->expr[id].hasval)
1124  *value = callback->expr[id].val;
1125  else if (callback->expr[id].spi_plan)
1126  plan = callback->expr[id].spi_plan;
1127  else {
1128  /* see if nodata1expr is available */
1129  id = 1;
1130  if (callback->expr[id].hasval)
1131  *value = callback->expr[id].val;
1132  else if (callback->expr[id].spi_plan)
1133  plan = callback->expr[id].spi_plan;
1134  else
1135  *nodata = 1;
1136  }
1137  }
1138  }
1139 
1140  /* run prepared plan */
1141  if (plan != NULL) {
1142  Datum values[12];
1143  bool nulls[12];
1144  int err = 0;
1145 
1146  TupleDesc tupdesc;
1147  SPITupleTable *tuptable = NULL;
1148  HeapTuple tuple;
1149  Datum datum;
1150  bool isnull = FALSE;
1151 
1152  POSTGIS_RT_DEBUGF(4, "Running plan %d", id);
1153 
1154  /* init values and nulls */
1155  memset(values, (Datum) NULL, sizeof(Datum) * callback->kw.count);
1156  memset(nulls, FALSE, sizeof(bool) * callback->kw.count);
1157 
1158  if (callback->expr[id].spi_argcount) {
1159  int idx = 0;
1160 
1161  for (i = 0; i < callback->kw.count; i++) {
1162  idx = callback->expr[id].spi_argpos[i];
1163  if (idx < 1) continue;
1164  idx--; /* 1-based now 0-based */
1165 
1166  switch (i) {
1167  /* [rast.x] */
1168  case 0:
1169  values[idx] = Int32GetDatum(arg->src_pixel[0][0] + 1);
1170  break;
1171  /* [rast.y] */
1172  case 1:
1173  values[idx] = Int32GetDatum(arg->src_pixel[0][1] + 1);
1174  break;
1175  /* [rast.val] */
1176  case 2:
1177  /* [rast] */
1178  case 3:
1179  if (!arg->nodata[0][0][0])
1180  values[idx] = Float8GetDatum(arg->values[0][0][0]);
1181  else
1182  nulls[idx] = TRUE;
1183  break;
1184 
1185  /* [rast1.x] */
1186  case 4:
1187  values[idx] = Int32GetDatum(arg->src_pixel[0][0] + 1);
1188  break;
1189  /* [rast1.y] */
1190  case 5:
1191  values[idx] = Int32GetDatum(arg->src_pixel[0][1] + 1);
1192  break;
1193  /* [rast1.val] */
1194  case 6:
1195  /* [rast1] */
1196  case 7:
1197  if (!arg->nodata[0][0][0])
1198  values[idx] = Float8GetDatum(arg->values[0][0][0]);
1199  else
1200  nulls[idx] = TRUE;
1201  break;
1202 
1203  /* [rast2.x] */
1204  case 8:
1205  values[idx] = Int32GetDatum(arg->src_pixel[1][0] + 1);
1206  break;
1207  /* [rast2.y] */
1208  case 9:
1209  values[idx] = Int32GetDatum(arg->src_pixel[1][1] + 1);
1210  break;
1211  /* [rast2.val] */
1212  case 10:
1213  /* [rast2] */
1214  case 11:
1215  if (!arg->nodata[1][0][0])
1216  values[idx] = Float8GetDatum(arg->values[1][0][0]);
1217  else
1218  nulls[idx] = TRUE;
1219  break;
1220  }
1221 
1222  }
1223  }
1224 
1225  /* run prepared plan */
1226  err = SPI_execute_plan(plan, values, nulls, TRUE, 1);
1227  if (err != SPI_OK_SELECT || SPI_tuptable == NULL || SPI_processed != 1) {
1228  elog(ERROR, "rtpg_nmapalgebraexpr_callback: Unexpected error when running prepared statement %d", id);
1229  return 0;
1230  }
1231 
1232  /* get output of prepared plan */
1233  tupdesc = SPI_tuptable->tupdesc;
1234  tuptable = SPI_tuptable;
1235  tuple = tuptable->vals[0];
1236 
1237  datum = SPI_getbinval(tuple, tupdesc, 1, &isnull);
1238  if (SPI_result == SPI_ERROR_NOATTRIBUTE) {
1239  if (SPI_tuptable) SPI_freetuptable(tuptable);
1240  elog(ERROR, "rtpg_nmapalgebraexpr_callback: Could not get result of prepared statement %d", id);
1241  return 0;
1242  }
1243 
1244  if (!isnull) {
1245  *value = DatumGetFloat8(datum);
1246  POSTGIS_RT_DEBUG(4, "Getting value from Datum");
1247  }
1248  else {
1249  /* 2 raster, check nodatanodataval */
1250  if (arg->rasters > 1) {
1251  if (callback->nodatanodata.hasval)
1252  *value = callback->nodatanodata.val;
1253  else
1254  *nodata = 1;
1255  }
1256  /* 1 raster, check nodataval */
1257  else {
1258  if (callback->expr[1].hasval)
1259  *value = callback->expr[1].val;
1260  else
1261  *nodata = 1;
1262  }
1263  }
1264 
1265  if (SPI_tuptable) SPI_freetuptable(tuptable);
1266  }
1267 
1268  POSTGIS_RT_DEBUGF(4, "(value, nodata) = (%f, %d)", *value, *nodata);
1269  return 1;
1270 }
struct rtpg_nmapalgebraexpr_callback_arg::@18 kw
#define POSTGIS_RT_DEBUGF(level, msg,...)
Definition: rtpostgis.h:57
struct rtpg_nmapalgebraexpr_callback_arg::@17 nodatanodata
uint16_t rasters
Definition: librtcore.h:2414
struct rtpg_nmapalgebraexpr_callback_arg::@16 expr[3]
double *** values
Definition: librtcore.h:2422
#define FALSE
Definition: dbfopen.c:168
int value
Definition: genraster.py:61
#define POSTGIS_RT_DEBUG(level, msg)
Definition: rtpostgis.h:53
#define TRUE
Definition: dbfopen.c:169
Here is the call graph for this function:
Here is the caller graph for this function: