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

Definition at line 18118 of file rt_pg.c.

References rtpg_union_arg_t::bandarg, ES_NONE, ET_LAST, ET_UNION, FALSE, window::gt, pixval::nband, rt_iterator_t::nband, rtpg_union_band_arg_t::nband, rt_iterator_t::nbnodata, rtpg_union_arg_t::numband, rtpg_union_band_arg_t::numraster, POSTGIS_RT_DEBUG, POSTGIS_RT_DEBUGF, PT_32BUI, PT_64BF, PT_END, rtrowdump::raster, rt_iterator_t::raster, rtpg_union_band_arg_t::raster, rt_band_destroy(), rt_band_get_hasnodata_flag(), rt_band_get_min_value(), rt_band_get_nodata(), rt_band_get_pixel_line(), rt_band_get_pixtype(), rt_band_set_pixel_line(), rt_pixtype_get_min_value(), rt_pixtype_name(), rt_raster_clone(), rt_raster_deserialize(), rt_raster_destroy(), rt_raster_from_two_rasters(), rt_raster_generate_new_band(), rt_raster_get_band(), rt_raster_get_geotransform_matrix(), rt_raster_get_height(), rt_raster_get_num_bands(), rt_raster_get_width(), rt_raster_has_band(), rt_raster_is_empty(), rt_raster_iterator(), rt_util_same_geotransform_matrix(), rtpg_strtoupper(), rtpg_union_arg_destroy(), rtpg_union_callback(), rtpg_union_noarg(), rtpg_union_unionarg_process(), rtpg_uniontype_index_from_name(), rtpg_union_band_arg_t::uniontype, UT_COUNT, UT_LAST, UT_MAX, UT_MEAN, UT_MIN, UT_RANGE, UT_SUM, and pixval::y.

18119 {
18120  MemoryContext aggcontext;
18121  MemoryContext oldcontext;
18122  rtpg_union_arg iwr = NULL;
18123  int skiparg = 0;
18124 
18125  rt_pgraster *pgraster = NULL;
18126  rt_raster raster = NULL;
18127  rt_raster _raster = NULL;
18128  rt_band _band = NULL;
18129  int nband = 1;
18130  int noerr = 1;
18131  int isempty[2] = {0};
18132  int hasband[2] = {0};
18133  int nargs = 0;
18134  double _offset[4] = {0.};
18135  int nbnodata = 0; /* 1 if adding bands */
18136 
18137  int i = 0;
18138  int j = 0;
18139  int k = 0;
18140 
18141  rt_iterator itrset;
18142  char *utypename = NULL;
18143  rtpg_union_type utype = UT_LAST;
18144  rt_pixtype pixtype = PT_END;
18145  int hasnodata = 1;
18146  double nodataval = 0;
18147 
18148  rt_raster iraster = NULL;
18149  rt_band iband = NULL;
18150  int reuserast = 0;
18151  int y = 0;
18152  uint16_t _dim[2] = {0};
18153  void *vals = NULL;
18154  uint16_t nvals = 0;
18155 
18156  POSTGIS_RT_DEBUG(3, "Starting...");
18157 
18158  /* cannot be called directly as this is exclusive aggregate function */
18159  if (!AggCheckCallContext(fcinfo, &aggcontext)) {
18160  elog(ERROR, "RASTER_union_transfn: Cannot be called in a non-aggregate context");
18161  PG_RETURN_NULL();
18162  }
18163 
18164  /* switch to aggcontext */
18165  oldcontext = MemoryContextSwitchTo(aggcontext);
18166 
18167  if (PG_ARGISNULL(0)) {
18168  POSTGIS_RT_DEBUG(3, "Creating state variable");
18169  /* allocate container in aggcontext */
18170  iwr = palloc(sizeof(struct rtpg_union_arg_t));
18171  if (iwr == NULL) {
18172  MemoryContextSwitchTo(oldcontext);
18173  elog(ERROR, "RASTER_union_transfn: Could not allocate memory for state variable");
18174  PG_RETURN_NULL();
18175  }
18176 
18177  iwr->numband = 0;
18178  iwr->bandarg = NULL;
18179 
18180  skiparg = 0;
18181  }
18182  else {
18183  POSTGIS_RT_DEBUG(3, "State variable already exists");
18184  iwr = (rtpg_union_arg) PG_GETARG_POINTER(0);
18185  skiparg = 1;
18186  }
18187 
18188  /* raster arg is NOT NULL */
18189  if (!PG_ARGISNULL(1)) {
18190  /* deserialize raster */
18191  pgraster = (rt_pgraster *) PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
18192 
18193  /* Get raster object */
18194  raster = rt_raster_deserialize(pgraster, FALSE);
18195  if (raster == NULL) {
18196 
18198  PG_FREE_IF_COPY(pgraster, 1);
18199 
18200  MemoryContextSwitchTo(oldcontext);
18201  elog(ERROR, "RASTER_union_transfn: Could not deserialize raster");
18202  PG_RETURN_NULL();
18203  }
18204  }
18205 
18206  /* process additional args if needed */
18207  nargs = PG_NARGS();
18208  POSTGIS_RT_DEBUGF(4, "nargs = %d", nargs);
18209  if (nargs > 2) {
18210  POSTGIS_RT_DEBUG(4, "processing additional arguments");
18211 
18212  /* if more than 2 arguments, determine the type of argument 3 */
18213  /* band number, UNION type or unionarg */
18214  if (!PG_ARGISNULL(2)) {
18215  Oid calltype = get_fn_expr_argtype(fcinfo->flinfo, 2);
18216 
18217  switch (calltype) {
18218  /* UNION type */
18219  case TEXTOID: {
18220  int idx = 0;
18221  int numband = 0;
18222 
18223  POSTGIS_RT_DEBUG(4, "Processing arg 3 as UNION type");
18224  nbnodata = 1;
18225 
18226  utypename = text_to_cstring(PG_GETARG_TEXT_P(2));
18227  utype = rtpg_uniontype_index_from_name(rtpg_strtoupper(utypename));
18228  POSTGIS_RT_DEBUGF(4, "Union type: %s", utypename);
18229 
18230  POSTGIS_RT_DEBUGF(4, "iwr->numband: %d", iwr->numband);
18231  /* see if we need to append new bands */
18232  if (raster) {
18233  idx = iwr->numband;
18234  numband = rt_raster_get_num_bands(raster);
18235  POSTGIS_RT_DEBUGF(4, "numband: %d", numband);
18236 
18237  /* only worry about appended bands */
18238  if (numband > iwr->numband)
18239  iwr->numband = numband;
18240  }
18241 
18242  if (!iwr->numband)
18243  iwr->numband = 1;
18244  POSTGIS_RT_DEBUGF(4, "iwr->numband: %d", iwr->numband);
18245  POSTGIS_RT_DEBUGF(4, "numband, idx: %d, %d", numband, idx);
18246 
18247  /* bandarg set. only possible after the first call to function */
18248  if (iwr->bandarg) {
18249  /* only reallocate if new bands need to be added */
18250  if (numband > idx) {
18251  POSTGIS_RT_DEBUG(4, "Reallocating iwr->bandarg");
18252  iwr->bandarg = repalloc(iwr->bandarg, sizeof(struct rtpg_union_band_arg_t) * iwr->numband);
18253  }
18254  /* prevent initial values step happening below */
18255  else
18256  idx = iwr->numband;
18257  }
18258  /* bandarg not set, first call to function */
18259  else {
18260  POSTGIS_RT_DEBUG(4, "Allocating iwr->bandarg");
18261  iwr->bandarg = palloc(sizeof(struct rtpg_union_band_arg_t) * iwr->numband);
18262  }
18263  if (iwr->bandarg == NULL) {
18264 
18266  if (raster != NULL) {
18267  rt_raster_destroy(raster);
18268  PG_FREE_IF_COPY(pgraster, 1);
18269  }
18270 
18271  MemoryContextSwitchTo(oldcontext);
18272  elog(ERROR, "RASTER_union_transfn: Could not allocate memory for band information");
18273  PG_RETURN_NULL();
18274  }
18275 
18276  /* set initial values for bands that are "new" */
18277  for (i = idx; i < iwr->numband; i++) {
18278  iwr->bandarg[i].uniontype = utype;
18279  iwr->bandarg[i].nband = i;
18280 
18281  if (
18282  utype == UT_MEAN ||
18283  utype == UT_RANGE
18284  ) {
18285  iwr->bandarg[i].numraster = 2;
18286  }
18287  else
18288  iwr->bandarg[i].numraster = 1;
18289  iwr->bandarg[i].raster = NULL;
18290  }
18291 
18292  break;
18293  }
18294  /* band number */
18295  case INT2OID:
18296  case INT4OID:
18297  if (skiparg)
18298  break;
18299 
18300  POSTGIS_RT_DEBUG(4, "Processing arg 3 as band number");
18301  nband = PG_GETARG_INT32(2);
18302  if (nband < 1) {
18303 
18305  if (raster != NULL) {
18306  rt_raster_destroy(raster);
18307  PG_FREE_IF_COPY(pgraster, 1);
18308  }
18309 
18310  MemoryContextSwitchTo(oldcontext);
18311  elog(ERROR, "RASTER_union_transfn: Band number must be greater than zero (1-based)");
18312  PG_RETURN_NULL();
18313  }
18314 
18315  iwr->numband = 1;
18316  iwr->bandarg = palloc(sizeof(struct rtpg_union_band_arg_t) * iwr->numband);
18317  if (iwr->bandarg == NULL) {
18318 
18320  if (raster != NULL) {
18321  rt_raster_destroy(raster);
18322  PG_FREE_IF_COPY(pgraster, 1);
18323  }
18324 
18325  MemoryContextSwitchTo(oldcontext);
18326  elog(ERROR, "RASTER_union_transfn: Could not allocate memory for band information");
18327  PG_RETURN_NULL();
18328  }
18329 
18330  iwr->bandarg[0].uniontype = UT_LAST;
18331  iwr->bandarg[0].nband = nband - 1;
18332 
18333  iwr->bandarg[0].numraster = 1;
18334  iwr->bandarg[0].raster = NULL;
18335  break;
18336  /* only other type allowed is unionarg */
18337  default:
18338  if (skiparg)
18339  break;
18340 
18341  POSTGIS_RT_DEBUG(4, "Processing arg 3 as unionarg");
18342  if (!rtpg_union_unionarg_process(iwr, PG_GETARG_ARRAYTYPE_P(2))) {
18343 
18345  if (raster != NULL) {
18346  rt_raster_destroy(raster);
18347  PG_FREE_IF_COPY(pgraster, 1);
18348  }
18349 
18350  MemoryContextSwitchTo(oldcontext);
18351  elog(ERROR, "RASTER_union_transfn: Could not process unionarg");
18352  PG_RETURN_NULL();
18353  }
18354 
18355  break;
18356  }
18357  }
18358 
18359  /* UNION type */
18360  if (nargs > 3 && !PG_ARGISNULL(3)) {
18361  utypename = text_to_cstring(PG_GETARG_TEXT_P(3));
18362  utype = rtpg_uniontype_index_from_name(rtpg_strtoupper(utypename));
18363  iwr->bandarg[0].uniontype = utype;
18364  POSTGIS_RT_DEBUGF(4, "Union type: %s", utypename);
18365 
18366  if (
18367  utype == UT_MEAN ||
18368  utype == UT_RANGE
18369  ) {
18370  iwr->bandarg[0].numraster = 2;
18371  }
18372  }
18373 
18374  /* allocate space for pointers to rt_raster */
18375  for (i = 0; i < iwr->numband; i++) {
18376  POSTGIS_RT_DEBUGF(4, "iwr->bandarg[%d].raster @ %p", i, iwr->bandarg[i].raster);
18377 
18378  /* no need to allocate */
18379  if (iwr->bandarg[i].raster != NULL)
18380  continue;
18381 
18382  POSTGIS_RT_DEBUGF(4, "Allocating space for working rasters of band %d", i);
18383 
18384  iwr->bandarg[i].raster = (rt_raster *) palloc(sizeof(rt_raster) * iwr->bandarg[i].numraster);
18385  if (iwr->bandarg[i].raster == NULL) {
18386 
18388  if (raster != NULL) {
18389  rt_raster_destroy(raster);
18390  PG_FREE_IF_COPY(pgraster, 1);
18391  }
18392 
18393  MemoryContextSwitchTo(oldcontext);
18394  elog(ERROR, "RASTER_union_transfn: Could not allocate memory for working raster(s)");
18395  PG_RETURN_NULL();
18396  }
18397 
18398  memset(iwr->bandarg[i].raster, 0, sizeof(rt_raster) * iwr->bandarg[i].numraster);
18399 
18400  /* add new working rt_raster but only if working raster already exists */
18401  if (i > 0 && !rt_raster_is_empty(iwr->bandarg[0].raster[0])) {
18402  for (j = 0; j < iwr->bandarg[i].numraster; j++) {
18403  iwr->bandarg[i].raster[j] = rt_raster_clone(iwr->bandarg[0].raster[0], 0); /* shallow clone */
18404  if (iwr->bandarg[i].raster[j] == NULL) {
18405 
18407  if (raster != NULL) {
18408  rt_raster_destroy(raster);
18409  PG_FREE_IF_COPY(pgraster, 1);
18410  }
18411 
18412  MemoryContextSwitchTo(oldcontext);
18413  elog(ERROR, "RASTER_union_transfn: Could not create working raster");
18414  PG_RETURN_NULL();
18415  }
18416  }
18417  }
18418  }
18419  }
18420  /* only raster, no additional args */
18421  /* only do this if raster isn't empty */
18422  else {
18423  POSTGIS_RT_DEBUG(4, "no additional args, checking input raster");
18424  nbnodata = 1;
18425  if (!rtpg_union_noarg(iwr, raster)) {
18426 
18428  if (raster != NULL) {
18429  rt_raster_destroy(raster);
18430  PG_FREE_IF_COPY(pgraster, 1);
18431  }
18432 
18433  MemoryContextSwitchTo(oldcontext);
18434  elog(ERROR, "RASTER_union_transfn: Could not check and balance number of bands");
18435  PG_RETURN_NULL();
18436  }
18437  }
18438 
18439  /* init itrset */
18440  itrset = palloc(sizeof(struct rt_iterator_t) * 2);
18441  if (itrset == NULL) {
18442 
18444  if (raster != NULL) {
18445  rt_raster_destroy(raster);
18446  PG_FREE_IF_COPY(pgraster, 1);
18447  }
18448 
18449  MemoryContextSwitchTo(oldcontext);
18450  elog(ERROR, "RASTER_union_transfn: Could not allocate memory for iterator arguments");
18451  PG_RETURN_NULL();
18452  }
18453 
18454  /* by band to UNION */
18455  for (i = 0; i < iwr->numband; i++) {
18456 
18457  /* by raster */
18458  for (j = 0; j < iwr->bandarg[i].numraster; j++) {
18459  reuserast = 0;
18460 
18461  /* type of union */
18462  utype = iwr->bandarg[i].uniontype;
18463 
18464  /* raster flags */
18465  isempty[0] = rt_raster_is_empty(iwr->bandarg[i].raster[j]);
18466  isempty[1] = rt_raster_is_empty(raster);
18467 
18468  if (!isempty[0])
18469  hasband[0] = rt_raster_has_band(iwr->bandarg[i].raster[j], 0);
18470  if (!isempty[1])
18471  hasband[1] = rt_raster_has_band(raster, iwr->bandarg[i].nband);
18472 
18473  /* determine pixtype, hasnodata and nodataval */
18474  _band = NULL;
18475  if (!isempty[0] && hasband[0])
18476  _band = rt_raster_get_band(iwr->bandarg[i].raster[j], 0);
18477  else if (!isempty[1] && hasband[1])
18478  _band = rt_raster_get_band(raster, iwr->bandarg[i].nband);
18479  else {
18480  pixtype = PT_64BF;
18481  hasnodata = 1;
18482  nodataval = rt_pixtype_get_min_value(pixtype);
18483  }
18484  if (_band != NULL) {
18485  pixtype = rt_band_get_pixtype(_band);
18486  hasnodata = 1;
18487  if (rt_band_get_hasnodata_flag(_band))
18488  rt_band_get_nodata(_band, &nodataval);
18489  else
18490  nodataval = rt_band_get_min_value(_band);
18491  }
18492 
18493  /* UT_MEAN and UT_RANGE require two passes */
18494  /* UT_MEAN: first for UT_COUNT and second for UT_SUM */
18495  if (iwr->bandarg[i].uniontype == UT_MEAN) {
18496  /* first pass, UT_COUNT */
18497  if (j < 1)
18498  utype = UT_COUNT;
18499  else
18500  utype = UT_SUM;
18501  }
18502  /* UT_RANGE: first for UT_MIN and second for UT_MAX */
18503  else if (iwr->bandarg[i].uniontype == UT_RANGE) {
18504  /* first pass, UT_MIN */
18505  if (j < 1)
18506  utype = UT_MIN;
18507  else
18508  utype = UT_MAX;
18509  }
18510 
18511  /* force band settings for UT_COUNT */
18512  if (utype == UT_COUNT) {
18513  pixtype = PT_32BUI;
18514  hasnodata = 0;
18515  nodataval = 0;
18516  }
18517 
18518  POSTGIS_RT_DEBUGF(4, "(pixtype, hasnodata, nodataval) = (%s, %d, %f)", rt_pixtype_name(pixtype), hasnodata, nodataval);
18519 
18520  /* set itrset */
18521  itrset[0].raster = iwr->bandarg[i].raster[j];
18522  itrset[0].nband = 0;
18523  itrset[1].raster = raster;
18524  itrset[1].nband = iwr->bandarg[i].nband;
18525 
18526  /* allow use NODATA to replace missing bands */
18527  if (nbnodata) {
18528  itrset[0].nbnodata = 1;
18529  itrset[1].nbnodata = 1;
18530  }
18531  /* missing bands are not ignored */
18532  else {
18533  itrset[0].nbnodata = 0;
18534  itrset[1].nbnodata = 0;
18535  }
18536 
18537  /* if rasters AND bands are present, use copy approach */
18538  if (!isempty[0] && !isempty[1] && hasband[0] && hasband[1]) {
18539  POSTGIS_RT_DEBUG(3, "using line method");
18540 
18541  /* generate empty out raster */
18543  iwr->bandarg[i].raster[j], raster,
18544  ET_UNION,
18545  &iraster, _offset
18546  ) != ES_NONE) {
18547 
18548  pfree(itrset);
18550  if (raster != NULL) {
18551  rt_raster_destroy(raster);
18552  PG_FREE_IF_COPY(pgraster, 1);
18553  }
18554 
18555  MemoryContextSwitchTo(oldcontext);
18556  elog(ERROR, "RASTER_union_transfn: Could not create internal raster");
18557  PG_RETURN_NULL();
18558  }
18559  POSTGIS_RT_DEBUGF(4, "_offset = %f, %f, %f, %f",
18560  _offset[0], _offset[1], _offset[2], _offset[3]);
18561 
18562  /* rasters are spatially the same? */
18563  if (
18564  rt_raster_get_width(iwr->bandarg[i].raster[j]) == rt_raster_get_width(iraster) &&
18566  ) {
18567  double igt[6] = {0};
18568  double gt[6] = {0};
18569 
18571  rt_raster_get_geotransform_matrix(iraster, igt);
18572 
18573  reuserast = rt_util_same_geotransform_matrix(gt, igt);
18574  }
18575 
18576  /* use internal raster */
18577  if (!reuserast) {
18578  /* create band of same type */
18580  iraster,
18581  pixtype,
18582  nodataval,
18583  hasnodata, nodataval,
18584  0
18585  ) == -1) {
18586 
18587  pfree(itrset);
18589  rt_raster_destroy(iraster);
18590  if (raster != NULL) {
18591  rt_raster_destroy(raster);
18592  PG_FREE_IF_COPY(pgraster, 1);
18593  }
18594 
18595  MemoryContextSwitchTo(oldcontext);
18596  elog(ERROR, "RASTER_union_transfn: Could not add new band to internal raster");
18597  PG_RETURN_NULL();
18598  }
18599  iband = rt_raster_get_band(iraster, 0);
18600 
18601  /* copy working raster to output raster */
18602  _dim[0] = rt_raster_get_width(iwr->bandarg[i].raster[j]);
18603  _dim[1] = rt_raster_get_height(iwr->bandarg[i].raster[j]);
18604  for (y = 0; y < _dim[1]; y++) {
18605  POSTGIS_RT_DEBUGF(4, "Getting pixel line of working raster at (x, y, length) = (0, %d, %d)", y, _dim[0]);
18607  _band,
18608  0, y,
18609  _dim[0],
18610  &vals, &nvals
18611  ) != ES_NONE) {
18612 
18613  pfree(itrset);
18615  rt_band_destroy(iband);
18616  rt_raster_destroy(iraster);
18617  if (raster != NULL) {
18618  rt_raster_destroy(raster);
18619  PG_FREE_IF_COPY(pgraster, 1);
18620  }
18621 
18622  MemoryContextSwitchTo(oldcontext);
18623  elog(ERROR, "RASTER_union_transfn: Could not get pixel line from band of working raster");
18624  PG_RETURN_NULL();
18625  }
18626 
18627  POSTGIS_RT_DEBUGF(4, "Setting pixel line at (x, y, length) = (%d, %d, %d)", (int) _offset[0], (int) _offset[1] + y, nvals);
18629  iband,
18630  (int) _offset[0], (int) _offset[1] + y,
18631  vals, nvals
18632  ) != ES_NONE) {
18633 
18634  pfree(itrset);
18636  rt_band_destroy(iband);
18637  rt_raster_destroy(iraster);
18638  if (raster != NULL) {
18639  rt_raster_destroy(raster);
18640  PG_FREE_IF_COPY(pgraster, 1);
18641  }
18642 
18643  MemoryContextSwitchTo(oldcontext);
18644  elog(ERROR, "RASTER_union_transfn: Could not set pixel line to band of internal raster");
18645  PG_RETURN_NULL();
18646  }
18647  }
18648  }
18649  else {
18650  rt_raster_destroy(iraster);
18651  iraster = iwr->bandarg[i].raster[j];
18652  iband = rt_raster_get_band(iraster, 0);
18653  }
18654 
18655  /* run iterator for extent of input raster */
18656  noerr = rt_raster_iterator(
18657  itrset, 2,
18658  ET_LAST, NULL,
18659  pixtype,
18660  hasnodata, nodataval,
18661  0, 0,
18662  &utype,
18664  &_raster
18665  );
18666  if (noerr != ES_NONE) {
18667 
18668  pfree(itrset);
18670  if (!reuserast) {
18671  rt_band_destroy(iband);
18672  rt_raster_destroy(iraster);
18673  }
18674  if (raster != NULL) {
18675  rt_raster_destroy(raster);
18676  PG_FREE_IF_COPY(pgraster, 1);
18677  }
18678 
18679  MemoryContextSwitchTo(oldcontext);
18680  elog(ERROR, "RASTER_union_transfn: Could not run raster iterator function");
18681  PG_RETURN_NULL();
18682  }
18683 
18684  /* with iterator raster, copy data to output raster */
18685  _band = rt_raster_get_band(_raster, 0);
18686  _dim[0] = rt_raster_get_width(_raster);
18687  _dim[1] = rt_raster_get_height(_raster);
18688  for (y = 0; y < _dim[1]; y++) {
18689  POSTGIS_RT_DEBUGF(4, "Getting pixel line of iterator raster at (x, y, length) = (0, %d, %d)", y, _dim[0]);
18691  _band,
18692  0, y,
18693  _dim[0],
18694  &vals, &nvals
18695  ) != ES_NONE) {
18696 
18697  pfree(itrset);
18699  if (!reuserast) {
18700  rt_band_destroy(iband);
18701  rt_raster_destroy(iraster);
18702  }
18703  if (raster != NULL) {
18704  rt_raster_destroy(raster);
18705  PG_FREE_IF_COPY(pgraster, 1);
18706  }
18707 
18708  MemoryContextSwitchTo(oldcontext);
18709  elog(ERROR, "RASTER_union_transfn: Could not get pixel line from band of working raster");
18710  PG_RETURN_NULL();
18711  }
18712 
18713  POSTGIS_RT_DEBUGF(4, "Setting pixel line at (x, y, length) = (%d, %d, %d)", (int) _offset[2], (int) _offset[3] + y, nvals);
18715  iband,
18716  (int) _offset[2], (int) _offset[3] + y,
18717  vals, nvals
18718  ) != ES_NONE) {
18719 
18720  pfree(itrset);
18722  if (!reuserast) {
18723  rt_band_destroy(iband);
18724  rt_raster_destroy(iraster);
18725  }
18726  if (raster != NULL) {
18727  rt_raster_destroy(raster);
18728  PG_FREE_IF_COPY(pgraster, 1);
18729  }
18730 
18731  MemoryContextSwitchTo(oldcontext);
18732  elog(ERROR, "RASTER_union_transfn: Could not set pixel line to band of internal raster");
18733  PG_RETURN_NULL();
18734  }
18735  }
18736 
18737  /* free _raster */
18738  rt_band_destroy(_band);
18739  rt_raster_destroy(_raster);
18740 
18741  /* replace working raster with output raster */
18742  _raster = iraster;
18743  }
18744  else {
18745  POSTGIS_RT_DEBUG(3, "using pixel method");
18746 
18747  /* pass everything to iterator */
18748  noerr = rt_raster_iterator(
18749  itrset, 2,
18750  ET_UNION, NULL,
18751  pixtype,
18752  hasnodata, nodataval,
18753  0, 0,
18754  &utype,
18756  &_raster
18757  );
18758 
18759  if (noerr != ES_NONE) {
18760 
18761  pfree(itrset);
18763  if (raster != NULL) {
18764  rt_raster_destroy(raster);
18765  PG_FREE_IF_COPY(pgraster, 1);
18766  }
18767 
18768  MemoryContextSwitchTo(oldcontext);
18769  elog(ERROR, "RASTER_union_transfn: Could not run raster iterator function");
18770  PG_RETURN_NULL();
18771  }
18772  }
18773 
18774  /* replace working raster */
18775  if (iwr->bandarg[i].raster[j] != NULL && !reuserast) {
18776  for (k = rt_raster_get_num_bands(iwr->bandarg[i].raster[j]) - 1; k >= 0; k--)
18778  rt_raster_destroy(iwr->bandarg[i].raster[j]);
18779  }
18780  iwr->bandarg[i].raster[j] = _raster;
18781  }
18782 
18783  }
18784 
18785  pfree(itrset);
18786  if (raster != NULL) {
18787  rt_raster_destroy(raster);
18788  PG_FREE_IF_COPY(pgraster, 1);
18789  }
18790 
18791  /* switch back to local context */
18792  MemoryContextSwitchTo(oldcontext);
18793 
18794  POSTGIS_RT_DEBUG(3, "Finished");
18795 
18796  PG_RETURN_POINTER(iwr);
18797 }
int rt_raster_get_num_bands(rt_raster raster)
Definition: rt_api.c:5677
static char * rtpg_strtoupper(char *str)
Definition: rt_pg.c:730
void rt_raster_destroy(rt_raster raster)
Release memory associated to a raster.
Definition: rt_api.c:5387
static int rtpg_union_callback(rt_iterator_arg arg, void *userarg, double *value, int *nodata)
Definition: rt_pg.c:17795
const char * rt_pixtype_name(rt_pixtype pixtype)
Definition: rt_api.c:1168
rtpg_union_band_arg bandarg
Definition: rt_pg.c:17764
tuple gt
Definition: window.py:79
Definition: rt_api.h:184
rt_pixtype rt_band_get_pixtype(rt_band band)
Return pixeltype of this band.
Definition: rt_api.c:1900
rtpg_union_type
Definition: rt_pg.c:17717
int rt_raster_has_band(rt_raster raster, int nband)
Return TRUE if the raster has a band of this number.
Definition: rt_api.c:8563
rt_raster * raster
Definition: rt_pg.c:17758
tuple raster
Be careful!! Zeros function's input parameter can be a (height x width) array, not (width x height): ...
Definition: rtrowdump.py:123
rt_errorstate rt_band_set_pixel_line(rt_band band, int x, int y, void *vals, uint32_t len)
Set values of multiple pixels.
Definition: rt_api.c:2181
double rt_pixtype_get_min_value(rt_pixtype pixtype)
Return minimum value possible for pixel type.
Definition: rt_api.c:1206
rt_errorstate rt_raster_from_two_rasters(rt_raster rast1, rt_raster rast2, rt_extenttype extenttype, rt_raster *rtnraster, double *offset)
Definition: rt_api.c:12876
static void rtpg_union_arg_destroy(rtpg_union_arg arg)
Definition: rt_pg.c:17767
static int rtpg_union_noarg(rtpg_union_arg arg, rt_raster raster)
Definition: rt_pg.c:18066
void rt_raster_get_geotransform_matrix(rt_raster raster, double *gt)
Get 6-element array of raster geotransform matrix.
Definition: rt_api.c:6005
rt_pixtype
Definition: rt_api.h:172
#define POSTGIS_RT_DEBUG(level, msg)
Definition: rt_pg.h:58
tuple nband
Definition: pixval.py:52
double rt_band_get_min_value(rt_band band)
Returns the minimal possible value for the band according to the pixel type.
Definition: rt_api.c:3073
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
static int rtpg_union_unionarg_process(rtpg_union_arg arg, ArrayType *array)
Definition: rt_pg.c:17958
rt_raster raster
Definition: rt_api.h:2360
void rt_band_destroy(rt_band band)
Destroy a raster band.
Definition: rt_api.c:1650
uint16_t nband
Definition: rt_api.h:2361
uint16_t rt_raster_get_height(rt_raster raster)
Definition: rt_api.c:5434
rt_errorstate rt_band_get_pixel_line(rt_band band, int x, int y, uint16_t len, void **vals, uint16_t *nvals)
Get values of multiple pixels.
Definition: rt_api.c:2465
rt_band rt_raster_get_band(rt_raster raster, int n)
Return Nth band, or NULL if unavailable.
Definition: rt_api.c:5686
#define FALSE
Definition: dbfopen.c:169
uint8_t nbnodata
Definition: rt_api.h:2362
Struct definitions.
Definition: rt_api.h:2175
#define POSTGIS_RT_DEBUGF(level, msg,...)
Definition: rt_pg.h:62
int rt_raster_is_empty(rt_raster raster)
Return TRUE if the raster is empty.
Definition: rt_api.c:8550
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
rt_raster rt_raster_deserialize(void *serialized, int header_only)
Return a raster from a serialized form.
Definition: rt_api.c:8350
rt_raster rt_raster_clone(rt_raster raster, uint8_t deep)
Clone an existing raster.
Definition: rt_api.c:8740
rtpg_union_type uniontype
Definition: rt_pg.c:17755
int rt_util_same_geotransform_matrix(double *gt1, double *gt2)
Definition: rt_api.c:595
static rtpg_union_type rtpg_uniontype_index_from_name(const char *cutype)
Definition: rt_pg.c:17729
int rt_band_get_hasnodata_flag(rt_band band)
Get hasnodata flag value.
Definition: rt_api.c:2002
tuple y
Definition: pixval.py:54
uint16_t rt_raster_get_width(rt_raster raster)
Definition: rt_api.c:5426
int rt_raster_generate_new_band(rt_raster raster, rt_pixtype pixtype, double initialvalue, uint32_t hasnodata, double nodatavalue, int index)
Generate a new inline band and add it to a raster.
Definition: rt_api.c:5784

Here is the call graph for this function: