PostGIS  2.5.0beta2dev-r@@SVN_REVISION@@

◆ rtpg_nmapalgebra_rastbandarg_process()

static int rtpg_nmapalgebra_rastbandarg_process ( rtpg_nmapalgebra_arg  arg,
ArrayType *  array,
int *  allnull,
int *  allempty,
int *  noband 
)
static

Definition at line 172 of file rtpg_mapalgebra.c.

References FALSE, rtpg_nmapalgebra_arg_t::hasband, rtpg_nmapalgebra_arg_t::isempty, rtpg_nmapalgebra_arg_t::mask, pixval::nband, rtpg_nmapalgebra_arg_t::nband, rtpg_nmapalgebra_arg_t::numraster, rtpg_nmapalgebra_arg_t::ownsdata, rtpg_nmapalgebra_arg_t::pgraster, POSTGIS_RT_DEBUG, POSTGIS_RT_DEBUGF, rtpg_nmapalgebra_arg_t::raster, rt_raster_deserialize(), rt_raster_has_band(), and rt_raster_is_empty().

Referenced by RASTER_nMapAlgebra(), and RASTER_nMapAlgebraExpr().

172  {
173  Oid etype;
174  Datum *e;
175  bool *nulls;
176  int16 typlen;
177  bool typbyval;
178  char typalign;
179  int n = 0;
180 
181  HeapTupleHeader tup;
182  bool isnull;
183  Datum tupv;
184 
185  int i;
186  int j;
187  int nband;
188 
189  if (arg == NULL || array == NULL) {
190  elog(ERROR, "rtpg_nmapalgebra_rastbandarg_process: NULL values not permitted for parameters");
191  return 0;
192  }
193 
194  etype = ARR_ELEMTYPE(array);
195  get_typlenbyvalalign(etype, &typlen, &typbyval, &typalign);
196 
197  deconstruct_array(
198  array,
199  etype,
200  typlen, typbyval, typalign,
201  &e, &nulls, &n
202  );
203 
204  if (!n) {
205  elog(ERROR, "rtpg_nmapalgebra_rastbandarg_process: Invalid argument for rastbandarg");
206  return 0;
207  }
208 
209  /* prep arg */
210  arg->numraster = n;
211  arg->pgraster = palloc(sizeof(rt_pgraster *) * arg->numraster);
212  arg->raster = palloc(sizeof(rt_raster) * arg->numraster);
213  arg->isempty = palloc(sizeof(uint8_t) * arg->numraster);
214  arg->ownsdata = palloc(sizeof(uint8_t) * arg->numraster);
215  arg->nband = palloc(sizeof(int) * arg->numraster);
216  arg->hasband = palloc(sizeof(uint8_t) * arg->numraster);
217  arg->mask = palloc(sizeof(struct rt_mask_t));
218  if (
219  arg->pgraster == NULL ||
220  arg->raster == NULL ||
221  arg->isempty == NULL ||
222  arg->ownsdata == NULL ||
223  arg->nband == NULL ||
224  arg->hasband == NULL ||
225  arg->mask == NULL
226  ) {
227  elog(ERROR, "rtpg_nmapalgebra_rastbandarg_process: Could not allocate memory for processing rastbandarg");
228  return 0;
229  }
230 
231  *allnull = 0;
232  *allempty = 0;
233  *noband = 0;
234 
235  /* process each element */
236  for (i = 0; i < n; i++) {
237  if (nulls[i]) {
238  arg->numraster--;
239  continue;
240  }
241 
242  POSTGIS_RT_DEBUGF(4, "Processing rastbandarg at index %d", i);
243 
244  arg->raster[i] = NULL;
245  arg->isempty[i] = 0;
246  arg->ownsdata[i] = 1;
247  arg->nband[i] = 0;
248  arg->hasband[i] = 0;
249 
250  /* each element is a tuple */
251  tup = (HeapTupleHeader) DatumGetPointer(e[i]);
252  if (NULL == tup) {
253  elog(ERROR, "rtpg_nmapalgebra_rastbandarg_process: Invalid argument for rastbandarg at index %d", i);
254  return 0;
255  }
256 
257  /* first element, raster */
258  POSTGIS_RT_DEBUG(4, "Processing first element (raster)");
259  tupv = GetAttributeByName(tup, "rast", &isnull);
260  if (isnull) {
261  elog(NOTICE, "First argument (nband) of rastbandarg at index %d is NULL. Assuming NULL raster", i);
262  arg->isempty[i] = 1;
263  arg->ownsdata[i] = 0;
264 
265  (*allnull)++;
266  (*allempty)++;
267  (*noband)++;
268 
269  continue;
270  }
271 
272  arg->pgraster[i] = (rt_pgraster *) PG_DETOAST_DATUM(tupv);
273 
274  /* see if this is a copy of an existing pgraster */
275  for (j = 0; j < i; j++) {
276  if (!arg->isempty[j] && (arg->pgraster[i] == arg->pgraster[j])) {
277  POSTGIS_RT_DEBUG(4, "raster matching existing same raster found");
278  arg->raster[i] = arg->raster[j];
279  arg->ownsdata[i] = 0;
280  break;
281  }
282  }
283 
284  if (arg->ownsdata[i]) {
285  POSTGIS_RT_DEBUG(4, "deserializing raster");
286  arg->raster[i] = rt_raster_deserialize(arg->pgraster[i], FALSE);
287  if (arg->raster[i] == NULL) {
288  elog(ERROR, "rtpg_nmapalgebra_rastbandarg_process: Could not deserialize raster at index %d", i);
289  return 0;
290  }
291  }
292 
293  /* is raster empty? */
294  arg->isempty[i] = rt_raster_is_empty(arg->raster[i]);
295  if (arg->isempty[i]) {
296  (*allempty)++;
297  (*noband)++;
298 
299  continue;
300  }
301 
302  /* second element, nband */
303  POSTGIS_RT_DEBUG(4, "Processing second element (nband)");
304  tupv = GetAttributeByName(tup, "nband", &isnull);
305  if (isnull) {
306  nband = 1;
307  elog(NOTICE, "First argument (nband) of rastbandarg at index %d is NULL. Assuming nband = %d", i, nband);
308  }
309  else
310  nband = DatumGetInt32(tupv);
311 
312  if (nband < 1) {
313  elog(ERROR, "rtpg_nmapalgebra_rastbandarg_process: Band number provided for rastbandarg at index %d must be greater than zero (1-based)", i);
314  return 0;
315  }
316 
317  arg->nband[i] = nband - 1;
318  arg->hasband[i] = rt_raster_has_band(arg->raster[i], arg->nband[i]);
319  if (!arg->hasband[i]) {
320  (*noband)++;
321  POSTGIS_RT_DEBUGF(4, "Band at index %d not found in raster", nband);
322  }
323  }
324 
325  if (arg->numraster < n) {
326  arg->pgraster = repalloc(arg->pgraster, sizeof(rt_pgraster *) * arg->numraster);
327  arg->raster = repalloc(arg->raster, sizeof(rt_raster) * arg->numraster);
328  arg->isempty = repalloc(arg->isempty, sizeof(uint8_t) * arg->numraster);
329  arg->ownsdata = repalloc(arg->ownsdata, sizeof(uint8_t) * arg->numraster);
330  arg->nband = repalloc(arg->nband, sizeof(int) * arg->numraster);
331  arg->hasband = repalloc(arg->hasband, sizeof(uint8_t) * arg->numraster);
332  if (
333  arg->pgraster == NULL ||
334  arg->raster == NULL ||
335  arg->isempty == NULL ||
336  arg->ownsdata == NULL ||
337  arg->nband == NULL ||
338  arg->hasband == NULL
339  ) {
340  elog(ERROR, "rtpg_nmapalgebra_rastbandarg_process: Could not reallocate memory for processed rastbandarg");
341  return 0;
342  }
343  }
344 
345  POSTGIS_RT_DEBUGF(4, "arg->numraster = %d", arg->numraster);
346 
347  return 1;
348 }
rt_pgraster ** pgraster
int rt_raster_is_empty(rt_raster raster)
Return TRUE if the raster is empty.
Definition: rt_raster.c:1334
#define POSTGIS_RT_DEBUGF(level, msg,...)
Definition: rtpostgis.h:65
nband
Definition: pixval.py:52
int rt_raster_has_band(rt_raster raster, int nband)
Return TRUE if the raster has a band of this number.
Definition: rt_raster.c:1347
#define FALSE
Definition: dbfopen.c:168
Struct definitions.
Definition: librtcore.h:2250
#define POSTGIS_RT_DEBUG(level, msg)
Definition: rtpostgis.h:61
unsigned char uint8_t
Definition: uthash.h:79
rt_raster rt_raster_deserialize(void *serialized, int header_only)
Return a raster from a serialized form.
Definition: rt_serialize.c:717
Here is the call graph for this function:
Here is the caller graph for this function: