PostGIS  2.1.10dev-r@@SVN_REVISION@@
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.

Parameters
band: the band to get nearest pixel(s) from
x: pixel column (0-based)
y: pixel row (0-based)
distancex: the number of pixels around the specified pixel along the X axis
distancey: the number of pixels around the specified pixel along the Y axis
exclude_nodata_value: if non-zero, ignore nodata values to check for pixels with value
npixels: return set of rt_pixel object or NULL
Returns
-1 on error, otherwise the number of rt_pixel objects in npixels
Parameters
band: the band to get nearest pixel(s) from
x: the column of the pixel (0-based)
y: the line of the pixel (0-based)
distancex: the number of pixels around the specified pixel along the X axis
distancey: the number of pixels around the specified pixel along the Y axis
exclude_nodata_value: if non-zero, ignore nodata values to check for pixels with value
npixels: return set of rt_pixel object or NULL
Returns
-1 on error, otherwise the number of rt_pixel objects in npixels

Definition at line 2702 of file rt_api.c.

References genraster::count, distance(), ES_NONE, FALSE, rt_band_t::hasnodata, rt_band_t::height, rt_band_t::isnodata, rt_pixel_t::nodata, rt_band_t::nodataval, rt_band_t::pixtype, pixval::pixval, RASTER_DEBUG, RASTER_DEBUGF, rt_band_get_pixel(), rt_pixtype_get_min_value(), rt_pixtype_name(), rtalloc(), rtdealloc(), rterror(), rtrealloc(), rt_pixel_t::value, rt_band_t::width, rt_pixel_t::x, and rt_pixel_t::y.

Referenced by RASTER_nearestValue(), RASTER_neighborhood(), rt_raster_iterator(), and test_band_get_nearest_pixel().

2708  {
2709  rt_pixel npixel = NULL;
2710  int extent[4] = {0};
2711  int max_extent[4] = {0};
2712  int d0 = 0;
2713  int distance[2] = {0};
2714  uint32_t _d[2] = {0};
2715  uint32_t i = 0;
2716  uint32_t j = 0;
2717  uint32_t k = 0;
2718  int _max = 0;
2719  int _x = 0;
2720  int _y = 0;
2721  int *_min = NULL;
2722  double pixval = 0;
2723  double minval = 0;
2724  uint32_t count = 0;
2725  int isnodata = 0;
2726 
2727  int inextent = 0;
2728 
2729  assert(NULL != band);
2730  assert(NULL != npixels);
2731 
2732  RASTER_DEBUG(3, "Starting");
2733 
2734  /* process distance */
2735  distance[0] = distancex;
2736  distance[1] = distancey;
2737 
2738  /* no distance, means get nearest pixels and return */
2739  if (!distance[0] && !distance[1])
2740  d0 = 1;
2741 
2742  RASTER_DEBUGF(4, "Selected pixel: %d x %d", x, y);
2743  RASTER_DEBUGF(4, "Distances: %d x %d", distance[0], distance[1]);
2744 
2745  /* shortcuts if outside band extent */
2746  if (
2747  exclude_nodata_value && (
2748  (x < 0 || x > band->width) ||
2749  (y < 0 || y > band->height)
2750  )
2751  ) {
2752  /* no distances specified, jump to pixel close to extent */
2753  if (d0) {
2754  if (x < 0)
2755  x = -1;
2756  else if (x > band->width)
2757  x = band->width;
2758 
2759  if (y < 0)
2760  y = -1;
2761  else if (y > band->height)
2762  y = band->height;
2763 
2764  RASTER_DEBUGF(4, "Moved selected pixel: %d x %d", x, y);
2765  }
2766  /*
2767  distances specified
2768  if distances won't capture extent of band, return 0
2769  */
2770  else if (
2771  ((x < 0 && abs(x) > distance[0]) || (x - band->width >= distance[0])) ||
2772  ((y < 0 && abs(y) > distance[1]) || (y - band->height >= distance[1]))
2773  ) {
2774  RASTER_DEBUG(4, "No nearest pixels possible for provided pixel and distances");
2775  return 0;
2776  }
2777  }
2778 
2779  /* no NODATA, exclude is FALSE */
2780  if (!band->hasnodata)
2781  exclude_nodata_value = FALSE;
2782  /* band is NODATA and excluding NODATA */
2783  else if (exclude_nodata_value && band->isnodata) {
2784  RASTER_DEBUG(4, "No nearest pixels possible as band is NODATA and excluding NODATA values");
2785  return 0;
2786  }
2787 
2788  /* determine the maximum distance to prevent an infinite loop */
2789  if (d0) {
2790  int a, b;
2791 
2792  /* X axis */
2793  a = abs(x);
2794  b = abs(x - band->width);
2795 
2796  if (a > b)
2797  distance[0] = a;
2798  else
2799  distance[0] = b;
2800 
2801  /* Y axis */
2802  a = abs(y);
2803  b = abs(y - band->height);
2804  if (a > b)
2805  distance[1] = a;
2806  else
2807  distance[1] = b;
2808 
2809  RASTER_DEBUGF(4, "Maximum distances: %d x %d", distance[0], distance[1]);
2810  }
2811 
2812  /* minimum possible value for pixel type */
2813  minval = rt_pixtype_get_min_value(band->pixtype);
2814  RASTER_DEBUGF(4, "pixtype: %s", rt_pixtype_name(band->pixtype));
2815  RASTER_DEBUGF(4, "minval: %f", minval);
2816 
2817  /* set variables */
2818  count = 0;
2819  *npixels = NULL;
2820 
2821  /* maximum extent */
2822  max_extent[0] = x - distance[0]; /* min X */
2823  max_extent[1] = y - distance[1]; /* min Y */
2824  max_extent[2] = x + distance[0]; /* max X */
2825  max_extent[3] = y + distance[1]; /* max Y */
2826  RASTER_DEBUGF(4, "Maximum Extent: (%d, %d, %d, %d)",
2827  max_extent[0], max_extent[1], max_extent[2], max_extent[3]);
2828 
2829  _d[0] = 0;
2830  _d[1] = 0;
2831  do {
2832  _d[0]++;
2833  _d[1]++;
2834 
2835  extent[0] = x - _d[0]; /* min x */
2836  extent[1] = y - _d[1]; /* min y */
2837  extent[2] = x + _d[0]; /* max x */
2838  extent[3] = y + _d[1]; /* max y */
2839 
2840  RASTER_DEBUGF(4, "Processing distances: %d x %d", _d[0], _d[1]);
2841  RASTER_DEBUGF(4, "Extent: (%d, %d, %d, %d)",
2842  extent[0], extent[1], extent[2], extent[3]);
2843 
2844  for (i = 0; i < 2; i++) {
2845 
2846  /* by row */
2847  if (i < 1)
2848  _max = extent[2] - extent[0] + 1;
2849  /* by column */
2850  else
2851  _max = extent[3] - extent[1] + 1;
2852  _max = abs(_max);
2853 
2854  for (j = 0; j < 2; j++) {
2855  /* by row */
2856  if (i < 1) {
2857  _x = extent[0];
2858  _min = &_x;
2859 
2860  /* top row */
2861  if (j < 1)
2862  _y = extent[1];
2863  /* bottom row */
2864  else
2865  _y = extent[3];
2866  }
2867  /* by column */
2868  else {
2869  _y = extent[1] + 1;
2870  _min = &_y;
2871 
2872  /* left column */
2873  if (j < 1) {
2874  _x = extent[0];
2875  _max -= 2;
2876  }
2877  /* right column */
2878  else
2879  _x = extent[2];
2880  }
2881 
2882  RASTER_DEBUGF(4, "_min, _max: %d, %d", *_min, _max);
2883  for (k = 0; k < _max; k++) {
2884  /* check that _x and _y are not outside max extent */
2885  if (
2886  _x < max_extent[0] || _x > max_extent[2] ||
2887  _y < max_extent[1] || _y > max_extent[3]
2888  ) {
2889  (*_min)++;
2890  continue;
2891  }
2892 
2893  /* outside band extent, set to NODATA */
2894  if (
2895  (_x < 0 || _x >= band->width) ||
2896  (_y < 0 || _y >= band->height)
2897  ) {
2898  /* no NODATA, set to minimum possible value */
2899  if (!band->hasnodata)
2900  pixval = minval;
2901  /* has NODATA, use NODATA */
2902  else
2903  pixval = band->nodataval;
2904  RASTER_DEBUGF(4, "NODATA pixel outside band extent: (x, y, val) = (%d, %d, %f)", _x, _y, pixval);
2905  inextent = 0;
2906  isnodata = 1;
2907  }
2908  else {
2909  if (rt_band_get_pixel(
2910  band,
2911  _x, _y,
2912  &pixval,
2913  &isnodata
2914  ) != ES_NONE) {
2915  rterror("rt_band_get_nearest_pixel: Could not get pixel value");
2916  if (count) rtdealloc(*npixels);
2917  return -1;
2918  }
2919  RASTER_DEBUGF(4, "Pixel: (x, y, val) = (%d, %d, %f)", _x, _y, pixval);
2920  inextent = 1;
2921  }
2922 
2923  /* use pixval? */
2924  if (!exclude_nodata_value || (exclude_nodata_value && !isnodata)) {
2925  /* add pixel to result set */
2926  RASTER_DEBUGF(4, "Adding pixel to set of nearest pixels: (x, y, val) = (%d, %d, %f)", _x, _y, pixval);
2927  count++;
2928 
2929  if (*npixels == NULL)
2930  *npixels = (rt_pixel) rtalloc(sizeof(struct rt_pixel_t) * count);
2931  else
2932  *npixels = (rt_pixel) rtrealloc(*npixels, sizeof(struct rt_pixel_t) * count);
2933  if (*npixels == NULL) {
2934  rterror("rt_band_get_nearest_pixel: Could not allocate memory for nearest pixel(s)");
2935  return -1;
2936  }
2937 
2938  npixel = &((*npixels)[count - 1]);
2939  npixel->x = _x;
2940  npixel->y = _y;
2941  npixel->value = pixval;
2942 
2943  /* special case for when outside band extent */
2944  if (!inextent && !band->hasnodata)
2945  npixel->nodata = 1;
2946  else
2947  npixel->nodata = 0;
2948  }
2949 
2950  (*_min)++;
2951  }
2952  }
2953  }
2954 
2955  /* distance threshholds met */
2956  if (_d[0] >= distance[0] && _d[1] >= distance[1])
2957  break;
2958  else if (d0 && count)
2959  break;
2960  }
2961  while (1);
2962 
2963  RASTER_DEBUGF(3, "Nearest pixels in return: %d", count);
2964 
2965  return count;
2966 }
void rtdealloc(void *mem)
Definition: rt_api.c:882
const char * rt_pixtype_name(rt_pixtype pixtype)
Definition: rt_api.c:1168
rt_pixtype pixtype
Definition: rt_api.h:2239
uint16_t height
Definition: rt_api.h:2242
double value
Definition: rt_api.h:2263
double rt_pixtype_get_min_value(rt_pixtype pixtype)
Return minimum value possible for pixel type.
Definition: rt_api.c:1206
struct rt_pixel_t * rt_pixel
Definition: rt_api.h:135
tuple pixval
Definition: pixval.py:93
#define RASTER_DEBUG(level, msg)
Definition: rt_api.h:281
#define RASTER_DEBUGF(level, msg,...)
Definition: rt_api.h:285
Definition: pixval.py:1
rt_errorstate rt_band_get_pixel(rt_band band, int x, int y, double *value, int *nodata)
Get pixel value.
Definition: rt_api.c:2549
int count
Definition: genraster.py:57
double nodataval
Definition: rt_api.h:2246
uint8_t nodata
Definition: rt_api.h:2262
uint16_t width
Definition: rt_api.h:2241
tuple x
Definition: pixval.py:53
Datum distance(PG_FUNCTION_ARGS)
void * rtalloc(size_t size)
Raster core memory management functions.
Definition: rt_api.c:867
void rterror(const char *fmt,...)
Raster core error and info handlers.
Definition: rt_api.c:895
int32_t isnodata
Definition: rt_api.h:2244
#define FALSE
Definition: dbfopen.c:169
int32_t hasnodata
Definition: rt_api.h:2243
tuple y
Definition: pixval.py:54
void * rtrealloc(void *mem, size_t size)
Definition: rt_api.c:875

Here is the call graph for this function:

Here is the caller graph for this function: