PostGIS  2.4.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 1099 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().

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