PostGIS  3.7.0dev-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 69 of file rt_mapalgebra.c.

73  {
74  rt_band band = NULL;
75  uint32_t width = 0;
76  uint32_t height = 0;
77  int numval = 0;
78  int memsize = 0;
79  void *mem = NULL;
80  uint32_t src_hasnodata = 0;
81  double src_nodataval = 0.0;
82  int isnodata = 0;
83 
84  int rtn;
85  uint32_t x;
86  uint32_t y;
87  int i;
88  double or = 0;
89  double ov = 0;
90  double nr = 0;
91  double nv = 0;
92  int do_nv = 0;
93  rt_reclassexpr expr = NULL;
94 
95  assert(NULL != srcband);
96  assert(NULL != exprset && exprcount > 0);
97  RASTER_DEBUGF(4, "exprcount = %d", exprcount);
98  RASTER_DEBUGF(4, "exprset @ %p", exprset);
99 
100  /* source nodata */
101  src_hasnodata = rt_band_get_hasnodata_flag(srcband);
102  if (src_hasnodata)
103  rt_band_get_nodata(srcband, &src_nodataval);
104 
105  /* size of memory block to allocate */
106  width = rt_band_get_width(srcband);
107  height = rt_band_get_height(srcband);
108  numval = width * height;
109  memsize = rt_pixtype_size(pixtype) * numval;
110  mem = (int *) rtalloc(memsize);
111  if (!mem) {
112  rterror("rt_band_reclass: Could not allocate memory for band");
113  return 0;
114  }
115 
116  band = rt_band_new_inline(width, height, pixtype, hasnodata, nodataval, mem);
117  if (!band) {
118  rterror("rt_band_reclass: Could not create new band");
119  rtdealloc(mem);
120  return 0;
121  }
122  rt_band_set_ownsdata_flag(band, 1); /* we DO own this data!!! */
123  rt_band_init_value(band, hasnodata ? nodataval : 0.0);
124 
125  RASTER_DEBUGF(3, "rt_band_reclass: new band @ %p", band);
126 
127  for (x = 0; x < width; x++) {
128  for (y = 0; y < height; y++) {
129  rtn = rt_band_get_pixel(srcband, x, y, &ov, &isnodata);
130 
131  /* error getting value, skip */
132  if (rtn != ES_NONE) {
133  RASTER_DEBUGF(3, "Cannot get value at %d, %d", x, y);
134  continue;
135  }
136  RASTER_DEBUGF(4, "(x, y, ov, isnodata) = (%d, %d, %f, %d)", x, y, ov, isnodata);
137 
138  do {
139  do_nv = 0;
140 
141  /* no data*/
142  if (hasnodata && isnodata) {
143  do_nv = 1;
144  break;
145  }
146 
147  for (i = 0; i < exprcount; i++) {
148  expr = exprset[i];
149 
150  /* ov matches min and max*/
151  if (
152  FLT_EQ(expr->src.min, ov) &&
153  FLT_EQ(expr->src.max, ov)
154  ) {
155  do_nv = 1;
156  break;
157  }
158 
159  /* process min */
160  if ((
161  expr->src.exc_min && (
162  expr->src.min > ov ||
163  FLT_EQ(expr->src.min, ov)
164  )) || (
165  expr->src.inc_min && (
166  expr->src.min < ov ||
167  FLT_EQ(expr->src.min, ov)
168  )) || (
169  expr->src.min < ov
170  )) {
171  /* process max */
172  if ((
173  expr->src.exc_max && (
174  ov > expr->src.max ||
175  FLT_EQ(expr->src.max, ov)
176  )) || (
177  expr->src.inc_max && (
178  ov < expr->src.max ||
179  FLT_EQ(expr->src.max, ov)
180  )) || (
181  ov < expr->src.max
182  )) {
183  do_nv = 1;
184  break;
185  }
186  }
187  }
188  }
189  while (0);
190 
191  /* no expression matched, do not continue */
192  if (!do_nv) continue;
193  RASTER_DEBUGF(3, "Using exprset[%d] unless NODATA", i);
194 
195  /* converting a value from one range to another range
196  OldRange = (OldMax - OldMin)
197  NewRange = (NewMax - NewMin)
198  NewValue = (((OldValue - OldMin) * NewRange) / OldRange) + NewMin
199  */
200 
201  /* NODATA */
202  if (hasnodata && isnodata) {
203  nv = nodataval;
204  }
205  /*
206  "src" min and max is the same, prevent division by zero
207  set nv to "dst" min, which should be the same as "dst" max
208  */
209  else if (FLT_EQ(expr->src.max, expr->src.min)) {
210  nv = expr->dst.min;
211  }
212  else {
213  or = expr->src.max - expr->src.min;
214  nr = expr->dst.max - expr->dst.min;
215  nv = (((ov - expr->src.min) * nr) / or) + expr->dst.min;
216 
217  /* if dst range is from high to low */
218  if (expr->dst.min > expr->dst.max) {
219  if (nv > expr->dst.min)
220  nv = expr->dst.min;
221  else if (nv < expr->dst.max)
222  nv = expr->dst.max;
223  }
224  /* if dst range is from low to high */
225  else {
226  if (nv < expr->dst.min)
227  nv = expr->dst.min;
228  else if (nv > expr->dst.max)
229  nv = expr->dst.max;
230  }
231  }
232 
233  /* round the value for integers */
234  nv = rt_band_reclass_round_integer(pixtype, nv);
235 
236  RASTER_DEBUGF(4, "(%d, %d) ov: %f or: %f - %f nr: %f - %f nv: %f"
237  , x
238  , y
239  , ov
240  , (NULL != expr) ? expr->src.min : 0
241  , (NULL != expr) ? expr->src.max : 0
242  , (NULL != expr) ? expr->dst.min : 0
243  , (NULL != expr) ? expr->dst.max : 0
244  , nv
245  );
246  if (rt_band_set_pixel(band, x, y, nv, NULL) != ES_NONE) {
247  rterror("rt_band_reclass: Could not assign value to new band");
249  rtdealloc(mem);
250  return 0;
251  }
252 
253  expr = NULL;
254  }
255  }
256 
257  return band;
258 }
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
#define RASTER_DEBUGF(level, msg,...)
Definition: librtcore.h:306
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
#define FLT_EQ(x, y)
Definition: librtcore.h:2424
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
if(!(yy_init))
band
Definition: ovdump.py:58
static double rt_band_reclass_round_integer(rt_pixtype pixtype, double nv)
Definition: rt_mapalgebra.c:38
struct rt_reclassexpr_t::rt_reclassrange src
struct rt_reclassexpr_t::rt_reclassrange dst

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, 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_init_value(), rt_band_new_inline(), rt_band_reclass_round_integer(), rt_band_set_ownsdata_flag(), rt_band_set_pixel(), rt_pixtype_size(), rtalloc(), rtdealloc(), rterror(), rt_reclassexpr_t::src, pixval::x, and pixval::y.

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

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