PostGIS  2.2.8dev-r@@SVN_REVISION@@

◆ RASTER_union_finalfn()

Datum RASTER_union_finalfn ( PG_FUNCTION_ARGS  )

Definition at line 2745 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().

2746 {
2747  rtpg_union_arg iwr;
2748  rt_raster _rtn = NULL;
2749  rt_raster _raster = NULL;
2750  rt_pgraster *pgraster = NULL;
2751 
2752  int i = 0;
2753  int j = 0;
2754  rt_iterator itrset = NULL;
2755  rt_band _band = NULL;
2756  int noerr = 1;
2757  int status = 0;
2758  rt_pixtype pixtype = PT_END;
2759  int hasnodata = 0;
2760  double nodataval = 0;
2761 
2762  POSTGIS_RT_DEBUG(3, "Starting...");
2763 
2764  /* cannot be called directly as this is exclusive aggregate function */
2765  if (!AggCheckCallContext(fcinfo, NULL)) {
2766  elog(ERROR, "RASTER_union_finalfn: Cannot be called in a non-aggregate context");
2767  PG_RETURN_NULL();
2768  }
2769 
2770  /* NULL, return null */
2771  if (PG_ARGISNULL(0))
2772  PG_RETURN_NULL();
2773 
2774  iwr = (rtpg_union_arg) PG_GETARG_POINTER(0);
2775 
2776  /* init itrset */
2777  itrset = palloc(sizeof(struct rt_iterator_t) * 2);
2778  if (itrset == NULL) {
2780  elog(ERROR, "RASTER_union_finalfn: Could not allocate memory for iterator arguments");
2781  PG_RETURN_NULL();
2782  }
2783 
2784  for (i = 0; i < iwr->numband; i++) {
2785  if (
2786  iwr->bandarg[i].uniontype == UT_MEAN ||
2787  iwr->bandarg[i].uniontype == UT_RANGE
2788  ) {
2789  /* raster containing the SUM or MAX is at index 1 */
2790  _band = rt_raster_get_band(iwr->bandarg[i].raster[1], 0);
2791 
2792  pixtype = rt_band_get_pixtype(_band);
2793  hasnodata = rt_band_get_hasnodata_flag(_band);
2794  if (hasnodata)
2795  rt_band_get_nodata(_band, &nodataval);
2796  POSTGIS_RT_DEBUGF(4, "(pixtype, hasnodata, nodataval) = (%s, %d, %f)", rt_pixtype_name(pixtype), hasnodata, nodataval);
2797 
2798  itrset[0].raster = iwr->bandarg[i].raster[0];
2799  itrset[0].nband = 0;
2800  itrset[1].raster = iwr->bandarg[i].raster[1];
2801  itrset[1].nband = 0;
2802 
2803  /* pass everything to iterator */
2804  if (iwr->bandarg[i].uniontype == UT_MEAN) {
2805  noerr = rt_raster_iterator(
2806  itrset, 2,
2807  ET_UNION, NULL,
2808  pixtype,
2809  hasnodata, nodataval,
2810  0, 0,
2811  NULL,
2812  NULL,
2814  &_raster
2815  );
2816  }
2817  else if (iwr->bandarg[i].uniontype == UT_RANGE) {
2818  noerr = rt_raster_iterator(
2819  itrset, 2,
2820  ET_UNION, NULL,
2821  pixtype,
2822  hasnodata, nodataval,
2823  0, 0,
2824  NULL,
2825  NULL,
2827  &_raster
2828  );
2829  }
2830 
2831  if (noerr != ES_NONE) {
2832  pfree(itrset);
2834  if (_rtn != NULL)
2835  rt_raster_destroy(_rtn);
2836  elog(ERROR, "RASTER_union_finalfn: Could not run raster iterator function");
2837  PG_RETURN_NULL();
2838  }
2839  }
2840  else
2841  _raster = iwr->bandarg[i].raster[0];
2842 
2843  /* first band, _rtn doesn't exist */
2844  if (i < 1) {
2845  uint32_t bandNums[1] = {0};
2846  _rtn = rt_raster_from_band(_raster, bandNums, 1);
2847  status = (_rtn == NULL) ? -1 : 0;
2848  }
2849  else
2850  status = rt_raster_copy_band(_rtn, _raster, 0, i);
2851 
2852  POSTGIS_RT_DEBUG(4, "destroying source rasters");
2853 
2854  /* destroy source rasters */
2855  if (
2856  iwr->bandarg[i].uniontype == UT_MEAN ||
2857  iwr->bandarg[i].uniontype == UT_RANGE
2858  ) {
2859  rt_raster_destroy(_raster);
2860  }
2861 
2862  for (j = 0; j < iwr->bandarg[i].numraster; j++) {
2863  if (iwr->bandarg[i].raster[j] == NULL)
2864  continue;
2865  rt_raster_destroy(iwr->bandarg[i].raster[j]);
2866  iwr->bandarg[i].raster[j] = NULL;
2867  }
2868 
2869  if (status < 0) {
2871  rt_raster_destroy(_rtn);
2872  elog(ERROR, "RASTER_union_finalfn: Could not add band to final raster");
2873  PG_RETURN_NULL();
2874  }
2875  }
2876 
2877  /* cleanup */
2878  pfree(itrset);
2880 
2881  if (!_rtn) PG_RETURN_NULL();
2882 
2883  pgraster = rt_raster_serialize(_rtn);
2884  rt_raster_destroy(_rtn);
2885 
2886  POSTGIS_RT_DEBUG(3, "Finished");
2887 
2888  if (!pgraster)
2889  PG_RETURN_NULL();
2890 
2891  SET_VARSIZE(pgraster, pgraster->size);
2892  PG_RETURN_POINTER(pgraster);
2893 }
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:197
#define POSTGIS_RT_DEBUGF(level, msg,...)
Definition: rtpostgis.h:57
rt_errorstate rt_band_get_nodata(rt_band band, double *nodata)
Get NODATA value.
Definition: rt_band.c:1597
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:2406
uint16_t nband
Definition: librtcore.h:2407
static void rtpg_union_arg_destroy(rtpg_union_arg arg)
Struct definitions.
Definition: librtcore.h:2213
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:53
Here is the call graph for this function:
Here is the caller graph for this function: