PostGIS  3.3.9dev-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 1106 of file rtpg_mapalgebra.c.

1109  {
1111  SPIPlanPtr plan = NULL;
1112  int i = 0;
1113  uint8_t id = 0;
1114 
1115  if (arg == NULL)
1116  return 0;
1117 
1118  *value = 0;
1119  *nodata = 0;
1120 
1121  /* 2 raster */
1122  if (arg->rasters > 1) {
1123  /* nodata1 = 1 AND nodata2 = 1, nodatanodataval */
1124  if (arg->nodata[0][0][0] && arg->nodata[1][0][0]) {
1125  if (callback->nodatanodata.hasval)
1126  *value = callback->nodatanodata.val;
1127  else
1128  *nodata = 1;
1129  }
1130  /* nodata1 = 1 AND nodata2 != 1, nodata1expr */
1131  else if (arg->nodata[0][0][0] && !arg->nodata[1][0][0]) {
1132  id = 1;
1133  if (callback->expr[id].hasval)
1134  *value = callback->expr[id].val;
1135  else if (callback->expr[id].spi_plan)
1136  plan = callback->expr[id].spi_plan;
1137  else
1138  *nodata = 1;
1139  }
1140  /* nodata1 != 1 AND nodata2 = 1, nodata2expr */
1141  else if (!arg->nodata[0][0][0] && arg->nodata[1][0][0]) {
1142  id = 2;
1143  if (callback->expr[id].hasval)
1144  *value = callback->expr[id].val;
1145  else if (callback->expr[id].spi_plan)
1146  plan = callback->expr[id].spi_plan;
1147  else
1148  *nodata = 1;
1149  }
1150  /* expression */
1151  else {
1152  id = 0;
1153  if (callback->expr[id].hasval)
1154  *value = callback->expr[id].val;
1155  else if (callback->expr[id].spi_plan)
1156  plan = callback->expr[id].spi_plan;
1157  else {
1158  if (callback->nodatanodata.hasval)
1159  *value = callback->nodatanodata.val;
1160  else
1161  *nodata = 1;
1162  }
1163  }
1164  }
1165  /* 1 raster */
1166  else {
1167  /* nodata = 1, nodata1expr */
1168  if (arg->nodata[0][0][0]) {
1169  id = 1;
1170  if (callback->expr[id].hasval)
1171  *value = callback->expr[id].val;
1172  else if (callback->expr[id].spi_plan)
1173  plan = callback->expr[id].spi_plan;
1174  else
1175  *nodata = 1;
1176  }
1177  /* expression */
1178  else {
1179  id = 0;
1180  if (callback->expr[id].hasval)
1181  *value = callback->expr[id].val;
1182  else if (callback->expr[id].spi_plan)
1183  plan = callback->expr[id].spi_plan;
1184  else {
1185  /* see if nodata1expr is available */
1186  id = 1;
1187  if (callback->expr[id].hasval)
1188  *value = callback->expr[id].val;
1189  else if (callback->expr[id].spi_plan)
1190  plan = callback->expr[id].spi_plan;
1191  else
1192  *nodata = 1;
1193  }
1194  }
1195  }
1196 
1197  /* run prepared plan */
1198  if (plan != NULL) {
1199  Datum values[12];
1200  char nulls[12];
1201  int err = 0;
1202 
1203  TupleDesc tupdesc;
1204  SPITupleTable *tuptable = NULL;
1205  HeapTuple tuple;
1206  Datum datum;
1207  bool isnull = FALSE;
1208 
1209  POSTGIS_RT_DEBUGF(4, "Running plan %d", id);
1210 
1211  /* init values and nulls */
1212  memset(values, (Datum) NULL, sizeof(Datum) * callback->kw.count);
1213  memset(nulls, FALSE, sizeof(char) * callback->kw.count);
1214 
1215  if (callback->expr[id].spi_argcount) {
1216  int idx = 0;
1217 
1218  for (i = 0; i < callback->kw.count; i++) {
1219  idx = callback->expr[id].spi_argpos[i];
1220  if (idx < 1) continue;
1221  idx--; /* 1-based now 0-based */
1222 
1223  if (arg->rasters == 1 && i > 7) {
1224  elog(ERROR, "rtpg_nmapalgebraexpr_callback: rast2 argument specified in single-raster invocation");
1225  return 0;
1226  }
1227 
1228  switch (i) {
1229  /* [rast.x] */
1230  case 0:
1231  values[idx] = Int32GetDatum(arg->src_pixel[0][0] + 1);
1232  break;
1233  /* [rast.y] */
1234  case 1:
1235  values[idx] = Int32GetDatum(arg->src_pixel[0][1] + 1);
1236  break;
1237  /* [rast.val] */
1238  case 2:
1239  /* [rast] */
1240  case 3:
1241  if (!arg->nodata[0][0][0])
1242  values[idx] = Float8GetDatum(arg->values[0][0][0]);
1243  else
1244  nulls[idx] = TRUE;
1245  break;
1246 
1247  /* [rast1.x] */
1248  case 4:
1249  values[idx] = Int32GetDatum(arg->src_pixel[0][0] + 1);
1250  break;
1251  /* [rast1.y] */
1252  case 5:
1253  values[idx] = Int32GetDatum(arg->src_pixel[0][1] + 1);
1254  break;
1255  /* [rast1.val] */
1256  case 6:
1257  /* [rast1] */
1258  case 7:
1259  if (!arg->nodata[0][0][0])
1260  values[idx] = Float8GetDatum(arg->values[0][0][0]);
1261  else
1262  nulls[idx] = TRUE;
1263  break;
1264 
1265  /* [rast2.x] */
1266  case 8:
1267  values[idx] = Int32GetDatum(arg->src_pixel[1][0] + 1);
1268  break;
1269  /* [rast2.y] */
1270  case 9:
1271  values[idx] = Int32GetDatum(arg->src_pixel[1][1] + 1);
1272  break;
1273  /* [rast2.val] */
1274  case 10:
1275  /* [rast2] */
1276  case 11:
1277  if (!arg->nodata[1][0][0])
1278  values[idx] = Float8GetDatum(arg->values[1][0][0]);
1279  else
1280  nulls[idx] = TRUE;
1281  break;
1282  }
1283 
1284  }
1285  }
1286 
1287  /* run prepared plan */
1288  err = SPI_execute_plan(plan, values, nulls, TRUE, 1);
1289  if (err != SPI_OK_SELECT || SPI_tuptable == NULL || SPI_processed != 1) {
1290  elog(ERROR, "rtpg_nmapalgebraexpr_callback: Unexpected error when running prepared statement %d", id);
1291  return 0;
1292  }
1293 
1294  /* get output of prepared plan */
1295  tupdesc = SPI_tuptable->tupdesc;
1296  tuptable = SPI_tuptable;
1297  tuple = tuptable->vals[0];
1298 
1299  datum = SPI_getbinval(tuple, tupdesc, 1, &isnull);
1300  if (SPI_result == SPI_ERROR_NOATTRIBUTE) {
1301  if (SPI_tuptable) SPI_freetuptable(tuptable);
1302  elog(ERROR, "rtpg_nmapalgebraexpr_callback: Could not get result of prepared statement %d", id);
1303  return 0;
1304  }
1305 
1306  if (!isnull) {
1307  *value = DatumGetFloat8(datum);
1308  POSTGIS_RT_DEBUG(4, "Getting value from Datum");
1309  }
1310  else {
1311  /* 2 raster, check nodatanodataval */
1312  if (arg->rasters > 1) {
1313  if (callback->nodatanodata.hasval)
1314  *value = callback->nodatanodata.val;
1315  else
1316  *nodata = 1;
1317  }
1318  /* 1 raster, check nodataval */
1319  else {
1320  if (callback->expr[1].hasval)
1321  *value = callback->expr[1].val;
1322  else
1323  *nodata = 1;
1324  }
1325  }
1326 
1327  if (SPI_tuptable) SPI_freetuptable(tuptable);
1328  }
1329 
1330  POSTGIS_RT_DEBUGF(4, "(value, nodata) = (%f, %d)", *value, *nodata);
1331  return 1;
1332 }
#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:69
#define POSTGIS_RT_DEBUGF(level, msg,...)
Definition: rtpostgis.h:73
double *** values
Definition: librtcore.h:2605
uint16_t rasters
Definition: librtcore.h:2597
struct rtpg_nmapalgebraexpr_callback_arg::@24 kw
struct rtpg_nmapalgebraexpr_callback_arg::@23 nodatanodata
struct rtpg_nmapalgebraexpr_callback_arg::@22 expr[3]

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: