PostGIS  3.4.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
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 1260 of file rt_band.c.

1264 {
1265  double xcenter, ycenter;
1266  double values[2][2];
1267  double nodatavalue = 0.0;
1268  int nodatas[2][2];
1269  int x[2][2];
1270  int y[2][2];
1271  int xcell, ycell;
1272  int xdir, ydir;
1273  int i, j;
1274  uint16_t width, height;
1275 
1276  /* Cell coordinates */
1277  xcell = (int)floor(xr);
1278  ycell = (int)floor(yr);
1279  xcenter = xcell + 0.5;
1280  ycenter = ycell + 0.5;
1281 
1282  /* Raster geometry */
1283  width = rt_band_get_width(band);
1284  height = rt_band_get_height(band);
1285 
1286  /* Reject out-of-range sample */
1287  if(xcell < 0 || ycell < 0 || xcell >= width || ycell >= height) {
1288  rtwarn("Attempting to get pixel value with out of range raster coordinates: (%d, %d)", xcell, ycell);
1289  return ES_ERROR;
1290  }
1291 
1292  /* Quadrant of 2x2 grid the raster coordinate falls in */
1293  xdir = xr < xcenter ? 1 : 0;
1294  ydir = yr < ycenter ? 1 : 0;
1295 
1297  rt_band_get_nodata(band, &nodatavalue);
1298  }
1299  else {
1300  nodatavalue = 0.0;
1301  }
1302 
1303  /* Read the 2x2 values from the band */
1304  for (i = 0; i < 2; i++) {
1305  for (j = 0; j < 2; j++) {
1306  double value = nodatavalue;
1307  int nodata = 0;
1308  int xij = xcell + (i - xdir);
1309  int yij = ycell + (j - ydir);
1310 
1311  if(xij < 0 || yij < 0 || xij >= width || yij >= height) {
1312  nodata = 1;
1313  }
1314  else {
1316  band, xij, yij,
1317  &value, &nodata
1318  );
1319  if (err != ES_NONE)
1320  nodata = 1;
1321  }
1322  x[i][j] = xij;
1323  y[i][j] = yij;
1324  values[i][j] = value;
1325  nodatas[i][j] = nodata;
1326  }
1327  }
1328 
1329  /* Point falls in nodata cell, just return nodata */
1330  if (nodatas[xdir][ydir]) {
1331  *r_value = nodatavalue;
1332  *r_nodata = 1;
1333  return ES_NONE;
1334  }
1335 
1336  /* Normalize raster coordinate to the bottom left */
1337  /* so we are working on a unit square */
1338  xr = xr - (x[0][0] + 0.5);
1339  yr = yr - (y[0][0] + 0.5);
1340 
1341  /* Point is in cell with values, so we take nodata */
1342  /* neighbors off the table by matching them to the */
1343  /* most controlling cell */
1344  for (i = 0; i < 2; i++) {
1345  for (j = 0; j < 2; j++) {
1346  if (nodatas[i][j])
1347  values[i][j] = values[xdir][ydir];
1348  }
1349  }
1350 
1351  /* Calculate bilinear value */
1352  /* https://en.wikipedia.org/wiki/Bilinear_interpolation#Unit_square */
1353  *r_nodata = 0;
1354  *r_value = values[0][0] * (1-xr) * (1-yr) +
1355  values[1][0] * (1-yr) * xr +
1356  values[0][1] * (1-xr) * yr +
1357  values[1][1] * xr * yr;
1358 
1359  return ES_NONE;
1360 }
#define FALSE
Definition: dbfopen.c:72
void rtwarn(const char *fmt,...)
Definition: rt_context.c:244
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:640
int rt_band_get_hasnodata_flag(rt_band band)
Get hasnodata flag value.
Definition: rt_band.c:674
rt_errorstate rt_band_get_pixel(rt_band band, int x, int y, double *value, int *nodata)
Get pixel value.
Definition: rt_band.c:1376
rt_errorstate rt_band_get_nodata(rt_band band, double *nodata)
Get NODATA value.
Definition: rt_band.c:1887
uint16_t rt_band_get_height(rt_band band)
Return height of this band.
Definition: rt_band.c:649

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: