PostGIS  2.4.9dev-r@@SVN_REVISION@@

◆ rtpg_nmapalgebra_callback()

static int rtpg_nmapalgebra_callback ( rt_iterator_arg  arg,
void *  userarg,
double *  value,
int *  nodata 
)
static

Definition at line 365 of file rtpg_mapalgebra.c.

References rt_iterator_arg_t::columns, rt_iterator_arg_t::dst_pixel, if(), rt_iterator_arg_t::nodata, PG_FUNCTION_INFO_V1(), POSTGIS_RT_DEBUGF, RASTER_nMapAlgebra(), rt_iterator_arg_t::rasters, rt_iterator_arg_t::rows, rt_iterator_arg_t::src_pixel, rtpg_nmapalgebra_callback_arg::ufc_info, rtpg_nmapalgebra_callback_arg::ufc_rettype, rt_iterator_arg_t::values, pixval::x, and pixval::y.

Referenced by RASTER_nMapAlgebra().

368  {
370 
371  int16 typlen;
372  bool typbyval;
373  char typalign;
374 
375  ArrayType *mdValues = NULL;
376  Datum *_values = NULL;
377  bool *_nodata = NULL;
378 
379  ArrayType *mdPos = NULL;
380  Datum *_pos = NULL;
381  bool *_null = NULL;
382 
383  int i = 0;
384  int x = 0;
385  int y = 0;
386  int z = 0;
387  int dim[3] = {0};
388  int lbound[3] = {1, 1, 1};
389  Datum datum = (Datum) NULL;
390 
391  if (arg == NULL)
392  return 0;
393 
394  *value = 0;
395  *nodata = 0;
396 
397  dim[0] = arg->rasters;
398  dim[1] = arg->rows;
399  dim[2] = arg->columns;
400 
401  _values = palloc(sizeof(Datum) * arg->rasters * arg->rows * arg->columns);
402  _nodata = palloc(sizeof(bool) * arg->rasters * arg->rows * arg->columns);
403  if (_values == NULL || _nodata == NULL) {
404  elog(ERROR, "rtpg_nmapalgebra_callback: Could not allocate memory for values array");
405  return 0;
406  }
407 
408  /* build mdValues */
409  i = 0;
410  /* raster */
411  for (z = 0; z < arg->rasters; z++) {
412  /* Y axis */
413  for (y = 0; y < arg->rows; y++) {
414  /* X axis */
415  for (x = 0; x < arg->columns; x++) {
416  POSTGIS_RT_DEBUGF(4, "(z, y ,x) = (%d, %d, %d)", z, y, x);
417  POSTGIS_RT_DEBUGF(4, "(value, nodata) = (%f, %d)", arg->values[z][y][x], arg->nodata[z][y][x]);
418 
419  _nodata[i] = (bool) arg->nodata[z][y][x];
420  if (!_nodata[i])
421  _values[i] = Float8GetDatum(arg->values[z][y][x]);
422  else
423  _values[i] = (Datum) NULL;
424 
425  i++;
426  }
427  }
428  }
429 
430  /* info about the type of item in the multi-dimensional array (float8). */
431  get_typlenbyvalalign(FLOAT8OID, &typlen, &typbyval, &typalign);
432 
433  /* construct mdValues */
434  mdValues = construct_md_array(
435  _values, _nodata,
436  3, dim, lbound,
437  FLOAT8OID,
438  typlen, typbyval, typalign
439  );
440  pfree(_nodata);
441  pfree(_values);
442 
443  _pos = palloc(sizeof(Datum) * (arg->rasters + 1) * 2);
444  _null = palloc(sizeof(bool) * (arg->rasters + 1) * 2);
445  if (_pos == NULL || _null == NULL) {
446  pfree(mdValues);
447  elog(ERROR, "rtpg_nmapalgebra_callback: Could not allocate memory for position array");
448  return 0;
449  }
450  memset(_null, 0, sizeof(bool) * (arg->rasters + 1) * 2);
451 
452  /* build mdPos */
453  i = 0;
454  _pos[i] = arg->dst_pixel[0] + 1;
455  i++;
456  _pos[i] = arg->dst_pixel[1] + 1;
457  i++;
458 
459  for (z = 0; z < arg->rasters; z++) {
460  _pos[i] = arg->src_pixel[z][0] + 1;
461  i++;
462 
463  _pos[i] = arg->src_pixel[z][1] + 1;
464  i++;
465  }
466 
467  /* info about the type of item in the multi-dimensional array (int4). */
468  get_typlenbyvalalign(INT4OID, &typlen, &typbyval, &typalign);
469 
470  /* reuse dim and lbound, just tweak to what we need */
471  dim[0] = arg->rasters + 1;
472  dim[1] = 2;
473  lbound[0] = 0;
474 
475  /* construct mdPos */
476  mdPos = construct_md_array(
477  _pos, _null,
478  2, dim, lbound,
479  INT4OID,
480  typlen, typbyval, typalign
481  );
482  pfree(_pos);
483  pfree(_null);
484 
485 #if POSTGIS_PGSQL_VERSION < 120
486  callback->ufc_info.arg[0] = PointerGetDatum(mdValues);
487  callback->ufc_info.arg[1] = PointerGetDatum(mdPos);
488 #else
489  callback->ufc_info->args[0].value = PointerGetDatum(mdValues);
490  callback->ufc_info->args[1].value = PointerGetDatum(mdPos);
491 #endif
492 
493  /* call user callback function */
494 #if POSTGIS_PGSQL_VERSION < 120
495  datum = FunctionCallInvoke(&(callback->ufc_info));
496 #else
497  datum = FunctionCallInvoke(callback->ufc_info);
498 #endif
499  pfree(mdValues);
500  pfree(mdPos);
501 
502  /* result is not null*/
503 #if POSTGIS_PGSQL_VERSION < 120
504  if (!callback->ufc_info.isnull) {
505 #else
506  if (!callback->ufc_info->isnull)
507  {
508 #endif
509  switch (callback->ufc_rettype) {
510  case FLOAT8OID:
511  *value = DatumGetFloat8(datum);
512  break;
513  case FLOAT4OID:
514  *value = (double) DatumGetFloat4(datum);
515  break;
516  case INT4OID:
517  *value = (double) DatumGetInt32(datum);
518  break;
519  case INT2OID:
520  *value = (double) DatumGetInt16(datum);
521  break;
522  }
523  }
524  else
525  *nodata = 1;
526 
527  return 1;
528 }
#define POSTGIS_RT_DEBUGF(level, msg,...)
Definition: rtpostgis.h:65
uint32_t columns
Definition: librtcore.h:2406
uint16_t rasters
Definition: librtcore.h:2402
double *** values
Definition: librtcore.h:2410
int value
Definition: genraster.py:61
if(!(yy_init))
FunctionCallInfoData ufc_info
Here is the call graph for this function:
Here is the caller graph for this function: