Count the number of times provided value(s) occur in the band.
1612 {
1615 uint8_t *
data = NULL;
1616 double nodata = 0;
1617
1618 int scale = 0;
1619 int doround = 0;
1620 double tmpd = 0;
1621 uint32_t i = 0;
1622
1625 int rtn;
1626 double pxlval;
1627 int isnodata = 0;
1628 double rpxlval;
1629 uint32_t total = 0;
1630 uint32_t vcnts_count = 0;
1631 uint32_t new_valuecount = 0;
1632
1633#if POSTGIS_DEBUG_LEVEL > 0
1634 clock_t start, stop;
1635 double elapsed = 0;
1636#endif
1637
1639#if POSTGIS_DEBUG_LEVEL > 0
1640 start = clock();
1641#endif
1642
1643 assert(NULL != band);
1644 assert(NULL != rtn_count);
1645
1647 if (data == NULL) {
1648 rterror(
"rt_band_get_summary_stats: Cannot get band data");
1649 return NULL;
1650 }
1651
1652 pixtype =
band->pixtype;
1653
1657 }
1658 else {
1659 exclude_nodata_value = 0;
1661 }
1662
1663 RASTER_DEBUGF(3,
"exclude_nodata_value = %d", exclude_nodata_value);
1664
1665
1666 if (roundto < 0 ||
FLT_EQ(roundto, 0.0)) {
1667 roundto = 0;
1668 scale = 0;
1669 }
1670
1671 else if (roundto < 1) {
1672 switch (pixtype) {
1673
1683 roundto = 0;
1684 break;
1685
1688 for (scale = 0; scale <= 20; scale++) {
1689 tmpd = roundto * pow(10, scale);
1690 if (
FLT_EQ((tmpd - ((
int) tmpd)), 0.0))
break;
1691 }
1692 break;
1694 break;
1695 }
1696 }
1697
1698 else {
1699 for (scale = 0; scale >= -20; scale--) {
1700 tmpd = roundto * pow(10, scale);
1701 if (tmpd < 1 ||
FLT_EQ(tmpd, 1.0)) {
1702 if (scale == 0) doround = 1;
1703 break;
1704 }
1705 }
1706 }
1707
1708 if (scale != 0 || doround)
1709 doround = 1;
1710 else
1711 doround = 0;
1714
1715
1716 if (search_values_count > 0 && NULL != search_values) {
1718 if (NULL == vcnts) {
1719 rterror(
"rt_band_get_count_of_values: Could not allocate memory for value counts");
1720 *rtn_count = 0;
1721 return NULL;
1722 }
1723
1724 for (i = 0; i < search_values_count; i++) {
1727 if (!doround)
1728 vcnts[i].
value = search_values[i];
1729 else
1730 vcnts[i].
value =
ROUND(search_values[i], scale);
1731 }
1732 vcnts_count = i;
1733 }
1734 else
1735 search_values_count = 0;
1736 RASTER_DEBUGF(3,
"search_values_count = %d", search_values_count);
1737
1738
1740 if (exclude_nodata_value) {
1741 rtwarn(
"All pixels of band have the NODATA value");
1742 return NULL;
1743 }
1744 else {
1745 if (search_values_count > 0) {
1746
1747 for (i = 0; i < search_values_count; i++) {
1748 if (!doround)
1749 tmpd = nodata;
1750 else
1751 tmpd =
ROUND(nodata, scale);
1752
1753 if (
FLT_NEQ(tmpd, vcnts[i].value))
1754 continue;
1755
1757 if (NULL != rtn_total) *rtn_total = vcnts[i].
count;
1759 }
1760
1761 *rtn_count = vcnts_count;
1762 }
1763
1764 else {
1766 if (NULL == vcnts) {
1767 rterror(
"rt_band_get_count_of_values: Could not allocate memory for value counts");
1768 *rtn_count = 0;
1769 return NULL;
1770 }
1771
1772 vcnts->
value = nodata;
1774 if (NULL != rtn_total) *rtn_total = vcnts[i].
count;
1776
1777 *rtn_count = 1;
1778 }
1779
1780 return vcnts;
1781 }
1782 }
1783
1784 for (x = 0;
x <
band->width;
x++) {
1785 for (y = 0;
y <
band->height;
y++) {
1787
1788
1790 continue;
1791
1792 if (!exclude_nodata_value || (exclude_nodata_value && !isnodata)) {
1793 total++;
1794 if (doround) {
1795 rpxlval =
ROUND(pxlval, scale);
1796 }
1797 else
1798 rpxlval = pxlval;
1799 RASTER_DEBUGF(5,
"(pxlval, rpxlval) => (%0.6f, %0.6f)", pxlval, rpxlval);
1800
1801 new_valuecount = 1;
1802
1803 for (i = 0; i < vcnts_count; i++) {
1804
1805 if (
FLT_EQ(vcnts[i].value, rpxlval)) {
1807 new_valuecount = 0;
1808 RASTER_DEBUGF(5,
"(value, count) => (%0.6f, %d)", vcnts[i].value, vcnts[i].count);
1809 break;
1810 }
1811 }
1812
1813
1814
1815
1816
1817
1818 if (!new_valuecount || search_values_count > 0) continue;
1819
1820
1822 if (NULL == vcnts) {
1823 rterror(
"rt_band_get_count_of_values: Could not allocate memory for value counts");
1824 *rtn_count = 0;
1825 return NULL;
1826 }
1827
1828 vcnts[vcnts_count].
value = rpxlval;
1829 vcnts[vcnts_count].
count = 1;
1830 vcnts[vcnts_count].
percent = 0;
1831 RASTER_DEBUGF(5,
"(value, count) => (%0.6f, %d)", vcnts[vcnts_count].value, vcnts[vcnts_count].count);
1832 vcnts_count++;
1833 }
1834 }
1835 }
1836
1837#if POSTGIS_DEBUG_LEVEL > 0
1838 stop = clock();
1839 elapsed = ((double) (stop - start)) / CLOCKS_PER_SEC;
1841#endif
1842
1843 for (i = 0; i < vcnts_count; i++) {
1844 vcnts[i].
percent = (double) vcnts[i].count / total;
1845 RASTER_DEBUGF(5,
"(value, count) => (%0.6f, %d)", vcnts[i].value, vcnts[i].count);
1846 }
1847
1849 if (NULL != rtn_total) *rtn_total = total;
1850 *rtn_count = vcnts_count;
1851 return vcnts;
1852}
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.
#define RASTER_DEBUG(level, msg)
#define RASTER_DEBUGF(level, msg,...)
void void void rtwarn(const char *fmt,...) __attribute__((format(printf
int rt_band_get_hasnodata_flag(rt_band band)
Get hasnodata flag value.
void * rt_band_get_data(rt_band band)
Get pointer to raster band data.
rt_errorstate rt_band_get_pixel(rt_band band, int x, int y, double *value, int *nodata)
Get pixel value.
int rt_band_get_isnodata_flag(rt_band band)
Get isnodata flag value.
void * rtrealloc(void *mem, size_t size)
struct rt_valuecount_t * rt_valuecount
rt_errorstate rt_band_get_nodata(rt_band band, double *nodata)
Get NODATA value.