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

◆ rt_band_get_nearest_pixel()

uint32_t 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 1680 of file rt_band.c.

1686 {
1687 rt_pixel npixel = NULL;
1688 int extent[4] = {0};
1689 int max_extent[4] = {0};
1690 int d0 = 0;
1691 uint32_t distance[2] = {0};
1692 uint32_t _d[2] = {0};
1693 uint32_t i = 0;
1694 uint32_t j = 0;
1695 uint32_t k = 0;
1696 int _max = 0;
1697 int _x = 0;
1698 int _y = 0;
1699 int *_min = NULL;
1700 double pixval = 0;
1701 double minval = 0;
1702 uint32_t count = 0;
1703 int isnodata = 0;
1704
1705 int inextent = 0;
1706
1707 assert(NULL != band);
1708 assert(NULL != npixels);
1709
1710 RASTER_DEBUG(3, "Starting");
1711
1712 /* process distance */
1713 distance[0] = distancex;
1714 distance[1] = distancey;
1715
1716 /* no distance, means get nearest pixels and return */
1717 if (!distance[0] && !distance[1])
1718 d0 = 1;
1719
1720 RASTER_DEBUGF(4, "Selected pixel: %d x %d", x, y);
1721 RASTER_DEBUGF(4, "Distances: %d x %d", distance[0], distance[1]);
1722
1723 /* shortcuts if outside band extent */
1724 if (
1725 exclude_nodata_value && (
1726 (x < 0 || x > band->width) ||
1727 (y < 0 || y > band->height)
1728 )
1729 ) {
1730 /* no distances specified, jump to pixel close to extent */
1731 if (d0) {
1732 if (x < 0)
1733 x = -1;
1734 else if (x > band->width)
1735 x = band->width;
1736
1737 if (y < 0)
1738 y = -1;
1739 else if (y > band->height)
1740 y = band->height;
1741
1742 RASTER_DEBUGF(4, "Moved selected pixel: %d x %d", x, y);
1743 }
1744 /*
1745 distances specified
1746 if distances won't capture extent of band, return 0
1747 */
1748 else if (
1749 ((x < 0 && (uint32_t) abs(x) > distance[0]) || (x - band->width >= (int)distance[0])) ||
1750 ((y < 0 && (uint32_t) abs(y) > distance[1]) || (y - band->height >= (int)distance[1]))
1751 ) {
1752 RASTER_DEBUG(4, "No nearest pixels possible for provided pixel and distances");
1753 return 0;
1754 }
1755 }
1756
1757 /* no NODATA, exclude is FALSE */
1758 if (!band->hasnodata)
1759 exclude_nodata_value = FALSE;
1760 /* band is NODATA and excluding NODATA */
1761 else if (exclude_nodata_value && band->isnodata) {
1762 RASTER_DEBUG(4, "No nearest pixels possible as band is NODATA and excluding NODATA values");
1763 return 0;
1764 }
1765
1766 /* determine the maximum distance to prevent an infinite loop */
1767 if (d0) {
1768 int a, b;
1769
1770 /* X axis */
1771 a = abs(x);
1772 b = abs(x - band->width);
1773
1774 if (a > b)
1775 distance[0] = a;
1776 else
1777 distance[0] = b;
1778
1779 /* Y axis */
1780 a = abs(y);
1781 b = abs(y - band->height);
1782 if (a > b)
1783 distance[1] = a;
1784 else
1785 distance[1] = b;
1786
1787 RASTER_DEBUGF(4, "Maximum distances: %d x %d", distance[0], distance[1]);
1788 }
1789
1790 /* minimum possible value for pixel type */
1791 minval = rt_pixtype_get_min_value(band->pixtype);
1792 RASTER_DEBUGF(4, "pixtype: %s", rt_pixtype_name(band->pixtype));
1793 RASTER_DEBUGF(4, "minval: %f", minval);
1794
1795 /* set variables */
1796 count = 0;
1797 *npixels = NULL;
1798
1799 /* maximum extent */
1800 max_extent[0] = x - (int)distance[0]; /* min X */
1801 max_extent[1] = y - (int)distance[1]; /* min Y */
1802 max_extent[2] = x + (int)distance[0]; /* max X */
1803 max_extent[3] = y + (int)distance[1]; /* max Y */
1804 RASTER_DEBUGF(4, "Maximum Extent: (%d, %d, %d, %d)",
1805 max_extent[0], max_extent[1], max_extent[2], max_extent[3]);
1806
1807 _d[0] = 0;
1808 _d[1] = 0;
1809 do {
1810 _d[0]++;
1811 _d[1]++;
1812
1813 extent[0] = x - (int)_d[0]; /* min x */
1814 extent[1] = y - (int)_d[1]; /* min y */
1815 extent[2] = x + (int)_d[0]; /* max x */
1816 extent[3] = y + (int)_d[1]; /* max y */
1817
1818 RASTER_DEBUGF(4, "Processing distances: %d x %d", _d[0], _d[1]);
1819 RASTER_DEBUGF(4, "Extent: (%d, %d, %d, %d)",
1820 extent[0], extent[1], extent[2], extent[3]);
1821
1822 for (i = 0; i < 2; i++) {
1823
1824 /* by row */
1825 if (i < 1)
1826 _max = extent[2] - extent[0] + 1;
1827 /* by column */
1828 else
1829 _max = extent[3] - extent[1] + 1;
1830 _max = abs(_max);
1831
1832 for (j = 0; j < 2; j++) {
1833 /* by row */
1834 if (i < 1) {
1835 _x = extent[0];
1836 _min = &_x;
1837
1838 /* top row */
1839 if (j < 1)
1840 _y = extent[1];
1841 /* bottom row */
1842 else
1843 _y = extent[3];
1844 }
1845 /* by column */
1846 else {
1847 _y = extent[1] + 1;
1848 _min = &_y;
1849
1850 /* left column */
1851 if (j < 1) {
1852 _x = extent[0];
1853 _max -= 2;
1854 }
1855 /* right column */
1856 else
1857 _x = extent[2];
1858 }
1859
1860 RASTER_DEBUGF(4, "_min, _max: %d, %d", *_min, _max);
1861 for (k = 0; k < (uint32_t) _max; k++) {
1862 /* check that _x and _y are not outside max extent */
1863 if (
1864 _x < max_extent[0] || _x > max_extent[2] ||
1865 _y < max_extent[1] || _y > max_extent[3]
1866 ) {
1867 (*_min)++;
1868 continue;
1869 }
1870
1871 /* outside band extent, set to NODATA */
1872 if (
1873 (_x < 0 || _x >= band->width) ||
1874 (_y < 0 || _y >= band->height)
1875 ) {
1876 /* no NODATA, set to minimum possible value */
1877 if (!band->hasnodata)
1878 pixval = minval;
1879 /* has NODATA, use NODATA */
1880 else
1881 pixval = band->nodataval;
1882 RASTER_DEBUGF(4, "NODATA pixel outside band extent: (x, y, val) = (%d, %d, %f)", _x, _y, pixval);
1883 inextent = 0;
1884 isnodata = 1;
1885 }
1886 else {
1888 band,
1889 _x, _y,
1890 &pixval,
1891 &isnodata
1892 ) != ES_NONE) {
1893 rterror("rt_band_get_nearest_pixel: Could not get pixel value");
1894 if (count) rtdealloc(*npixels);
1895 return -1;
1896 }
1897 RASTER_DEBUGF(4, "Pixel: (x, y, val) = (%d, %d, %f)", _x, _y, pixval);
1898 inextent = 1;
1899 }
1900
1901 /* use pixval? */
1902 if (!exclude_nodata_value || (exclude_nodata_value && !isnodata)) {
1903 /* add pixel to result set */
1904 RASTER_DEBUGF(4, "Adding pixel to set of nearest pixels: (x, y, val) = (%d, %d, %f)", _x, _y, pixval);
1905 count++;
1906
1907 if (*npixels == NULL)
1908 *npixels = (rt_pixel) rtalloc(sizeof(struct rt_pixel_t) * count);
1909 else
1910 *npixels = (rt_pixel) rtrealloc(*npixels, sizeof(struct rt_pixel_t) * count);
1911 if (*npixels == NULL) {
1912 rterror("rt_band_get_nearest_pixel: Could not allocate memory for nearest pixel(s)");
1913 return -1;
1914 }
1915
1916 npixel = &((*npixels)[count - 1]);
1917 npixel->x = _x;
1918 npixel->y = _y;
1919 npixel->value = pixval;
1920
1921 /* special case for when outside band extent */
1922 if (!inextent && !band->hasnodata)
1923 npixel->nodata = 1;
1924 else
1925 npixel->nodata = 0;
1926 }
1927
1928 (*_min)++;
1929 }
1930 }
1931 }
1932
1933 /* distance thresholds met */
1934 if (_d[0] >= distance[0] && _d[1] >= distance[1])
1935 break;
1936 else if (d0 && count)
1937 break;
1938 }
1939 while (1);
1940
1941 RASTER_DEBUGF(3, "Nearest pixels in return: %d", count);
1942
1943 return count;
1944}
#define FALSE
Definition dbfopen.c:72
void rterror(const char *fmt,...) __attribute__((format(printf
Wrappers used for reporting errors and info.
void * rtalloc(size_t size)
Wrappers used for managing memory.
Definition rt_context.c:191
#define RASTER_DEBUG(level, msg)
Definition librtcore.h:302
#define RASTER_DEBUGF(level, msg,...)
Definition librtcore.h:306
double rt_pixtype_get_min_value(rt_pixtype pixtype)
Return minimum value possible for pixel type.
Definition rt_pixel.c:150
struct rt_pixel_t * rt_pixel
Definition librtcore.h:148
const char * rt_pixtype_name(rt_pixtype pixtype)
Definition rt_pixel.c:110
@ ES_NONE
Definition librtcore.h:182
void * rtrealloc(void *mem, size_t size)
Definition rt_context.c:199
void rtdealloc(void *mem)
Definition rt_context.c:206
static double distance(double x1, double y1, double x2, double y2)
Definition lwtree.c:1032
int count
Definition genraster.py:57
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
double value
Definition librtcore.h:2528
uint8_t nodata
Definition librtcore.h:2527

References distance(), ES_NONE, FALSE, rt_pixel_t::nodata, 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_pixel_t::x, and rt_pixel_t::y.

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

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