38#define SWAP(x, y) { double t; t = x; x = y; y = t; }
39#define ORDER(x, y) if (x > y) SWAP(x, y)
41static double pivot(
double *left,
double *right) {
45 m = *(left + (right - left) / 2);
58 for (p = left + 1; p <= right; ++p) {
60 return (*p < *left) ? *left : *p;
68 while (left <= right) {
69 while (*left <
pivot) ++left;
70 while (*right >=
pivot) --right;
83 double p =
pivot(left, right);
113 int exclude_nodata_value,
double sample,
int inc_vals,
114 uint64_t *cK,
double *cM,
double *cQ
122 int hasnodata =
FALSE;
124 double *values = NULL;
129 uint32_t do_sample = 0;
130 uint32_t sample_size = 0;
131 uint32_t sample_per = 0;
132 uint32_t sample_int = 0;
140#if POSTGIS_DEBUG_LEVEL > 0
146#if POSTGIS_DEBUG_LEVEL > 0
150 assert(NULL != band);
153 if (band->width < 1 || band->height < 1) {
156 rterror(
"rt_band_get_summary_stats: Could not allocate memory for stats");
160 rtwarn(
"Band is empty as width and/or height is 0");
166 stats->
min = stats->
max = 0;
175 if (hasnodata !=
FALSE)
178 exclude_nodata_value = 0;
182 RASTER_DEBUGF(3,
"exclude_nodata_value = %d", exclude_nodata_value);
188 rterror(
"rt_band_get_summary_stats: Could not allocate memory for stats");
196 if (exclude_nodata_value) {
197 rtwarn(
"All pixels of band have the NODATA value");
200 stats->
min = stats->
max = 0;
206 stats->
count = band->width * band->height;
207 stats->
min = stats->
max = nodata;
209 stats->
mean = nodata;
218 (sample < 0 ||
FLT_EQ(sample, 0.0)) ||
219 (sample > 1 ||
FLT_EQ(sample, 1.0))
230 sample_size = band->width * band->height;
231 sample_per = band->height;
239 sample_size = round((band->width * band->height) * sample);
240 sample_per = round(sample_size / band->width);
243 sample_int = round(band->height / sample_per);
247 RASTER_DEBUGF(3,
"sampling %d of %d available pixels w/ %d per set"
248 , sample_size, (band->width * band->height), sample_per);
251 values =
rtalloc(
sizeof(
double) * sample_size);
252 if (NULL == values) {
253 rtwarn(
"Could not allocate memory for values");
261 rterror(
"rt_band_get_summary_stats: Could not allocate memory for stats");
269 stats->
min = stats->
max = 0;
273 for (x = 0, j = 0, k = 0; x < band->width; x++) {
277 for (i = 0, z = 0; i < sample_per; i++) {
281 offset = (rand() % sample_int) + 1;
283 diff = sample_int - offset;
286 if (y >= band->height || z > sample_per)
break;
291 if (rtn ==
ES_NONE && (!exclude_nodata_value || (exclude_nodata_value && !isnodata))) {
294 if (inc_vals) values[k] = value;
309 Q += (((k - 1) * pow(value - M, 2)) / k);
310 M += ((value - M ) / k);
321 *cQ += (((*cK - 1) * pow(value - *cM, 2)) / *cK);
322 *cM += ((value - *cM ) / *cK);
327 if (stats->
count < 1) {
329 stats->
min = stats->
max = value;
332 if (value < stats->min)
334 if (value > stats->
max)
350 if (sample_size != k) {
351 values =
rtrealloc(values, k *
sizeof(
double));
358 stats->
mean = sum / k;
362 stats->
stddev = sqrt(Q / k);
368 stats->
stddev = sqrt(Q / (k - 1));
376 if (do_sample && k < 1)
377 rtwarn(
"All sampled pixels of band have the NODATA value");
379#if POSTGIS_DEBUG_LEVEL > 0
381 elapsed = ((double) (stop - start)) / CLOCKS_PER_SEC;
382 RASTER_DEBUGF(3,
"(time, count, mean, stddev, min, max) = (%0.4f, %d, %f, %f, %f, %f)",
415 uint32_t bin_count,
double *bin_width, uint32_t bin_width_count,
416 int right,
double min,
double max,
429#if POSTGIS_DEBUG_LEVEL > 0
435#if POSTGIS_DEBUG_LEVEL > 0
439 assert(NULL != stats);
440 assert(NULL != rtn_count);
443 rterror(
"rt_util_get_histogram: rt_bandstats object has no value");
448 if (NULL != bin_width && bin_width_count > 0) {
449 for (i = 0; i < bin_width_count; i++) {
450 if (bin_width[i] < 0 ||
FLT_EQ(bin_width[i], 0.0)) {
451 rterror(
"rt_util_get_histogram: bin_width element is less than or equal to zero");
472 if (bin_count <= 0) {
480 if (stats->
count < 30)
481 bin_count = ceil(sqrt(stats->
count));
484 bin_count = ceil(log2((
double) stats->
count) + 1.);
487 if (bin_width_count > 0 && NULL != bin_width) {
489 if (bin_width_count > bin_count)
490 bin_count = bin_width_count;
491 else if (bin_width_count > 1) {
493 for (i = 0; i < bin_width_count; i++) tmp += bin_width[i];
494 bin_count = ceil((qmax - qmin) / tmp) * bin_width_count;
497 bin_count = ceil((qmax - qmin) / bin_width[0]);
506 if (
FLT_EQ(qmax, qmin)) bin_count = 1;
514 rterror(
"rt_util_get_histogram: Could not allocate memory for histogram");
524 *rtn_count = bin_count;
529 if (bin_width_count == 0) {
533 if (NULL == bin_width) {
534 bin_width =
rtalloc(
sizeof(
double));
535 if (NULL == bin_width) {
536 rterror(
"rt_util_get_histogram: Could not allocate memory for bin widths");
542 bin_width[0] = (qmax - qmin) / bin_count;
548 rterror(
"rt_util_get_histogram: Could not allocate memory for histogram");
556 for (i = 0; i < bin_count;) {
557 for (j = 0; j < bin_width_count; j++) {
582 bins[bin_count - 1].
inc_max = 1;
585 if (bins[bin_count - 1].max < qmax)
586 bins[bin_count - 1].
max = qmax;
589 bins[bin_count - 1].
inc_min = 1;
592 if (bins[bin_count - 1].min > qmin)
593 bins[bin_count - 1].
min = qmin;
597 for (i = 0; i < stats->
count; i++) {
602 for (j = 0; j < bin_count; j++) {
604 (!bins[j].inc_max && value < bins[j].max) || (
606 (value < bins[j].max) ||
607 FLT_EQ(value, bins[j].max)
619 for (j = 0; j < bin_count; j++) {
621 (!bins[j].inc_min && value > bins[j].min) || (
623 (value > bins[j].min) ||
624 FLT_EQ(value, bins[j].min)
636 for (i = 0; i < bin_count; i++) {
637 bins[i].
percent = ((double) bins[i].count) / sum;
640#if POSTGIS_DEBUG_LEVEL > 0
642 elapsed = ((double) (stop - start)) / CLOCKS_PER_SEC;
645 for (j = 0; j < bin_count; j++) {
646 RASTER_DEBUGF(5,
"(min, max, inc_min, inc_max, count, sum, percent) = (%f, %f, %d, %d, %d, %d, %f)",
647 bins[j].min, bins[j].max, bins[j].inc_min, bins[j].inc_max, bins[j].count, sum, bins[j].percent);
652 *rtn_count = bin_count;
675 double *quantiles,
int quantiles_count,
679 int init_quantiles = 0;
684#if POSTGIS_DEBUG_LEVEL > 0
690#if POSTGIS_DEBUG_LEVEL > 0
694 assert(NULL != stats);
695 assert(NULL != rtn_count);
698 rterror(
"rt_band_get_quantiles: rt_bandstats object has no value");
703 if (NULL == quantiles) {
705 if (quantiles_count < 2)
708 quantiles =
rtalloc(
sizeof(
double) * quantiles_count);
710 if (NULL == quantiles) {
711 rterror(
"rt_band_get_quantiles: Could not allocate memory for quantile input");
716 for (i = 0; i <= quantiles_count; i++)
717 quantiles[i] = ((
double) i) / quantiles_count;
722 for (i = 0; i < quantiles_count; i++) {
723 if (quantiles[i] < 0. || quantiles[i] > 1.) {
724 rterror(
"rt_band_get_quantiles: Quantile value not between 0 and 1");
725 if (init_quantiles)
rtdealloc(quantiles);
729 quicksort(quantiles, quantiles + quantiles_count - 1);
734 rterror(
"rt_band_get_quantiles: Could not allocate memory for quantile output");
735 if (init_quantiles)
rtdealloc(quantiles);
751 for (i = 0; i < quantiles_count; i++) {
754 h = ((stats->
count - 1.) * quantiles[i]) + 1.;
765#if POSTGIS_DEBUG_LEVEL > 0
767 elapsed = ((double) (stop - start)) / CLOCKS_PER_SEC;
771 *rtn_count = quantiles_count;
772 if (init_quantiles)
rtdealloc(quantiles);
788 if (NULL != element->
next)
804 if (NULL == element) {
807 if (NULL == qle)
return NULL;
815 if (NULL != idx) *idx = 0;
819 if (NULL != idx) *idx += 1;
820 if (NULL != element->
next)
826 if (NULL == qle)
return NULL;
841 RASTER_DEBUGF(4,
"insert qle @ %p before current element", qle);
842 if (NULL == qle)
return NULL;
857 if (NULL == element)
return 0;
860 if (NULL == element->
prev && NULL != element->
next) {
864 else if (NULL != element->
prev && NULL == element->
next) {
868 else if (NULL != element->
prev && NULL != element->
next) {
883 if (NULL == *list)
return 0;
885 for (i = 0; i < list_count; i++) {
886 element = (*list)[i].head;
887 while (NULL != element->
next) {
900 uint32_t anchor = (uint32_t) floor(idx / 100);
902 if (qll->
tail == qle)
return;
942 uint32_t i = 0, j = 0;
950 if (
value > (qll->
index[i]).element->value)
continue;
958 for (j = 1; j < i; j++) {
961 *index = (i - j) * 100;
1013 int exclude_nodata_value,
double sample,
1016 double *quantiles, uint32_t quantiles_count,
1020 int init_quantiles = 0;
1025 const uint32_t MAX_VALUES = 750;
1027 uint8_t *data = NULL;
1039 uint32_t offset = 0;
1043 uint32_t do_sample = 0;
1044 uint32_t sample_size = 0;
1045 uint32_t sample_per = 0;
1046 uint32_t sample_int = 0;
1051 assert(NULL != band);
1052 assert(cov_count > 1);
1053 assert(NULL != rtn_count);
1058 rterror(
"rt_band_get_summary_stats: Cannot get band data");
1063 exclude_nodata_value = 0;
1064 RASTER_DEBUGF(3,
"exclude_nodata_value = %d", exclude_nodata_value);
1067 if (NULL == *qlls) {
1069 if (NULL == quantiles) {
1071 if (quantiles_count < 2)
1072 quantiles_count = 5;
1074 quantiles =
rtalloc(
sizeof(
double) * quantiles_count);
1076 if (NULL == quantiles) {
1077 rterror(
"rt_band_get_quantiles_stream: Could not allocate memory for quantile input");
1082 for (i = 0; i <= quantiles_count; i++)
1083 quantiles[i] = ((
double) i) / quantiles_count;
1088 for (i = 0; i < quantiles_count; i++) {
1089 if (quantiles[i] < 0. || quantiles[i] > 1.) {
1090 rterror(
"rt_band_get_quantiles_stream: Quantile value not between 0 and 1");
1091 if (init_quantiles)
rtdealloc(quantiles);
1095 quicksort(quantiles, quantiles + quantiles_count - 1);
1098 *qlls_count = quantiles_count * 2;
1101 if (NULL == *qlls) {
1102 rterror(
"rt_band_get_quantiles_stream: Could not allocate memory for quantile output");
1103 if (init_quantiles)
rtdealloc(quantiles);
1107 j = (uint32_t) floor(MAX_VALUES / 100.) + 1;
1108 for (i = 0; i < *qlls_count; i++) {
1109 qll = &((*qlls)[i]);
1110 qll->
quantile = quantiles[(i * quantiles_count) / *qlls_count];
1119 if (NULL == qll->
index) {
1120 rterror(
"rt_band_get_quantiles_stream: Could not allocate memory for quantile output");
1121 if (init_quantiles)
rtdealloc(quantiles);
1131 if (qll->
tau < 1) qll->
tau = 1;
1136 qll->
tau = cov_count - (*qlls)[i - 1].tau + 1;
1139 RASTER_DEBUGF(4,
"qll init: (algeq, quantile, count, tau, sum1, sum2) = (%d, %f, %d, %llu, %llu, %llu)",
1144 if (init_quantiles)
rtdealloc(quantiles);
1149 (sample < 0 ||
FLT_EQ(sample, 0.0)) ||
1150 (sample > 1 ||
FLT_EQ(sample, 1.0))
1161 sample_size = band->width * band->height;
1162 sample_per = band->height;
1170 sample_size = round((band->width * band->height) * sample);
1171 sample_per = round(sample_size / band->width);
1172 sample_int = round(band->height / sample_per);
1175 RASTER_DEBUGF(3,
"sampling %d of %d available pixels w/ %d per set"
1176 , sample_size, (band->width * band->height), sample_per);
1178 for (x = 0, j = 0, k = 0; x < band->width; x++) {
1184 RASTER_DEBUG(3,
"Skipping quantile calculation as band is NODATA");
1188 for (i = 0, z = 0; i < sample_per; i++) {
1192 offset = (rand() % sample_int) + 1;
1194 diff = sample_int - offset;
1197 if (y >= band->height || z > sample_per)
break;
1202 if (status ==
ES_NONE && (!exclude_nodata_value || (exclude_nodata_value && !isnodata))) {
1205 for (a = 0; a < *qlls_count; a++) {
1206 qll = &((*qlls)[a]);
1209 RASTER_DEBUGF(5,
"qll before: (algeq, quantile, count, tau, sum1, sum2) = (%d, %f, %d, %lld, %lld, %lld)",
1215 if (NULL != qll->
head) {
1216 if (value < qll->head->value)
1230 if (NULL != qll->
head) {
1274 else if (qll->
count < MAX_VALUES) {
1286 if (NULL == qle)
return NULL;
1292 if (NULL == qle->
prev)
1295 if (NULL == qle->
next)
1306 RASTER_DEBUGF(5,
"qle, prev, next, head, tail = %p, %p, %p, %p, %p", qle, qle->
prev, qle->
next, qll->
head, qll->
tail);
1309 else if (qll->
algeq) {
1312 if (value < qll->head->value) {
1342 if (NULL == qle)
return NULL;
1348 if (NULL == qle->
prev)
1351 if (NULL == qle->
next)
1364 while (NULL != qle) {
1412 if (NULL == qle)
return NULL;
1418 if (NULL == qle->
prev)
1421 if (NULL == qle->
next)
1434 while (NULL != qle) {
1502 RASTER_DEBUGF(5,
"qll after: (algeq, quantile, count, tau, sum1, sum2) = (%d, %f, %d, %lld, %lld, %lld)",
1509 RASTER_DEBUGF(5,
"skipping value at (x, y) = (%u, %lld)", x, y);
1517 *rtn_count = *qlls_count / 2;
1519 if (NULL == rtn)
return NULL;
1522 for (i = 0, k = 0; i < *qlls_count; i++) {
1523 qll = &((*qlls)[i]);
1526 for (x = 0; x < k; x++) {
1532 if (exists)
continue;
1534 RASTER_DEBUGF(5,
"qll: (algeq, quantile, count, tau, sum1, sum2) = (%d, %f, %d, %lld, %lld, %lld)",
1542 if (qll->
head == NULL || qll->
tail == NULL)
1553 for (j = i + 1; j < *qlls_count; j++) {
1556 RASTER_DEBUGF(5,
"qlls[%d]: (algeq, quantile, count, tau, sum1, sum2) = (%d, %f, %d, %lld, %lld, %lld)",
1557 j, (*qlls)[j].algeq, (*qlls)[j].quantile, (*qlls)[j].
count, (*qlls)[j].tau, (*qlls)[j].sum1, (*qlls)[j].sum2);
1558 RASTER_DEBUGF(5,
"qlls[%d]: (head, tail) = (%p, %p)", j, (*qlls)[j].head, (*qlls)[j].tail);
1567 if ((*qlls)[j].algeq) {
1568 rtn[k].
value = ((qle->
value * qle->
count) + ((*qlls)[j].head->value * (*qlls)[j].head->count)) / (qle->
count + (*qlls)[j].head->count);
1569 RASTER_DEBUGF(5,
"qlls[%d].head: (value, count) = (%f, %d)", j, (*qlls)[j].head->value, (*qlls)[j].head->count);
1572 rtn[k].
value = ((qle->
value * qle->
count) + ((*qlls)[j].tail->value * (*qlls)[j].tail->count)) / (qle->
count + (*qlls)[j].tail->count);
1573 RASTER_DEBUGF(5,
"qlls[%d].tail: (value, count) = (%f, %d)", j, (*qlls)[j].tail->value, (*qlls)[j].tail->count);
1610 rt_band band,
int exclude_nodata_value,
1611 double *search_values, uint32_t search_values_count,
double roundto,
1612 uint32_t *rtn_total, uint32_t *rtn_count
1616 uint8_t *data = NULL;
1631 uint32_t vcnts_count = 0;
1632 uint32_t new_valuecount = 0;
1634#if POSTGIS_DEBUG_LEVEL > 0
1635 clock_t start, stop;
1640#if POSTGIS_DEBUG_LEVEL > 0
1644 assert(NULL != band);
1645 assert(NULL != rtn_count);
1649 rterror(
"rt_band_get_summary_stats: Cannot get band data");
1653 pixtype = band->pixtype;
1660 exclude_nodata_value = 0;
1664 RASTER_DEBUGF(3,
"exclude_nodata_value = %d", exclude_nodata_value);
1667 if (roundto < 0 ||
FLT_EQ(roundto, 0.0)) {
1672 else if (roundto < 1) {
1690 for (scale = 0; scale <= 20; scale++)
1692 tmpd = roundto * pow(10, scale);
1693 if (
FLT_EQ((tmpd - ((
int)tmpd)), 0.0))
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;
1712 if (scale != 0 || doround)
1720 if (search_values_count > 0 && NULL != search_values) {
1722 if (NULL == vcnts) {
1723 rterror(
"rt_band_get_count_of_values: Could not allocate memory for value counts");
1728 for (i = 0; i < search_values_count; i++) {
1732 vcnts[i].
value = search_values[i];
1734 vcnts[i].
value =
ROUND(search_values[i], scale);
1739 search_values_count = 0;
1740 RASTER_DEBUGF(3,
"search_values_count = %d", search_values_count);
1744 if (exclude_nodata_value) {
1745 rtwarn(
"All pixels of band have the NODATA value");
1749 if (search_values_count > 0) {
1751 for (i = 0; i < search_values_count; i++) {
1755 tmpd =
ROUND(nodata, scale);
1760 vcnts[i].
count = band->width * band->height;
1761 if (NULL != rtn_total) *rtn_total = vcnts[i].
count;
1765 *rtn_count = vcnts_count;
1770 if (NULL == vcnts) {
1771 rterror(
"rt_band_get_count_of_values: Could not allocate memory for value counts");
1776 vcnts->
value = nodata;
1777 vcnts->
count = band->width * band->height;
1778 if (NULL != rtn_total) *rtn_total = vcnts[i].
count;
1788 for (x = 0; x < band->width; x++) {
1789 for (y = 0; y < band->height; y++) {
1796 if (!exclude_nodata_value || (exclude_nodata_value && !isnodata)) {
1799 rpxlval =
ROUND(pxlval, scale);
1803 RASTER_DEBUGF(5,
"(pxlval, rpxlval) => (%0.6f, %0.6f)", pxlval, rpxlval);
1807 for (i = 0; i < vcnts_count; i++) {
1822 if (!new_valuecount || search_values_count > 0)
continue;
1826 if (NULL == vcnts) {
1827 rterror(
"rt_band_get_count_of_values: Could not allocate memory for value counts");
1832 vcnts[vcnts_count].
value = rpxlval;
1833 vcnts[vcnts_count].
count = 1;
1834 vcnts[vcnts_count].
percent = 0;
1841#if POSTGIS_DEBUG_LEVEL > 0
1843 elapsed = ((double) (stop - start)) / CLOCKS_PER_SEC;
1847 for (i = 0; i < vcnts_count; i++) {
1853 if (NULL != rtn_total) *rtn_total = total;
1854 *rtn_count = vcnts_count;
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.
struct rt_bandstats_t * rt_bandstats
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.
void rtdealloc(void *mem)
This library is the generic raster handling section of PostGIS.
static struct quantile_llist_element * quantile_llist_index_search(struct quantile_llist *qll, double value, uint32_t *index)
static void quantile_llist_index_update(struct quantile_llist *qll, struct quantile_llist_element *qle, uint32_t idx)
static struct quantile_llist_element * quantile_llist_insert(struct quantile_llist_element *element, double value, uint32_t *idx)
static void quantile_llist_index_delete(struct quantile_llist *qll, struct quantile_llist_element *qle)
static struct quantile_llist_element * quantile_llist_search(struct quantile_llist_element *element, double needle)
rt_quantile rt_band_get_quantiles_stream(rt_band band, int exclude_nodata_value, double sample, uint64_t cov_count, struct quantile_llist **qlls, uint32_t *qlls_count, double *quantiles, uint32_t quantiles_count, uint32_t *rtn_count)
Compute the default set of or requested quantiles for a coverage.
int quantile_llist_destroy(struct quantile_llist **list, uint32_t list_count)
static void quicksort(double *left, double *right)
static int quantile_llist_delete(struct quantile_llist_element *element)
static double * partition(double *left, double *right, double pivot)
static double pivot(double *left, double *right)
rt_histogram rt_band_get_histogram(rt_bandstats stats, uint32_t bin_count, double *bin_width, uint32_t bin_width_count, int right, double min, double max, uint32_t *rtn_count)
Count the distribution of data.
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.
static void quantile_llist_index_reset(struct quantile_llist *qll)
rt_quantile rt_band_get_quantiles(rt_bandstats stats, double *quantiles, int quantiles_count, uint32_t *rtn_count)
Compute the default set of or requested quantiles for a set of data the quantile formula used is same...
rt_bandstats rt_band_get_summary_stats(rt_band band, int exclude_nodata_value, double sample, int inc_vals, uint64_t *cK, double *cM, double *cQ)
Compute summary statistics for a band.
struct quantile_llist_element * prev
struct quantile_llist_element * next
struct quantile_llist_element * element
struct quantile_llist_element * head
struct quantile_llist_element * tail
struct quantile_llist_index * index