59 uint16_t width, uint16_t height,
61 uint32_t hasnodata,
double nodataval,
70 rterror(
"rt_band_new_inline: Out of memory allocating rt_band");
91 rterror(
"rt_band_new_inline: Could not set NODATA value");
120 uint16_t width, uint16_t height,
122 uint32_t hasnodata,
double nodataval,
123 uint8_t bandNum,
const char* path
128 assert(NULL != path);
132 rterror(
"rt_band_new_offline: Out of memory allocating rt_band");
152 rterror(
"rt_band_new_offline: Could not set NODATA value");
160 pathlen = strlen(path);
163 rterror(
"rt_band_new_offline: Out of memory allocating offline path");
189 assert(band != NULL);
205 rterror(
"rt_band_duplicate: Out of memory allocating online band data");
220 rterror(
"rt_band_duplicate: Could not copy band");
230 assert(NULL != band);
267 assert(NULL != band);
271 RASTER_DEBUG(3,
"rt_band_get_ext_path: Band is not offline");
279 assert(NULL != band);
280 assert(NULL != bandnum);
285 RASTER_DEBUG(3,
"rt_band_get_ext_band_num: Band is not offline");
303 assert(NULL != band);
332 GDALDatasetH hdsSrc = NULL;
334 VRTDatasetH hdsDst = NULL;
335 VRTSourcedRasterBandH hbandDst = NULL;
338 double offset[2] = {0};
345 assert(band != NULL);
346 assert(band->
raster != NULL);
349 rterror(
"rt_band_load_offline_data: Band is not offline");
353 rterror(
"rt_band_load_offline_data: Offline band does not a have a specified file");
359 rterror(
"rt_band_load_offline_data: Access to offline bands disabled");
368 if (hdsSrc == NULL) {
369 rterror(
"rt_band_load_offline_data: Cannot open offline raster: %s", band->
data.
offline.path);
374 nband = GDALGetRasterCount(hdsSrc);
376 rterror(
"rt_band_load_offline_data: No bands found in offline raster: %s", band->
data.
offline.path);
382 rterror(
"rt_band_load_offline_data: Specified band %d not found in offline raster: %s", band->
data.
offline.bandNum, band->
data.
offline.path);
389 RASTER_DEBUGF(3,
"Raster geotransform (%f, %f, %f, %f, %f, %f)",
390 gt[0], gt[1], gt[2], gt[3], gt[4], gt[5]);
393 if (GDALGetGeoTransform(hdsSrc, ogt) != CE_None) {
394 RASTER_DEBUG(4,
"Using default geotransform matrix (0, 1, 0, 0, 0, -1)");
402 RASTER_DEBUGF(3,
"Offline geotransform (%f, %f, %f, %f, %f, %f)",
403 ogt[0], ogt[1], ogt[2], ogt[3], ogt[4], ogt[5]);
413 rterror(
"rt_band_load_offline_data: Could not test alignment of in-db representation of out-db raster");
418 rtwarn(
"The in-db representation of the out-db raster is not aligned. Band data may be incorrect");
425 &(offset[0]), &(offset[1]),
433 GDALSetGeoTransform(hdsDst, gt);
440 hbandDst = (VRTSourcedRasterBandH) GDALGetRasterBand(hdsDst, 1);
443 GDALSetRasterNoDataValue(hbandDst, band->
nodataval);
446 hbandDst, GDALGetRasterBand(hdsSrc, band->
data.
offline.bandNum + 1),
447 fabs(offset[0]), fabs(offset[1]),
451 "near", VRT_NODATA_UNSET
455 VRTFlushCache(hdsDst);
472 rterror(
"rt_band_load_offline_data: Cannot load data from offline raster: %s", band->
data.
offline.path);
478 rterror(
"rt_band_load_offline_data: Cannot load data from offline raster: %s", band->
data.
offline.path);
500 assert(NULL != band);
509 assert(NULL != band);
518 assert(NULL != band);
527 assert(NULL != band);
535 assert(NULL != band);
542 assert(NULL != band);
550 assert(NULL != band);
556 RASTER_DEBUG(3,
"Setting isnodata to FALSE as band no longer has NODATA");
563 assert(NULL != band);
570 rterror(
"rt_band_set_isnodata_flag: Cannot set isnodata flag as band has no NODATA");
582 assert(NULL != band);
602 int32_t checkvalint = 0;
604 float checkvalfloat = 0;
605 double checkvaldouble = 0;
607 assert(NULL != band);
609 if (converted != NULL)
674 rterror(
"rt_band_set_nodata: Unknown pixeltype %d", pixtype);
690 checkvalint, checkvaluint,
691 checkvalfloat, checkvaldouble,
693 ) && converted != NULL) {
730 assert(NULL != band);
731 assert(vals != NULL && len > 0);
736 rterror(
"rt_band_set_pixel_line not implemented yet for OFFDB bands");
744 x < 0 || x >= band->
width ||
745 y < 0 || y >= band->
height 747 rterror(
"rt_band_set_pixel_line: Coordinates out of range (%d, %d) vs (%d, %d)", x, y, band->
width, band->
height);
752 offset = x + (y * band->
width);
757 rterror(
"rt_band_set_pixel_line: Could not apply pixels as values length exceeds end of data");
769 memcpy(ptr, vals, size * len);
773 uint16_t *ptr = (uint16_t *) data;
775 memcpy(ptr, vals, size * len);
779 int16_t *ptr = (int16_t *) data;
781 memcpy(ptr, vals, size * len);
787 memcpy(ptr, vals, size * len);
791 int32_t *ptr = (int32_t *) data;
793 memcpy(ptr, vals, size * len);
797 float *ptr = (
float *) data;
799 memcpy(ptr, vals, size * len);
803 double *ptr = (
double *) data;
805 memcpy(ptr, vals, size * len);
809 rterror(
"rt_band_set_pixel_line: Unknown pixeltype %d", pixtype);
814 #if POSTGIS_DEBUG_LEVEL > 0 848 unsigned char*
data = NULL;
851 int32_t checkvalint = 0;
853 float checkvalfloat = 0;
854 double checkvaldouble = 0;
856 assert(NULL != band);
858 if (converted != NULL)
862 rterror(
"rt_band_set_pixel not implemented yet for OFFDB bands");
869 x < 0 || x >= band->
width ||
870 y < 0 || y >= band->
height 872 rterror(
"rt_band_set_pixel: Coordinates out of range");
884 #if POSTGIS_RASTER_WARN_ON_TRUNCATION > 0 885 rtwarn(
"Value for pixel %d x %d has been corrected as clamped value becomes NODATA", x, y);
889 if (converted != NULL)
895 offset = x + (y * band->
width);
900 checkvalint = data[offset];
905 checkvalint = data[offset];
910 checkvalint = data[offset];
915 checkvalint = (int8_t) data[offset];
920 checkvalint = data[offset];
924 int16_t *ptr = (int16_t*) data;
926 checkvalint = (int16_t) ptr[offset];
930 uint16_t *ptr = (uint16_t*) data;
932 checkvalint = ptr[offset];
936 int32_t *ptr = (int32_t*) data;
938 checkvalint = (int32_t) ptr[offset];
944 checkvaluint = ptr[offset];
948 float *ptr = (
float*) data;
950 checkvalfloat = ptr[offset];
954 double *ptr = (
double*) data;
956 checkvaldouble = ptr[offset];
960 rterror(
"rt_band_set_pixel: Unknown pixeltype %d", pixtype);
967 RASTER_DEBUG(3,
"Band has a value that is not NODATA. Setting isnodata to FALSE");
974 checkvalint, checkvaluint,
975 checkvalfloat, checkvaldouble,
977 ) && converted != NULL) {
1008 void **vals, uint16_t *nvals
1014 uint16_t _nvals = 0;
1018 assert(NULL != band);
1019 assert(vals != NULL && nvals != NULL);
1025 x < 0 || x >= band->
width ||
1026 y < 0 || y >= band->
height 1028 rtwarn(
"Attempting to get pixel values with out of range raster coordinates: (%d, %d)", x, y);
1037 rterror(
"rt_band_get_pixel_line: Cannot get band data");
1042 offset = x + (y * band->
width);
1052 if (((
int) (offset + _nvals)) > maxlen) {
1053 _nvals = maxlen - offset;
1054 rtwarn(
"Limiting returning number values to %d", _nvals);
1058 ptr = data + (offset * pixsize);
1060 _vals =
rtalloc(_nvals * pixsize);
1061 if (_vals == NULL) {
1062 rterror(
"rt_band_get_pixel_line: Could not allocate memory for pixel values");
1067 memcpy(_vals, ptr, _nvals * pixsize);
1098 assert(NULL != band);
1099 assert(NULL != value);
1106 x < 0 || x >= band->
width ||
1107 y < 0 || y >= band->
height 1109 rtwarn(
"Attempting to get pixel value with out of range raster coordinates: (%d, %d)", x, y);
1115 RASTER_DEBUG(3,
"Band's isnodata flag is TRUE. Returning NODATA value");
1117 if (nodata != NULL) *nodata = 1;
1123 rterror(
"rt_band_get_pixel: Cannot get band data");
1128 offset = x + (y * band->
width);
1134 #ifdef OPTIMIZE_SPACE 1136 int byteOffset = offset / 8;
1137 int bitOffset = offset % 8;
1141 *value = getBits(data, val, 1, bitOffset);
1146 #ifdef OPTIMIZE_SPACE 1148 int byteOffset = offset / 4;
1149 int bitOffset = offset % 4;
1153 *value = getBits(data, val, 2, bitOffset);
1158 #ifdef OPTIMIZE_SPACE 1160 int byteOffset = offset / 2;
1161 int bitOffset = offset % 2;
1165 *value = getBits(data, val, 2, bitOffset);
1170 int8_t val = data[offset];
1180 int16_t *ptr = (int16_t*) data;
1181 *value = ptr[offset];
1185 uint16_t *ptr = (uint16_t*) data;
1186 *value = ptr[offset];
1190 int32_t *ptr = (int32_t*) data;
1191 *value = ptr[offset];
1196 *value = ptr[offset];
1200 float *ptr = (
float*) data;
1201 *value = ptr[offset];
1205 double *ptr = (
double*) data;
1206 *value = ptr[offset];
1210 rterror(
"rt_band_get_pixel: Unknown pixeltype %d", pixtype);
1216 if (band->
hasnodata && nodata != NULL) {
1244 uint16_t distancex, uint16_t distancey,
1245 int exclude_nodata_value,
1249 int extent[4] = {0};
1250 int max_extent[4] = {0};
1268 assert(NULL != band);
1269 assert(NULL != npixels);
1274 distance[0] = distancex;
1275 distance[1] = distancey;
1278 if (!distance[0] && !distance[1])
1282 RASTER_DEBUGF(4,
"Distances: %d x %d", distance[0], distance[1]);
1286 exclude_nodata_value && (
1287 (x < 0 || x > band->
width) ||
1288 (y < 0 || y > band->
height)
1295 else if (x > band->
width)
1300 else if (y > band->
height)
1310 ((x < 0 && abs(x) > distance[0]) || (x - band->
width >= distance[0])) ||
1311 ((y < 0 && abs(y) > distance[1]) || (y - band->
height >= distance[1]))
1313 RASTER_DEBUG(4,
"No nearest pixels possible for provided pixel and distances");
1320 exclude_nodata_value =
FALSE;
1322 else if (exclude_nodata_value && band->
isnodata) {
1323 RASTER_DEBUG(4,
"No nearest pixels possible as band is NODATA and excluding NODATA values");
1333 b = abs(x - band->
width);
1342 b = abs(y - band->
height);
1348 RASTER_DEBUGF(4,
"Maximum distances: %d x %d", distance[0], distance[1]);
1361 max_extent[0] = x - distance[0];
1362 max_extent[1] = y - distance[1];
1363 max_extent[2] = x + distance[0];
1364 max_extent[3] = y + distance[1];
1366 max_extent[0], max_extent[1], max_extent[2], max_extent[3]);
1374 extent[0] = x - _d[0];
1375 extent[1] = y - _d[1];
1376 extent[2] = x + _d[0];
1377 extent[3] = y + _d[1];
1379 RASTER_DEBUGF(4,
"Processing distances: %d x %d", _d[0], _d[1]);
1381 extent[0], extent[1], extent[2], extent[3]);
1383 for (i = 0; i < 2; i++) {
1387 _max = extent[2] - extent[0] + 1;
1390 _max = extent[3] - extent[1] + 1;
1393 for (j = 0; j < 2; j++) {
1422 for (k = 0; k < _max; k++) {
1425 _x < max_extent[0] || _x > max_extent[2] ||
1426 _y < max_extent[1] || _y > max_extent[3]
1434 (_x < 0 || _x >= band->
width) ||
1435 (_y < 0 || _y >= band->
height)
1443 RASTER_DEBUGF(4,
"NODATA pixel outside band extent: (x, y, val) = (%d, %d, %f)", _x, _y, pixval);
1454 rterror(
"rt_band_get_nearest_pixel: Could not get pixel value");
1458 RASTER_DEBUGF(4,
"Pixel: (x, y, val) = (%d, %d, %f)", _x, _y, pixval);
1463 if (!exclude_nodata_value || (exclude_nodata_value && !isnodata)) {
1465 RASTER_DEBUGF(4,
"Adding pixel to set of nearest pixels: (x, y, val) = (%d, %d, %f)", _x, _y, pixval);
1468 if (*npixels == NULL)
1472 if (*npixels == NULL) {
1473 rterror(
"rt_band_get_nearest_pixel: Could not allocate memory for nearest pixel(s)");
1477 npixel = &((*npixels)[count - 1]);
1495 if (_d[0] >= distance[0] && _d[1] >= distance[1])
1497 else if (d0 && count)
1521 double *searchset,
int searchcount,
1535 assert(NULL != band);
1536 assert(NULL != pixels);
1537 assert(NULL != searchset && searchcount > 0);
1540 exclude_nodata_value =
FALSE;
1542 else if (exclude_nodata_value && band->
isnodata) {
1543 RASTER_DEBUG(4,
"Pixels cannot be searched as band is NODATA and excluding NODATA values");
1547 for (x = 0; x < band->
width; x++) {
1548 for (y = 0; y < band->
height; y++) {
1551 rterror(
"rt_band_get_pixel_of_value: Cannot get band pixel");
1554 else if (exclude_nodata_value && isnodata)
1557 for (i = 0; i < searchcount; i++) {
1562 if (
FLT_NEQ(pixval, searchset[i]) || !isequal)
1567 if (*pixels == NULL)
1571 if (*pixels == NULL) {
1572 rterror(
"rt_band_get_pixel_of_value: Could not allocate memory for pixel(s)");
1576 pixel = &((*pixels)[count - 1]);
1598 assert(NULL != band);
1599 assert(NULL != nodata);
1604 rterror(
"rt_band_get_nodata: Band has no NODATA value");
1613 assert(NULL != band);
1624 assert(NULL != band);
1636 for (i = 0; i < band->
width; i++) {
1637 for (j = 0; j < band->
height; j++) {
1640 rterror(
"rt_band_check_is_nodata: Cannot get band pixel");
1643 else if (!isnodata) {
1668 assert(NULL != band);
1685 return isequal ? 1 : 0;
1704 double *newval,
int *corrected
1708 assert(NULL != band);
1709 assert(NULL != newval);
1711 if (corrected != NULL)
1777 *newval += FLT_EPSILON;
1779 *newval -= FLT_EPSILON;
1784 rterror(
"rt_band_corrected_clamped_value: Unknown pixeltype %d", band->
pixtype);
1788 if (corrected != NULL)
rt_errorstate rt_band_set_pixel(rt_band band, int x, int y, double val, int *converted)
Set single pixel's value.
char enable_outdb_rasters
int32_t rt_util_clamp_to_32BSI(double value)
rt_errorstate rt_band_set_nodata(rt_band band, double val, int *converted)
Set nodata value.
uint32_t rt_util_clamp_to_32BUI(double value)
int rt_util_gdal_register_all(int force_register_all)
rt_errorstate rt_raster_same_alignment(rt_raster rast1, rt_raster rast2, int *aligned, char **reason)
rt_band rt_band_new_offline(uint16_t width, uint16_t height, rt_pixtype pixtype, uint32_t hasnodata, double nodataval, uint8_t bandNum, const char *path)
Create an out-db rt_band.
struct rt_pixel_t * rt_pixel
int rt_band_get_hasnodata_flag(rt_band band)
Get hasnodata flag value.
void rt_raster_set_geotransform_matrix(rt_raster raster, double *gt)
Set raster's geotransform using 6-element array.
void rt_raster_get_geotransform_matrix(rt_raster raster, double *gt)
Get 6-element array of raster geotransform matrix.
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.
rt_pixtype rt_band_get_pixtype(rt_band band)
Return pixeltype of this band.
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.
uint16_t rt_band_get_width(rt_band band)
Return width of this band.
int rt_band_check_is_nodata(rt_band band)
Returns TRUE if the band is only nodata values.
rt_errorstate rt_band_get_pixel_line(rt_band band, int x, int y, uint16_t len, void **vals, uint16_t *nvals)
Get values of multiple pixels.
void rt_band_set_ownsdata_flag(rt_band band, int flag)
uint16_t rt_util_clamp_to_16BUI(double value)
rt_errorstate rt_band_get_ext_band_num(rt_band band, uint8_t *bandnum)
Return bands' external band number (only valid when rt_band_is_offline returns non-zero).
rt_errorstate rt_band_set_pixel_line(rt_band band, int x, int y, void *vals, uint32_t len)
Set values of multiple pixels.
GDALDataType rt_util_pixtype_to_gdal_datatype(rt_pixtype pt)
Convert rt_pixtype to GDALDataType.
void rtwarn(const char *fmt,...)
rt_band rt_band_duplicate(rt_band band)
Create a new band duplicated from source band.
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.
rt_errorstate rt_band_get_pixel(rt_band band, int x, int y, double *value, int *nodata)
Get pixel value.
double rt_pixtype_get_min_value(rt_pixtype pixtype)
Return minimum value possible for pixel type.
void rt_raster_set_srid(rt_raster raster, int32_t srid)
Set raster's SRID.
#define RASTER_DEBUGF(level, msg,...)
void rt_raster_destroy(rt_raster raster)
Release memory associated to a raster.
rt_errorstate rt_raster_geopoint_to_cell(rt_raster raster, double xw, double yw, double *xr, double *yr, double *igt)
Convert an xw, yw map point to a xr, yr raster point.
rt_raster rt_raster_new(uint32_t width, uint32_t height)
Construct a raster with given dimensions.
Datum distance(PG_FUNCTION_ARGS)
uint8_t rt_util_clamp_to_4BUI(double value)
uint8_t rt_util_clamp_to_8BUI(double value)
void rt_band_destroy(rt_band band)
Destroy a raster band.
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)
rt_errorstate rt_band_set_isnodata_flag(rt_band band, int flag)
Set isnodata flag value.
int rt_band_clamped_value_is_nodata(rt_band band, double val)
Compare clamped value to band's clamped NODATA value.
void rtdealloc(void *mem)
const char * rt_band_get_ext_path(rt_band band)
Return band's external path (only valid when rt_band_is_offline returns non-zero).
rt_errorstate rt_band_corrected_clamped_value(rt_band band, double val, double *newval, int *corrected)
Correct value when clamped value is equal to clamped NODATA value.
void rt_band_set_hasnodata_flag(rt_band band, int flag)
Set hasnodata flag value.
uint16_t rt_band_get_height(rt_band band)
Return height of this band.
#define RASTER_DEBUG(level, msg)
This library is the generic raster handling section of PostGIS.
const char * rt_pixtype_name(rt_pixtype pixtype)
int rt_band_get_ownsdata_flag(rt_band band)
Return 0 (FALSE) or non-zero (TRUE) indicating if rt_band is responsible for managing the memory for ...
uint8_t rt_util_clamp_to_2BUI(double value)
float rt_util_clamp_to_32F(double value)
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.
rt_raster rt_raster_from_gdal_dataset(GDALDatasetH ds)
Return a raster from a GDAL dataset.
rt_errorstate rt_band_load_offline_data(rt_band band)
Load offline band's data.
int rt_band_is_offline(rt_band band)
Return non-zero if the given band data is on the filesystem.
void * rt_band_get_data(rt_band band)
Get pointer to raster band data.
double rt_band_get_min_value(rt_band band)
Returns the minimal possible value for the band according to the pixel type.
GDALDatasetH rt_util_gdal_open(const char *fn, GDALAccess fn_access, int shared)
rt_errorstate rt_pixtype_compare_clamped_values(rt_pixtype pixtype, double val, double refval, int *isequal)
Test to see if two values are equal when clamped.
int rt_band_get_pixel_of_value(rt_band band, int exclude_nodata_value, double *searchset, int searchcount, rt_pixel *pixels)
Search band for pixel(s) with search values.
int rt_band_get_isnodata_flag(rt_band band)
Get isnodata flag value.
rt_errorstate rt_band_get_nodata(rt_band band, double *nodata)
Get NODATA value.
int16_t rt_util_clamp_to_16BSI(double value)