PostGIS  3.0.6dev-r@@SVN_REVISION@@

◆ RASTER_union_finalfn()

Datum RASTER_union_finalfn ( PG_FUNCTION_ARGS  )

Definition at line 2799 of file rtpg_mapalgebra.c.

2800 {
2801  rtpg_union_arg iwr;
2802  rt_raster _rtn = NULL;
2803  rt_raster _raster = NULL;
2804  rt_pgraster *pgraster = NULL;
2805 
2806  int i = 0;
2807  int j = 0;
2808  rt_iterator itrset = NULL;
2809  rt_band _band = NULL;
2810  int noerr = 1;
2811  int status = 0;
2812  rt_pixtype pixtype = PT_END;
2813  int hasnodata = 0;
2814  double nodataval = 0;
2815 
2816  POSTGIS_RT_DEBUG(3, "Starting...");
2817 
2818  /* cannot be called directly as this is exclusive aggregate function */
2819  if (!AggCheckCallContext(fcinfo, NULL)) {
2820  elog(ERROR, "RASTER_union_finalfn: Cannot be called in a non-aggregate context");
2821  PG_RETURN_NULL();
2822  }
2823 
2824  /* NULL, return null */
2825  if (PG_ARGISNULL(0))
2826  PG_RETURN_NULL();
2827 
2828  iwr = (rtpg_union_arg) PG_GETARG_POINTER(0);
2829 
2830  /* init itrset */
2831  itrset = palloc(sizeof(struct rt_iterator_t) * 2);
2832  if (itrset == NULL) {
2834  elog(ERROR, "RASTER_union_finalfn: Could not allocate memory for iterator arguments");
2835  PG_RETURN_NULL();
2836  }
2837 
2838  for (i = 0; i < iwr->numband; i++) {
2839  if (
2840  iwr->bandarg[i].uniontype == UT_MEAN ||
2841  iwr->bandarg[i].uniontype == UT_RANGE
2842  ) {
2843  /* raster containing the SUM or MAX is at index 1 */
2844  _band = rt_raster_get_band(iwr->bandarg[i].raster[1], 0);
2845 
2846  pixtype = rt_band_get_pixtype(_band);
2847  hasnodata = rt_band_get_hasnodata_flag(_band);
2848  if (hasnodata)
2849  rt_band_get_nodata(_band, &nodataval);
2850  POSTGIS_RT_DEBUGF(4, "(pixtype, hasnodata, nodataval) = (%s, %d, %f)", rt_pixtype_name(pixtype), hasnodata, nodataval);
2851 
2852  itrset[0].raster = iwr->bandarg[i].raster[0];
2853  itrset[0].nband = 0;
2854  itrset[1].raster = iwr->bandarg[i].raster[1];
2855  itrset[1].nband = 0;
2856 
2857  /* pass everything to iterator */
2858  if (iwr->bandarg[i].uniontype == UT_MEAN) {
2859  noerr = rt_raster_iterator(
2860  itrset, 2,
2861  ET_UNION, NULL,
2862  pixtype,
2863  hasnodata, nodataval,
2864  0, 0,
2865  NULL,
2866  NULL,
2868  &_raster
2869  );
2870  }
2871  else if (iwr->bandarg[i].uniontype == UT_RANGE) {
2872  noerr = rt_raster_iterator(
2873  itrset, 2,
2874  ET_UNION, NULL,
2875  pixtype,
2876  hasnodata, nodataval,
2877  0, 0,
2878  NULL,
2879  NULL,
2881  &_raster
2882  );
2883  }
2884 
2885  if (noerr != ES_NONE) {
2886  pfree(itrset);
2888  if (_rtn != NULL)
2889  rt_raster_destroy(_rtn);
2890  elog(ERROR, "RASTER_union_finalfn: Could not run raster iterator function");
2891  PG_RETURN_NULL();
2892  }
2893  }
2894  else {
2895  _raster = iwr->bandarg[i].raster[0];
2896  if (_raster == NULL)
2897  continue;
2898  }
2899 
2900  /* first band, _rtn doesn't exist */
2901  if (i < 1) {
2902  uint32_t bandNums[1] = {0};
2903  _rtn = rt_raster_from_band(_raster, bandNums, 1);
2904  status = (_rtn == NULL) ? -1 : 0;
2905  }
2906  else
2907  status = rt_raster_copy_band(_rtn, _raster, 0, i);
2908 
2909  POSTGIS_RT_DEBUG(4, "destroying source rasters");
2910 
2911  /* destroy source rasters */
2912  if (
2913  iwr->bandarg[i].uniontype == UT_MEAN ||
2914  iwr->bandarg[i].uniontype == UT_RANGE
2915  ) {
2916  rt_raster_destroy(_raster);
2917  }
2918 
2919  for (j = 0; j < iwr->bandarg[i].numraster; j++) {
2920  if (iwr->bandarg[i].raster[j] == NULL)
2921  continue;
2922  rt_raster_destroy(iwr->bandarg[i].raster[j]);
2923  iwr->bandarg[i].raster[j] = NULL;
2924  }
2925 
2926  if (status < 0) {
2928  rt_raster_destroy(_rtn);
2929  elog(ERROR, "RASTER_union_finalfn: Could not add band to final raster");
2930  PG_RETURN_NULL();
2931  }
2932  }
2933 
2934  /* cleanup */
2935  /* For Windowing functions, it is important to leave */
2936  /* the state intact, knowing that the aggcontext will be */
2937  /* freed by PgSQL when the statement is complete. */
2938  /* https://trac.osgeo.org/postgis/ticket/4770 */
2939  // pfree(itrset);
2940  // rtpg_union_arg_destroy(iwr);
2941 
2942  if (!_rtn) PG_RETURN_NULL();
2943 
2944  pgraster = rt_raster_serialize(_rtn);
2945  rt_raster_destroy(_rtn);
2946 
2947  POSTGIS_RT_DEBUG(3, "Finished");
2948 
2949  if (!pgraster)
2950  PG_RETURN_NULL();
2951 
2952  SET_VARSIZE(pgraster, pgraster->size);
2953  PG_RETURN_POINTER(pgraster);
2954 }
int rt_band_get_hasnodata_flag(rt_band band)
Get hasnodata flag value.
Definition: rt_band.c:674
void rt_raster_destroy(rt_raster raster)
Release memory associated to a raster.
Definition: rt_raster.c:82
rt_pixtype
Definition: librtcore.h:185
@ PT_END
Definition: librtcore.h:197
void * rt_raster_serialize(rt_raster raster)
Return this raster in serialized form.
Definition: rt_serialize.c:521
@ ES_NONE
Definition: librtcore.h:180
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.
@ ET_UNION
Definition: librtcore.h:202
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:1430
rt_errorstate rt_band_get_nodata(rt_band band, double *nodata)
Get NODATA value.
Definition: rt_band.c:1730
rt_pixtype rt_band_get_pixtype(rt_band band)
Return pixeltype of this band.
Definition: rt_band.c:631
const char * rt_pixtype_name(rt_pixtype pixtype)
Definition: rt_pixel.c:110
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:1365
rt_band rt_raster_get_band(rt_raster raster, int bandNum)
Return Nth band, or NULL if unavailable.
Definition: rt_raster.c:381
static int rtpg_union_mean_callback(rt_iterator_arg arg, void *userarg, double *value, int *nodata)
static int rtpg_union_range_callback(rt_iterator_arg arg, void *userarg, double *value, int *nodata)
static void rtpg_union_arg_destroy(rtpg_union_arg arg)
struct rtpg_union_arg_t * rtpg_union_arg
@ UT_MEAN
@ UT_RANGE
#define POSTGIS_RT_DEBUG(level, msg)
Definition: rtpostgis.h:61
#define POSTGIS_RT_DEBUGF(level, msg,...)
Definition: rtpostgis.h:65
rt_raster raster
Definition: librtcore.h:2444
uint16_t nband
Definition: librtcore.h:2445
Struct definitions.
Definition: librtcore.h:2251
rtpg_union_band_arg bandarg
rtpg_union_type uniontype

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, rt_iterator_t::raster, rtpg_union_band_arg_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.

Here is the call graph for this function: