Count the distribution of data.
417 {
419 int init_width = 0;
420 uint32_t i;
421 uint32_t j;
422 double tmp;
424 int sum = 0;
425 double qmin;
426 double qmax;
427
428#if POSTGIS_DEBUG_LEVEL > 0
429 clock_t start, stop;
430 double elapsed = 0;
431#endif
432
434#if POSTGIS_DEBUG_LEVEL > 0
435 start = clock();
436#endif
437
438 assert(NULL != stats);
439 assert(NULL != rtn_count);
440
442 rterror(
"rt_util_get_histogram: rt_bandstats object has no value");
443 return NULL;
444 }
445
446
447 if (NULL != bin_width && bin_width_count > 0) {
448 for (i = 0; i < bin_width_count; i++) {
449 if (bin_width[i] < 0 ||
FLT_EQ(bin_width[i], 0.0)) {
450 rterror(
"rt_util_get_histogram: bin_width element is less than or equal to zero");
451 return NULL;
452 }
453 }
454 }
455
456
460 }
461 else {
462 qmin = min;
463 qmax = max;
464 if (qmin > qmax) {
465 qmin = max;
466 qmax = min;
467 }
468 }
469
470
471 if (bin_count <= 0) {
472
473
474
475
476
477
478
479 if (stats->
count < 30)
480 bin_count = ceil(sqrt(stats->
count));
481
482 else
483 bin_count = ceil(log2((
double) stats->
count) + 1.);
484
485
486 if (bin_width_count > 0 && NULL != bin_width) {
487
488 if (bin_width_count > bin_count)
489 bin_count = bin_width_count;
490 else if (bin_width_count > 1) {
491 tmp = 0;
492 for (i = 0; i < bin_width_count; i++) tmp += bin_width[i];
493 bin_count = ceil((qmax - qmin) / tmp) * bin_width_count;
494 }
495 else
496 bin_count = ceil((qmax - qmin) / bin_width[0]);
497 }
498
499 else {
500 bin_width_count = 0;
501 }
502 }
503
504
505 if (
FLT_EQ(qmax, qmin)) bin_count = 1;
506
508
509
510 if (bin_count < 2) {
512 if (NULL == bins) {
513 rterror(
"rt_util_get_histogram: Could not allocate memory for histogram");
514 return NULL;
515 }
516
522
523 *rtn_count = bin_count;
524 return bins;
525 }
526
527
528 if (bin_width_count == 0) {
529 bin_width_count = 1;
530
531
532 if (NULL == bin_width) {
533 bin_width =
rtalloc(
sizeof(
double));
534 if (NULL == bin_width) {
535 rterror(
"rt_util_get_histogram: Could not allocate memory for bin widths");
536 return NULL;
537 }
538 init_width = 1;
539 }
540
541 bin_width[0] = (qmax - qmin) / bin_count;
542 }
543
544
546 if (NULL == bins) {
547 rterror(
"rt_util_get_histogram: Could not allocate memory for histogram");
549 return NULL;
550 }
551 if (!right)
552 tmp = qmin;
553 else
554 tmp = qmax;
555 for (i = 0; i < bin_count;) {
556 for (j = 0; j < bin_width_count; j++) {
559
560 if (!right) {
562 tmp += bin_width[j];
564
567 }
568 else {
570 tmp -= bin_width[j];
572
575 }
576
577 i++;
578 }
579 }
580 if (!right) {
581 bins[bin_count - 1].
inc_max = 1;
582
583
584 if (bins[bin_count - 1].max < qmax)
585 bins[bin_count - 1].
max = qmax;
586 }
587 else {
588 bins[bin_count - 1].
inc_min = 1;
589
590
591 if (bins[bin_count - 1].min > qmin)
592 bins[bin_count - 1].
min = qmin;
593 }
594
595
596 for (i = 0; i < stats->
count; i++) {
598
599
600 if (!right) {
601 for (j = 0; j < bin_count; j++) {
602 if (
603 (!bins[j].inc_max && value < bins[j].max) || (
604 bins[j].inc_max && (
605 (value < bins[j].max) ||
606 FLT_EQ(value, bins[j].max)
607 )
608 )
609 ) {
611 sum++;
612 break;
613 }
614 }
615 }
616
617 else {
618 for (j = 0; j < bin_count; j++) {
619 if (
620 (!bins[j].inc_min && value > bins[j].min) || (
621 bins[j].inc_min && (
622 (value > bins[j].min) ||
623 FLT_EQ(value, bins[j].min)
624 )
625 )
626 ) {
628 sum++;
629 break;
630 }
631 }
632 }
633 }
634
635 for (i = 0; i < bin_count; i++) {
636 bins[i].
percent = ((double) bins[i].count) / sum;
637 }
638
639#if POSTGIS_DEBUG_LEVEL > 0
640 stop = clock();
641 elapsed = ((double) (stop - start)) / CLOCKS_PER_SEC;
643
644 for (j = 0; j < bin_count; j++) {
645 RASTER_DEBUGF(5,
"(min, max, inc_min, inc_max, count, sum, percent) = (%f, %f, %d, %d, %d, %d, %f)",
646 bins[j].min, bins[j].max, bins[j].inc_min, bins[j].inc_max, bins[j].count, sum, bins[j].percent);
647 }
648#endif
649
651 *rtn_count = bin_count;
653 return bins;
654}
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)