Count the distribution of data.
418 {
420 int init_width = 0;
421 uint32_t i;
422 uint32_t j;
423 double tmp;
425 int sum = 0;
426 double qmin;
427 double qmax;
428
429#if POSTGIS_DEBUG_LEVEL > 0
430 clock_t start, stop;
431 double elapsed = 0;
432#endif
433
435#if POSTGIS_DEBUG_LEVEL > 0
436 start = clock();
437#endif
438
439 assert(NULL != stats);
440 assert(NULL != rtn_count);
441
443 rterror(
"rt_util_get_histogram: rt_bandstats object has no value");
444 return NULL;
445 }
446
447
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");
452 return NULL;
453 }
454 }
455 }
456
457
461 }
462 else {
463 qmin = min;
464 qmax = max;
465 if (qmin > qmax) {
466 qmin = max;
467 qmax = min;
468 }
469 }
470
471
472 if (bin_count <= 0) {
473
474
475
476
477
478
479
480 if (stats->
count < 30)
481 bin_count = ceil(sqrt(stats->
count));
482
483 else
484 bin_count = ceil(log2((
double) stats->
count) + 1.);
485
486
487 if (bin_width_count > 0 && NULL != bin_width) {
488
489 if (bin_width_count > bin_count)
490 bin_count = bin_width_count;
491 else if (bin_width_count > 1) {
492 tmp = 0;
493 for (i = 0; i < bin_width_count; i++) tmp += bin_width[i];
494 bin_count = ceil((qmax - qmin) / tmp) * bin_width_count;
495 }
496 else
497 bin_count = ceil((qmax - qmin) / bin_width[0]);
498 }
499
500 else {
501 bin_width_count = 0;
502 }
503 }
504
505
506 if (
FLT_EQ(qmax, qmin)) bin_count = 1;
507
509
510
511 if (bin_count < 2) {
513 if (NULL == bins) {
514 rterror(
"rt_util_get_histogram: Could not allocate memory for histogram");
515 return NULL;
516 }
517
523
524 *rtn_count = bin_count;
525 return bins;
526 }
527
528
529 if (bin_width_count == 0) {
530 bin_width_count = 1;
531
532
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");
537 return NULL;
538 }
539 init_width = 1;
540 }
541
542 bin_width[0] = (qmax - qmin) / bin_count;
543 }
544
545
547 if (NULL == bins) {
548 rterror(
"rt_util_get_histogram: Could not allocate memory for histogram");
550 return NULL;
551 }
552 if (!right)
553 tmp = qmin;
554 else
555 tmp = qmax;
556 for (i = 0; i < bin_count;) {
557 for (j = 0; j < bin_width_count; j++) {
560
561 if (!right) {
563 tmp += bin_width[j];
565
568 }
569 else {
571 tmp -= bin_width[j];
573
576 }
577
578 i++;
579 }
580 }
581 if (!right) {
582 bins[bin_count - 1].
inc_max = 1;
583
584
585 if (bins[bin_count - 1].max < qmax)
586 bins[bin_count - 1].
max = qmax;
587 }
588 else {
589 bins[bin_count - 1].
inc_min = 1;
590
591
592 if (bins[bin_count - 1].min > qmin)
593 bins[bin_count - 1].
min = qmin;
594 }
595
596
597 for (i = 0; i < stats->
count; i++) {
599
600
601 if (!right) {
602 for (j = 0; j < bin_count; j++) {
603 if (
604 (!bins[j].inc_max && value < bins[j].max) || (
605 bins[j].inc_max && (
606 (value < bins[j].max) ||
607 FLT_EQ(value, bins[j].max)
608 )
609 )
610 ) {
612 sum++;
613 break;
614 }
615 }
616 }
617
618 else {
619 for (j = 0; j < bin_count; j++) {
620 if (
621 (!bins[j].inc_min && value > bins[j].min) || (
622 bins[j].inc_min && (
623 (value > bins[j].min) ||
624 FLT_EQ(value, bins[j].min)
625 )
626 )
627 ) {
629 sum++;
630 break;
631 }
632 }
633 }
634 }
635
636 for (i = 0; i < bin_count; i++) {
637 bins[i].
percent = ((double) bins[i].count) / sum;
638 }
639
640#if POSTGIS_DEBUG_LEVEL > 0
641 stop = clock();
642 elapsed = ((double) (stop - start)) / CLOCKS_PER_SEC;
644
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);
648 }
649#endif
650
652 *rtn_count = bin_count;
654 return bins;
655}
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 rtdealloc(void *mem)