PostGIS 3.0.6dev-r@@SVN_REVISION@@
Loading...
Searching...
No Matches

◆ 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.

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}
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:667
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
uint16_t rt_band_get_width(rt_band band)
Return width of this band.
Definition rt_band.c:640
#define RASTER_DEBUGF(level, msg,...)
Definition librtcore.h:299
int8_t rt_util_clamp_to_8BSI(double value)
Definition rt_util.c:49
uint8_t rt_util_clamp_to_1BB(double value)
Definition rt_util.c:34
int32_t rt_util_clamp_to_32BSI(double value)
Definition rt_util.c:69
int rt_band_get_hasnodata_flag(rt_band band)
Get hasnodata flag value.
Definition rt_band.c:674
rt_errorstate rt_band_get_pixel(rt_band band, int x, int y, double *value, int *nodata)
Get pixel value.
Definition rt_band.c:1221
@ PT_32BUI
Definition librtcore.h:194
@ PT_2BUI
Definition librtcore.h:187
@ PT_32BSI
Definition librtcore.h:193
@ PT_4BUI
Definition librtcore.h:188
@ PT_32BF
Definition librtcore.h:195
@ PT_1BB
Definition librtcore.h:186
@ PT_16BUI
Definition librtcore.h:192
@ PT_8BSI
Definition librtcore.h:189
@ PT_16BSI
Definition librtcore.h:191
@ PT_64BF
Definition librtcore.h:196
@ PT_8BUI
Definition librtcore.h:190
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:629
#define FLT_EQ(x, y)
Definition librtcore.h:2235
uint8_t rt_util_clamp_to_2BUI(double value)
Definition rt_util.c:39
uint8_t rt_util_clamp_to_8BUI(double value)
Definition rt_util.c:54
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:974
@ ES_NONE
Definition librtcore.h:180
void rt_band_destroy(rt_band band)
Destroy a raster band.
Definition rt_band.c:340
int16_t rt_util_clamp_to_16BSI(double value)
Definition rt_util.c:59
rt_errorstate rt_band_get_nodata(rt_band band, double *nodata)
Get NODATA value.
Definition rt_band.c:1730
uint8_t rt_util_clamp_to_4BUI(double value)
Definition rt_util.c:44
void rtdealloc(void *mem)
Definition rt_context.c:186
uint16_t rt_util_clamp_to_16BUI(double value)
Definition rt_util.c:64
uint32_t rt_util_clamp_to_32BUI(double value)
Definition rt_util.c:74
float rt_util_clamp_to_32F(double value)
Definition rt_util.c:79
uint16_t rt_band_get_height(rt_band band)
Return height of this band.
Definition rt_band.c:649
int rt_pixtype_size(rt_pixtype pixtype)
Return size in bytes of a value in the given pixtype.
Definition rt_pixel.c:39
struct rt_reclassexpr_t::rt_reclassrange src
struct rt_reclassexpr_t::rt_reclassrange dst

References rt_reclassexpr_t::dst, ES_NONE, rt_reclassexpr_t::rt_reclassrange::exc_max, rt_reclassexpr_t::rt_reclassrange::exc_min, FLT_EQ, 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(), and rt_reclassexpr_t::src.

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: