PostGIS 3.7.0dev-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 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");
248 rt_band_destroy(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:113
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:64
void rt_band_set_ownsdata_flag(rt_band band, int flag)
Definition rt_band.c:826
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:799
#define RASTER_DEBUGF(level, msg,...)
Definition librtcore.h:308
int rt_band_get_hasnodata_flag(rt_band band)
Get hasnodata flag value.
Definition rt_band.c:833
rt_errorstate rt_band_get_pixel(rt_band band, int x, int y, double *value, int *nodata)
Get pixel value.
Definition rt_band.c:1551
#define FLT_EQ(x, y)
Definition librtcore.h:2436
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:1140
@ ES_NONE
Definition librtcore.h:182
void rt_band_destroy(rt_band band)
Destroy a raster band.
Definition rt_band.c:499
rt_errorstate rt_band_get_nodata(rt_band band, double *nodata)
Get NODATA value.
Definition rt_band.c:2067
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:808
int rt_pixtype_size(rt_pixtype pixtype)
Return size in bytes of a value in the given pixtype.
Definition rt_pixel.c:40
static double rt_band_reclass_round_integer(rt_pixtype pixtype, double nv)
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, 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(), 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: