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

◆ 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: 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__);
382 rt_band_destroy(band);
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: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
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
rt_pixtype
Definition librtcore.h:188
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 int rt_classpair_cmp(const void *aptr, const void *bptr)
static double rt_band_reclass_round_integer(rt_pixtype pixtype, double nv)
rt_pixtype dsttype
Definition librtcore.h:2653
struct rt_classpair_t * pairs
Definition librtcore.h:2654

References 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(), and rt_classpair_t::src.

Referenced by RASTER_reclass_exact().

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