52 uint32_t hasnodata,
double nodataval,
62 double src_nodataval = 0.0;
76 assert(NULL != srcband);
77 assert(NULL != exprset && exprcount > 0);
89 numval = width * height;
93 rterror(
"rt_band_reclass: Could not allocate memory for band");
99 memset(mem, 0, memsize);
103 int32_t checkvalint = 0;
105 double checkvaldouble = 0;
106 float checkvalfloat = 0;
113 for (i = 0; i < numval; i++)
114 ptr[i] = clamped_initval;
115 checkvalint = ptr[0];
122 for (i = 0; i < numval; i++)
123 ptr[i] = clamped_initval;
124 checkvalint = ptr[0];
131 for (i = 0; i < numval; i++)
132 ptr[i] = clamped_initval;
133 checkvalint = ptr[0];
140 for (i = 0; i < numval; i++)
141 ptr[i] = clamped_initval;
142 checkvalint = ptr[0];
149 for (i = 0; i < numval; i++)
150 ptr[i] = clamped_initval;
151 checkvalint = ptr[0];
158 for (i = 0; i < numval; i++)
159 ptr[i] = clamped_initval;
160 checkvalint = ptr[0];
167 for (i = 0; i < numval; i++)
168 ptr[i] = clamped_initval;
169 checkvalint = ptr[0];
176 for (i = 0; i < numval; i++)
177 ptr[i] = clamped_initval;
178 checkvalint = ptr[0];
185 for (i = 0; i < numval; i++)
186 ptr[i] = clamped_initval;
187 checkvaluint = ptr[0];
194 for (i = 0; i < numval; i++)
195 ptr[i] = clamped_initval;
196 checkvalfloat = ptr[0];
202 for (i = 0; i < numval; i++)
204 checkvaldouble = ptr[0];
209 rterror(
"rt_band_reclass: Unknown pixeltype %d", pixtype);
218 checkvalint, checkvaluint,
219 checkvalfloat, checkvaldouble,
223 RASTER_DEBUGF(3,
"rt_band_reclass: width = %d height = %d", width, height);
227 rterror(
"rt_band_reclass: Could not create new band");
234 for (x = 0; x < width; x++) {
235 for (y = 0; y < height; y++) {
243 RASTER_DEBUGF(4,
"(x, y, ov, isnodata) = (%d, %d, %f, %d)", x, y, ov, isnodata);
249 if (hasnodata && isnodata) {
254 for (i = 0; i < exprcount; i++) {
285 ov < expr->src.max ||
299 if (!do_nv)
continue;
309 if (hasnodata && isnodata) {
322 nv = (((ov - expr->
src.
min) * nr) / or) + expr->
dst.
min;
328 else if (nv < expr->dst.max)
333 if (nv < expr->dst.min)
335 else if (nv > expr->
dst.
max)
357 RASTER_DEBUGF(4,
"(%d, %d) ov: %f or: %f - %f nr: %f - %f nv: %f" 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
368 rterror(
"rt_band_reclass: Could not assign value to new band");
421 static _rti_iterator_arg
423 _rti_iterator_arg _param;
426 if (_param == NULL) {
427 rterror(
"_rti_iterator_arg_init: Could not allocate memory for _rti_iterator_arg");
436 _param->
width = NULL;
463 if (_param->
raster != NULL)
467 if (_param->
width != NULL)
469 if (_param->
height != NULL)
483 if (_param->
offset != NULL) {
484 for (i = 0; i < _param->
count; i++) {
485 if (_param->
offset[i] == NULL)
509 if (_param->
arg != NULL) {
515 for (i = 0; i < _param->
count; i++) {
532 _rti_iterator_arg _param,
534 uint16_t distancex, uint16_t distancey,
535 int *allnull,
int *allempty
540 _param->
count = itrcount;
563 _param->
width == NULL ||
572 rterror(
"_rti_iterator_arg_populate: Could not allocate memory for children of _rti_iterator_arg");
584 for (i = 0; i < itrcount; i++) {
588 _param->
width[i] = 0;
600 if (itrset[i].
raster == NULL) {
619 if (!itrset[i].nbnodata) {
620 rterror(
"_rti_iterator_arg_populate: Band %d not found for raster %d", itrset[i].nband, i);
624 RASTER_DEBUGF(4,
"Band %d not found for raster %d. Using NODATA", itrset[i].nband, i);
632 rterror(
"_rti_iterator_arg_populate: Could not get band %d for raster %d", itrset[i].nband, i);
660 if (_param->
offset[i] == NULL) {
661 rterror(
"_rti_iterator_arg_populate: Could not allocate memory for offsets");
677 rterror(
"_rti_iterator_arg_empty_init: Could not allocate memory for empty values and NODATA");
686 rterror(
"_rti_iterator_arg_empty_init: Could not allocate memory for elements of empty values and NODATA");
704 if (_param->
arg == NULL) {
705 rterror(
"_rti_iterator_arg_callback_init: Could not allocate memory for rt_iterator_arg");
718 rterror(
"_rti_iterator_arg_callback_init: Could not allocate memory for element of rt_iterator_arg");
721 memset(_param->
arg->
values, 0,
sizeof(
double **) * _param->
count);
725 for (i = 0; i < _param->
count; i++) {
729 rterror(
"_rti_iterator_arg_callback_init: Could not allocate memory for position elements of rt_iterator_arg");
750 for (i = 0; i < _param->
count; i++) {
817 uint16_t distancex, uint16_t distancey,
836 _rti_iterator_arg _param = NULL;
861 assert(itrset != NULL && itrcount > 0);
862 assert(rtnraster != NULL);
868 if (callback == NULL) {
869 rterror(
"rt_raster_iterator: Callback function not provided");
875 rterror(
"rt_raster_iterator: Custom extent cannot be empty if extent type is ET_CUSTOM");
881 rterror(
"rt_raster_iterator: Pixel type cannot be PT_END");
887 rterror(
"rt_raster_iterator: Could not initialize internal variables");
893 rterror(
"rt_raster_iterator: Could not populate for internal variables");
899 if (allnull == itrcount) {
900 RASTER_DEBUG(3,
"all rasters are NULL, returning NULL");
907 else if (allempty == itrcount) {
908 RASTER_DEBUG(3,
"all rasters are empty, returning empty raster");
913 if (rtnrast == NULL) {
914 rterror(
"rt_raster_iterator: Could not create empty raster");
919 *rtnraster = rtnrast;
930 RASTER_DEBUG(4,
"using custom extent as reference raster");
935 for (i = 0; i < itrcount; i++) {
937 RASTER_DEBUGF(4,
"using raster at index %d as reference raster", i);
946 rterror(
"rt_raster_iterator: Could not find reference raster to use for alignment tests");
957 if (extenttype ==
ET_CUSTOM && rast != customextent) {
959 rterror(
"rt_raster_iterator: Could not test for alignment between reference raster and custom extent");
971 for (i = 0; i < itrcount; i++) {
977 rterror(
"rt_raster_iterator: Could not test for alignment between reference raster and raster %d", i);
983 RASTER_DEBUGF(5,
"raster at index %d alignment: %d", i, aligned);
994 rterror(
"rt_raster_iterator: The set of rasters provided (custom extent included, if appropriate) do not have the same alignment");
1003 switch (extenttype) {
1008 if (rtnrast == NULL) {
1009 rterror(
"rt_raster_iterator: Could not allocate memory for output raster");
1016 for (i = 0; i < itrcount; i++) {
1023 rtnrast->
bands = NULL;
1027 for (i = i + 1; i < itrcount; i++) {
1034 if (rast == NULL || status !=
ES_NONE) {
1035 rterror(
"rt_raster_iterator: Could not compute %s extent of rasters",
1036 extenttype ==
ET_UNION ?
"union" :
"intersection" 1044 rtinfo(
"rt_raster_iterator: Computed raster for %s extent is empty",
1045 extenttype ==
ET_UNION ?
"union" :
"intersection" 1073 if (i < 0) i = itrcount - 1;
1076 if (_param->
raster[i] == NULL) {
1077 RASTER_DEBUGF(3,
"returning NULL as %s raster is NULL and extent type is ET_%s",
1078 (i == 0 ?
"first" : (i == 1 ?
"second" :
"last")),
1079 (i == 0 ?
"FIRST" : (i == 1 ?
"SECOND" :
"LAST"))
1087 else if (_param->
isempty[i]) {
1088 RASTER_DEBUGF(3,
"returning empty raster as %s raster is empty and extent type is ET_%s",
1089 (i == 0 ?
"first" : (i == 1 ?
"second" :
"last")),
1090 (i == 0 ?
"FIRST" : (i == 1 ?
"SECOND" :
"LAST"))
1096 if (rtnrast == NULL) {
1097 rterror(
"rt_raster_iterator: Could not create empty raster");
1102 *rtnraster = rtnrast;
1108 if (rtnrast == NULL) {
1109 rterror(
"rt_raster_iterator: Could not allocate memory for output raster");
1116 switch (extenttype) {
1126 rtnrast->
bands = NULL;
1133 RASTER_DEBUGF(4,
"rtnrast (width, height, ulx, uly, scalex, scaley, skewx, skewy, srid) = (%d, %d, %f, %f, %f, %f, %f, %f, %d)",
1147 rterror(
"rt_raster_iterator: Could not initialize empty values and NODATA");
1160 hasnodata, nodataval,
1163 rterror(
"rt_raster_iterator: Could not add new band to output raster");
1173 if (rtnband == NULL) {
1174 rterror(
"rt_raster_iterator: Could not get new band from output raster");
1187 rterror(
"rt_raster_iterator: Could not initialize callback function argument");
1197 for (i = 0; i < itrcount; i++) {
1204 rterror(
"rt_raster_iterator: Could not compute raster offsets");
1213 _param->
offset[i][0] = offset[2];
1214 _param->
offset[i][1] = offset[3];
1215 RASTER_DEBUGF(4,
"rast %d offset: %f %f", i, offset[2], offset[3]);
1221 for (_y = 0; _y < _height; _y++) {
1222 for (_x = 0; _x < _width; _x++) {
1223 RASTER_DEBUGF(4,
"iterating output pixel (x, y) = (%d, %d)", _x, _y);
1228 for (i = 0; i < itrcount; i++) {
1241 RASTER_DEBUG(4,
"empty raster, band does not exist or band is NODATA. using empty values and NODATA");
1253 x = _x - (int) _param->
offset[i][0];
1254 y = _y - (
int) _param->
offset[i][1];
1263 if (distancex > 0 && distancey > 0) {
1269 distancex, distancey,
1274 rterror(
"rt_raster_iterator: Could not get pixel neighborhood");
1287 (x >= 0 && x < _param->
width[i]) &&
1288 (y >= 0 && y < _param->
height[i])
1297 rterror(
"rt_raster_iterator: Could not get the pixel value of band");
1309 RASTER_DEBUG(4,
"Outside band extent, setting value to NODATA");
1328 if (npixels == NULL) {
1329 rterror(
"rt_raster_iterator: Could not reallocate memory for neighborhood");
1338 npixels[status - 1].
x =
x;
1339 npixels[status - 1].
y =
y;
1340 npixels[status - 1].
nodata = 1;
1344 if ((!_param->
band.
hasnodata[i] && inextent) || !isnodata) {
1345 npixels[status - 1].
nodata = 0;
1347 RASTER_DEBUGF(4,
"value, nodata: %f, %d", value, npixels[status - 1].nodata);
1351 npixels, status, mask,
1353 distancex, distancey,
1360 rterror(
"rt_raster_iterator: Could not create 2D array of neighborhood");
1374 status = callback(_param->
arg, userarg, &value, &nodata);
1381 rterror(
"rt_raster_iterator: Callback function returned an error");
1394 RASTER_DEBUGF(4,
"burning pixel (%d, %d) with value: %f", _x, _y, value);
1396 else if (!hasnodata) {
1398 RASTER_DEBUGF(4,
"burning pixel (%d, %d) with minval: %f", _x, _y, minval);
1404 rterror(
"rt_raster_iterator: Could not set pixel value");
1418 *rtnraster = rtnrast;
1443 static _rti_colormap_arg
1445 _rti_colormap_arg
arg = NULL;
1449 rterror(
"_rti_colormap_arg_init: Could not allocate memory for _rti_color_arg");
1463 if (arg->
raster == NULL) {
1464 rterror(
"_rti_colormap_arg_init: Could not create output raster");
1482 if (arg->
raster != NULL) {
1495 for (i = 0; i < arg->
nexpr; i++) {
1496 if (arg->
expr[i] != NULL)
1524 _rti_colormap_arg
arg = NULL;
1531 assert(colormap != NULL);
1538 if (colormap->
nentry < 1) {
1539 rterror(
"rt_raster_colormap: colormap must have at least one entry");
1545 rterror(
"rt_raster_colormap: raster has no band at index %d", nband);
1551 rterror(
"rt_raster_colormap: Could not get band at index %d", nband);
1558 rterror(
"rt_raster_colormap: Could not initialize internal variables");
1569 if (colormap->
ncolor < 1) {
1570 rterror(
"rt_raster_colormap: At least one color must be provided");
1574 else if (colormap->
ncolor > 4) {
1575 rtinfo(
"More than four colors indicated. Using only the first four colors");
1582 if (arg->
pos == NULL) {
1583 rterror(
"rt_raster_colormap: Could not allocate memory for valid entries");
1587 for (i = 0, j = 0; i < colormap->
nentry; i++) {
1594 rtwarn(
"More than one colormap entry found for NODATA value. Only using first NOTDATA entry");
1604 if (colormap->
method == CM_INTERPOLATE && arg->
npos < 2) {
1605 rtwarn(
"Method INTERPOLATE requires at least two non-NODATA colormap entries. Using NEAREST instead");
1606 colormap->
method = CM_NEAREST;
1611 rtinfo(
"Band at index %d has no NODATA value. Ignoring NODATA entry", nband);
1619 if (colormap->
method == CM_INTERPOLATE)
1622 else if (colormap->
method == CM_EXACT)
1629 if (arg->
expr == NULL) {
1630 rterror(
"rt_raster_colormap: Could not allocate memory for reclass expressions");
1637 for (i = 0; i < arg->
nexpr; i++) {
1639 if (arg->
expr[i] == NULL) {
1640 rterror(
"rt_raster_colormap: Could not allocate memory for reclass expression");
1648 for (i = 0; i < colormap->
ncolor; i++) {
1668 RASTER_DEBUGF(4,
"NODATA expr[%d]->src (min, max, in, ix, en, ex) = (%f, %f, %d, %d, %d, %d)",
1677 RASTER_DEBUGF(4,
"NODATA expr[%d]->dst (min, max, in, ix, en, ex) = (%f, %f, %d, %d, %d, %d)",
1691 for (j = 0; j < arg->
npos; j++) {
1692 if (colormap->
method == CM_INTERPOLATE) {
1693 if (j == arg->
npos - 1)
1713 else if (colormap->
method == CM_NEAREST) {
1716 if (j != arg->
npos - 1) {
1749 else if (colormap->
method == CM_EXACT) {
1767 RASTER_DEBUGF(4,
"expr[%d]->src (min, max, in, ix, en, ex) = (%f, %f, %d, %d, %d, %d)",
1777 RASTER_DEBUGF(4,
"expr[%d]->dst (min, max, in, ix, en, ex) = (%f, %f, %d, %d, %d, %d)",
1791 if (colormap->
method == CM_EXACT) {
1808 RASTER_DEBUGF(4,
"expr[%d]->src (min, max, in, ix, en, ex) = (%f, %f, %d, %d, %d, %d)",
1818 RASTER_DEBUGF(4,
"expr[%d]->dst (min, max, in, ix, en, ex) = (%f, %f, %d, %d, %d, %d)",
1833 if (arg->
band == NULL) {
1834 rterror(
"rt_raster_colormap: Could not reclassify band");
1841 rterror(
"rt_raster_colormap: Could not add reclassified band to output raster");
int32_t rt_util_clamp_to_32BSI(double value)
struct _rti_iterator_arg_t::@9 distance
uint32_t rt_util_clamp_to_32BUI(double value)
double rt_raster_get_x_offset(rt_raster raster)
Get raster x offset, in projection units.
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.
int rt_raster_get_num_bands(rt_raster raster)
double rt_raster_get_y_skew(rt_raster raster)
Get skew about the Y axis.
rt_errorstate rt_raster_same_alignment(rt_raster rast1, rt_raster rast2, int *aligned, char **reason)
struct _rti_iterator_arg_t::@10 dimension
struct rt_pixel_t * rt_pixel
rt_errorstate rt_pixel_set_to_array(rt_pixel npixel, int count, rt_mask mask, int x, int y, uint16_t distancex, uint16_t distancey, double ***value, int ***nodata, int *dimx, int *dimy)
static _rti_colormap_arg _rti_colormap_arg_init(rt_raster raster)
static _rti_iterator_arg _rti_iterator_arg_init()
struct rt_reclassexpr_t::rt_reclassrange dst
static int _rti_iterator_arg_empty_init(_rti_iterator_arg _param)
rt_errorstate rt_raster_from_two_rasters(rt_raster rast1, rt_raster rast2, rt_extenttype extenttype, rt_raster *rtnraster, double *offset)
void rterror(const char *fmt,...)
Wrappers used for reporting errors and info.
void * rtalloc(size_t size)
Wrappers used for managing memory.
void * rtrealloc(void *mem, size_t size)
rt_errorstate
Enum definitions.
void rt_band_destroy(rt_band band)
Destroy a raster band.
static void _rti_colormap_arg_destroy(_rti_colormap_arg arg)
int rt_raster_is_empty(rt_raster raster)
Return TRUE if the raster is empty.
struct _rti_colormap_arg_t * _rti_colormap_arg
rt_errorstate rt_band_get_nodata(rt_band band, double *nodata)
Get NODATA value.
uint16_t rt_util_clamp_to_16BUI(double value)
void rt_band_set_ownsdata_flag(rt_band band, int flag)
struct rt_reclassexpr_t::rt_reclassrange src
rt_errorstate rt_raster_iterator(rt_iterator itrset, uint16_t itrcount, rt_extenttype extenttype, rt_raster customextent, rt_pixtype pixtype, uint8_t hasnodata, double nodataval, uint16_t distancex, uint16_t distancey, rt_mask mask, void *userarg, int(*callback)(rt_iterator_arg arg, void *userarg, double *value, int *nodata), rt_raster *rtnraster)
n-raster iterator.
void rtwarn(const char *fmt,...)
struct _rti_iterator_arg_t::@11 empty
rt_errorstate rt_band_get_pixel(rt_band band, int x, int y, double *value, int *nodata)
Get pixel value.
enum rt_colormap_t::@7 method
void rt_raster_set_scale(rt_raster raster, double scaleX, double scaleY)
Set scale in projection units.
int rt_raster_generate_new_band(rt_raster raster, rt_pixtype pixtype, double initialvalue, uint32_t hasnodata, double nodatavalue, int index)
Generate a new inline band and add it to a raster.
rt_raster rt_raster_clone(rt_raster raster, uint8_t deep)
Clone an existing raster.
int8_t rt_util_clamp_to_8BSI(double value)
int rt_util_dbl_trunc_warning(double initialvalue, int32_t checkvalint, uint32_t checkvaluint, float checkvalfloat, double checkvaldouble, rt_pixtype pixtype)
rt_band rt_raster_get_band(rt_raster raster, int bandNum)
Return Nth band, or NULL if unavailable.
void rtinfo(const char *fmt,...)
int rt_band_get_hasnodata_flag(rt_band band)
Get hasnodata flag value.
double rt_raster_get_x_scale(rt_raster raster)
Get scale X in projection units.
uint16_t rt_band_get_width(rt_band band)
Return width of this band.
int rt_raster_has_band(rt_raster raster, int nband)
Return TRUE if the raster has a band of this number.
uint16_t rt_band_get_height(rt_band band)
Return height of this band.
#define RASTER_DEBUGF(level, msg,...)
int32_t rt_raster_get_srid(rt_raster raster)
Get raster's SRID.
void rt_raster_destroy(rt_raster raster)
Release memory associated to a raster.
double rt_raster_get_y_scale(rt_raster raster)
Get scale Y in projection units.
rt_raster rt_raster_new(uint32_t width, uint32_t height)
Construct a raster with given dimensions.
double rt_raster_get_x_skew(rt_raster raster)
Get skew about the X axis.
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.
uint8_t rt_util_clamp_to_4BUI(double value)
uint8_t rt_util_clamp_to_8BUI(double value)
int rt_pixtype_size(rt_pixtype pixtype)
Return size in bytes of a value in the given pixtype.
uint8_t rt_util_clamp_to_1BB(double value)
static void _rti_iterator_arg_callback_clean(_rti_iterator_arg _param)
uint16_t rt_raster_get_width(rt_raster raster)
void rtdealloc(void *mem)
static int _rti_iterator_arg_callback_init(_rti_iterator_arg _param)
#define RASTER_DEBUG(level, msg)
double rt_band_get_min_value(rt_band band)
Returns the minimal possible value for the band according to the pixel type.
This library is the generic raster handling section of PostGIS.
int rt_raster_add_band(rt_raster raster, rt_band band, int index)
Add band data to a raster.
struct _rti_iterator_arg_t * _rti_iterator_arg
uint8_t rt_util_clamp_to_2BUI(double value)
int rt_band_get_isnodata_flag(rt_band band)
Get isnodata flag value.
float rt_util_clamp_to_32F(double value)
rt_errorstate rt_band_set_pixel(rt_band band, int x, int y, double val, int *converted)
Set single pixel's value.
static int _rti_iterator_arg_populate(_rti_iterator_arg _param, rt_iterator itrset, uint16_t itrcount, uint16_t distancex, uint16_t distancey, int *allnull, int *allempty)
uint16_t rt_raster_get_height(rt_raster raster)
static void _rti_iterator_arg_destroy(_rti_iterator_arg _param)
rt_raster rt_raster_colormap(rt_raster raster, int nband, rt_colormap colormap)
Returns a new raster with up to four 8BUI bands (RGBA) from applying a colormap to the user-specified...
int rt_band_get_nearest_pixel(rt_band band, int x, int y, uint16_t distancex, uint16_t distancey, int exclude_nodata_value, rt_pixel *npixels)
Get nearest pixel(s) with value (not NODATA) to specified pixel.
struct _rti_iterator_arg_t::@8 band
double rt_raster_get_y_offset(rt_raster raster)
Get raster y offset, in projection units.
rt_colormap_entry nodataentry
int16_t rt_util_clamp_to_16BSI(double value)