PostGIS  3.7.0dev-r@@SVN_REVISION@@

◆ rt_band_reclass_exact()

rt_band rt_band_reclass_exact ( rt_band  srcband,
rt_reclassmap  map,
uint32_t  hasnodata,
double  nodataval 
)

Returns new band with values reclassified.

Parameters
srcband: the band who's values will be reclassified
map: the src and dst values to remapping
hasnodata: indicates if the band has a nodata value
nodataval: nodata value for the new band
Returns
a new rt_band or NULL on error
Parameters
srcband: the band who's values will be reclassified
map: rt_reclassmap with src->dst mappings
hasnodata: indicates if the user is supplying a nodata
nodataval: user supplied nodata value for the new band
Returns
a new rt_band or NULL on error

Definition at line 288 of file rt_mapalgebra.c.

291  {
292  rt_band band = NULL;
293  uint32_t width = 0;
294  uint32_t height = 0;
295  int numval = 0;
296  int memsize = 0;
297  void *mem = NULL;
298  uint32_t src_hasnodata = 0;
299  rt_pixtype pixtype;
300 
301  assert(NULL != srcband);
302  assert(NULL != map);
303 
304  /* Validate that the map has consistent array lengths */
305  if (map->count == 0)
306  rterror("%s: reclassification map must contain at least one class pair", __func__);
307 
308  /* Need a nodataval from somewhere */
309  src_hasnodata = rt_band_get_hasnodata_flag(srcband);
310  if (!(src_hasnodata || hasnodata))
311  rterror("%s: source band missing nodata value and nodata value not supplied", __func__);
312 
313  /*
314  * Use the nodata value of the input in the case where user
315  * does not supply a nodataval
316  */
317  if (!hasnodata && src_hasnodata) {
318  rt_band_get_nodata(srcband, &nodataval);
319  hasnodata = src_hasnodata;
320  }
321 
322  /* size of memory block to allocate */
323  width = rt_band_get_width(srcband);
324  height = rt_band_get_height(srcband);
325  numval = width * height;
326  pixtype = map->dsttype;
327  memsize = rt_pixtype_size(pixtype) * numval;
328  mem = (int *) rtalloc(memsize);
329  if (!mem)
330  rterror("%s: Could not allocate memory for band", __func__);
331 
332  band = rt_band_new_inline(width, height, pixtype, hasnodata, nodataval, mem);
333  if (! band) {
334  rterror("%s: Could not add band to raster. Aborting", __func__);
335  rtdealloc(mem);
336  return NULL;
337  }
338  rt_band_set_ownsdata_flag(band, 1); /* we own this data */
339 
340  /*
341  * apply nodata as baseline value and then only
342  * map in values that match our map
343  */
344  rt_band_init_value(band, nodataval);
345 
346  /*
347  * Put the rt_classpairs in order of source value
348  * so we can bsearch them
349  */
350  qsort(map->pairs, map->count, sizeof(struct rt_classpair_t), rt_classpair_cmp);
351 
352  for (uint32_t x = 0; x < width; x++) {
353  for (uint32_t y = 0; y < height; y++) {
354  int isnodata;
355  double nv = nodataval;
356  struct rt_classpair_t query = {0.0, 0.0};
357  struct rt_classpair_t *rslt;
358 
359  /* get pixel, skip on error */
360  if (rt_band_get_pixel(srcband, x, y, &query.src, &isnodata) != ES_NONE)
361  continue;
362 
363  /* output was already initialized to nodataval */
364  if (isnodata)
365  continue;
366  /*
367  * Look for pixel value in map.
368  * If not in map, skip, leaving the nodata value in place.
369  * Otherwise continue and replace with new value
370  */
371  rslt = bsearch(&query, map->pairs, map->count, sizeof(struct rt_classpair_t), rt_classpair_cmp);
372  if (!rslt)
373  continue;
374  else
375  nv = rslt->dst;
376 
377  /* round the new value for integer pixel types */
378  nv = rt_band_reclass_round_integer(pixtype, nv);
379 
380  if (rt_band_set_pixel(band, x, y, nv, NULL) != ES_NONE) {
381  rterror("%s: Could not assign value to new band", __func__);
383  rtdealloc(mem);
384  return NULL;
385  }
386  }
387  }
388 
389  return band;
390 }
void rt_band_init_value(rt_band band, double initval)
Fill in the cells of a band with a starting value frequently used to init with nodata value.
Definition: rt_band.c:112
rt_band rt_band_new_inline(uint16_t width, uint16_t height, rt_pixtype pixtype, uint32_t hasnodata, double nodataval, uint8_t *data)
Create an in-db rt_band with no data.
Definition: rt_band.c:63
void rt_band_set_ownsdata_flag(rt_band band, int flag)
Definition: rt_band.c:818
void rterror(const char *fmt,...) __attribute__((format(printf
Wrappers used for reporting errors and info.
void * rtalloc(size_t size)
Wrappers used for managing memory.
Definition: rt_context.c:191
uint16_t rt_band_get_width(rt_band band)
Return width of this band.
Definition: rt_band.c:791
int rt_band_get_hasnodata_flag(rt_band band)
Get hasnodata flag value.
Definition: rt_band.c:825
rt_errorstate rt_band_get_pixel(rt_band band, int x, int y, double *value, int *nodata)
Get pixel value.
Definition: rt_band.c:1527
rt_pixtype
Definition: librtcore.h:187
rt_errorstate rt_band_set_pixel(rt_band band, int x, int y, double val, int *converted)
Set single pixel's value.
Definition: rt_band.c:1125
@ ES_NONE
Definition: librtcore.h:182
void rt_band_destroy(rt_band band)
Destroy a raster band.
Definition: rt_band.c:491
rt_errorstate rt_band_get_nodata(rt_band band, double *nodata)
Get NODATA value.
Definition: rt_band.c:2038
void rtdealloc(void *mem)
Definition: rt_context.c:206
uint16_t rt_band_get_height(rt_band band)
Return height of this band.
Definition: rt_band.c:800
int rt_pixtype_size(rt_pixtype pixtype)
Return size in bytes of a value in the given pixtype.
Definition: rt_pixel.c:39
band
Definition: ovdump.py:58
static int rt_classpair_cmp(const void *aptr, const void *bptr)
static double rt_band_reclass_round_integer(rt_pixtype pixtype, double nv)
Definition: rt_mapalgebra.c:38
uint32_t count
Definition: librtcore.h:2639
rt_pixtype dsttype
Definition: librtcore.h:2641
struct rt_classpair_t * pairs
Definition: librtcore.h:2642

References ovdump::band, rt_reclassmap_t::count, rt_classpair_t::dst, rt_reclassmap_t::dsttype, ES_NONE, rt_reclassmap_t::pairs, rt_band_destroy(), rt_band_get_hasnodata_flag(), rt_band_get_height(), rt_band_get_nodata(), rt_band_get_pixel(), rt_band_get_width(), rt_band_init_value(), rt_band_new_inline(), rt_band_reclass_round_integer(), rt_band_set_ownsdata_flag(), rt_band_set_pixel(), rt_classpair_cmp(), rt_pixtype_size(), rtalloc(), rtdealloc(), rterror(), rt_classpair_t::src, pixval::x, and pixval::y.

Referenced by RASTER_reclass_exact().

Here is the call graph for this function:
Here is the caller graph for this function: