PostGIS  3.7.0dev-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 1066 of file rtpg_mapalgebra.c.

1069  {
1071  SPIPlanPtr plan = NULL;
1072  int i = 0;
1073  uint8_t id = 0;
1074 
1075  if (arg == NULL)
1076  return 0;
1077 
1078  *value = 0;
1079  *nodata = 0;
1080 
1081  /* 2 raster */
1082  if (arg->rasters > 1) {
1083  /* nodata1 = 1 AND nodata2 = 1, nodatanodataval */
1084  if (arg->nodata[0][0][0] && arg->nodata[1][0][0]) {
1085  if (callback->nodatanodata.hasval)
1086  *value = callback->nodatanodata.val;
1087  else
1088  *nodata = 1;
1089  }
1090  /* nodata1 = 1 AND nodata2 != 1, nodata1expr */
1091  else if (arg->nodata[0][0][0] && !arg->nodata[1][0][0]) {
1092  id = 1;
1093  if (callback->expr[id].hasval)
1094  *value = callback->expr[id].val;
1095  else if (callback->expr[id].spi_plan)
1096  plan = callback->expr[id].spi_plan;
1097  else
1098  *nodata = 1;
1099  }
1100  /* nodata1 != 1 AND nodata2 = 1, nodata2expr */
1101  else if (!arg->nodata[0][0][0] && arg->nodata[1][0][0]) {
1102  id = 2;
1103  if (callback->expr[id].hasval)
1104  *value = callback->expr[id].val;
1105  else if (callback->expr[id].spi_plan)
1106  plan = callback->expr[id].spi_plan;
1107  else
1108  *nodata = 1;
1109  }
1110  /* expression */
1111  else {
1112  id = 0;
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  if (callback->nodatanodata.hasval)
1119  *value = callback->nodatanodata.val;
1120  else
1121  *nodata = 1;
1122  }
1123  }
1124  }
1125  /* 1 raster */
1126  else {
1127  /* nodata = 1, nodata1expr */
1128  if (arg->nodata[0][0][0]) {
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  /* expression */
1138  else {
1139  id = 0;
1140  if (callback->expr[id].hasval)
1141  *value = callback->expr[id].val;
1142  else if (callback->expr[id].spi_plan)
1143  plan = callback->expr[id].spi_plan;
1144  else {
1145  /* see if nodata1expr is available */
1146  id = 1;
1147  if (callback->expr[id].hasval)
1148  *value = callback->expr[id].val;
1149  else if (callback->expr[id].spi_plan)
1150  plan = callback->expr[id].spi_plan;
1151  else
1152  *nodata = 1;
1153  }
1154  }
1155  }
1156 
1157  /* run prepared plan */
1158  if (plan != NULL) {
1159  Datum values[12];
1160  char nulls[12];
1161  int err = 0;
1162 
1163  TupleDesc tupdesc;
1164  SPITupleTable *tuptable = NULL;
1165  HeapTuple tuple;
1166  Datum datum;
1167  bool isnull = FALSE;
1168 
1169  POSTGIS_RT_DEBUGF(4, "Running plan %d", id);
1170 
1171  /* init values and nulls */
1172  memset(values, (Datum) NULL, sizeof(Datum) * callback->kw.count);
1173  memset(nulls, FALSE, sizeof(char) * callback->kw.count);
1174 
1175  if (callback->expr[id].spi_argcount) {
1176  int idx = 0;
1177 
1178  for (i = 0; i < callback->kw.count; i++) {
1179  idx = callback->expr[id].spi_argpos[i];
1180  if (idx < 1) continue;
1181  idx--; /* 1-based now 0-based */
1182 
1183  if (arg->rasters == 1 && i > 7) {
1184  elog(ERROR, "rtpg_nmapalgebraexpr_callback: rast2 argument specified in single-raster invocation");
1185  return 0;
1186  }
1187 
1188  switch (i) {
1189  /* [rast.x] */
1190  case 0:
1191  values[idx] = Int32GetDatum(arg->src_pixel[0][0] + 1);
1192  break;
1193  /* [rast.y] */
1194  case 1:
1195  values[idx] = Int32GetDatum(arg->src_pixel[0][1] + 1);
1196  break;
1197  /* [rast.val] */
1198  case 2:
1199  /* [rast] */
1200  case 3:
1201  if (!arg->nodata[0][0][0])
1202  values[idx] = Float8GetDatum(arg->values[0][0][0]);
1203  else
1204  nulls[idx] = TRUE;
1205  break;
1206 
1207  /* [rast1.x] */
1208  case 4:
1209  values[idx] = Int32GetDatum(arg->src_pixel[0][0] + 1);
1210  break;
1211  /* [rast1.y] */
1212  case 5:
1213  values[idx] = Int32GetDatum(arg->src_pixel[0][1] + 1);
1214  break;
1215  /* [rast1.val] */
1216  case 6:
1217  /* [rast1] */
1218  case 7:
1219  if (!arg->nodata[0][0][0])
1220  values[idx] = Float8GetDatum(arg->values[0][0][0]);
1221  else
1222  nulls[idx] = TRUE;
1223  break;
1224 
1225  /* [rast2.x] */
1226  case 8:
1227  values[idx] = Int32GetDatum(arg->src_pixel[1][0] + 1);
1228  break;
1229  /* [rast2.y] */
1230  case 9:
1231  values[idx] = Int32GetDatum(arg->src_pixel[1][1] + 1);
1232  break;
1233  /* [rast2.val] */
1234  case 10:
1235  /* [rast2] */
1236  case 11:
1237  if (!arg->nodata[1][0][0])
1238  values[idx] = Float8GetDatum(arg->values[1][0][0]);
1239  else
1240  nulls[idx] = TRUE;
1241  break;
1242  }
1243 
1244  }
1245  }
1246 
1247  /* run prepared plan */
1248  err = SPI_execute_plan(plan, values, nulls, TRUE, 1);
1249  if (err != SPI_OK_SELECT || SPI_tuptable == NULL || SPI_processed != 1) {
1250  elog(ERROR, "rtpg_nmapalgebraexpr_callback: Unexpected error when running prepared statement %d", id);
1251  return 0;
1252  }
1253 
1254  /* get output of prepared plan */
1255  tupdesc = SPI_tuptable->tupdesc;
1256  tuptable = SPI_tuptable;
1257  tuple = tuptable->vals[0];
1258 
1259  datum = SPI_getbinval(tuple, tupdesc, 1, &isnull);
1260  if (SPI_result == SPI_ERROR_NOATTRIBUTE) {
1261  if (SPI_tuptable) SPI_freetuptable(tuptable);
1262  elog(ERROR, "rtpg_nmapalgebraexpr_callback: Could not get result of prepared statement %d", id);
1263  return 0;
1264  }
1265 
1266  if (!isnull) {
1267  *value = DatumGetFloat8(datum);
1268  POSTGIS_RT_DEBUG(4, "Getting value from Datum");
1269  }
1270  else {
1271  /* 2 raster, check nodatanodataval */
1272  if (arg->rasters > 1) {
1273  if (callback->nodatanodata.hasval)
1274  *value = callback->nodatanodata.val;
1275  else
1276  *nodata = 1;
1277  }
1278  /* 1 raster, check nodataval */
1279  else {
1280  if (callback->expr[1].hasval)
1281  *value = callback->expr[1].val;
1282  else
1283  *nodata = 1;
1284  }
1285  }
1286 
1287  if (SPI_tuptable) SPI_freetuptable(tuptable);
1288  }
1289 
1290  POSTGIS_RT_DEBUGF(4, "(value, nodata) = (%f, %d)", *value, *nodata);
1291  return 1;
1292 }
#define TRUE
Definition: dbfopen.c:73
#define FALSE
Definition: dbfopen.c:72
int value
Definition: genraster.py:62
#define POSTGIS_RT_DEBUG(level, msg)
Definition: rtpostgis.h:65
#define POSTGIS_RT_DEBUGF(level, msg,...)
Definition: rtpostgis.h:69
double *** values
Definition: librtcore.h:2663
uint16_t rasters
Definition: librtcore.h:2655
struct rtpg_nmapalgebraexpr_callback_arg::@26 nodatanodata
struct rtpg_nmapalgebraexpr_callback_arg::@25 expr[3]
struct rtpg_nmapalgebraexpr_callback_arg::@27 kw

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, POSTGIS_RT_DEBUG, POSTGIS_RT_DEBUGF, 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, genraster::value, and rt_iterator_arg_t::values.

Referenced by RASTER_nMapAlgebraExpr().

Here is the caller graph for this function: