PostGIS  2.1.10dev-r@@SVN_REVISION@@
Datum RASTER_union_finalfn ( PG_FUNCTION_ARGS  )

Definition at line 18801 of file rt_pg.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, 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.

18802 {
18803  rtpg_union_arg iwr;
18804  rt_raster _rtn = NULL;
18805  rt_raster _raster = NULL;
18806  rt_pgraster *pgraster = NULL;
18807 
18808  int i = 0;
18809  int j = 0;
18810  rt_iterator itrset = NULL;
18811  rt_band _band = NULL;
18812  int noerr = 1;
18813  int status = 0;
18814  rt_pixtype pixtype = PT_END;
18815  int hasnodata = 0;
18816  double nodataval = 0;
18817 
18818  POSTGIS_RT_DEBUG(3, "Starting...");
18819 
18820  /* cannot be called directly as this is exclusive aggregate function */
18821  if (!AggCheckCallContext(fcinfo, NULL)) {
18822  elog(ERROR, "RASTER_union_finalfn: Cannot be called in a non-aggregate context");
18823  PG_RETURN_NULL();
18824  }
18825 
18826  /* NULL, return null */
18827  if (PG_ARGISNULL(0))
18828  PG_RETURN_NULL();
18829 
18830  iwr = (rtpg_union_arg) PG_GETARG_POINTER(0);
18831 
18832  /* init itrset */
18833  itrset = palloc(sizeof(struct rt_iterator_t) * 2);
18834  if (itrset == NULL) {
18836  elog(ERROR, "RASTER_union_finalfn: Could not allocate memory for iterator arguments");
18837  PG_RETURN_NULL();
18838  }
18839 
18840  for (i = 0; i < iwr->numband; i++) {
18841  if (
18842  iwr->bandarg[i].uniontype == UT_MEAN ||
18843  iwr->bandarg[i].uniontype == UT_RANGE
18844  ) {
18845  /* raster containing the SUM or MAX is at index 1 */
18846  _band = rt_raster_get_band(iwr->bandarg[i].raster[1], 0);
18847 
18848  pixtype = rt_band_get_pixtype(_band);
18849  hasnodata = rt_band_get_hasnodata_flag(_band);
18850  if (hasnodata)
18851  rt_band_get_nodata(_band, &nodataval);
18852  POSTGIS_RT_DEBUGF(4, "(pixtype, hasnodata, nodataval) = (%s, %d, %f)", rt_pixtype_name(pixtype), hasnodata, nodataval);
18853 
18854  itrset[0].raster = iwr->bandarg[i].raster[0];
18855  itrset[0].nband = 0;
18856  itrset[1].raster = iwr->bandarg[i].raster[1];
18857  itrset[1].nband = 0;
18858 
18859  /* pass everything to iterator */
18860  if (iwr->bandarg[i].uniontype == UT_MEAN) {
18861  noerr = rt_raster_iterator(
18862  itrset, 2,
18863  ET_UNION, NULL,
18864  pixtype,
18865  hasnodata, nodataval,
18866  0, 0,
18867  NULL,
18869  &_raster
18870  );
18871  }
18872  else if (iwr->bandarg[i].uniontype == UT_RANGE) {
18873  noerr = rt_raster_iterator(
18874  itrset, 2,
18875  ET_UNION, NULL,
18876  pixtype,
18877  hasnodata, nodataval,
18878  0, 0,
18879  NULL,
18881  &_raster
18882  );
18883  }
18884 
18885  if (noerr != ES_NONE) {
18886  pfree(itrset);
18888  if (_rtn != NULL)
18889  rt_raster_destroy(_rtn);
18890  elog(ERROR, "RASTER_union_finalfn: Could not run raster iterator function");
18891  PG_RETURN_NULL();
18892  }
18893  }
18894  else
18895  _raster = iwr->bandarg[i].raster[0];
18896 
18897  /* first band, _rtn doesn't exist */
18898  if (i < 1) {
18899  uint32_t bandNums[1] = {0};
18900  _rtn = rt_raster_from_band(_raster, bandNums, 1);
18901  status = (_rtn == NULL) ? -1 : 0;
18902  }
18903  else
18904  status = rt_raster_copy_band(_rtn, _raster, 0, i);
18905 
18906  POSTGIS_RT_DEBUG(4, "destroying source rasters");
18907 
18908  /* destroy source rasters */
18909  if (
18910  iwr->bandarg[i].uniontype == UT_MEAN ||
18911  iwr->bandarg[i].uniontype == UT_RANGE
18912  ) {
18913  rt_raster_destroy(_raster);
18914  }
18915 
18916  for (j = 0; j < iwr->bandarg[i].numraster; j++) {
18917  if (iwr->bandarg[i].raster[j] == NULL)
18918  continue;
18919  rt_raster_destroy(iwr->bandarg[i].raster[j]);
18920  iwr->bandarg[i].raster[j] = NULL;
18921  }
18922 
18923  if (status < 0) {
18925  rt_raster_destroy(_rtn);
18926  elog(ERROR, "RASTER_union_finalfn: Could not add band to final raster");
18927  PG_RETURN_NULL();
18928  }
18929  }
18930 
18931  /* cleanup */
18932  pfree(itrset);
18934 
18935  if (!_rtn) PG_RETURN_NULL();
18936 
18937  pgraster = rt_raster_serialize(_rtn);
18938  rt_raster_destroy(_rtn);
18939 
18940  POSTGIS_RT_DEBUG(3, "Finished");
18941 
18942  if (!pgraster)
18943  PG_RETURN_NULL();
18944 
18945  SET_VARSIZE(pgraster, pgraster->size);
18946  PG_RETURN_POINTER(pgraster);
18947 }
void * rt_raster_serialize(rt_raster raster)
Return this raster in serialized form.
Definition: rt_api.c:8158
void rt_raster_destroy(rt_raster raster)
Release memory associated to a raster.
Definition: rt_api.c:5387
static int rtpg_union_range_callback(rt_iterator_arg arg, void *userarg, double *value, int *nodata)
Definition: rt_pg.c:17922
const char * rt_pixtype_name(rt_pixtype pixtype)
Definition: rt_api.c:1168
rtpg_union_band_arg bandarg
Definition: rt_pg.c:17764
static int rtpg_union_mean_callback(rt_iterator_arg arg, void *userarg, double *value, int *nodata)
Definition: rt_pg.c:17886
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_api.c:8582
Definition: rt_api.h:184
rt_pixtype rt_band_get_pixtype(rt_band band)
Return pixeltype of this band.
Definition: rt_api.c:1900
rt_raster * raster
Definition: rt_pg.c:17758
static void rtpg_union_arg_destroy(rtpg_union_arg arg)
Definition: rt_pg.c:17767
rt_pixtype
Definition: rt_api.h:172
#define POSTGIS_RT_DEBUG(level, msg)
Definition: rt_pg.h:58
struct rtpg_union_arg_t * rtpg_union_arg
Definition: rt_pg.c:17761
rt_errorstate rt_band_get_nodata(rt_band band, double *nodata)
Get NODATA value.
Definition: rt_api.c:3058
rt_raster raster
Definition: rt_api.h:2360
uint16_t nband
Definition: rt_api.h:2361
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_api.c:8643
rt_band rt_raster_get_band(rt_raster raster, int n)
Return Nth band, or NULL if unavailable.
Definition: rt_api.c:5686
Struct definitions.
Definition: rt_api.h:2175
#define POSTGIS_RT_DEBUGF(level, msg,...)
Definition: rt_pg.h:62
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, void *userarg, int(*callback)(rt_iterator_arg arg, void *userarg, double *value, int *nodata), rt_raster *rtnraster)
n-raster iterator.
Definition: rt_api.c:13927
rtpg_union_type uniontype
Definition: rt_pg.c:17755
int rt_band_get_hasnodata_flag(rt_band band)
Get hasnodata flag value.
Definition: rt_api.c:2002

Here is the call graph for this function: