PostGIS  2.1.10dev-r@@SVN_REVISION@@
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 5009 of file rt_api.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().

5013  {
5014  rt_band band = NULL;
5015  uint32_t width = 0;
5016  uint32_t height = 0;
5017  int numval = 0;
5018  int memsize = 0;
5019  void *mem = NULL;
5020  uint32_t src_hasnodata = 0;
5021  double src_nodataval = 0.0;
5022  int isnodata = 0;
5023 
5024  int rtn;
5025  uint32_t x;
5026  uint32_t y;
5027  int i;
5028  double or = 0;
5029  double ov = 0;
5030  double nr = 0;
5031  double nv = 0;
5032  int do_nv = 0;
5033  rt_reclassexpr expr = NULL;
5034 
5035  assert(NULL != srcband);
5036  assert(NULL != exprset && exprcount > 0);
5037  RASTER_DEBUGF(4, "exprcount = %d", exprcount);
5038  RASTER_DEBUGF(4, "exprset @ %p", exprset);
5039 
5040  /* source nodata */
5041  src_hasnodata = rt_band_get_hasnodata_flag(srcband);
5042  if (src_hasnodata)
5043  rt_band_get_nodata(srcband, &src_nodataval);
5044 
5045  /* size of memory block to allocate */
5046  width = rt_band_get_width(srcband);
5047  height = rt_band_get_height(srcband);
5048  numval = width * height;
5049  memsize = rt_pixtype_size(pixtype) * numval;
5050  mem = (int *) rtalloc(memsize);
5051  if (!mem) {
5052  rterror("rt_band_reclass: Could not allocate memory for band");
5053  return 0;
5054  }
5055 
5056  /* initialize to zero */
5057  if (!hasnodata) {
5058  memset(mem, 0, memsize);
5059  }
5060  /* initialize to nodataval */
5061  else {
5062  int32_t checkvalint = 0;
5063  uint32_t checkvaluint = 0;
5064  double checkvaldouble = 0;
5065  float checkvalfloat = 0;
5066 
5067  switch (pixtype) {
5068  case PT_1BB:
5069  {
5070  uint8_t *ptr = mem;
5071  uint8_t clamped_initval = rt_util_clamp_to_1BB(nodataval);
5072  for (i = 0; i < numval; i++)
5073  ptr[i] = clamped_initval;
5074  checkvalint = ptr[0];
5075  break;
5076  }
5077  case PT_2BUI:
5078  {
5079  uint8_t *ptr = mem;
5080  uint8_t clamped_initval = rt_util_clamp_to_2BUI(nodataval);
5081  for (i = 0; i < numval; i++)
5082  ptr[i] = clamped_initval;
5083  checkvalint = ptr[0];
5084  break;
5085  }
5086  case PT_4BUI:
5087  {
5088  uint8_t *ptr = mem;
5089  uint8_t clamped_initval = rt_util_clamp_to_4BUI(nodataval);
5090  for (i = 0; i < numval; i++)
5091  ptr[i] = clamped_initval;
5092  checkvalint = ptr[0];
5093  break;
5094  }
5095  case PT_8BSI:
5096  {
5097  int8_t *ptr = mem;
5098  int8_t clamped_initval = rt_util_clamp_to_8BSI(nodataval);
5099  for (i = 0; i < numval; i++)
5100  ptr[i] = clamped_initval;
5101  checkvalint = ptr[0];
5102  break;
5103  }
5104  case PT_8BUI:
5105  {
5106  uint8_t *ptr = mem;
5107  uint8_t clamped_initval = rt_util_clamp_to_8BUI(nodataval);
5108  for (i = 0; i < numval; i++)
5109  ptr[i] = clamped_initval;
5110  checkvalint = ptr[0];
5111  break;
5112  }
5113  case PT_16BSI:
5114  {
5115  int16_t *ptr = mem;
5116  int16_t clamped_initval = rt_util_clamp_to_16BSI(nodataval);
5117  for (i = 0; i < numval; i++)
5118  ptr[i] = clamped_initval;
5119  checkvalint = ptr[0];
5120  break;
5121  }
5122  case PT_16BUI:
5123  {
5124  uint16_t *ptr = mem;
5125  uint16_t clamped_initval = rt_util_clamp_to_16BUI(nodataval);
5126  for (i = 0; i < numval; i++)
5127  ptr[i] = clamped_initval;
5128  checkvalint = ptr[0];
5129  break;
5130  }
5131  case PT_32BSI:
5132  {
5133  int32_t *ptr = mem;
5134  int32_t clamped_initval = rt_util_clamp_to_32BSI(nodataval);
5135  for (i = 0; i < numval; i++)
5136  ptr[i] = clamped_initval;
5137  checkvalint = ptr[0];
5138  break;
5139  }
5140  case PT_32BUI:
5141  {
5142  uint32_t *ptr = mem;
5143  uint32_t clamped_initval = rt_util_clamp_to_32BUI(nodataval);
5144  for (i = 0; i < numval; i++)
5145  ptr[i] = clamped_initval;
5146  checkvaluint = ptr[0];
5147  break;
5148  }
5149  case PT_32BF:
5150  {
5151  float *ptr = mem;
5152  float clamped_initval = rt_util_clamp_to_32F(nodataval);
5153  for (i = 0; i < numval; i++)
5154  ptr[i] = clamped_initval;
5155  checkvalfloat = ptr[0];
5156  break;
5157  }
5158  case PT_64BF:
5159  {
5160  double *ptr = mem;
5161  for (i = 0; i < numval; i++)
5162  ptr[i] = nodataval;
5163  checkvaldouble = ptr[0];
5164  break;
5165  }
5166  default:
5167  {
5168  rterror("rt_band_reclass: Unknown pixeltype %d", pixtype);
5169  rtdealloc(mem);
5170  return 0;
5171  }
5172  }
5173 
5174  /* Overflow checking */
5176  nodataval,
5177  checkvalint, checkvaluint,
5178  checkvalfloat, checkvaldouble,
5179  pixtype
5180  );
5181  }
5182  RASTER_DEBUGF(3, "rt_band_reclass: width = %d height = %d", width, height);
5183 
5184  band = rt_band_new_inline(width, height, pixtype, hasnodata, nodataval, mem);
5185  if (!band) {
5186  rterror("rt_band_reclass: Could not create new band");
5187  rtdealloc(mem);
5188  return 0;
5189  }
5190  rt_band_set_ownsdata_flag(band, 1); /* we DO own this data!!! */
5191  RASTER_DEBUGF(3, "rt_band_reclass: new band @ %p", band);
5192 
5193  for (x = 0; x < width; x++) {
5194  for (y = 0; y < height; y++) {
5195  rtn = rt_band_get_pixel(srcband, x, y, &ov, &isnodata);
5196 
5197  /* error getting value, skip */
5198  if (rtn != ES_NONE) {
5199  RASTER_DEBUGF(3, "Cannot get value at %d, %d", x, y);
5200  continue;
5201  }
5202 
5203  do {
5204  do_nv = 0;
5205 
5206  /* no data*/
5207  if (hasnodata && isnodata) {
5208  do_nv = 1;
5209  break;
5210  }
5211 
5212  for (i = 0; i < exprcount; i++) {
5213  expr = exprset[i];
5214 
5215  /* ov matches min and max*/
5216  if (
5217  FLT_EQ(expr->src.min, ov) &&
5218  FLT_EQ(expr->src.max, ov)
5219  ) {
5220  do_nv = 1;
5221  break;
5222  }
5223 
5224  /* process min */
5225  if ((
5226  expr->src.exc_min && (
5227  expr->src.min > ov ||
5228  FLT_EQ(expr->src.min, ov)
5229  )) || (
5230  expr->src.inc_min && (
5231  expr->src.min < ov ||
5232  FLT_EQ(expr->src.min, ov)
5233  )) || (
5234  expr->src.min < ov
5235  )) {
5236  /* process max */
5237  if ((
5238  expr->src.exc_max && (
5239  ov > expr->src.max ||
5240  FLT_EQ(expr->src.max, ov)
5241  )) || (
5242  expr->src.inc_max && (
5243  ov < expr->src.max ||
5244  FLT_EQ(expr->src.max, ov)
5245  )) || (
5246  ov < expr->src.max
5247  )) {
5248  do_nv = 1;
5249  break;
5250  }
5251  }
5252  }
5253  }
5254  while (0);
5255 
5256  /* no expression matched, do not continue */
5257  if (!do_nv) continue;
5258  RASTER_DEBUGF(3, "Using exprset[%d] unless NODATA", i);
5259 
5260  /* converting a value from one range to another range
5261  OldRange = (OldMax - OldMin)
5262  NewRange = (NewMax - NewMin)
5263  NewValue = (((OldValue - OldMin) * NewRange) / OldRange) + NewMin
5264  */
5265 
5266  /* NODATA */
5267  if (hasnodata && isnodata) {
5268  nv = nodataval;
5269  }
5270  /*
5271  "src" min and max is the same, prevent division by zero
5272  set nv to "dst" min, which should be the same as "dst" max
5273  */
5274  else if (FLT_EQ(expr->src.max, expr->src.min)) {
5275  nv = expr->dst.min;
5276  }
5277  else {
5278  or = expr->src.max - expr->src.min;
5279  nr = expr->dst.max - expr->dst.min;
5280  nv = (((ov - expr->src.min) * nr) / or) + expr->dst.min;
5281 
5282  /* if dst range is from high to low */
5283  if (expr->dst.min > expr->dst.max) {
5284  if (nv > expr->dst.min)
5285  nv = expr->dst.min;
5286  else if (nv < expr->dst.max)
5287  nv = expr->dst.max;
5288  }
5289  /* if dst range is from low to high */
5290  else {
5291  if (nv < expr->dst.min)
5292  nv = expr->dst.min;
5293  else if (nv > expr->dst.max)
5294  nv = expr->dst.max;
5295  }
5296  }
5297 
5298  /* round the value for integers */
5299  switch (pixtype) {
5300  case PT_1BB:
5301  case PT_2BUI:
5302  case PT_4BUI:
5303  case PT_8BSI:
5304  case PT_8BUI:
5305  case PT_16BSI:
5306  case PT_16BUI:
5307  case PT_32BSI:
5308  case PT_32BUI:
5309  nv = round(nv);
5310  break;
5311  default:
5312  break;
5313  }
5314 
5315  RASTER_DEBUGF(4, "(%d, %d) ov: %f or: %f - %f nr: %f - %f nv: %f"
5316  , x
5317  , y
5318  , ov
5319  , (NULL != expr) ? expr->src.min : 0
5320  , (NULL != expr) ? expr->src.max : 0
5321  , (NULL != expr) ? expr->dst.min : 0
5322  , (NULL != expr) ? expr->dst.max : 0
5323  , nv
5324  );
5325  if (rt_band_set_pixel(band, x, y, nv, NULL) != ES_NONE) {
5326  rterror("rt_band_reclass: Could not assign value to new band");
5327  rt_band_destroy(band);
5328  rtdealloc(mem);
5329  return 0;
5330  }
5331 
5332  expr = NULL;
5333  }
5334  }
5335 
5336  return band;
5337 }
uint8_t rt_util_clamp_to_8BUI(double value)
Definition: rt_api.c:109
uint8_t rt_util_clamp_to_4BUI(double value)
Definition: rt_api.c:99
void rtdealloc(void *mem)
Definition: rt_api.c:882
float rt_util_clamp_to_32F(double value)
Definition: rt_api.c:134
struct rt_reclassexpr_t::rt_reclassrange dst
int32_t rt_util_clamp_to_32BSI(double value)
Definition: rt_api.c:124
uint8_t rt_util_clamp_to_1BB(double value)
Definition: rt_api.c:89
tuple band
Definition: ovdump.py:57
int rt_util_dbl_trunc_warning(double initialvalue, int32_t checkvalint, uint32_t checkvaluint, float checkvalfloat, double checkvaldouble, rt_pixtype pixtype)
Definition: rt_api.c:934
uint8_t rt_util_clamp_to_2BUI(double value)
Definition: rt_api.c:94
Definition: rt_api.h:173
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_api.c:1466
int rt_pixtype_size(rt_pixtype pixtype)
Return size in bytes of a value in the given pixtype.
Definition: rt_api.c:1097
uint16_t rt_util_clamp_to_16BUI(double value)
Definition: rt_api.c:119
struct rt_reclassexpr_t::rt_reclassrange src
uint32_t rt_util_clamp_to_32BUI(double value)
Definition: rt_api.c:129
#define RASTER_DEBUGF(level, msg,...)
Definition: rt_api.h:285
void rt_band_set_ownsdata_flag(rt_band band, int flag)
Definition: rt_api.c:1936
rt_errorstate rt_band_get_nodata(rt_band band, double *nodata)
Get NODATA value.
Definition: rt_api.c:3058
rt_errorstate rt_band_get_pixel(rt_band band, int x, int y, double *value, int *nodata)
Get pixel value.
Definition: rt_api.c:2549
uint16_t rt_band_get_width(rt_band band)
Return width of this band.
Definition: rt_api.c:1909
#define FLT_EQ(x, y)
Definition: rt_api.h:2159
tuple x
Definition: pixval.py:53
void rt_band_destroy(rt_band band)
Destroy a raster band.
Definition: rt_api.c:1650
void * rtalloc(size_t size)
Raster core memory management functions.
Definition: rt_api.c:867
void rterror(const char *fmt,...)
Raster core error and info handlers.
Definition: rt_api.c:895
int8_t rt_util_clamp_to_8BSI(double value)
Definition: rt_api.c:104
uint16_t rt_band_get_height(rt_band band)
Return height of this band.
Definition: rt_api.c:1918
int rt_band_get_hasnodata_flag(rt_band band)
Get hasnodata flag value.
Definition: rt_api.c:2002
tuple y
Definition: pixval.py:54
if(!(yy_init))
Definition: lwin_wkt_lex.c:860
int16_t rt_util_clamp_to_16BSI(double value)
Definition: rt_api.c:114
rt_errorstate rt_band_set_pixel(rt_band band, int x, int y, double val, int *converted)
Set single pixel's value.
Definition: rt_api.c:2302

Here is the call graph for this function:

Here is the caller graph for this function: