PostGIS  2.5.7dev-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 1108 of file rtpg_mapalgebra.c.

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

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: