PostGIS  2.4.9dev-r@@SVN_REVISION@@

◆ rt_band_reclass()

rt_band rt_band_reclass ( rt_band  srcband,
rt_pixtype  pixtype,
uint32_t  hasnodata,
double  nodataval,
rt_reclassexpr exprset,
int  exprcount 
)

Returns new band with values reclassified.

Parameters
srcband: the band who's values will be reclassified
pixtype: pixel type of the new band
hasnodata: indicates if the band has a nodata value
nodataval: nodata value for the new band
exprset: array of rt_reclassexpr structs
exprcount: number of elements in expr
Returns
a new rt_band or NULL on error

Definition at line 50 of file rt_mapalgebra.c.

References ovdump::band, rt_reclassexpr_t::dst, ES_NONE, rt_reclassexpr_t::rt_reclassrange::exc_max, rt_reclassexpr_t::rt_reclassrange::exc_min, FLT_EQ, if(), rt_reclassexpr_t::rt_reclassrange::inc_max, rt_reclassexpr_t::rt_reclassrange::inc_min, rt_reclassexpr_t::rt_reclassrange::max, rt_reclassexpr_t::rt_reclassrange::min, PT_16BSI, PT_16BUI, PT_1BB, PT_2BUI, PT_32BF, PT_32BSI, PT_32BUI, PT_4BUI, PT_64BF, PT_8BSI, PT_8BUI, RASTER_DEBUGF, 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_new_inline(), rt_band_set_ownsdata_flag(), rt_band_set_pixel(), rt_pixtype_size(), rt_util_clamp_to_16BSI(), rt_util_clamp_to_16BUI(), rt_util_clamp_to_1BB(), rt_util_clamp_to_2BUI(), rt_util_clamp_to_32BSI(), rt_util_clamp_to_32BUI(), rt_util_clamp_to_32F(), rt_util_clamp_to_4BUI(), rt_util_clamp_to_8BSI(), rt_util_clamp_to_8BUI(), rt_util_dbl_trunc_warning(), rtalloc(), rtdealloc(), rterror(), rt_reclassexpr_t::src, pixval::x, and pixval::y.

Referenced by RASTER_reclass(), rt_raster_colormap(), and test_band_reclass().

54  {
55  rt_band band = NULL;
56  uint32_t width = 0;
57  uint32_t height = 0;
58  int numval = 0;
59  int memsize = 0;
60  void *mem = NULL;
61  uint32_t src_hasnodata = 0;
62  double src_nodataval = 0.0;
63  int isnodata = 0;
64 
65  int rtn;
66  uint32_t x;
67  uint32_t y;
68  int i;
69  double or = 0;
70  double ov = 0;
71  double nr = 0;
72  double nv = 0;
73  int do_nv = 0;
74  rt_reclassexpr expr = NULL;
75 
76  assert(NULL != srcband);
77  assert(NULL != exprset && exprcount > 0);
78  RASTER_DEBUGF(4, "exprcount = %d", exprcount);
79  RASTER_DEBUGF(4, "exprset @ %p", exprset);
80 
81  /* source nodata */
82  src_hasnodata = rt_band_get_hasnodata_flag(srcband);
83  if (src_hasnodata)
84  rt_band_get_nodata(srcband, &src_nodataval);
85 
86  /* size of memory block to allocate */
87  width = rt_band_get_width(srcband);
88  height = rt_band_get_height(srcband);
89  numval = width * height;
90  memsize = rt_pixtype_size(pixtype) * numval;
91  mem = (int *) rtalloc(memsize);
92  if (!mem) {
93  rterror("rt_band_reclass: Could not allocate memory for band");
94  return 0;
95  }
96 
97  /* initialize to zero */
98  if (!hasnodata) {
99  memset(mem, 0, memsize);
100  }
101  /* initialize to nodataval */
102  else {
103  int32_t checkvalint = 0;
104  uint32_t checkvaluint = 0;
105  double checkvaldouble = 0;
106  float checkvalfloat = 0;
107 
108  switch (pixtype) {
109  case PT_1BB:
110  {
111  uint8_t *ptr = mem;
112  uint8_t clamped_initval = rt_util_clamp_to_1BB(nodataval);
113  for (i = 0; i < numval; i++)
114  ptr[i] = clamped_initval;
115  checkvalint = ptr[0];
116  break;
117  }
118  case PT_2BUI:
119  {
120  uint8_t *ptr = mem;
121  uint8_t clamped_initval = rt_util_clamp_to_2BUI(nodataval);
122  for (i = 0; i < numval; i++)
123  ptr[i] = clamped_initval;
124  checkvalint = ptr[0];
125  break;
126  }
127  case PT_4BUI:
128  {
129  uint8_t *ptr = mem;
130  uint8_t clamped_initval = rt_util_clamp_to_4BUI(nodataval);
131  for (i = 0; i < numval; i++)
132  ptr[i] = clamped_initval;
133  checkvalint = ptr[0];
134  break;
135  }
136  case PT_8BSI:
137  {
138  int8_t *ptr = mem;
139  int8_t clamped_initval = rt_util_clamp_to_8BSI(nodataval);
140  for (i = 0; i < numval; i++)
141  ptr[i] = clamped_initval;
142  checkvalint = ptr[0];
143  break;
144  }
145  case PT_8BUI:
146  {
147  uint8_t *ptr = mem;
148  uint8_t clamped_initval = rt_util_clamp_to_8BUI(nodataval);
149  for (i = 0; i < numval; i++)
150  ptr[i] = clamped_initval;
151  checkvalint = ptr[0];
152  break;
153  }
154  case PT_16BSI:
155  {
156  int16_t *ptr = mem;
157  int16_t clamped_initval = rt_util_clamp_to_16BSI(nodataval);
158  for (i = 0; i < numval; i++)
159  ptr[i] = clamped_initval;
160  checkvalint = ptr[0];
161  break;
162  }
163  case PT_16BUI:
164  {
165  uint16_t *ptr = mem;
166  uint16_t clamped_initval = rt_util_clamp_to_16BUI(nodataval);
167  for (i = 0; i < numval; i++)
168  ptr[i] = clamped_initval;
169  checkvalint = ptr[0];
170  break;
171  }
172  case PT_32BSI:
173  {
174  int32_t *ptr = mem;
175  int32_t clamped_initval = rt_util_clamp_to_32BSI(nodataval);
176  for (i = 0; i < numval; i++)
177  ptr[i] = clamped_initval;
178  checkvalint = ptr[0];
179  break;
180  }
181  case PT_32BUI:
182  {
183  uint32_t *ptr = mem;
184  uint32_t clamped_initval = rt_util_clamp_to_32BUI(nodataval);
185  for (i = 0; i < numval; i++)
186  ptr[i] = clamped_initval;
187  checkvaluint = ptr[0];
188  break;
189  }
190  case PT_32BF:
191  {
192  float *ptr = mem;
193  float clamped_initval = rt_util_clamp_to_32F(nodataval);
194  for (i = 0; i < numval; i++)
195  ptr[i] = clamped_initval;
196  checkvalfloat = ptr[0];
197  break;
198  }
199  case PT_64BF:
200  {
201  double *ptr = mem;
202  for (i = 0; i < numval; i++)
203  ptr[i] = nodataval;
204  checkvaldouble = ptr[0];
205  break;
206  }
207  default:
208  {
209  rterror("rt_band_reclass: Unknown pixeltype %d", pixtype);
210  rtdealloc(mem);
211  return 0;
212  }
213  }
214 
215  /* Overflow checking */
217  nodataval,
218  checkvalint, checkvaluint,
219  checkvalfloat, checkvaldouble,
220  pixtype
221  );
222  }
223  RASTER_DEBUGF(3, "rt_band_reclass: width = %d height = %d", width, height);
224 
225  band = rt_band_new_inline(width, height, pixtype, hasnodata, nodataval, mem);
226  if (!band) {
227  rterror("rt_band_reclass: Could not create new band");
228  rtdealloc(mem);
229  return 0;
230  }
231  rt_band_set_ownsdata_flag(band, 1); /* we DO own this data!!! */
232  RASTER_DEBUGF(3, "rt_band_reclass: new band @ %p", band);
233 
234  for (x = 0; x < width; x++) {
235  for (y = 0; y < height; y++) {
236  rtn = rt_band_get_pixel(srcband, x, y, &ov, &isnodata);
237 
238  /* error getting value, skip */
239  if (rtn != ES_NONE) {
240  RASTER_DEBUGF(3, "Cannot get value at %d, %d", x, y);
241  continue;
242  }
243  RASTER_DEBUGF(4, "(x, y, ov, isnodata) = (%d, %d, %f, %d)", x, y, ov, isnodata);
244 
245  do {
246  do_nv = 0;
247 
248  /* no data*/
249  if (hasnodata && isnodata) {
250  do_nv = 1;
251  break;
252  }
253 
254  for (i = 0; i < exprcount; i++) {
255  expr = exprset[i];
256 
257  /* ov matches min and max*/
258  if (
259  FLT_EQ(expr->src.min, ov) &&
260  FLT_EQ(expr->src.max, ov)
261  ) {
262  do_nv = 1;
263  break;
264  }
265 
266  /* process min */
267  if ((
268  expr->src.exc_min && (
269  expr->src.min > ov ||
270  FLT_EQ(expr->src.min, ov)
271  )) || (
272  expr->src.inc_min && (
273  expr->src.min < ov ||
274  FLT_EQ(expr->src.min, ov)
275  )) || (
276  expr->src.min < ov
277  )) {
278  /* process max */
279  if ((
280  expr->src.exc_max && (
281  ov > expr->src.max ||
282  FLT_EQ(expr->src.max, ov)
283  )) || (
284  expr->src.inc_max && (
285  ov < expr->src.max ||
286  FLT_EQ(expr->src.max, ov)
287  )) || (
288  ov < expr->src.max
289  )) {
290  do_nv = 1;
291  break;
292  }
293  }
294  }
295  }
296  while (0);
297 
298  /* no expression matched, do not continue */
299  if (!do_nv) continue;
300  RASTER_DEBUGF(3, "Using exprset[%d] unless NODATA", i);
301 
302  /* converting a value from one range to another range
303  OldRange = (OldMax - OldMin)
304  NewRange = (NewMax - NewMin)
305  NewValue = (((OldValue - OldMin) * NewRange) / OldRange) + NewMin
306  */
307 
308  /* NODATA */
309  if (hasnodata && isnodata) {
310  nv = nodataval;
311  }
312  /*
313  "src" min and max is the same, prevent division by zero
314  set nv to "dst" min, which should be the same as "dst" max
315  */
316  else if (FLT_EQ(expr->src.max, expr->src.min)) {
317  nv = expr->dst.min;
318  }
319  else {
320  or = expr->src.max - expr->src.min;
321  nr = expr->dst.max - expr->dst.min;
322  nv = (((ov - expr->src.min) * nr) / or) + expr->dst.min;
323 
324  /* if dst range is from high to low */
325  if (expr->dst.min > expr->dst.max) {
326  if (nv > expr->dst.min)
327  nv = expr->dst.min;
328  else if (nv < expr->dst.max)
329  nv = expr->dst.max;
330  }
331  /* if dst range is from low to high */
332  else {
333  if (nv < expr->dst.min)
334  nv = expr->dst.min;
335  else if (nv > expr->dst.max)
336  nv = expr->dst.max;
337  }
338  }
339 
340  /* round the value for integers */
341  switch (pixtype) {
342  case PT_1BB:
343  case PT_2BUI:
344  case PT_4BUI:
345  case PT_8BSI:
346  case PT_8BUI:
347  case PT_16BSI:
348  case PT_16BUI:
349  case PT_32BSI:
350  case PT_32BUI:
351  nv = round(nv);
352  break;
353  default:
354  break;
355  }
356 
357  RASTER_DEBUGF(4, "(%d, %d) ov: %f or: %f - %f nr: %f - %f nv: %f"
358  , x
359  , y
360  , ov
361  , (NULL != expr) ? expr->src.min : 0
362  , (NULL != expr) ? expr->src.max : 0
363  , (NULL != expr) ? expr->dst.min : 0
364  , (NULL != expr) ? expr->dst.max : 0
365  , nv
366  );
367  if (rt_band_set_pixel(band, x, y, nv, NULL) != ES_NONE) {
368  rterror("rt_band_reclass: Could not assign value to new band");
369  rt_band_destroy(band);
370  rtdealloc(mem);
371  return 0;
372  }
373 
374  expr = NULL;
375  }
376  }
377 
378  return band;
379 }
int32_t rt_util_clamp_to_32BSI(double value)
Definition: rt_util.c:69
uint32_t rt_util_clamp_to_32BUI(double value)
Definition: rt_util.c:74
struct rt_reclassexpr_t::rt_reclassrange dst
band
Definition: ovdump.py:57
#define FLT_EQ(x, y)
Definition: librtcore.h:2185
void rterror(const char *fmt,...)
Wrappers used for reporting errors and info.
Definition: rt_context.c:199
void * rtalloc(size_t size)
Wrappers used for managing memory.
Definition: rt_context.c:171
void rt_band_destroy(rt_band band)
Destroy a raster band.
Definition: rt_band.c:242
rt_errorstate rt_band_get_nodata(rt_band band, double *nodata)
Get NODATA value.
Definition: rt_band.c:1597
unsigned int uint32_t
Definition: uthash.h:78
uint16_t rt_util_clamp_to_16BUI(double value)
Definition: rt_util.c:64
void rt_band_set_ownsdata_flag(rt_band band, int flag)
Definition: rt_band.c:534
struct rt_reclassexpr_t::rt_reclassrange src
rt_errorstate rt_band_get_pixel(rt_band band, int x, int y, double *value, int *nodata)
Get pixel value.
Definition: rt_band.c:1088
int8_t rt_util_clamp_to_8BSI(double value)
Definition: rt_util.c:49
int rt_util_dbl_trunc_warning(double initialvalue, int32_t checkvalint, uint32_t checkvaluint, float checkvalfloat, double checkvaldouble, rt_pixtype pixtype)
Definition: rt_util.c:625
int rt_band_get_hasnodata_flag(rt_band band)
Get hasnodata flag value.
Definition: rt_band.c:541
uint16_t rt_band_get_width(rt_band band)
Return width of this band.
Definition: rt_band.c:507
uint16_t rt_band_get_height(rt_band band)
Return height of this band.
Definition: rt_band.c:516
#define RASTER_DEBUGF(level, msg,...)
Definition: librtcore.h:299
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:58
uint8_t rt_util_clamp_to_4BUI(double value)
Definition: rt_util.c:44
uint8_t rt_util_clamp_to_8BUI(double value)
Definition: rt_util.c:54
int rt_pixtype_size(rt_pixtype pixtype)
Return size in bytes of a value in the given pixtype.
Definition: rt_pixel.c:39
uint8_t rt_util_clamp_to_1BB(double value)
Definition: rt_util.c:34
void rtdealloc(void *mem)
Definition: rt_context.c:186
uint8_t rt_util_clamp_to_2BUI(double value)
Definition: rt_util.c:39
float rt_util_clamp_to_32F(double value)
Definition: rt_util.c:79
rt_errorstate rt_band_set_pixel(rt_band band, int x, int y, double val, int *converted)
Set single pixel&#39;s value.
Definition: rt_band.c:841
unsigned char uint8_t
Definition: uthash.h:79
if(!(yy_init))
int16_t rt_util_clamp_to_16BSI(double value)
Definition: rt_util.c:59
Here is the call graph for this function:
Here is the caller graph for this function: