PostGIS  2.5.1dev-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 1046 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().

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