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

◆ rt_band_get_pixel_bilinear()

rt_errorstate rt_band_get_pixel_bilinear ( rt_band  band,
double  xr,
double  yr,
double *  r_value,
int *  r_nodata 
)

Retrieve a point value from the raster using a world coordinate and bilinear interpolation.

Parameters
rast: the raster to read for values
bandnum: the band to read for the values
xw: x world coordinate in
yw: y world coordinate in
r_value: return pointer for point value
r_nodata: return pointer for if this is a nodata
Returns
ES_ERROR on error, otherwise ES_NONE

Definition at line 1435 of file rt_band.c.

1439{
1440 double xcenter, ycenter;
1441 double values[2][2];
1442 double nodatavalue = 0.0;
1443 int nodatas[2][2];
1444 int x[2][2];
1445 int y[2][2];
1446 int xcell, ycell;
1447 int xdir, ydir;
1448 int i, j;
1449 uint16_t width, height;
1450
1451 /* Cell coordinates */
1452 xcell = (int)floor(xr);
1453 ycell = (int)floor(yr);
1454 xcenter = xcell + 0.5;
1455 ycenter = ycell + 0.5;
1456
1457 /* Raster geometry */
1458 width = rt_band_get_width(band);
1459 height = rt_band_get_height(band);
1460
1461 /* Reject out-of-range sample */
1462 if(xcell < 0 || ycell < 0 || xcell >= width || ycell >= height) {
1463 rtwarn("Attempting to get pixel value with out of range raster coordinates: (%d, %d)", xcell, ycell);
1464 return ES_ERROR;
1465 }
1466
1467 /* Quadrant of 2x2 grid the raster coordinate falls in */
1468 xdir = xr < xcenter ? 1 : 0;
1469 ydir = yr < ycenter ? 1 : 0;
1470
1471 if (rt_band_get_hasnodata_flag(band) != FALSE) {
1472 rt_band_get_nodata(band, &nodatavalue);
1473 }
1474 else {
1475 nodatavalue = 0.0;
1476 }
1477
1478 /* Read the 2x2 values from the band */
1479 for (i = 0; i < 2; i++) {
1480 for (j = 0; j < 2; j++) {
1481 double value = nodatavalue;
1482 int nodata = 0;
1483 int xij = xcell + (i - xdir);
1484 int yij = ycell + (j - ydir);
1485
1486 if(xij < 0 || yij < 0 || xij >= width || yij >= height) {
1487 nodata = 1;
1488 }
1489 else {
1491 band, xij, yij,
1492 &value, &nodata
1493 );
1494 if (err != ES_NONE)
1495 nodata = 1;
1496 }
1497 x[i][j] = xij;
1498 y[i][j] = yij;
1499 values[i][j] = value;
1500 nodatas[i][j] = nodata;
1501 }
1502 }
1503
1504 /* Point falls in nodata cell, just return nodata */
1505 if (nodatas[xdir][ydir]) {
1506 *r_value = nodatavalue;
1507 *r_nodata = 1;
1508 return ES_NONE;
1509 }
1510
1511 /* Normalize raster coordinate to the bottom left */
1512 /* so we are working on a unit square */
1513 xr = xr - (x[0][0] + 0.5);
1514 yr = yr - (y[0][0] + 0.5);
1515
1516 /* Point is in cell with values, so we take nodata */
1517 /* neighbors off the table by matching them to the */
1518 /* most controlling cell */
1519 for (i = 0; i < 2; i++) {
1520 for (j = 0; j < 2; j++) {
1521 if (nodatas[i][j])
1522 values[i][j] = values[xdir][ydir];
1523 }
1524 }
1525
1526 /* Calculate bilinear value */
1527 /* https://en.wikipedia.org/wiki/Bilinear_interpolation#Unit_square */
1528 *r_nodata = 0;
1529 *r_value = values[0][0] * (1-xr) * (1-yr) +
1530 values[1][0] * (1-yr) * xr +
1531 values[0][1] * (1-xr) * yr +
1532 values[1][1] * xr * yr;
1533
1534 return ES_NONE;
1535}
#define FALSE
Definition dbfopen.c:72
void void void rtwarn(const char *fmt,...) __attribute__((format(printf
rt_errorstate
Enum definitions.
Definition librtcore.h:181
@ ES_NONE
Definition librtcore.h:182
@ ES_ERROR
Definition librtcore.h:183
int value
Definition genraster.py:62
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_errorstate rt_band_get_nodata(rt_band band, double *nodata)
Get NODATA value.
Definition rt_band.c:2067
uint16_t rt_band_get_height(rt_band band)
Return height of this band.
Definition rt_band.c:808

References ES_ERROR, ES_NONE, FALSE, rt_band_get_hasnodata_flag(), rt_band_get_height(), rt_band_get_nodata(), rt_band_get_pixel(), rt_band_get_width(), and rtwarn().

Referenced by rt_band_get_pixel_resample(), and test_raster_get_pixel_bilinear().

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