PostGIS  2.4.9dev-r@@SVN_REVISION@@

◆ RASTER_union_finalfn()

Datum RASTER_union_finalfn ( PG_FUNCTION_ARGS  )

Definition at line 2795 of file rtpg_mapalgebra.c.

References rtpg_union_arg_t::bandarg, ES_NONE, ET_UNION, rt_iterator_t::nband, rtpg_union_arg_t::numband, rtpg_union_band_arg_t::numraster, POSTGIS_RT_DEBUG, POSTGIS_RT_DEBUGF, PT_END, rtpg_union_band_arg_t::raster, rt_iterator_t::raster, rt_band_get_hasnodata_flag(), rt_band_get_nodata(), rt_band_get_pixtype(), rt_pixtype_name(), rt_raster_copy_band(), rt_raster_destroy(), rt_raster_from_band(), rt_raster_get_band(), rt_raster_iterator(), rt_raster_serialize(), rtpg_union_arg_destroy(), rtpg_union_mean_callback(), rtpg_union_range_callback(), rt_raster_serialized_t::size, rtpg_union_band_arg_t::uniontype, UT_MEAN, and UT_RANGE.

Referenced by RASTER_union_transfn().

2796 {
2797  rtpg_union_arg iwr;
2798  rt_raster _rtn = NULL;
2799  rt_raster _raster = NULL;
2800  rt_pgraster *pgraster = NULL;
2801 
2802  int i = 0;
2803  int j = 0;
2804  rt_iterator itrset = NULL;
2805  rt_band _band = NULL;
2806  int noerr = 1;
2807  int status = 0;
2808  rt_pixtype pixtype = PT_END;
2809  int hasnodata = 0;
2810  double nodataval = 0;
2811 
2812  POSTGIS_RT_DEBUG(3, "Starting...");
2813 
2814  /* cannot be called directly as this is exclusive aggregate function */
2815  if (!AggCheckCallContext(fcinfo, NULL)) {
2816  elog(ERROR, "RASTER_union_finalfn: Cannot be called in a non-aggregate context");
2817  PG_RETURN_NULL();
2818  }
2819 
2820  /* NULL, return null */
2821  if (PG_ARGISNULL(0))
2822  PG_RETURN_NULL();
2823 
2824  iwr = (rtpg_union_arg) PG_GETARG_POINTER(0);
2825 
2826  /* init itrset */
2827  itrset = palloc(sizeof(struct rt_iterator_t) * 2);
2828  if (itrset == NULL) {
2830  elog(ERROR, "RASTER_union_finalfn: Could not allocate memory for iterator arguments");
2831  PG_RETURN_NULL();
2832  }
2833 
2834  for (i = 0; i < iwr->numband; i++) {
2835  if (
2836  iwr->bandarg[i].uniontype == UT_MEAN ||
2837  iwr->bandarg[i].uniontype == UT_RANGE
2838  ) {
2839  /* raster containing the SUM or MAX is at index 1 */
2840  _band = rt_raster_get_band(iwr->bandarg[i].raster[1], 0);
2841 
2842  pixtype = rt_band_get_pixtype(_band);
2843  hasnodata = rt_band_get_hasnodata_flag(_band);
2844  if (hasnodata)
2845  rt_band_get_nodata(_band, &nodataval);
2846  POSTGIS_RT_DEBUGF(4, "(pixtype, hasnodata, nodataval) = (%s, %d, %f)", rt_pixtype_name(pixtype), hasnodata, nodataval);
2847 
2848  itrset[0].raster = iwr->bandarg[i].raster[0];
2849  itrset[0].nband = 0;
2850  itrset[1].raster = iwr->bandarg[i].raster[1];
2851  itrset[1].nband = 0;
2852 
2853  /* pass everything to iterator */
2854  if (iwr->bandarg[i].uniontype == UT_MEAN) {
2855  noerr = rt_raster_iterator(
2856  itrset, 2,
2857  ET_UNION, NULL,
2858  pixtype,
2859  hasnodata, nodataval,
2860  0, 0,
2861  NULL,
2862  NULL,
2864  &_raster
2865  );
2866  }
2867  else if (iwr->bandarg[i].uniontype == UT_RANGE) {
2868  noerr = rt_raster_iterator(
2869  itrset, 2,
2870  ET_UNION, NULL,
2871  pixtype,
2872  hasnodata, nodataval,
2873  0, 0,
2874  NULL,
2875  NULL,
2877  &_raster
2878  );
2879  }
2880 
2881  if (noerr != ES_NONE) {
2882  pfree(itrset);
2884  if (_rtn != NULL)
2885  rt_raster_destroy(_rtn);
2886  elog(ERROR, "RASTER_union_finalfn: Could not run raster iterator function");
2887  PG_RETURN_NULL();
2888  }
2889  }
2890  else
2891  _raster = iwr->bandarg[i].raster[0];
2892 
2893  /* first band, _rtn doesn't exist */
2894  if (i < 1) {
2895  uint32_t bandNums[1] = {0};
2896  _rtn = rt_raster_from_band(_raster, bandNums, 1);
2897  status = (_rtn == NULL) ? -1 : 0;
2898  }
2899  else
2900  status = rt_raster_copy_band(_rtn, _raster, 0, i);
2901 
2902  POSTGIS_RT_DEBUG(4, "destroying source rasters");
2903 
2904  /* destroy source rasters */
2905  if (
2906  iwr->bandarg[i].uniontype == UT_MEAN ||
2907  iwr->bandarg[i].uniontype == UT_RANGE
2908  ) {
2909  rt_raster_destroy(_raster);
2910  }
2911 
2912  for (j = 0; j < iwr->bandarg[i].numraster; j++) {
2913  if (iwr->bandarg[i].raster[j] == NULL)
2914  continue;
2915  rt_raster_destroy(iwr->bandarg[i].raster[j]);
2916  iwr->bandarg[i].raster[j] = NULL;
2917  }
2918 
2919  if (status < 0) {
2921  rt_raster_destroy(_rtn);
2922  elog(ERROR, "RASTER_union_finalfn: Could not add band to final raster");
2923  PG_RETURN_NULL();
2924  }
2925  }
2926 
2927  /* cleanup */
2928  pfree(itrset);
2930 
2931  if (!_rtn) PG_RETURN_NULL();
2932 
2933  pgraster = rt_raster_serialize(_rtn);
2934  rt_raster_destroy(_rtn);
2935 
2936  POSTGIS_RT_DEBUG(3, "Finished");
2937 
2938  if (!pgraster)
2939  PG_RETURN_NULL();
2940 
2941  SET_VARSIZE(pgraster, pgraster->size);
2942  PG_RETURN_POINTER(pgraster);
2943 }
static int rtpg_union_range_callback(rt_iterator_arg arg, void *userarg, double *value, int *nodata)
void * rt_raster_serialize(rt_raster raster)
Return this raster in serialized form.
Definition: rt_serialize.c:521
rt_raster rt_raster_from_band(rt_raster raster, uint32_t *bandNums, int count)
Construct a new rt_raster from an existing rt_raster and an array of band numbers.
Definition: rt_raster.c:1439
rtpg_union_band_arg bandarg
rt_pixtype
Definition: librtcore.h:185
#define POSTGIS_RT_DEBUGF(level, msg,...)
Definition: rtpostgis.h:65
rt_errorstate rt_band_get_nodata(rt_band band, double *nodata)
Get NODATA value.
Definition: rt_band.c:1597
unsigned int uint32_t
Definition: uthash.h:78
static int rtpg_union_mean_callback(rt_iterator_arg arg, void *userarg, double *value, int *nodata)
rt_band rt_raster_get_band(rt_raster raster, int bandNum)
Return Nth band, or NULL if unavailable.
Definition: rt_raster.c:381
int rt_raster_copy_band(rt_raster torast, rt_raster fromrast, int fromindex, int toindex)
Copy one band from one raster to another.
Definition: rt_raster.c:1374
int rt_band_get_hasnodata_flag(rt_band band)
Get hasnodata flag value.
Definition: rt_band.c:541
void rt_raster_destroy(rt_raster raster)
Release memory associated to a raster.
Definition: rt_raster.c:82
rt_raster raster
Definition: librtcore.h:2394
uint16_t nband
Definition: librtcore.h:2395
static void rtpg_union_arg_destroy(rtpg_union_arg arg)
Struct definitions.
Definition: librtcore.h:2201
const char * rt_pixtype_name(rt_pixtype pixtype)
Definition: rt_pixel.c:110
rt_errorstate rt_raster_iterator(rt_iterator itrset, uint16_t itrcount, rt_extenttype extenttype, rt_raster customextent, rt_pixtype pixtype, uint8_t hasnodata, double nodataval, uint16_t distancex, uint16_t distancey, rt_mask mask, void *userarg, int(*callback)(rt_iterator_arg arg, void *userarg, double *value, int *nodata), rt_raster *rtnraster)
n-raster iterator.
rt_pixtype rt_band_get_pixtype(rt_band band)
Return pixeltype of this band.
Definition: rt_band.c:498
struct rtpg_union_arg_t * rtpg_union_arg
rtpg_union_type uniontype
#define POSTGIS_RT_DEBUG(level, msg)
Definition: rtpostgis.h:61
Here is the call graph for this function:
Here is the caller graph for this function: