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

◆ rt_band_get_value_count()

rt_valuecount rt_band_get_value_count ( rt_band  band,
int  exclude_nodata_value,
double *  search_values,
uint32_t  search_values_count,
double  roundto,
uint32_t *  rtn_total,
uint32_t *  rtn_count 
)

Count the number of times provided value(s) occur in the band.

Parameters
band: the band to query for minimum and maximum pixel values
exclude_nodata_value: if non-zero, ignore nodata values
search_values: array of values to count
search_values_count: the number of search values
roundto: the decimal place to round the values to
rtn_total: the number of pixels examined in the band
rtn_count: the number of value counts being returned
Returns
the number of times the provide value(s) occur or NULL

Definition at line 1609 of file rt_statistics.c.

1613 {
1614 rt_valuecount vcnts = NULL;
1615 rt_pixtype pixtype = PT_END;
1616 uint8_t *data = NULL;
1617 double nodata = 0;
1618
1619 int scale = 0;
1620 int doround = 0;
1621 double tmpd = 0;
1622 uint32_t i = 0;
1623
1624 uint32_t x = 0;
1625 uint32_t y = 0;
1626 int rtn;
1627 double pxlval;
1628 int isnodata = 0;
1629 double rpxlval;
1630 uint32_t total = 0;
1631 uint32_t vcnts_count = 0;
1632 uint32_t new_valuecount = 0;
1633
1634#if POSTGIS_DEBUG_LEVEL > 0
1635 clock_t start, stop;
1636 double elapsed = 0;
1637#endif
1638
1639 RASTER_DEBUG(3, "starting");
1640#if POSTGIS_DEBUG_LEVEL > 0
1641 start = clock();
1642#endif
1643
1644 assert(NULL != band);
1645 assert(NULL != rtn_count);
1646
1647 data = rt_band_get_data(band);
1648 if (data == NULL) {
1649 rterror("rt_band_get_summary_stats: Cannot get band data");
1650 return NULL;
1651 }
1652
1653 pixtype = band->pixtype;
1654
1655 if (rt_band_get_hasnodata_flag(band)) {
1656 rt_band_get_nodata(band, &nodata);
1657 RASTER_DEBUGF(3, "hasnodata, nodataval = 1, %f", nodata);
1658 }
1659 else {
1660 exclude_nodata_value = 0;
1661 RASTER_DEBUG(3, "hasnodata, nodataval = 0, 0");
1662 }
1663
1664 RASTER_DEBUGF(3, "exclude_nodata_value = %d", exclude_nodata_value);
1665
1666 /* process roundto */
1667 if (roundto < 0 || FLT_EQ(roundto, 0.0)) {
1668 roundto = 0;
1669 scale = 0;
1670 }
1671 /* tenths, hundredths, thousandths, etc */
1672 else if (roundto < 1) {
1673 switch (pixtype) {
1674 /* integer band types don't have digits after the decimal place */
1675 case PT_1BB:
1676 case PT_2BUI:
1677 case PT_4BUI:
1678 case PT_8BSI:
1679 case PT_8BUI:
1680 case PT_16BSI:
1681 case PT_16BUI:
1682 case PT_32BSI:
1683 case PT_32BUI:
1684 roundto = 0;
1685 break;
1686 /* floating points, check the rounding */
1687 case PT_16BF:
1688 case PT_32BF:
1689 case PT_64BF:
1690 for (scale = 0; scale <= 20; scale++)
1691 {
1692 tmpd = roundto * pow(10, scale);
1693 if (FLT_EQ((tmpd - ((int)tmpd)), 0.0))
1694 break;
1695 }
1696 break;
1697 case PT_END:
1698 break;
1699 }
1700 }
1701 /* ones, tens, hundreds, etc */
1702 else {
1703 for (scale = 0; scale >= -20; scale--) {
1704 tmpd = roundto * pow(10, scale);
1705 if (tmpd < 1 || FLT_EQ(tmpd, 1.0)) {
1706 if (scale == 0) doround = 1;
1707 break;
1708 }
1709 }
1710 }
1711
1712 if (scale != 0 || doround)
1713 doround = 1;
1714 else
1715 doround = 0;
1716 RASTER_DEBUGF(3, "scale = %d", scale);
1717 RASTER_DEBUGF(3, "doround = %d", doround);
1718
1719 /* process search_values */
1720 if (search_values_count > 0 && NULL != search_values) {
1721 vcnts = (rt_valuecount) rtalloc(sizeof(struct rt_valuecount_t) * search_values_count);
1722 if (NULL == vcnts) {
1723 rterror("rt_band_get_count_of_values: Could not allocate memory for value counts");
1724 *rtn_count = 0;
1725 return NULL;
1726 }
1727
1728 for (i = 0; i < search_values_count; i++) {
1729 vcnts[i].count = 0;
1730 vcnts[i].percent = 0;
1731 if (!doround)
1732 vcnts[i].value = search_values[i];
1733 else
1734 vcnts[i].value = ROUND(search_values[i], scale);
1735 }
1736 vcnts_count = i;
1737 }
1738 else
1739 search_values_count = 0;
1740 RASTER_DEBUGF(3, "search_values_count = %d", search_values_count);
1741
1742 /* entire band is nodata */
1743 if (rt_band_get_isnodata_flag(band) != FALSE) {
1744 if (exclude_nodata_value) {
1745 rtwarn("All pixels of band have the NODATA value");
1746 return NULL;
1747 }
1748 else {
1749 if (search_values_count > 0) {
1750 /* check for nodata match */
1751 for (i = 0; i < search_values_count; i++) {
1752 if (!doround)
1753 tmpd = nodata;
1754 else
1755 tmpd = ROUND(nodata, scale);
1756
1757 if (FLT_NEQ(tmpd, vcnts[i].value))
1758 continue;
1759
1760 vcnts[i].count = band->width * band->height;
1761 if (NULL != rtn_total) *rtn_total = vcnts[i].count;
1762 vcnts->percent = 1.0;
1763 }
1764
1765 *rtn_count = vcnts_count;
1766 }
1767 /* no defined search values */
1768 else {
1769 vcnts = (rt_valuecount) rtalloc(sizeof(struct rt_valuecount_t));
1770 if (NULL == vcnts) {
1771 rterror("rt_band_get_count_of_values: Could not allocate memory for value counts");
1772 *rtn_count = 0;
1773 return NULL;
1774 }
1775
1776 vcnts->value = nodata;
1777 vcnts->count = band->width * band->height;
1778 if (NULL != rtn_total) *rtn_total = vcnts[i].count;
1779 vcnts->percent = 1.0;
1780
1781 *rtn_count = 1;
1782 }
1783
1784 return vcnts;
1785 }
1786 }
1787
1788 for (x = 0; x < band->width; x++) {
1789 for (y = 0; y < band->height; y++) {
1790 rtn = rt_band_get_pixel(band, x, y, &pxlval, &isnodata);
1791
1792 /* error getting value, continue */
1793 if (rtn != ES_NONE)
1794 continue;
1795
1796 if (!exclude_nodata_value || (exclude_nodata_value && !isnodata)) {
1797 total++;
1798 if (doround) {
1799 rpxlval = ROUND(pxlval, scale);
1800 }
1801 else
1802 rpxlval = pxlval;
1803 RASTER_DEBUGF(5, "(pxlval, rpxlval) => (%0.6f, %0.6f)", pxlval, rpxlval);
1804
1805 new_valuecount = 1;
1806 /* search for match in existing valuecounts */
1807 for (i = 0; i < vcnts_count; i++) {
1808 /* match found */
1809 if (FLT_EQ(vcnts[i].value, rpxlval)) {
1810 vcnts[i].count++;
1811 new_valuecount = 0;
1812 RASTER_DEBUGF(5, "(value, count) => (%0.6f, %d)", vcnts[i].value, vcnts[i].count);
1813 break;
1814 }
1815 }
1816
1817 /*
1818 don't add new valuecount either because
1819 - no need for new one
1820 - user-defined search values
1821 */
1822 if (!new_valuecount || search_values_count > 0) continue;
1823
1824 /* add new valuecount */
1825 vcnts = rtrealloc(vcnts, sizeof(struct rt_valuecount_t) * (vcnts_count + 1));
1826 if (NULL == vcnts) {
1827 rterror("rt_band_get_count_of_values: Could not allocate memory for value counts");
1828 *rtn_count = 0;
1829 return NULL;
1830 }
1831
1832 vcnts[vcnts_count].value = rpxlval;
1833 vcnts[vcnts_count].count = 1;
1834 vcnts[vcnts_count].percent = 0;
1835 RASTER_DEBUGF(5, "(value, count) => (%0.6f, %d)", vcnts[vcnts_count].value, vcnts[vcnts_count].count);
1836 vcnts_count++;
1837 }
1838 }
1839 }
1840
1841#if POSTGIS_DEBUG_LEVEL > 0
1842 stop = clock();
1843 elapsed = ((double) (stop - start)) / CLOCKS_PER_SEC;
1844 RASTER_DEBUGF(3, "elapsed time = %0.4f", elapsed);
1845#endif
1846
1847 for (i = 0; i < vcnts_count; i++) {
1848 vcnts[i].percent = (double) vcnts[i].count / total;
1849 RASTER_DEBUGF(5, "(value, count) => (%0.6f, %d)", vcnts[i].value, vcnts[i].count);
1850 }
1851
1852 RASTER_DEBUG(3, "done");
1853 if (NULL != rtn_total) *rtn_total = total;
1854 *rtn_count = vcnts_count;
1855 return vcnts;
1856}
#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 FLT_NEQ(x, y)
Definition librtcore.h:2435
#define RASTER_DEBUG(level, msg)
Definition librtcore.h:304
#define RASTER_DEBUGF(level, msg,...)
Definition librtcore.h:308
void void void rtwarn(const char *fmt,...) __attribute__((format(printf
int rt_band_get_hasnodata_flag(rt_band band)
Get hasnodata flag value.
Definition rt_band.c:833
void * rt_band_get_data(rt_band band)
Get pointer to raster band data.
Definition rt_band.c:559
#define ROUND(x, y)
Definition librtcore.h:2443
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_pixtype
Definition librtcore.h:188
@ PT_32BUI
Definition librtcore.h:197
@ PT_16BF
Definition librtcore.h:198
@ PT_2BUI
Definition librtcore.h:190
@ PT_32BSI
Definition librtcore.h:196
@ PT_END
Definition librtcore.h:201
@ PT_4BUI
Definition librtcore.h:191
@ PT_32BF
Definition librtcore.h:199
@ PT_1BB
Definition librtcore.h:189
@ PT_16BUI
Definition librtcore.h:195
@ PT_8BSI
Definition librtcore.h:192
@ PT_16BSI
Definition librtcore.h:194
@ PT_64BF
Definition librtcore.h:200
@ PT_8BUI
Definition librtcore.h:193
int rt_band_get_isnodata_flag(rt_band band)
Get isnodata flag value.
Definition rt_band.c:873
#define FLT_EQ(x, y)
Definition librtcore.h:2436
@ ES_NONE
Definition librtcore.h:182
void * rtrealloc(void *mem, size_t size)
Definition rt_context.c:199
struct rt_valuecount_t * rt_valuecount
Definition librtcore.h:154
rt_errorstate rt_band_get_nodata(rt_band band, double *nodata)
Get NODATA value.
Definition rt_band.c:2067

References quantile_llist_element::count, rt_valuecount_t::count, ES_NONE, FALSE, FLT_EQ, FLT_NEQ, rt_valuecount_t::percent, PT_16BF, PT_16BSI, PT_16BUI, PT_1BB, PT_2BUI, PT_32BF, PT_32BSI, PT_32BUI, PT_4BUI, PT_64BF, PT_8BSI, PT_8BUI, PT_END, RASTER_DEBUG, RASTER_DEBUGF, ROUND, rt_band_get_data(), rt_band_get_hasnodata_flag(), rt_band_get_isnodata_flag(), rt_band_get_nodata(), rt_band_get_pixel(), rtalloc(), rterror(), rtrealloc(), rtwarn(), quantile_llist_element::value, and rt_valuecount_t::value.

Referenced by RASTER_valueCount(), RASTER_valueCountCoverage(), and test_band_value_count().

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