PostGIS  3.7.0dev-r@@SVN_REVISION@@

◆ 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
band: the band to read for values
xr: x unrounded raster coordinate
yr: y unrounded raster coordinate
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
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 1411 of file rt_band.c.

1415 {
1416  double xcenter, ycenter;
1417  double values[2][2];
1418  double nodatavalue = 0.0;
1419  int nodatas[2][2];
1420  int x[2][2];
1421  int y[2][2];
1422  int xcell, ycell;
1423  int xdir, ydir;
1424  int i, j;
1425  uint16_t width, height;
1426 
1427  /* Cell coordinates */
1428  xcell = (int)floor(xr);
1429  ycell = (int)floor(yr);
1430  xcenter = xcell + 0.5;
1431  ycenter = ycell + 0.5;
1432 
1433  /* Raster geometry */
1434  width = rt_band_get_width(band);
1435  height = rt_band_get_height(band);
1436 
1437  /* Reject out-of-range sample */
1438  if(xcell < 0 || ycell < 0 || xcell >= width || ycell >= height) {
1439  rtwarn("Attempting to get pixel value with out of range raster coordinates: (%d, %d)", xcell, ycell);
1440  return ES_ERROR;
1441  }
1442 
1443  /* Quadrant of 2x2 grid the raster coordinate falls in */
1444  xdir = xr < xcenter ? 1 : 0;
1445  ydir = yr < ycenter ? 1 : 0;
1446 
1448  rt_band_get_nodata(band, &nodatavalue);
1449  }
1450  else {
1451  nodatavalue = 0.0;
1452  }
1453 
1454  /* Read the 2x2 values from the band */
1455  for (i = 0; i < 2; i++) {
1456  for (j = 0; j < 2; j++) {
1457  double value = nodatavalue;
1458  int nodata = 0;
1459  int xij = xcell + (i - xdir);
1460  int yij = ycell + (j - ydir);
1461 
1462  if(xij < 0 || yij < 0 || xij >= width || yij >= height) {
1463  nodata = 1;
1464  }
1465  else {
1467  band, xij, yij,
1468  &value, &nodata
1469  );
1470  if (err != ES_NONE)
1471  nodata = 1;
1472  }
1473  x[i][j] = xij;
1474  y[i][j] = yij;
1475  values[i][j] = value;
1476  nodatas[i][j] = nodata;
1477  }
1478  }
1479 
1480  /* Point falls in nodata cell, just return nodata */
1481  if (nodatas[xdir][ydir]) {
1482  *r_value = nodatavalue;
1483  *r_nodata = 1;
1484  return ES_NONE;
1485  }
1486 
1487  /* Normalize raster coordinate to the bottom left */
1488  /* so we are working on a unit square */
1489  xr = xr - (x[0][0] + 0.5);
1490  yr = yr - (y[0][0] + 0.5);
1491 
1492  /* Point is in cell with values, so we take nodata */
1493  /* neighbors off the table by matching them to the */
1494  /* most controlling cell */
1495  for (i = 0; i < 2; i++) {
1496  for (j = 0; j < 2; j++) {
1497  if (nodatas[i][j])
1498  values[i][j] = values[xdir][ydir];
1499  }
1500  }
1501 
1502  /* Calculate bilinear value */
1503  /* https://en.wikipedia.org/wiki/Bilinear_interpolation#Unit_square */
1504  *r_nodata = 0;
1505  *r_value = values[0][0] * (1-xr) * (1-yr) +
1506  values[1][0] * (1-yr) * xr +
1507  values[0][1] * (1-xr) * yr +
1508  values[1][1] * xr * yr;
1509 
1510  return ES_NONE;
1511 }
#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
band
Definition: ovdump.py:58
uint16_t rt_band_get_width(rt_band band)
Return width of this band.
Definition: rt_band.c:791
int rt_band_get_hasnodata_flag(rt_band band)
Get hasnodata flag value.
Definition: rt_band.c:825
rt_errorstate rt_band_get_pixel(rt_band band, int x, int y, double *value, int *nodata)
Get pixel value.
Definition: rt_band.c:1527
rt_errorstate rt_band_get_nodata(rt_band band, double *nodata)
Get NODATA value.
Definition: rt_band.c:2038
uint16_t rt_band_get_height(rt_band band)
Return height of this band.
Definition: rt_band.c:800

References ovdump::band, 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(), rtwarn(), genraster::value, pixval::x, and pixval::y.

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: