76 for (i = 0; i < 8; i++) number_of_returns_of_given_pulse[i] = 0;
77 for (i = 0; i < 32; i++) classification[i] = 0;
78 classification_synthetic = 0;
79 classification_keypoint = 0;
80 classification_withheld = 0;
101 if (point->
x < min.x) min.x = point->
x;
102 else if (point->
x > max.x) max.x = point->
x;
103 if (point->
y < min.y) min.y = point->
y;
104 else if (point->
y > max.y) max.y = point->
y;
105 if (point->
z < min.z) min.z = point->
z;
106 else if (point->
z > max.z) max.z = point->
z;
134 if (point->
rgb[0] < min.rgb[0]) min.rgb[0] = point->
rgb[0];
135 else if (point->
rgb[0] > max.rgb[0]) max.rgb[0] = point->
rgb[0];
136 if (point->
rgb[1] < min.rgb[1]) min.rgb[1] = point->
rgb[1];
137 else if (point->
rgb[1] > max.rgb[1]) max.rgb[1] = point->
rgb[1];
138 if (point->
rgb[2] < min.rgb[2]) min.rgb[2] = point->
rgb[2];
139 else if (point->
rgb[2] > max.rgb[2]) max.rgb[2] = point->
rgb[2];
166 this->one_over_step = 1.0f/
step;
178 if (bins_pos) free(bins_pos);
179 if (bins_neg) free(bins_neg);
180 if (values_pos) free(values_pos);
181 if (values_neg) free(values_neg);
224 bins_pos = (
U32*)malloc(
sizeof(
U32)*size_pos);
225 for (i = 0; i < size_pos; i++) bins_pos[i] = 0;
229 I32 new_size = bin + 1024;
230 bins_pos = (
U32*)realloc(bins_pos,
sizeof(
U32)*new_size);
231 for (i = size_pos; i < new_size; i++) bins_pos[i] = 0;
246 bins_neg = (
U32*)malloc(
sizeof(
U32)*size_neg);
247 for (i = 0; i < size_neg; i++) bins_neg[i] = 0;
251 I32 new_size = bin + 1024;
252 bins_neg = (
U32*)realloc(bins_neg,
sizeof(
U32)*new_size);
253 for (i = size_neg; i < new_size; i++) bins_neg[i] = 0;
280 bins_pos = (
U32*)malloc(
sizeof(
U32)*size_pos);
281 values_pos = (
F64*)malloc(
sizeof(
F64)*size_pos);
282 for (i = 0; i < size_pos; i++) { bins_pos[i] = 0; values_pos[i] = 0; }
286 I32 new_size = bin + 1024;
287 bins_pos = (
U32*)realloc(bins_pos,
sizeof(
U32)*new_size);
288 values_pos = (
F64*)realloc(values_pos,
sizeof(
F64)*new_size);
289 for (i = size_pos; i < new_size; i++) { bins_pos[i] = 0; values_pos[i] = 0; }
294 values_pos[bin] += value;
305 bins_neg = (
U32*)malloc(
sizeof(
U32)*size_neg);
306 values_neg = (
F64*)malloc(
sizeof(
F64)*size_pos);
307 for (i = 0; i < size_neg; i++) { bins_neg[i] = 0; values_neg[i] = 0; }
311 I32 new_size = bin + 1024;
312 bins_neg = (
U32*)realloc(bins_neg,
sizeof(
U32)*new_size);
313 values_neg = (
F64*)realloc(values_neg,
sizeof(
F64)*new_size);
314 for (i = size_neg; i < new_size; i++) { bins_neg[i] = 0; values_neg[i] = 0; }
319 values_neg[bin] += value;
331 fprintf(file,
"%s histogram of %s averages with bin size %g\012", name, name_avg, 1.0f/one_over_step);
333 fprintf(file,
"%s histogram of averages with bin size %g\012", name, 1.0f/one_over_step);
336 fprintf(file,
"%s histogram with bin size %g\012", name, 1.0f/one_over_step);
340 for (i = size_neg-1; i >= 0; i--)
344 bin = -(i+1) + anker;
345 if (one_over_step == 1)
348 fprintf(file,
" bin %d has average %g (of %d)\012", bin, values_neg[i]/bins_neg[i], bins_neg[i]);
350 fprintf(file,
" bin %d has %d\012", bin, bins_neg[i]);
355 fprintf(file,
" bin [%g,%g) has average %g (of %d)\012", ((
F32)bin)/one_over_step, ((
F32)(bin+1))/one_over_step, values_neg[i]/bins_neg[i], bins_neg[i]);
357 fprintf(file,
" bin [%g,%g) has %d\012", ((
F32)bin)/one_over_step, ((
F32)(bin+1))/one_over_step, bins_neg[i]);
364 for (i = 0; i < size_pos; i++)
369 if (one_over_step == 1)
372 fprintf(file,
" bin %d has average %g (of %d)\012", bin, values_pos[i]/bins_pos[i], bins_pos[i]);
374 fprintf(file,
" bin %d has %d\012", bin, bins_pos[i]);
379 fprintf(file,
" bin [%g,%g) average has %g (of %d)\012", ((
F32)bin)/one_over_step, ((
F32)(bin+1))/one_over_step, values_pos[i]/bins_pos[i], bins_pos[i]);
381 fprintf(file,
" bin [%g,%g) has %d\012", ((
F32)bin)/one_over_step, ((
F32)(bin+1))/one_over_step, bins_pos[i]);
387 fprintf(file,
" average %s %g\012", name, total/count);
389 fprintf(file,
" average %g\012", total/count);
400 classification_bin = 0;
402 point_source_id_bin = 0;
404 wavepacket_index_bin = 0;
405 wavepacket_offset_bin = 0;
406 wavepacket_size_bin = 0;
407 wavepacket_location_bin = 0;
409 classification_bin_intensity = 0;
410 classification_bin_scan_angle = 0;
411 scan_angle_bin_z = 0;
412 scan_angle_bin_intensity = 0;
413 scan_angle_bin_number_of_returns = 0;
414 return_map_bin_intensity = 0;
420 if (x_bin)
delete x_bin;
421 if (y_bin)
delete y_bin;
422 if (z_bin)
delete z_bin;
423 if (intensity_bin)
delete intensity_bin;
424 if (classification_bin)
delete classification_bin;
425 if (scan_angle_bin)
delete scan_angle_bin;
426 if (point_source_id_bin)
delete point_source_id_bin;
427 if (gps_time_bin)
delete gps_time_bin;
428 if (wavepacket_index_bin)
delete wavepacket_index_bin;
429 if (wavepacket_offset_bin)
delete wavepacket_offset_bin;
430 if (wavepacket_size_bin)
delete wavepacket_size_bin;
431 if (wavepacket_location_bin)
delete wavepacket_location_bin;
433 if (classification_bin_intensity)
delete classification_bin_intensity;
434 if (classification_bin_scan_angle)
delete classification_bin_scan_angle;
435 if (scan_angle_bin_z)
delete scan_angle_bin_z;
436 if (scan_angle_bin_intensity)
delete scan_angle_bin_intensity;
437 if (scan_angle_bin_number_of_returns)
delete scan_angle_bin_number_of_returns;
438 if (return_map_bin_intensity)
delete return_map_bin_intensity;
444 for (i = 1; i <
argc; i++)
446 if (argv[i][0] ==
'\0')
450 else if (strcmp(argv[i],
"-h") == 0 || strcmp(argv[i],
"-help") == 0)
454 else if (strcmp(argv[i],
"-histo") == 0)
458 fprintf(stderr,
"ERROR: '%s' needs 2 arguments: name step\n", argv[i]);
461 if (!histo(argv[i+1], (
F32)atof(argv[i+2])))
return FALSE;
462 *argv[i]=
'\0'; *argv[i+1]=
'\0'; *argv[i+2]=
'\0'; i+=2;
464 else if (strcmp(argv[i],
"-histo_avg") == 0)
468 fprintf(stderr,
"ERROR: '%s' needs 3 arguments: name step name_avg\n", argv[i]);
471 if (!histo_avg(argv[i+1], (
F32)atof(argv[i+2]), argv[i+3]))
return FALSE;
472 *argv[i]=
'\0'; *argv[i+1]=
'\0'; *argv[i+2]=
'\0'; *argv[i+3]=
'\0'; i+=3;
480 if (strcmp(name,
"x") == 0)
482 else if (strcmp(name,
"y") == 0)
484 else if (strcmp(name,
"z") == 0)
486 else if (strcmp(name,
"intensity") == 0)
487 intensity_bin =
new LASbin(step);
488 else if (strcmp(name,
"classification") == 0)
489 classification_bin =
new LASbin(step);
490 else if (strstr(name,
"scan_angle") != 0)
491 scan_angle_bin =
new LASbin(step);
492 else if (strstr(name,
"point_source") != 0)
493 point_source_id_bin =
new LASbin(step);
494 else if (strstr(name,
"gps_time") != 0)
495 gps_time_bin =
new LASbin(step);
496 else if (strstr(name,
"wavepacket_index") != 0)
497 wavepacket_index_bin =
new LASbin(step);
498 else if (strstr(name,
"wavepacket_offset") != 0)
499 wavepacket_offset_bin =
new LASbin(step);
500 else if (strstr(name,
"wavepacket_size") != 0)
501 wavepacket_size_bin =
new LASbin(step);
502 else if (strstr(name,
"wavepacket_location") != 0)
503 wavepacket_location_bin =
new LASbin(step);
506 fprintf(stderr,
"ERROR: histogram of '%s' not implemented\n", name);
515 if (strcmp(name,
"classification") == 0)
517 if (strcmp(name_avg,
"intensity") == 0)
518 classification_bin_intensity =
new LASbin(step);
519 else if (strstr(name_avg,
"scan_angle") != 0)
520 classification_bin_scan_angle =
new LASbin(step);
523 fprintf(stderr,
"ERROR: histogram of '%s' with '%s' averages not implemented\n", name, name_avg);
527 else if (strcmp(name,
"scan_angle") == 0)
529 if (strcmp(name_avg,
"z") == 0)
530 scan_angle_bin_z =
new LASbin(step);
531 else if (strcmp(name_avg,
"number_of_returns") == 0)
532 scan_angle_bin_number_of_returns =
new LASbin(step);
533 else if (strcmp(name_avg,
"intensity") == 0)
534 scan_angle_bin_intensity =
new LASbin(step);
537 fprintf(stderr,
"ERROR: histogram of '%s' with '%s' averages not implemented\n", name, name_avg);
541 else if (strcmp(name,
"return_map") == 0)
543 if (strcmp(name_avg,
"intensity") == 0)
544 return_map_bin_intensity =
new LASbin(1);
547 fprintf(stderr,
"ERROR: histogram of '%s' with '%s' averages not implemented\n", name, name_avg);
553 fprintf(stderr,
"ERROR: histogram of '%s' not implemented\n", name);
563 if (x_bin) x_bin->add(point->
x);
564 if (y_bin) y_bin->add(point->
y);
565 if (z_bin) z_bin->add(point->
z);
566 if (intensity_bin) intensity_bin->add(point->
intensity);
567 if (classification_bin) classification_bin->add(point->
classification);
569 if (point_source_id_bin) point_source_id_bin->add(point->
point_source_ID);
570 if (gps_time_bin) gps_time_bin->add(point->
gps_time);
578 if (scan_angle_bin_z) scan_angle_bin_z->add(point->
scan_angle_rank, point->
z);
581 if (return_map_bin_intensity)
585 return_map_bin_intensity->add((n == 1 ? 0 : (n == 2 ? r : (n == 3 ? r+2 : (n == 4 ? r+5 : (n == 5 ? r+9 : 15))))), point->
intensity);
592 if (x_bin) x_bin->report(file,
"x coordinate");
593 if (y_bin) y_bin->report(file,
"y coordinate");
594 if (z_bin) z_bin->report(file,
"z coordinate");
595 if (intensity_bin) intensity_bin->report(file,
"intensity");
596 if (classification_bin) classification_bin->report(file,
"classification");
597 if (scan_angle_bin) scan_angle_bin->report(file,
"scan angle");
598 if (point_source_id_bin) point_source_id_bin->report(file,
"point source id");
599 if (gps_time_bin) gps_time_bin->report(file,
"gps_time");
600 if (wavepacket_index_bin) wavepacket_index_bin->report(file,
"wavepacket_index");
601 if (wavepacket_offset_bin) wavepacket_offset_bin->report(file,
"wavepacket_offset");
602 if (wavepacket_size_bin) wavepacket_size_bin->report(file,
"wavepacket_size");
603 if (wavepacket_location_bin) wavepacket_location_bin->report(file,
"wavepacket_location");
605 if (classification_bin_intensity) classification_bin_intensity->report(file,
"classification",
"intensity");
606 if (classification_bin_scan_angle) classification_bin_scan_angle->report(file,
"classification",
"scan_angle");
607 if (scan_angle_bin_z) scan_angle_bin_z->report(file,
"scan angle",
"z coordinate");
608 if (scan_angle_bin_number_of_returns) scan_angle_bin_number_of_returns->report(file,
"scan_angle",
"number_of_returns");
609 if (scan_angle_bin_intensity) scan_angle_bin_intensity->report(file,
"scan angle",
"intensity");
610 if (return_map_bin_intensity) return_map_bin_intensity->report(file,
"return map",
"intensity");
616 if (grid_spacing < 0)
618 grid_spacing = -grid_spacing;
622 min_x = max_x = pos_x;
623 min_y = max_y = pos_y;
629 if (pos_x < min_x) min_x = pos_x;
else if (pos_x > max_x) max_x = pos_x;
630 if (pos_y < min_y) min_y = pos_y;
else if (pos_y > max_y) max_y = pos_y;
632 return add_internal(pos_x, pos_y);
637 if (grid_spacing < 0)
639 grid_spacing = -grid_spacing;
641 min_x = max_x = pos_x;
642 min_y = max_y = pos_y;
646 if (pos_x < min_x) min_x = pos_x;
else if (pos_x > max_x) max_x = pos_x;
647 if (pos_y < min_y) min_y = pos_y;
else if (pos_y > max_y) max_y = pos_y;
649 return add_internal(pos_x, pos_y);
654 pos_y = pos_y - anker;
663 ankers = &minus_ankers;
664 if ((
U32)pos_y < minus_plus_size && minus_plus_sizes[pos_y])
666 pos_x -= minus_ankers[pos_y];
670 array_size = &minus_minus_size;
671 array = &minus_minus;
672 array_sizes = &minus_minus_sizes;
676 array_size = &minus_plus_size;
678 array_sizes = &minus_plus_sizes;
684 array_size = &minus_plus_size;
686 array_sizes = &minus_plus_sizes;
691 ankers = &plus_ankers;
692 if ((
U32)pos_y < plus_plus_size && plus_plus_sizes[pos_y])
694 pos_x -= plus_ankers[pos_y];
698 array_size = &plus_minus_size;
700 array_sizes = &plus_minus_sizes;
704 array_size = &plus_plus_size;
706 array_sizes = &plus_plus_sizes;
712 array_size = &plus_plus_size;
714 array_sizes = &plus_plus_sizes;
718 if ((
U32)pos_y >= *array_size)
720 U32 array_size_new = ((pos_y/1024)+1)*1024;
723 if (array == &minus_plus || array == &plus_plus) *ankers = (
I32*)realloc(*ankers, array_size_new*
sizeof(
I32));
724 *array = (
U32**)realloc(*array, array_size_new*
sizeof(
U32*));
725 *array_sizes = (
U16*)realloc(*array_sizes, array_size_new*
sizeof(
U16));
729 if (array == &minus_plus || array == &plus_plus) *ankers = (
I32*)malloc(array_size_new*
sizeof(
I32));
730 *array = (
U32**)malloc(array_size_new*
sizeof(
U32*));
731 *array_sizes = (
U16*)malloc(array_size_new*
sizeof(
U16));
733 for (
U32 i = *array_size; i < array_size_new; i++)
736 (*array_sizes)[i] = 0;
738 *array_size = array_size_new;
743 (*ankers)[pos_y] = pos_x;
747 U32 pos_x_pos = pos_x/32;
748 if (pos_x_pos >= (*array_sizes)[pos_y])
750 U32 array_sizes_new = ((pos_x_pos/256)+1)*256;
751 if ((*array_sizes)[pos_y])
753 (*array)[pos_y] = (
U32*)realloc((*array)[pos_y], array_sizes_new*
sizeof(
U32));
757 (*array)[pos_y] = (
U32*)malloc(array_sizes_new*
sizeof(
U32));
759 for (
U16 i = (*array_sizes)[pos_y]; i < array_sizes_new; i++)
761 (*array)[pos_y][i] = 0;
763 (*array_sizes)[pos_y] = array_sizes_new;
765 U32 pos_x_bit = 1 << (pos_x%32);
766 if ((*array)[pos_y][pos_x_pos] & pos_x_bit)
return FALSE;
767 (*array)[pos_y][pos_x_pos] |= pos_x_bit;
776 return occupied(pos_x, pos_y);
781 if (grid_spacing < 0)
785 pos_y = pos_y - anker;
788 const U32*
const * array;
789 const U16* array_sizes;
793 ankers = minus_ankers;
794 if ((
U32)pos_y < minus_plus_size && minus_plus_sizes[pos_y])
796 pos_x -= minus_ankers[pos_y];
800 array_size = minus_minus_size;
802 array_sizes = minus_minus_sizes;
806 array_size = minus_plus_size;
808 array_sizes = minus_plus_sizes;
818 ankers = plus_ankers;
819 if ((
U32)pos_y < plus_plus_size && plus_plus_sizes[pos_y])
821 pos_x -= plus_ankers[pos_y];
825 array_size = plus_minus_size;
827 array_sizes = plus_minus_sizes;
831 array_size = plus_plus_size;
833 array_sizes = plus_plus_sizes;
842 if ((
U32)pos_y >= array_size)
847 U32 pos_x_pos = pos_x/32;
848 if (pos_x_pos >= array_sizes[pos_y])
852 U32 pos_x_bit = 1 << (pos_x%32);
853 if (array[pos_y][pos_x_pos] & pos_x_bit)
return TRUE;
859 if (grid_spacing < 0)
return FALSE;
865 min_x = min_y = max_x = max_y = 0;
866 if (grid_spacing > 0) grid_spacing = -grid_spacing;
867 if (minus_minus_size)
869 for (
U32 i = 0; i < minus_minus_size; i++)
if (minus_minus[i]) free(minus_minus[i]);
872 free(minus_minus_sizes);
873 minus_minus_sizes = 0;
874 minus_minus_size = 0;
880 for (
U32 i = 0; i < minus_plus_size; i++)
if (minus_plus[i]) free(minus_plus[i]);
883 free(minus_plus_sizes);
884 minus_plus_sizes = 0;
889 for (
U32 i = 0; i < plus_minus_size; i++)
if (plus_minus[i]) free(plus_minus[i]);
892 free(plus_minus_sizes);
893 plus_minus_sizes = 0;
900 for (
U32 i = 0; i < plus_plus_size; i++)
if (plus_plus[i]) free(plus_plus[i]);
903 free(plus_plus_sizes);
912 FILE*
file = fopen(file_name,
"w");
913 if (file == 0)
return FALSE;
914 fprintf(file,
"ncols %d\012", max_x-min_x+1);
915 fprintf(file,
"nrows %d\012", max_y-min_y+1);
916 fprintf(file,
"xllcorner %f\012", grid_spacing*min_x);
917 fprintf(file,
"yllcorner %f\012", grid_spacing*min_y);
918 fprintf(file,
"cellsize %lf\012", grid_spacing);
919 fprintf(file,
"NODATA_value %d\012", 0);
920 fprintf(file,
"\012");
922 for (pos_y = min_y; pos_y <= max_y; pos_y++)
924 for (pos_x = min_x; pos_x <= max_x; pos_x++)
926 if (occupied(pos_x, pos_y))
935 fprintf(file,
"\012");
943 min_x = min_y = max_x = max_y = 0;
944 this->grid_spacing = -grid_spacing;
946 minus_minus_size = 0;
948 minus_minus_sizes = 0;
951 minus_plus_sizes = 0;
955 plus_minus_sizes = 0;
BOOL write_asc_grid(const char *file_name) const
BOOL parse(int argc, char *argv[])
BOOL occupied(const LASpoint *point) const
BOOL add(const LASpoint *point)
void report(FILE *file) const
BOOL add(const LASpoint *point)
LASoccupancyGrid(F32 grid_spacing)
BOOL add(const LASpoint *point)
U32 number_of_point_records
void report(FILE *file, const char *name=0, const char *name_avg=0) const
void add(const LASpoint *point)
BOOL histo_avg(const char *name, F32 step, const char *name_avg)
U32 number_of_points_by_return[8]
BOOL add_internal(I32 pos_x, I32 pos_y)
BOOL histo(const char *name, F32 step)
U8 number_of_returns_of_given_pulse