int main() { //las testing tooo.... LASreadOpener lasreadopener; LASreader * lasreader; lasreadopener.set_file_name(las_path); lasreader = lasreadopener.open(); if(!lasreader){ PyErr_SetString(PyExc_IOError, "Could not open lidar file."); return NULL; } while(lasreader->read_point()) { //printf("%u of %u\n", pcnt++, npts); if(lasreader->point.classification != 1) continue; double x_coord = (lasreader->point.x * lasreader->point.quantizer->x_scale_factor) + lasreader->point.quantizer->x_offset; double y_coord = (lasreader->point.y * lasreader->point.quantizer->y_scale_factor) + lasreader->point.quantizer->y_offset; double z_coord = (lasreader->point.z * lasreader->point.quantizer->z_scale_factor) + lasreader->point.quantizer->z_offset; printf("(%lf, %lf, %lf)(%lf, %lf, %lf)", x_coord, y_coord, z_coord, lasreader->point.x, lasreader->point.quantizer->x_scale_factor,lasreader->point.quantizer->x_offset); } lasreader->close(); delete lasreader; /* int j; for(j = 0; j < 10000; j++) { List * float_list = initList(); int i; for(i = 0; i < 100; i++) { float fdata = (float) i; float * data = (float *) malloc(sizeof(float)); *data = fdata; if(!addFront(float_list, data)){ printf("Error\n"); return 0; } } freeList(float_list); } return 1; */ }
int main(int argc, char *argv[]) { int i; bool verbose = false; double start_time = 0.0; LASreadOpener lasreadopener; LASwriteOpener laswriteopener; if (argc == 1) { fprintf(stderr,"%s is better run in the command line\n", argv[0]); char file_name[256]; fprintf(stderr,"enter input file: "); fgets(file_name, 256, stdin); file_name[strlen(file_name)-1] = '\0'; lasreadopener.set_file_name(file_name); fprintf(stderr,"enter output file: "); fgets(file_name, 256, stdin); file_name[strlen(file_name)-1] = '\0'; laswriteopener.set_file_name(file_name); } else { lasreadopener.parse(argc, argv); laswriteopener.parse(argc, argv); } for (i = 1; i < argc; i++) { if (argv[i][0] == '\0') { continue; } else if (strcmp(argv[i],"-h") == 0 || strcmp(argv[i],"-help") == 0) { usage(); } else if (strcmp(argv[i],"-v") == 0 || strcmp(argv[i],"-verbose") == 0) { verbose = true; } else if (i == argc - 2 && !lasreadopener.active() && !laswriteopener.active()) { lasreadopener.set_file_name(argv[i]); } else if (i == argc - 1 && !lasreadopener.active() && !laswriteopener.active()) { lasreadopener.set_file_name(argv[i]); } else if (i == argc - 1 && lasreadopener.active() && !laswriteopener.active()) { laswriteopener.set_file_name(argv[i]); } else { fprintf(stderr, "ERROR: cannot understand argument '%s'\n", argv[i]); usage(); } } if (verbose) start_time = taketime(); // check input & output if (!lasreadopener.active()) { fprintf(stderr,"ERROR: no input specified\n"); usage(argc == 1); } if (!laswriteopener.active()) { fprintf(stderr,"ERROR: no output specified\n"); usage(argc == 1); } // open lasreader LASreader* lasreader = lasreadopener.open(); if (lasreader == 0) { fprintf(stderr, "ERROR: could not open lasreader\n"); byebye(argc==1); } // open laswriter LASwriter* laswriter = laswriteopener.open(&lasreader->header); if (laswriter == 0) { fprintf(stderr, "ERROR: could not open laswriter\n"); byebye(argc==1); } #ifdef _WIN32 if (verbose) fprintf(stderr, "reading %I64d points from '%s' and writing them modified to '%s'.\n", lasreader->npoints, lasreadopener.get_file_name(), laswriteopener.get_file_name()); #else if (verbose) fprintf(stderr, "reading %lld points from '%s' and writing them modified to '%s'.\n", lasreader->npoints, lasreadopener.get_file_name(), laswriteopener.get_file_name()); #endif // loop over points and modify them // where there is a point to read while (lasreader->read_point()) { // modify the point lasreader->point.set_point_source_ID(1020); lasreader->point.set_user_data(42); if (lasreader->point.get_classification() == 12) lasreader->point.set_classification(1); lasreader->point.set_Z(lasreader->point.get_Z() + 10); // write the modified point laswriter->write_point(&lasreader->point); // add it to the inventory laswriter->update_inventory(&lasreader->point); } laswriter->update_header(&lasreader->header, TRUE); I64 total_bytes = laswriter->close(); delete laswriter; #ifdef _WIN32 if (verbose) fprintf(stderr,"total time: %g sec %I64d bytes for %I64d points\n", taketime()-start_time, total_bytes, lasreader->p_count); #else if (verbose) fprintf(stderr,"total time: %g sec %lld bytes for %lld points\n", taketime()-start_time, total_bytes, lasreader->p_count); #endif lasreader->close(); delete lasreader; return 0; }
int main(int argc, char *argv[]) { int i; #ifdef COMPILE_WITH_GUI bool gui = false; #endif #ifdef COMPILE_WITH_MULTI_CORE I32 cores = 1; #endif bool verbose = false; bool report_diff = true; bool report_diff_diff = false; bool report_x = true; bool report_y = true; bool report_z = true; bool report_gps = false; bool report_rgb = false; bool output = false; U32 report_lines = 20; U32 array_max = 5000000; bool projection_was_set = false; double start_time = 0; double full_start_time = 0; LASreadOpener lasreadopener; GeoProjectionConverter geoprojectionconverter; LASwriteOpener laswriteopener; if (argc == 1) { #ifdef COMPILE_WITH_GUI return lasprecision_gui(argc, argv, 0); #else fprintf(stderr,"lasprecision.exe is better run in the command line\n"); char file_name[256]; fprintf(stderr,"enter input file: "); fgets(file_name, 256, stdin); file_name[strlen(file_name)-1] = '\0'; lasreadopener.set_file_name(file_name); fprintf(stderr,"enter output file: "); fgets(file_name, 256, stdin); file_name[strlen(file_name)-1] = '\0'; laswriteopener.set_file_name(file_name); #endif } else { for (i = 1; i < argc; i++) { if (argv[i][0] == '–') argv[i][0] = '-'; if (strcmp(argv[i],"-o") == 0 || strcmp(argv[i],"-olas") == 0 || strcmp(argv[i],"-olaz") == 0 || strcmp(argv[i],"-obin") == 0 || strcmp(argv[i],"-otxt") == 0 || strcmp(argv[i],"-reoffset") == 0 || strcmp(argv[i],"-rescale") == 0) { output = true; break; } } if (!geoprojectionconverter.parse(argc, argv)) byebye(true); if (!lasreadopener.parse(argc, argv)) byebye(true); if (!laswriteopener.parse(argc, argv)) byebye(true); } for (i = 1; i < argc; i++) { if (argv[i][0] == '\0') { continue; } else if (strcmp(argv[i],"-h") == 0 || strcmp(argv[i],"-help") == 0) { fprintf(stderr, "LAStools (by [email protected]) version %d\n", LAS_TOOLS_VERSION); usage(); } else if (strcmp(argv[i],"-v") == 0 || strcmp(argv[i],"-verbose") == 0) { verbose = true; } else if (strcmp(argv[i],"-version") == 0) { fprintf(stderr, "LAStools (by [email protected]) version %d\n", LAS_TOOLS_VERSION); byebye(); } else if (strcmp(argv[i],"-gui") == 0) { #ifdef COMPILE_WITH_GUI gui = true; #else fprintf(stderr, "WARNING: not compiled with GUI support. ignoring '-gui' ...\n"); #endif } else if (strcmp(argv[i],"-cores") == 0) { #ifdef COMPILE_WITH_MULTI_CORE if ((i+1) >= argc) { fprintf(stderr,"ERROR: '%s' needs 1 argument: number\n", argv[i]); usage(true); } argv[i][0] = '\0'; i++; cores = atoi(argv[i]); argv[i][0] = '\0'; #else fprintf(stderr, "WARNING: not compiled with multi-core batching. ignoring '-cores' ...\n"); i++; #endif } else if ((strcmp(argv[i],"-diff_diff") == 0) || (strcmp(argv[i],"-diff_diff_only") == 0)) { report_diff_diff = true; report_diff = false; } else if (strcmp(argv[i],"-no_x") == 0) { report_x = false; } else if (strcmp(argv[i],"-no_y") == 0) { report_y = false; } else if (strcmp(argv[i],"-no_z") == 0) { report_z = false; } else if (strcmp(argv[i],"-gps") == 0) { report_gps = true; } else if (strcmp(argv[i],"-rgb") == 0) { report_rgb = true; } else if (strcmp(argv[i],"-number") == 0) { if ((i+1) >= argc) { fprintf(stderr,"ERROR: '%s' needs 1 argument: max\n", argv[i]); byebye(true); } i++; array_max = atoi(argv[i]); } else if (strcmp(argv[i],"-lines") == 0) { if ((i+1) >= argc) { fprintf(stderr,"ERROR: '%s' needs 1 argument: number\n", argv[i]); byebye(true); } i++; report_lines = atoi(argv[i]); } else if (strcmp(argv[i],"-all") == 0) { array_max = U32_MAX; } else if ((argv[i][0] != '-') && (lasreadopener.get_file_name_number() == 0)) { lasreadopener.add_file_name(argv[i]); argv[i][0] = '\0'; } else { fprintf(stderr, "ERROR: cannot understand argument '%s'\n", argv[i]); byebye(true); } } #ifdef COMPILE_WITH_GUI if (gui) { return lasprecision_gui(argc, argv, &lasreadopener); } #endif #ifdef COMPILE_WITH_MULTI_CORE if ((cores > 1) && (lasreadopener.get_file_name_number() > 1) && (!lasreadopener.is_merged())) { return lasprecision_multi_core(argc, argv, &geoprojectionconverter, &lasreadopener, &laswriteopener, cores); } #endif // check input if (!lasreadopener.active()) { fprintf(stderr, "ERROR: no input specified\n"); byebye(true, argc==1); } // make sure we do not corrupt the input file if (lasreadopener.get_file_name() && laswriteopener.get_file_name() && (strcmp(lasreadopener.get_file_name(), laswriteopener.get_file_name()) == 0)) { fprintf(stderr, "ERROR: input and output file name are identical\n"); usage(true); } // check if projection info was set in the command line int number_of_keys; GeoProjectionGeoKeys* geo_keys = 0; int num_geo_double_params; double* geo_double_params = 0; if (geoprojectionconverter.has_projection()) { projection_was_set = geoprojectionconverter.get_geo_keys_from_projection(number_of_keys, &geo_keys, num_geo_double_params, &geo_double_params); } // possibly loop over multiple input files while (lasreadopener.active()) { if (verbose) full_start_time = start_time = taketime(); // open lasreader LASreader* lasreader = lasreadopener.open(); if (lasreader == 0) { fprintf(stderr, "ERROR: could not open lasreader\n"); byebye(true, argc==1); } // run presicion statistics across the first array_max points if (!output) { fprintf(stdout, "original scale factors: %g %g %g\n", lasreader->header.x_scale_factor, lasreader->header.y_scale_factor, lasreader->header.z_scale_factor); // create the arrays int* array_x = 0; int* array_y = 0; int* array_z = 0; if (report_x) { array_x = new int[array_max]; } if (report_y) { array_y = new int[array_max]; } if (report_z) { array_z = new int[array_max]; } double* array_gps = 0; if (report_gps && lasreader->point.have_gps_time) { array_gps = new double[array_max]; } short* array_r = 0; short* array_g = 0; short* array_b = 0; if (report_rgb && lasreader->point.have_rgb) { array_r = new short[array_max]; array_g = new short[array_max]; array_b = new short[array_max]; } // do the first pass fprintf(stderr, "loading first %u of %u points\n", array_max, (U32)lasreader->npoints); // loop over points unsigned int array_count = 0; while ((lasreader->read_point()) && (array_count < array_max)) { if (report_x) { array_x[array_count] = lasreader->point.get_X(); } if (report_y) { array_y[array_count] = lasreader->point.get_Y(); } if (report_z) { array_z[array_count] = lasreader->point.get_Z(); } if (report_gps && lasreader->point.have_gps_time) { array_gps[array_count] = lasreader->point.gps_time; } if (report_rgb && lasreader->point.have_rgb) { array_r[array_count] = lasreader->point.rgb[0]; array_g[array_count] = lasreader->point.rgb[1]; array_b[array_count] = lasreader->point.rgb[2]; } array_count++; } array_max = array_count; // sort values if (report_x) { quicksort_for_ints(array_x, 0, array_max-1); } if (report_y) { quicksort_for_ints(array_y, 0, array_max-1); } if (report_z) { quicksort_for_ints(array_z, 0, array_max-1); } if (report_gps && lasreader->point.have_gps_time) { quicksort_for_doubles(array_gps, 0, array_max-1); } if (report_rgb && lasreader->point.have_rgb) { quicksort_for_shorts(array_r, 0, array_max-1); quicksort_for_shorts(array_g, 0, array_max-1); quicksort_for_shorts(array_b, 0, array_max-1); } // create differences if (report_x) { for (array_count = 1; array_count < array_max; array_count++) { array_x[array_count-1] = array_x[array_count] - array_x[array_count-1]; } } if (report_y) { for (array_count = 1; array_count < array_max; array_count++) { array_y[array_count-1] = array_y[array_count] - array_y[array_count-1]; } } if (report_z) { for (array_count = 1; array_count < array_max; array_count++) { array_z[array_count-1] = array_z[array_count] - array_z[array_count-1]; } } if (report_gps && lasreader->point.have_gps_time) { for (array_count = 1; array_count < array_max; array_count++) { array_gps[array_count-1] = array_gps[array_count] - array_gps[array_count-1]; } } if (report_rgb && lasreader->point.have_rgb) { for (array_count = 1; array_count < array_max; array_count++) { array_r[array_count-1] = array_r[array_count] - array_r[array_count-1]; array_g[array_count-1] = array_g[array_count] - array_g[array_count-1]; array_b[array_count-1] = array_b[array_count] - array_b[array_count-1]; } } // sort differences if (report_x) { quicksort_for_ints(array_x, 0, array_max-2); } if (report_y) { quicksort_for_ints(array_y, 0, array_max-2); } if (report_z) { quicksort_for_ints(array_z, 0, array_max-2); } if (report_gps && lasreader->point.have_gps_time) { quicksort_for_doubles(array_gps, 0, array_max-2); } if (report_rgb && lasreader->point.have_rgb) { quicksort_for_shorts(array_r, 0, array_max-2); quicksort_for_shorts(array_g, 0, array_max-2); quicksort_for_shorts(array_b, 0, array_max-2); } // compute difference of differences, sort them, output histogram // first for X & Y & Z unsigned int count_lines, array_last, array_first; if (report_x) { if (report_diff) fprintf(stdout, "X differences \n"); for (count_lines = 0, array_first = 0, array_last = 0, array_count = 1; array_count < array_max; array_count++) { if (array_x[array_last] != array_x[array_count]) { if (report_diff && (count_lines < report_lines)) { count_lines++; fprintf(stdout, " %10d : %10d %g\n", array_x[array_last], array_count - array_last, lasreader->header.x_scale_factor*array_x[array_last]); } array_x[array_first] = array_x[array_count] - array_x[array_last]; array_last = array_count; array_first++; } } if (report_diff_diff) { fprintf(stdout, "X differences of differences\n"); quicksort_for_ints(array_x, 0, array_first-1); for (array_last = 0, array_count = 1; array_count < array_first; array_count++) { if (array_x[array_last] != array_x[array_count]) { fprintf(stdout, " %10d : %10d\n", array_x[array_last], array_count - array_last); array_last = array_count; } } } } if (report_y) { if (report_diff) fprintf(stdout, "Y differences \n"); for (count_lines = 0, array_first = 0, array_last = 0, array_count = 1; array_count < array_max; array_count++) { if (array_y[array_last] != array_y[array_count]) { if (report_diff && (count_lines < report_lines)) { count_lines++; fprintf(stdout, " %10d : %10d %g\n", array_y[array_last], array_count - array_last, lasreader->header.y_scale_factor*array_y[array_last]); } array_y[array_first] = array_y[array_count] - array_y[array_last]; array_last = array_count; array_first++; } } if (report_diff_diff) { fprintf(stdout, "Y differences of differences\n"); quicksort_for_ints(array_y, 0, array_first-1); for (array_last = 0, array_count = 1; array_count < array_first; array_count++) { if (array_y[array_last] != array_y[array_count]) { fprintf(stdout, " %10d : %10d\n", array_y[array_last], array_count - array_last); array_last = array_count; } } } } if (report_z) { if (report_diff) fprintf(stdout, "Z differences \n"); for (count_lines = 0, array_first = 0, array_last = 0, array_count = 1; array_count < array_max; array_count++) { if (array_z[array_last] != array_z[array_count]) { if (report_diff && (count_lines < report_lines)) { count_lines++; fprintf(stdout, " %10d : %10d %g\n", array_z[array_last], array_count - array_last, lasreader->header.z_scale_factor*array_z[array_last]); } array_z[array_first] = array_z[array_count] - array_z[array_last]; array_last = array_count; array_first++; } } if (report_diff_diff) { fprintf(stdout, "Z differences of differences\n"); quicksort_for_ints(array_z, 0, array_first-1); for (array_last = 0, array_count = 1; array_count < array_first; array_count++) { if (array_z[array_last] != array_z[array_count]) { fprintf(stdout, " %10d : %10d\n", array_z[array_last], array_count - array_last); array_last = array_count; } } } } // then for GPS if (report_gps && lasreader->point.have_gps_time) { if (report_diff) fprintf(stdout, "GPS time differences \n"); for (array_first = 0, array_last = 0, array_count = 1; array_count < array_max; array_count++) { if (array_gps[array_last] != array_gps[array_count]) { if (report_diff) fprintf(stdout, " %.10g : %10d\n", array_gps[array_last], array_count - array_last); array_gps[array_first] = array_gps[array_count] - array_gps[array_last]; array_last = array_count; array_first++; } } if (report_diff_diff) { fprintf(stdout, "GPS time differences of differences\n"); quicksort_for_doubles(array_gps, 0, array_first-1); for (array_last = 0, array_count = 1; array_count < array_first; array_count++) { if (array_gps[array_last] != array_gps[array_count]) { fprintf(stdout, " %.10g : %10d\n", array_gps[array_last], array_count - array_last); array_last = array_count; } } } } // then for R & G & B if (report_rgb && lasreader->point.have_rgb) { if (report_diff) fprintf(stdout, "R differences \n"); for (array_first = 0, array_last = 0, array_count = 1; array_count < array_max; array_count++) { if (array_r[array_last] != array_r[array_count]) { if (report_diff) fprintf(stdout, " %10d : %10d\n", array_r[array_last], array_count - array_last); array_r[array_first] = array_r[array_count] - array_r[array_last]; array_last = array_count; array_first++; } } if (report_diff_diff) { fprintf(stdout, "R differences of differences\n"); quicksort_for_shorts(array_r, 0, array_first-1); for (array_last = 0, array_count = 1; array_count < array_first; array_count++) { if (array_r[array_last] != array_r[array_count]) { fprintf(stdout, " %10d : %10d\n", array_r[array_last], array_count - array_last); array_last = array_count; } } } if (report_diff) fprintf(stdout, "G differences \n"); for (array_first = 0, array_last = 0, array_count = 1; array_count < array_max; array_count++) { if (array_g[array_last] != array_g[array_count]) { if (report_diff) fprintf(stdout, " %10d : %10d\n", array_g[array_last], array_count - array_last); array_g[array_first] = array_g[array_count] - array_g[array_last]; array_last = array_count; array_first++; } } if (report_diff_diff) { fprintf(stdout, "G differences of differences\n"); quicksort_for_shorts(array_g, 0, array_first-1); for (array_last = 0, array_count = 1; array_count < array_first; array_count++) { if (array_g[array_last] != array_g[array_count]) { fprintf(stdout, " %10d : %10d\n", array_g[array_last], array_count - array_last); array_last = array_count; } } } if (report_diff) fprintf(stdout, "B differences \n"); for (array_first = 0, array_last = 0, array_count = 1; array_count < array_max; array_count++) { if (array_b[array_last] != array_b[array_count]) { if (report_diff) fprintf(stdout, " %10d : %10d\n", array_b[array_last], array_count - array_last); array_b[array_first] = array_b[array_count] - array_b[array_last]; array_last = array_count; array_first++; } } if (report_diff_diff) { fprintf(stdout, "B differences of differences\n"); quicksort_for_shorts(array_b, 0, array_first-1); for (array_last = 0, array_count = 1; array_count < array_first; array_count++) { if (array_b[array_last] != array_b[array_count]) { fprintf(stdout, " %10d : %10d\n", array_b[array_last], array_count - array_last); array_last = array_count; } } } } if (array_x) delete [] array_x; if (array_y) delete [] array_y; if (array_z) delete [] array_z; if (array_gps) delete [] array_gps; if (array_r) delete [] array_r; if (array_g) delete [] array_g; if (array_b) delete [] array_b; } else { // check output fprintf(stdout, "new scale factors: %g %g %g\n", lasreader->header.x_scale_factor, lasreader->header.y_scale_factor, lasreader->header.z_scale_factor); // check output if (!laswriteopener.active()) { // create name from input name laswriteopener.make_file_name(lasreadopener.get_file_name()); } // prepare the header for the surviving points strncpy(lasreader->header.system_identifier, "LAStools (c) by rapidlasso GmbH", 32); lasreader->header.system_identifier[31] = '\0'; char temp[64]; sprintf(temp, "lasprecision (%d)", LAS_TOOLS_VERSION); strncpy(lasreader->header.generating_software, temp, 32); lasreader->header.generating_software[31] = '\0'; if (projection_was_set) { lasreader->header.set_geo_keys(number_of_keys, (LASvlr_key_entry*)geo_keys); if (geo_double_params) { lasreader->header.set_geo_double_params(num_geo_double_params, geo_double_params); } else { lasreader->header.del_geo_double_params(); } lasreader->header.del_geo_ascii_params(); } // open laswriter LASwriter* laswriter = laswriteopener.open(&lasreader->header); if (laswriter == 0) { fprintf(stderr, "ERROR: could not open laswriter\n"); usage(argc==1); } // loop over points while (lasreader->read_point()) { laswriter->write_point(&lasreader->point); laswriter->update_inventory(&lasreader->point); } laswriter->update_header(&lasreader->header, TRUE); laswriter->close(); delete laswriter; laswriteopener.set_file_name(0); } lasreader->close(); delete lasreader; } if (projection_was_set) { free(geo_keys); if (geo_double_params) { free(geo_double_params); } } byebye(false, argc==1); return 0; }
int main(int argc, char *argv[]) { int i; #ifdef COMPILE_WITH_GUI bool gui = false; #endif #ifdef COMPILE_WITH_MULTI_CORE I32 cores = 1; #endif bool verbose = false; F32 tile_size = 0.0f; U32 threshold = 1000; U32 minimum_points = 100000; I32 maximum_intervals = -20; BOOL append = FALSE; F64 start_time = 0.0; F64 total_start_time = 0.0; LASreadOpener lasreadopener; if (argc == 1) { #ifdef COMPILE_WITH_GUI return lasindex_gui(argc, argv, 0); #else fprintf(stderr,"lasindex.exe is better run in the command line or via the lastool.exe GUI\n"); char file_name[256]; fprintf(stderr,"enter input file: "); fgets(file_name, 256, stdin); file_name[strlen(file_name)-1] = '\0'; lasreadopener.set_file_name(file_name); #endif } else { for (i = 1; i < argc; i++) { if (argv[i][0] == '–') argv[i][0] = '-'; } if (!lasreadopener.parse(argc, argv)) byebye(true); } for (i = 1; i < argc; i++) { if (argv[i][0] == '\0') { continue; } else if (strcmp(argv[i],"-h") == 0 || strcmp(argv[i],"-help") == 0) { fprintf(stderr, "LAStools (by [email protected]) version %d\n", LAS_TOOLS_VERSION); usage(); } else if (strcmp(argv[i],"-v") == 0 || strcmp(argv[i],"-verbose") == 0) { verbose = true; } else if (strcmp(argv[i],"-version") == 0) { fprintf(stderr, "LAStools (by [email protected]) version %d\n", LAS_TOOLS_VERSION); byebye(); } else if (strcmp(argv[i],"-gui") == 0) { #ifdef COMPILE_WITH_GUI gui = true; #else fprintf(stderr, "WARNING: not compiled with GUI support. ignoring '-gui' ...\n"); #endif } else if (strcmp(argv[i],"-cores") == 0) { #ifdef COMPILE_WITH_MULTI_CORE if ((i+1) >= argc) { fprintf(stderr,"ERROR: '%s' needs 1 argument: number\n", argv[i]); usage(true); } argv[i][0] = '\0'; i++; cores = atoi(argv[i]); argv[i][0] = '\0'; #else fprintf(stderr, "WARNING: not compiled with multi-core batching. ignoring '-cores' ...\n"); i++; #endif } else if (strcmp(argv[i],"-tile_size") == 0) { if ((i+1) >= argc) { fprintf(stderr,"ERROR: '%s' needs 1 argument: size\n", argv[i]); byebye(true); } i++; tile_size = (F32)atof(argv[i]); } else if (strcmp(argv[i],"-maximum") == 0) { if ((i+1) >= argc) { fprintf(stderr,"ERROR: '%s' needs 1 argument: number\n", argv[i]); byebye(true); } i++; maximum_intervals = atoi(argv[i]); } else if (strcmp(argv[i],"-minimum") == 0) { if ((i+1) >= argc) { fprintf(stderr,"ERROR: '%s' needs 1 argument: number\n", argv[i]); byebye(true); } i++; minimum_points = atoi(argv[i]); } else if (strcmp(argv[i],"-threshold") == 0) { if ((i+1) >= argc) { fprintf(stderr,"ERROR: '%s' needs 1 argument: value\n", argv[i]); byebye(true); } i++; threshold = atoi(argv[i]); } else if (strcmp(argv[i],"-append") == 0) { append = TRUE; } else { fprintf(stderr, "ERROR: cannot understand argument '%s'\n", argv[i]); byebye(true); } } #ifdef COMPILE_WITH_GUI if (gui) { return lasindex_gui(argc, argv, &lasreadopener); } #endif #ifdef COMPILE_WITH_MULTI_CORE if (cores > 1) { if (lasreadopener.get_file_name_number() < 2) { fprintf(stderr,"WARNING: only %u input files. ignoring '-cores %d' ...\n", lasreadopener.get_file_name_number(), cores); } else if (lasreadopener.is_merged()) { fprintf(stderr,"WARNING: input files merged on-the-fly. ignoring '-cores %d' ...\n", cores); } else { return lasindex_multi_core(argc, argv, &lasreadopener, cores); } } #endif // check input if (!lasreadopener.active()) { fprintf(stderr,"ERROR: no input specified\n"); byebye(true, argc==1); } /* // lasquadtree test LASquadtree quadtree; quadtree.setup(0, 99, 0, 99, 10); quadtree.intersect_rectangle(10, 10, 20, 20); quadtree.get_intersected_cells(); while (quadtree.has_intersected_cells()) { F32 min[2],max[2]; quadtree.get_cell_bounding_box(quadtree.intersected_cell, min, max); fprintf(stderr," checking tile %d with %g/%g %g/%g\n", quadtree.intersected_cell, min[0], min[1], max[0], max[1]); } quadtree.intersect_tile(10, 10, 10); quadtree.get_intersected_cells(); while (quadtree.has_intersected_cells()) { F32 min[2],max[2]; quadtree.get_cell_bounding_box(quadtree.intersected_cell, min, max); fprintf(stderr," checking tile %d with %g/%g %g/%g\n", quadtree.intersected_cell, min[0], min[1], max[0], max[1]); } fprintf(stderr,"intersect circle\n"); quadtree.intersect_circle(10, 10, 10); quadtree.get_intersected_cells(); while (quadtree.has_intersected_cells()) { F32 min[2],max[2]; quadtree.get_cell_bounding_box(quadtree.intersected_cell, min, max); fprintf(stderr," checking tile %d with %g/%g %g/%g\n", quadtree.intersected_cell, min[0], min[1], max[0], max[1]); } */ // possibly loop over multiple input files if (verbose && lasreadopener.get_file_name_number() > 1) { total_start_time = taketime(); } while (lasreadopener.active()) { if (verbose) start_time = taketime(); // open lasreader LASreader* lasreader = lasreadopener.open(); if (lasreader == 0) { fprintf(stderr, "ERROR: could not open lasreader\n"); byebye(true, argc==1); } // setup the quadtree LASquadtree* lasquadtree = new LASquadtree; if (tile_size == 0.0f) { F32 t; if (((lasreader->header.max_x - lasreader->header.min_x) < 1000) && ((lasreader->header.max_y - lasreader->header.min_y) < 1000)) { t = 10.0f; } else if (((lasreader->header.max_x - lasreader->header.min_x) < 10000) && ((lasreader->header.max_y - lasreader->header.min_y) < 10000)) { t = 100.0f; } else if (((lasreader->header.max_x - lasreader->header.min_x) < 100000) && ((lasreader->header.max_y - lasreader->header.min_y) < 100000)) { t = 1000.0f; } else if (((lasreader->header.max_x - lasreader->header.min_x) < 1000000) && ((lasreader->header.max_y - lasreader->header.min_y) < 1000000)) { t = 10000.0f; } else { t = 100000.0f; } if (verbose) fprintf(stderr,"no tile size specified. setting it to %g ...\n", t); lasquadtree->setup(lasreader->header.min_x, lasreader->header.max_x, lasreader->header.min_y, lasreader->header.max_y, t); } else { lasquadtree->setup(lasreader->header.min_x, lasreader->header.max_x, lasreader->header.min_y, lasreader->header.max_y, tile_size); } // create index and add points LASindex lasindex; lasindex.prepare(lasquadtree, threshold); while (lasreader->read_point()) lasindex.add(lasreader->point.get_x(), lasreader->point.get_y(), (U32)(lasreader->p_count-1)); // delete the reader lasreader->close(); delete lasreader; // adaptive coarsening lasindex.complete(minimum_points, maximum_intervals); // write to file if (append) { lasindex.append(lasreadopener.get_file_name()); } else { lasindex.write(lasreadopener.get_file_name()); } if (verbose) fprintf(stderr,"done with '%s'. took %g sec.\n", lasreadopener.get_file_name(), taketime()-start_time); } if (verbose && lasreadopener.get_file_name_number() > 1) { fprintf(stderr,"done with %u files. total time %g sec.\n", lasreadopener.get_file_name_number(), taketime()-total_start_time); } byebye(false, argc==1); return 0; }
int main(int argc, char *argv[]) { int i; #ifdef COMPILE_WITH_GUI bool gui = false; #endif bool verbose = false; bool keep_lastiling = false; U32 chopchop = 0; bool projection_was_set = false; double start_time = 0; LASreadOpener lasreadopener; GeoProjectionConverter geoprojectionconverter; LASwriteOpener laswriteopener; if (argc == 1) { #ifdef COMPILE_WITH_GUI return lasmerge_gui(argc, argv, 0); #else fprintf(stderr,"%s is better run in the command line\n", argv[0]); char file_name[256]; fprintf(stderr,"enter input file 1: "); fgets(file_name, 256, stdin); file_name[strlen(file_name)-1] = '\0'; lasreadopener.add_file_name(file_name); fprintf(stderr,"enter input file 2: "); fgets(file_name, 256, stdin); file_name[strlen(file_name)-1] = '\0'; lasreadopener.add_file_name(file_name); fprintf(stderr,"enter output file: "); fgets(file_name, 256, stdin); file_name[strlen(file_name)-1] = '\0'; laswriteopener.set_file_name(file_name); #endif } else { for (i = 1; i < argc; i++) { if (argv[i][0] == '–') argv[i][0] = '-'; } if (!geoprojectionconverter.parse(argc, argv)) byebye(true); if (!lasreadopener.parse(argc, argv)) byebye(true); if (!laswriteopener.parse(argc, argv)) byebye(true); } for (i = 1; i < argc; i++) { if (argv[i][0] == '\0') { continue; } else if (strcmp(argv[i],"-h") == 0 || strcmp(argv[i],"-help") == 0) { fprintf(stderr, "LAStools (by [email protected]) version %d\n", LAS_TOOLS_VERSION); usage(); } else if (strcmp(argv[i],"-v") == 0 || strcmp(argv[i],"-verbose") == 0) { verbose = true; } else if (strcmp(argv[i],"-version") == 0) { fprintf(stderr, "LAStools (by [email protected]) version %d\n", LAS_TOOLS_VERSION); byebye(); } else if (strcmp(argv[i],"-gui") == 0) { #ifdef COMPILE_WITH_GUI gui = true; #else fprintf(stderr, "WARNING: not compiled with GUI support. ignoring '-gui' ...\n"); #endif } else if (strcmp(argv[i],"-split") == 0) { if ((i+1) >= argc) { fprintf(stderr,"ERROR: '%s' needs 1 argument: size\n", argv[i]); byebye(true); } i++; chopchop = atoi(argv[i]); } else if (strcmp(argv[i],"-keep_lastiling") == 0) { keep_lastiling = true; } else if ((argv[i][0] != '-') && (lasreadopener.get_file_name_number() == 0)) { lasreadopener.add_file_name(argv[i]); argv[i][0] = '\0'; } else { fprintf(stderr, "ERROR: cannot understand argument '%s'\n", argv[i]); byebye(true); } } #ifdef COMPILE_WITH_GUI if (gui) { return lasmerge_gui(argc, argv, &lasreadopener); } #endif // read all the input files merged lasreadopener.set_merged(TRUE); // maybe we want to keep the lastiling if (keep_lastiling) { lasreadopener.set_keep_lastiling(TRUE); } // we need to precompute the bounding box lasreadopener.set_populate_header(TRUE); // check input and output if (!lasreadopener.active()) { fprintf(stderr, "ERROR: no input specified\n"); byebye(true, argc==1); } if (!laswriteopener.active()) { fprintf(stderr, "ERROR: no output specified\n"); byebye(true, argc==1); } // make sure we do not corrupt the input file if (lasreadopener.get_file_name() && laswriteopener.get_file_name() && (strcmp(lasreadopener.get_file_name(), laswriteopener.get_file_name()) == 0)) { fprintf(stderr, "ERROR: input and output file name are identical\n"); usage(true); } // check if projection info was set in the command line int number_of_keys; GeoProjectionGeoKeys* geo_keys = 0; int num_geo_double_params; double* geo_double_params = 0; if (geoprojectionconverter.has_projection()) { projection_was_set = geoprojectionconverter.get_geo_keys_from_projection(number_of_keys, &geo_keys, num_geo_double_params, &geo_double_params); } if (verbose) start_time = taketime(); LASreader* lasreader = lasreadopener.open(); if (lasreader == 0) { fprintf(stderr, "ERROR: could not open lasreader\n"); byebye(true, argc==1); } #ifdef _WIN32 if (verbose) { fprintf(stderr,"merging headers took %g sec. there are %I64d points in total.\n", taketime()-start_time, lasreader->npoints); start_time = taketime(); } #else if (verbose) { fprintf(stderr,"merging headers took %g sec. there are %lld points in total.\n", taketime()-start_time, lasreader->npoints); start_time = taketime(); } #endif // prepare the header for the surviving points strncpy(lasreader->header.system_identifier, "LAStools (c) by rapidlasso GmbH", 32); lasreader->header.system_identifier[31] = '\0'; char temp[64]; sprintf(temp, "lasmerge (version %d)", LAS_TOOLS_VERSION); strncpy(lasreader->header.generating_software, temp, 32); lasreader->header.generating_software[31] = '\0'; if (projection_was_set) { lasreader->header.set_geo_keys(number_of_keys, (LASvlr_key_entry*)geo_keys); free(geo_keys); if (geo_double_params) { lasreader->header.set_geo_double_params(num_geo_double_params, geo_double_params); free(geo_double_params); } else { lasreader->header.del_geo_double_params(); } lasreader->header.del_geo_ascii_params(); } if (chopchop) { I32 file_number = 0; LASwriter* laswriter = 0; // loop over the points while (lasreader->read_point()) { if (laswriter == 0) { // open the next writer laswriteopener.make_file_name(0, file_number); file_number++; laswriter = laswriteopener.open(&lasreader->header); } laswriter->write_point(&lasreader->point); laswriter->update_inventory(&lasreader->point); if (laswriter->p_count == chopchop) { // close the current writer laswriter->update_header(&lasreader->header, TRUE); laswriter->close(); if (verbose) { fprintf(stderr,"splitting file '%s' took %g sec.\n", laswriteopener.get_file_name(), taketime()-start_time); start_time = taketime(); } delete laswriter; laswriter = 0; } } if (laswriter && laswriter->p_count) { // close the current writer laswriter->update_header(&lasreader->header, TRUE); laswriter->close(); if (verbose) { fprintf(stderr,"splitting file '%s' took %g sec.\n", laswriteopener.get_file_name(), taketime()-start_time); start_time = taketime(); } delete laswriter; laswriter = 0; } } else { // open the writer LASwriter* laswriter = laswriteopener.open(&lasreader->header); if (laswriter == 0) { fprintf(stderr, "ERROR: could not open laswriter\n"); byebye(true, argc==1); } // loop over the points while (lasreader->read_point()) { laswriter->write_point(&lasreader->point); laswriter->update_inventory(&lasreader->point); } // close the writer laswriter->update_header(&lasreader->header, TRUE); laswriter->close(); if (verbose) fprintf(stderr,"merging files took %g sec.\n", taketime()-start_time); delete laswriter; } lasreader->close(); delete lasreader; byebye(false, argc==1); return 0; }
void mexFunction (int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { int verbose = FALSE, got_R = FALSE, scanC = FALSE, scanD = FALSE, get_BB_only = FALSE; int i, argc = 0, n_arg_no_char = 0, classif = 0, intens = 0, nRet = 0, srcID = 0; unsigned int nPoints; char **argv, *fname = NULL, *parse_string = "xyz"; double *bbox, west, east, south, north, z_min = -1001, z_max, angle = 0; if (nrhs == 0) { mexPrintf ("usage: [xyz, bbox] = lasreader_mex ('filename', ['-A<ang>'], ['-C<class>'], ['-D<id>']\n"); mexPrintf (" [-I<intens>]', ['-N<return>'], ['-R<x_min/x_max/y_min/y_max[/z_min/z_max]>']);\n"); mexPrintf (" OR\n"); mexPrintf (" [class, bbox] = lasreader_mex ('filename', '-S'),\n\n"); mexPrintf (" OR\n"); mexPrintf (" [IDs, bbox] = lasreader_mex ('filename', '-D'),\n\n"); mexPrintf (" OR\n"); mexPrintf (" bbox = lasreader_mex ('filename', '-B'),\n\n"); mexPrintf ("First case usage:\n"); mexPrintf ("where xyz is 3xN array with the XYZ point coordinates:\n"); mexPrintf ("and bbox is a 1x6 vector with [xmin xmax ymin ymax zmin zmax]\n"); mexPrintf (" -A<ang> Clip out points with scan angle > ang\n"); mexPrintf (" -C<class> Retain only points with classification = class\n"); mexPrintf (" -D<id> Retain only points with Source IDs = id (DO NOT CONFUSE WITH -D)\n"); mexPrintf (" -D Scan file for a list of Source IDs (see below) (DO NOT CONFUSE WITH -D<id>).\n"); mexPrintf (" -I<intens> Clip out points with intensity < intens\n"); mexPrintf (" -N<return> Select first return (-N1) or last return (-N10)\n"); mexPrintf (" -R<x_min/x_max/y_min/y_max> - Clip to bounding box.\n"); mexPrintf (" Optionaly add z_min/z_max to make a 3D bounding box.\n\n"); mexPrintf (" -S Scan file for a list of Classifications (see below).\n"); mexPrintf (" -V Prints header contents info on ML shell.\n"); mexPrintf ("Second/Third cases:\n"); mexPrintf ("class|ID is a 1xN vector with a list of different classificatins|IDs\n"); mexPrintf ("present in file. No other data (except optional BBox) is return here.\n"); mexPrintf ("Fourth case:\n"); mexPrintf ("\tReturns only the bonding box 1x6 vector.\n"); return; } if (!mxIsChar(prhs[0])) mexErrMsgTxt ("First arg must contain the filename string.\n"); if (nlhs != 1 && get_BB_only) mexErrMsgTxt ("-B option implies one output only.\n"); fname = (char *) mxArrayToString (prhs[0]); /* Load the file name into a char string */ if (nrhs > 1) { argc = nrhs; for (i = 1; i < nrhs; i++) { /* Check input to find how many arguments are of type char */ if(!mxIsChar(prhs[i])) { argc--; n_arg_no_char++; /* Number of arguments that have a type other than char */ } } argc++; /* to account for the program's name to be inserted in argv[0] */ /* get the length of the input string */ argv = (char **)mxCalloc(argc, sizeof(char *)); argv[0] = "LASreader"; for (i = 1; i < argc; i++) argv[i] = (char *)mxArrayToString(prhs[i+n_arg_no_char-1]); } for (i = 1; i < argc; i++) { if (argv[i][0] == '-') { switch (argv[i][1]) { case 'A': angle = atof(&argv[i][2]); break; case 'B': get_BB_only = TRUE; break; case 'C': classif = atoi(&argv[i][2]); break; case 'D': if (argv[i][2]) srcID = atoi(&argv[i][2]); else scanD = TRUE; break; case 'I': intens = atoi(&argv[i][2]); break; case 'N': nRet = atoi(&argv[i][2]); break; case 'R': if (decode_R (argv[i], &west, &east, &south, &north, &z_min, &z_max)) mexErrMsgTxt("Error decoding -R option!"); got_R = TRUE; break; case 'S': scanC = TRUE; break; case 'V': verbose = TRUE; break; } } } LASreadOpener lasreadopener; lasreadopener.set_merged(FALSE); lasreadopener.set_populate_header(FALSE); lasreadopener.set_file_name(fname); LASreader *lasreader = lasreadopener.open(); if (!lasreader) mexErrMsgTxt("LASREADER Error! could not open lasreader!"); LASheader *header = &(lasreader->header); if (!header) mexErrMsgTxt("LASREADER: Unable to fetch header for file"); if (get_BB_only && (scanC || scanD) ) mexPrintf("LASREADER WARNING: option -B takes precedence over -C or -D\n"); else if (scanC && scanD) mexPrintf("LASREADER WARNING: option -C takes precedence over -D\n"); if (get_BB_only) { plhs[0] = mxCreateDoubleMatrix(1, 6, mxREAL); bbox = mxGetPr(plhs[0]); bbox[0] = header->min_x; bbox[1] = header->max_x; bbox[2] = header->min_y; bbox[3] = header->max_y; bbox[4] = header->min_z; bbox[5] = header->max_z; return; } if (verbose) print_header(header, FALSE); if (!(scanC || scanD)) { if ((got_R + nRet + intens + classif + angle + srcID) == 0) plain_xyz(plhs, lasreader, header->number_of_point_records); else conditional_xyz(plhs, lasreader, header, angle, classif, intens, nRet, srcID, got_R, west, east, south, north, z_min, z_max); } else if (scanC) /* Scan file for a list of different classifications */ get_classification_list ( plhs, lasreader); else if (scanD) /* Scan file for a list of different Source IDs */ get_ID_list ( plhs, lasreader); if (nlhs == 2) { plhs[1] = mxCreateDoubleMatrix(1, 6, mxREAL); bbox = mxGetPr(plhs[1]); bbox[0] = header->min_x; bbox[1] = header->max_x; bbox[2] = header->min_y; bbox[3] = header->max_y; bbox[4] = header->min_z; bbox[5] = header->max_z; } // close the reader lasreader->close(); delete lasreader; return; }
int main(int argc, char *argv[]) { int i; #ifdef COMPILE_WITH_GUI bool gui = false; #endif #ifdef COMPILE_WITH_MULTI_CORE I32 cores = 1; #endif bool verbose = false; bool projection_was_set = false; bool quiet = false; int file_creation_day = -1; int file_creation_year = -1; int set_version_major = -1; int set_version_minor = -1; int set_classification = -1; char* set_system_identifier = 0; char* set_generating_software = 0; bool set_ogc_wkt = false; double start_time = 0.0; LASreadOpener lasreadopener; GeoProjectionConverter geoprojectionconverter; LASwriteOpener laswriteopener; if (argc == 1) { #ifdef COMPILE_WITH_GUI return txt2las_gui(argc, argv, 0); #else char file_name[256]; fprintf(stderr,"%s is better run in the command line\n", argv[0]); fprintf(stderr,"enter input file: "); fgets(file_name, 256, stdin); file_name[strlen(file_name)-1] = '\0'; lasreadopener.set_file_name(file_name); fprintf(stderr,"enter output file: "); fgets(file_name, 256, stdin); file_name[strlen(file_name)-1] = '\0'; laswriteopener.set_file_name(file_name); #endif } else { // need to get those before lastransform->parse() routine gets them for (i = 1; i < argc; i++) { if (argv[i][0] == '–') argv[i][0] = '-'; if (strcmp(argv[i],"-scale_intensity") == 0) { if ((i+1) >= argc) { fprintf(stderr,"ERROR: '%s' needs 1 argument: factor\n", argv[i]); usage(true); } lasreadopener.set_scale_intensity((F32)atof(argv[i+1])); *argv[i]='\0'; *argv[i+1]='\0'; i+=1; } else if (strcmp(argv[i],"-translate_intensity") == 0) { if ((i+1) >= argc) { fprintf(stderr,"ERROR: '%s' needs 1 argument: offset\n", argv[i]); usage(true); } lasreadopener.set_translate_intensity((F32)atof(argv[i+1])); *argv[i]='\0'; *argv[i+1]='\0'; i+=1; } else if (strcmp(argv[i],"-translate_then_scale_intensity") == 0) { if ((i+2) >= argc) { fprintf(stderr,"ERROR: '%s' needs 2 arguments: offset factor\n", argv[i]); usage(true); } lasreadopener.set_translate_intensity((F32)atof(argv[i+1])); lasreadopener.set_scale_intensity((F32)atof(argv[i+2])); *argv[i]='\0'; *argv[i+1]='\0'; *argv[i+2]='\0'; i+=2; } else if (strcmp(argv[i],"-scale_scan_angle") == 0) { if ((i+1) >= argc) { fprintf(stderr,"ERROR: '%s' needs 1 argument: factor\n", argv[i]); usage(true); } lasreadopener.set_scale_scan_angle((F32)atof(argv[i+1])); *argv[i]='\0'; *argv[i+1]='\0'; i+=1; } } if (!lasreadopener.parse(argc, argv)) byebye(true); if (!geoprojectionconverter.parse(argc, argv)) byebye(true); if (!laswriteopener.parse(argc, argv)) byebye(true); } for (i = 1; i < argc; i++) { if (argv[i][0] == '\0') { continue; } else if (strcmp(argv[i],"-h") == 0 || strcmp(argv[i],"-help") == 0) { fprintf(stderr, "LAStools (by [email protected]) version %d\n", LAS_TOOLS_VERSION); usage(); } else if (strcmp(argv[i],"-v") == 0 || strcmp(argv[i],"-verbose") == 0) { verbose = true; } else if (strcmp(argv[i],"-version") == 0) { fprintf(stderr, "LAStools (by [email protected]) version %d\n", LAS_TOOLS_VERSION); byebye(); } else if (strcmp(argv[i],"-gui") == 0) { #ifdef COMPILE_WITH_GUI gui = true; #else fprintf(stderr, "WARNING: not compiled with GUI support. ignoring '-gui' ...\n"); #endif } else if (strcmp(argv[i],"-cores") == 0) { #ifdef COMPILE_WITH_MULTI_CORE if ((i+1) >= argc) { fprintf(stderr,"ERROR: '%s' needs 1 argument: number\n", argv[i]); usage(true); } argv[i][0] = '\0'; i++; cores = atoi(argv[i]); argv[i][0] = '\0'; #else fprintf(stderr, "WARNING: not compiled with multi-core batching. ignoring '-cores' ...\n"); i++; #endif } else if (strcmp(argv[i],"-quiet") == 0) { quiet = true; } else if (strcmp(argv[i],"-parse") == 0) { if ((i+1) >= argc) { fprintf(stderr,"ERROR: '%s' needs 1 argument: parse_string\n", argv[i]); usage(true); } i++; lasreadopener.set_parse_string(argv[i]); } else if (strcmp(argv[i],"-skip") == 0) { if ((i+1) >= argc) { fprintf(stderr,"ERROR: '%s' needs 1 argument: number_of_lines\n", argv[i]); usage(true); } i++; lasreadopener.set_skip_lines(atoi(argv[i])); } else if (strcmp(argv[i],"-set_scale") == 0) { if ((i+3) >= argc) { fprintf(stderr,"ERROR: '%s' needs 3 arguments: x y z\n", argv[i]); usage(true); } F64 scale_factor[3]; i++; sscanf(argv[i], "%lf", &(scale_factor[0])); i++; sscanf(argv[i], "%lf", &(scale_factor[1])); i++; sscanf(argv[i], "%lf", &(scale_factor[2])); lasreadopener.set_scale_factor(scale_factor); } else if (strcmp(argv[i],"-set_offset") == 0) { if ((i+3) >= argc) { fprintf(stderr,"ERROR: '%s' needs 3 arguments: x y z\n", argv[i]); usage(true); } F64 offset[3]; i++; sscanf(argv[i], "%lf", &(offset[0])); i++; sscanf(argv[i], "%lf", &(offset[1])); i++; sscanf(argv[i], "%lf", &(offset[2])); lasreadopener.set_offset(offset); } else if (strcmp(argv[i],"-add_extra") == 0 || strcmp(argv[i],"-add_attribute") == 0) { if ((i+3) >= argc) { fprintf(stderr,"ERROR: '%s' needs at least 3 arguments: data_type name description\n", argv[i]); usage(true); } if (((i+4) < argc) && (atof(argv[i+4]) != 0.0)) { if (((i+5) < argc) && ((atof(argv[i+5]) != 0.0) || (strcmp(argv[i+5], "0") == 0) || (strcmp(argv[i+5], "0.0") == 0))) { if (((i+6) < argc) && (atof(argv[i+6]) != 0.0)) { if (((i+7) < argc) && ((atof(argv[i+7]) != 0.0) || (strcmp(argv[i+7], "0") == 0) || (strcmp(argv[i+7], "0.0") == 0))) { lasreadopener.add_attribute(atoi(argv[i+1]), argv[i+2], argv[i+3], atof(argv[i+4]), atof(argv[i+5]), atof(argv[i+6]), atof(argv[i+7])); i+=7; } else { lasreadopener.add_attribute(atoi(argv[i+1]), argv[i+2], argv[i+3], atof(argv[i+4]), atof(argv[i+5]), atof(argv[i+6])); i+=6; } } else { lasreadopener.add_attribute(atoi(argv[i+1]), argv[i+2], argv[i+3], atof(argv[i+4]), atof(argv[i+5])); i+=5; } } else { lasreadopener.add_attribute(atoi(argv[i+1]), argv[i+2], argv[i+3], atof(argv[i+4])); i+=4; } } else { lasreadopener.add_attribute(atoi(argv[i+1]), argv[i+2], argv[i+3]); i+=3; } } else if (strcmp(argv[i],"-set_creation_date") == 0 || strcmp(argv[i],"-set_file_creation") == 0) { if ((i+2) >= argc) { fprintf(stderr,"ERROR: '%s' needs 2 arguments: day year\n", argv[i]); usage(true); } i++; sscanf(argv[i], "%d", &file_creation_day); i++; sscanf(argv[i], "%d", &file_creation_year); } else if (strcmp(argv[i],"-set_class") == 0 || strcmp(argv[i],"-set_classification") == 0) { if ((i+1) >= argc) { fprintf(stderr,"ERROR: '%s' needs 1 argument: value\n", argv[i]); usage(true); } i++; set_classification = atoi(argv[i]); } else if (strcmp(argv[i],"-set_system_identifier") == 0) { if ((i+1) >= argc) { fprintf(stderr,"ERROR: '%s' needs 1 argument: name\n", argv[i]); usage(true); } i++; set_system_identifier = argv[i]; } else if (strcmp(argv[i],"-set_generating_software") == 0) { if ((i+1) >= argc) { fprintf(stderr,"ERROR: '%s' needs 1 argument: name\n", argv[i]); usage(true); } i++; set_generating_software = argv[i]; } else if (strcmp(argv[i],"-set_ogc_wkt") == 0) { set_ogc_wkt = true; } else if (strcmp(argv[i],"-set_version") == 0) { if ((i+1) >= argc) { fprintf(stderr,"ERROR: '%s' needs 1 argument: major.minor\n", argv[i]); usage(true); } i++; if (sscanf(argv[i],"%d.%d",&set_version_major,&set_version_minor) != 2) { fprintf(stderr, "ERROR: cannot understand argument '%s' of '%s'\n", argv[i], argv[i-1]); usage(true); } } else if ((argv[i][0] != '-') && (lasreadopener.get_file_name_number() == 0)) { lasreadopener.add_file_name(argv[i]); argv[i][0] = '\0'; } else { fprintf(stderr, "ERROR: cannot understand argument '%s'\n", argv[i]); usage(true); } } #ifdef COMPILE_WITH_GUI if (gui) { return txt2las_gui(argc, argv, &lasreadopener); } #endif #ifdef COMPILE_WITH_MULTI_CORE if (cores > 1) { if (lasreadopener.get_file_name_number() < 2) { fprintf(stderr,"WARNING: only %u input files. ignoring '-cores %d' ...\n", lasreadopener.get_file_name_number(), cores); } else if (lasreadopener.is_merged()) { fprintf(stderr,"WARNING: input files merged on-the-fly. ignoring '-cores %d' ...\n", cores); } else { return txt2las_multi_core(argc, argv, &geoprojectionconverter, &lasreadopener, &laswriteopener, cores); } } #endif // make sure we have input if (!lasreadopener.active()) { fprintf(stderr, "ERROR: no input specified\n"); byebye(true, argc==1); } // make sure that input and output are not *both* piped if (lasreadopener.is_piped() && laswriteopener.is_piped()) { fprintf(stderr, "ERROR: input and output cannot both be piped\n"); byebye(true, argc==1); } // check if projection info was set in the command line int number_of_keys; GeoProjectionGeoKeys* geo_keys = 0; int num_geo_double_params; double* geo_double_params = 0; if (geoprojectionconverter.has_projection()) { projection_was_set = geoprojectionconverter.get_geo_keys_from_projection(number_of_keys, &geo_keys, num_geo_double_params, &geo_double_params); } // loop over multiple input files while (lasreadopener.active()) { if (verbose) start_time = taketime(); // open lasreader LASreader* lasreader = lasreadopener.open(); if (lasreader == 0) { fprintf(stderr, "ERROR: could not open lasreader\n"); byebye(true, argc==1); } // check output if (!laswriteopener.active()) { // create name from input name laswriteopener.make_file_name(lasreadopener.get_file_name(), -2); } // if the output was piped we need to precompute the bounding box, etc ... if (laswriteopener.is_piped()) { // because the output goes to a pipe we have to precompute the header // information with an additional pass. if (verbose) { fprintf(stderr, "piped output. extra read pass over file '%s' ...\n", lasreadopener.get_file_name()); } while (lasreader->read_point()); lasreader->close(); // output some stats if (verbose) { #ifdef _WIN32 fprintf(stderr, "npoints %I64d min %g %g %g max %g %g %g\n", lasreader->npoints, lasreader->header.min_x, lasreader->header.min_y, lasreader->header.min_z, lasreader->header.max_x, lasreader->header.max_y, lasreader->header.max_z); #else fprintf(stderr, "npoints %lld min %g %g %g max %g %g %g\n", lasreader->npoints, lasreader->header.min_x, lasreader->header.min_y, lasreader->header.min_z, lasreader->header.max_x, lasreader->header.max_y, lasreader->header.max_z); #endif fprintf(stderr, "return histogram %d %d %d %d %d\n", lasreader->header.number_of_points_by_return[0], lasreader->header.number_of_points_by_return[1], lasreader->header.number_of_points_by_return[2], lasreader->header.number_of_points_by_return[3], lasreader->header.number_of_points_by_return[4]); fprintf(stderr,"took %g sec.\n", taketime()-start_time); start_time = taketime(); } // reopen lasreader for the second pass if (!lasreadopener.reopen(lasreader)) { fprintf(stderr, "ERROR: could not reopen '%s' for main pass\n", lasreadopener.get_file_name()); byebye(true, argc==1); } } // populate header for (i = 0; i < 32; i++) { lasreader->header.system_identifier[i] = '\0'; lasreader->header.generating_software[i] = '\0'; } if (set_system_identifier) { strncpy(lasreader->header.system_identifier, set_system_identifier, 32); lasreader->header.system_identifier[31] = '\0'; } else { strncpy(lasreader->header.system_identifier, "LAStools (c) by rapidlasso GmbH", 32); lasreader->header.system_identifier[31] = '\0'; } if (set_generating_software) { strncpy(lasreader->header.generating_software, set_generating_software, 32); lasreader->header.generating_software[31] = '\0'; } else { char temp[64]; sprintf(temp, "txt2las (version %d)", LAS_TOOLS_VERSION); strncpy(lasreader->header.generating_software, temp, 32); lasreader->header.generating_software[31] = '\0'; } // maybe set creation date #ifdef _WIN32 if (lasreadopener.get_file_name() && file_creation_day == -1 && file_creation_year == -1) { WIN32_FILE_ATTRIBUTE_DATA attr; SYSTEMTIME creation; GetFileAttributesEx(lasreadopener.get_file_name(), GetFileExInfoStandard, &attr); FileTimeToSystemTime(&attr.ftCreationTime, &creation); int startday[13] = {-1, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}; file_creation_day = startday[creation.wMonth] + creation.wDay; file_creation_year = creation.wYear; // leap year handling if ((((creation.wYear)%4) == 0) && (creation.wMonth > 2)) file_creation_day++; } #endif if (file_creation_day == -1 && file_creation_year == -1) { lasreader->header.file_creation_day = (U16)333; lasreader->header.file_creation_year = (U16)2011; } else { lasreader->header.file_creation_day = (U16)file_creation_day; lasreader->header.file_creation_year = (U16)file_creation_year; } // maybe set version if (set_version_major != -1) lasreader->header.version_major = (U8)set_version_major; if (set_version_minor != -1) lasreader->header.version_minor = (U8)set_version_minor; if (set_version_minor == 3) { lasreader->header.header_size = 235; lasreader->header.offset_to_point_data = 235; } else if (set_version_minor == 4) { lasreader->header.header_size = 375; lasreader->header.offset_to_point_data = 375; } // maybe set projection if (projection_was_set) { lasreader->header.set_geo_keys(number_of_keys, (LASvlr_key_entry*)geo_keys); if (geo_double_params) { lasreader->header.set_geo_double_params(num_geo_double_params, geo_double_params); } else { lasreader->header.del_geo_double_params(); } lasreader->header.del_geo_ascii_params(); if (set_ogc_wkt) // maybe also set the OCG WKT { I32 len = 0; CHAR* ogc_wkt = 0; if (geoprojectionconverter.get_ogc_wkt_from_projection(len, &ogc_wkt, !geoprojectionconverter.has_projection(false))) { lasreader->header.set_geo_wkt_ogc_cs(len, ogc_wkt); free(ogc_wkt); if ((lasreader->header.version_minor >= 4) && (lasreader->header.point_data_format >= 6)) { lasreader->header.set_global_encoding_bit(LAS_TOOLS_GLOBAL_ENCODING_BIT_OGC_WKT_CRS); } } else { fprintf(stderr, "WARNING: cannot produce OCG WKT. ignoring '-set_ogc_wkt' for '%s'\n", lasreadopener.get_file_name()); } } } // open the output LASwriter* laswriter = laswriteopener.open(&lasreader->header); if (laswriter == 0) { fprintf(stderr, "ERROR: could not open laswriter\n"); byebye(true, argc==1); } if (verbose) fprintf(stderr, "reading file '%s' and writing to '%s'\n", lasreadopener.get_file_name(), laswriteopener.get_file_name()); // loop over points while (lasreader->read_point()) { // maybe set classification if (set_classification != -1) { lasreader->point.set_classification(set_classification); } // write the point laswriter->write_point(&lasreader->point); } lasreader->close(); if (!laswriteopener.is_piped()) { laswriter->update_header(&lasreader->header, FALSE, TRUE); if (verbose) { #ifdef _WIN32 fprintf(stderr, "npoints %I64d min %g %g %g max %g %g %g\n", lasreader->npoints, lasreader->header.min_x, lasreader->header.min_y, lasreader->header.min_z, lasreader->header.max_x, lasreader->header.max_y, lasreader->header.max_z); #else fprintf(stderr, "npoints %lld min %g %g %g max %g %g %g\n", lasreader->npoints, lasreader->header.min_x, lasreader->header.min_y, lasreader->header.min_z, lasreader->header.max_x, lasreader->header.max_y, lasreader->header.max_z); #endif fprintf(stderr, "return histogram %d %d %d %d %d\n", lasreader->header.number_of_points_by_return[0], lasreader->header.number_of_points_by_return[1], lasreader->header.number_of_points_by_return[2], lasreader->header.number_of_points_by_return[3], lasreader->header.number_of_points_by_return[4]); } } laswriter->close(); delete laswriter; delete lasreader; laswriteopener.set_file_name(0); if (verbose) fprintf(stderr,"took %g sec.\n", taketime()-start_time); } byebye(false, argc==1); return 0; }
int main(int argc, char *argv[]) { int i; #ifdef COMPILE_WITH_GUI bool gui = false; #endif #ifdef COMPILE_WITH_MULTI_CORE I32 cores = 1; #endif bool diff = false; bool verbose = false; CHAR separator_sign = ' '; CHAR* separator = "space"; bool opts = false; bool optx = false; CHAR header_comment_sign = '\0'; CHAR* parse_string = 0; CHAR* extra_string = 0; CHAR printstring[512]; double start_time = 0.0; LASreadOpener lasreadopener; LASwriteOpener laswriteopener; laswriteopener.set_format("txt"); if (argc == 1) { #ifdef COMPILE_WITH_GUI return las2txt_gui(argc, argv, 0); #else fprintf(stderr,"las2txt.exe is better run in the command line or via the lastool.exe GUI\n"); CHAR file_name[256]; fprintf(stderr,"enter input file: "); fgets(file_name, 256, stdin); file_name[strlen(file_name)-1] = '\0'; lasreadopener.set_file_name(file_name); fprintf(stderr,"enter output file: "); fgets(file_name, 256, stdin); file_name[strlen(file_name)-1] = '\0'; laswriteopener.set_file_name(file_name); #endif } else { for (i = 1; i < argc; i++) { if (argv[i][0] == '–') argv[i][0] = '-'; if (strcmp(argv[i],"-opts") == 0) { opts = TRUE; *argv[i]='\0'; } else if (strcmp(argv[i],"-optx") == 0) { optx = TRUE; *argv[i]='\0'; } } if (!lasreadopener.parse(argc, argv)) byebye(true); if (!laswriteopener.parse(argc, argv)) byebye(true); } for (i = 1; i < argc; i++) { if (argv[i][0] == '\0') { continue; } else if (strcmp(argv[i],"-h") == 0 || strcmp(argv[i],"-help") == 0) { fprintf(stderr, "LAStools (by [email protected]) version %d\n", LAS_TOOLS_VERSION); usage(); } else if (strcmp(argv[i],"-v") == 0 || strcmp(argv[i],"-verbose") == 0) { verbose = true; } else if (strcmp(argv[i],"-version") == 0) { fprintf(stderr, "LAStools (by [email protected]) version %d\n", LAS_TOOLS_VERSION); byebye(); } else if (strcmp(argv[i],"-gui") == 0) { #ifdef COMPILE_WITH_GUI gui = true; #else fprintf(stderr, "WARNING: not compiled with GUI support. ignoring '-gui' ...\n"); #endif } else if (strcmp(argv[i],"-cores") == 0) { #ifdef COMPILE_WITH_MULTI_CORE if ((i+1) >= argc) { fprintf(stderr,"ERROR: '%s' needs 1 argument: number\n", argv[i]); usage(true); } argv[i][0] = '\0'; i++; cores = atoi(argv[i]); argv[i][0] = '\0'; #else fprintf(stderr, "WARNING: not compiled with multi-core batching. ignoring '-cores' ...\n"); i++; #endif } else if (strcmp(argv[i],"-parse") == 0) { if ((i+1) >= argc) { fprintf(stderr,"ERROR: '%s' needs 1 argument: string\n", argv[i]); usage(true); } i++; if (parse_string) free(parse_string); parse_string = strdup(argv[i]); } else if (strcmp(argv[i],"-parse_all") == 0) { if (parse_string) free(parse_string); parse_string = strdup("txyzirndecaup"); } else if (strcmp(argv[i],"-extra") == 0) { if ((i+1) >= argc) { fprintf(stderr,"ERROR: '%s' needs 1 argument: string\n", argv[i]); usage(true); } i++; extra_string = argv[i]; } else if (strcmp(argv[i],"-sep") == 0) { if ((i+1) >= argc) { fprintf(stderr,"ERROR: '%s' needs 1 argument: separator\n", argv[i]); usage(true); } i++; separator = argv[i]; if (strcmp(separator,"comma") == 0 || strcmp(separator,"komma") == 0) { separator_sign = ','; } else if (strcmp(separator,"tab") == 0) { separator_sign = '\t'; } else if (strcmp(separator,"dot") == 0 || strcmp(separator,"period") == 0) { separator_sign = '.'; } else if (strcmp(separator,"colon") == 0) { separator_sign = ':'; } else if (strcmp(separator,"semicolon") == 0) { separator_sign = ';'; } else if (strcmp(separator,"hyphen") == 0 || strcmp(separator,"minus") == 0) { separator_sign = '-'; } else if (strcmp(separator,"space") == 0) { separator_sign = ' '; } else { fprintf(stderr, "ERROR: unknown seperator '%s'\n",separator); usage(true); } } else if (strcmp(argv[i],"-header") == 0) { if ((i+1) >= argc) { fprintf(stderr,"ERROR: '%s' needs 1 argument: comment\n", argv[i]); usage(true); } i++; if (strcmp(argv[i],"comma") == 0 || strcmp(argv[i],"komma") == 0) { header_comment_sign = ','; } else if (strcmp(argv[i],"colon") == 0) { header_comment_sign = ':'; } else if (strcmp(argv[i],"scolon") == 0 || strcmp(argv[i],"semicolon") == 0) { header_comment_sign = ';'; } else if (strcmp(argv[i],"pound") == 0 || strcmp(argv[i],"hash") == 0) { header_comment_sign = '#'; } else if (strcmp(argv[i],"percent") == 0) { header_comment_sign = '%'; } else if (strcmp(argv[i],"dollar") == 0) { header_comment_sign = '$'; } else if (strcmp(argv[i],"star") == 0) { header_comment_sign = '*'; } else { fprintf(stderr, "ERROR: unknown header comment symbol '%s'\n",argv[i]); usage(true); } } else if ((argv[i][0] != '-') && (lasreadopener.get_file_name_number() == 0)) { lasreadopener.add_file_name(argv[i]); argv[i][0] = '\0'; } else { fprintf(stderr, "ERROR: cannot understand argument '%s'\n", argv[i]); usage(true); } } #ifdef COMPILE_WITH_GUI if (gui) { return las2txt_gui(argc, argv, &lasreadopener); } #endif #ifdef COMPILE_WITH_MULTI_CORE if ((cores > 1) && (lasreadopener.get_file_name_number() > 1) && (!lasreadopener.is_merged())) { return las2txt_multi_core(argc, argv, &lasreadopener, &laswriteopener, cores); } #endif // check input if (!lasreadopener.active()) { fprintf(stderr,"ERROR: no input specified\n"); byebye(true, argc == 1); } // possibly loop over multiple input files while (lasreadopener.active()) { if (verbose) start_time = taketime(); // open lasreader LASreader* lasreader = lasreadopener.open(); if (lasreader == 0) { fprintf(stderr, "ERROR: could not open lasreader\n"); byebye(true, argc==1); } // (maybe) open laswaveform13reader LASwaveform13reader* laswaveform13reader = lasreadopener.open_waveform13(&lasreader->header); // get a pointer to the header LASheader* header = &(lasreader->header); // open output file FILE* file_out; if (laswriteopener.is_piped()) { file_out = stdout; } else { // create output file name if needed if (laswriteopener.get_file_name() == 0) { if (lasreadopener.get_file_name() == 0) { fprintf(stderr, "ERROR: no output file specified\n"); byebye(true, argc==1); } laswriteopener.make_file_name(lasreadopener.get_file_name(), -2); } const CHAR* file_name_out = laswriteopener.get_file_name(); // open output file file_out = fopen(file_name_out, "w"); // fail if output file does not open if (file_out == 0) { fprintf(stderr, "ERROR: could not open '%s' for write\n", file_name_out); byebye(true, argc==1); } laswriteopener.set_file_name(0); } // maybe PTS or PTX format if (opts) { // look for VRL with PTS or PTX info const LASvlr* ptsVLR = 0; const LASvlr* ptxVLR = 0; if ((ptsVLR = header->get_vlr("LAStools", 2000)) || (ptxVLR = header->get_vlr("LAStools", 2001))) { if ((parse_string == 0) || (strcmp(parse_string, "original") == 0)) { if (parse_string) free(parse_string); if (ptsVLR && (ptsVLR->record_length_after_header >= 32)) { parse_string = strdup((CHAR*)(ptsVLR->data + 16)); } else if (ptxVLR && (ptxVLR->record_length_after_header >= 32)) { parse_string = strdup((CHAR*)(ptxVLR->data + 16)); } else if (ptsVLR) { fprintf(stderr, "WARNING: found VLR for PTS with wrong payload size of %d.\n", ptsVLR->record_length_after_header); } else if (ptxVLR) { fprintf(stderr, "WARNING: found VLR for PTX with wrong payload size of %d.\n", ptxVLR->record_length_after_header); } } } else { fprintf(stderr, "WARNING: found no VLR with PTS or PTX info.\n"); } if (header->version_minor >= 4) { #ifdef _WIN32 fprintf(file_out, "%I64d \012", header->extended_number_of_point_records); #else fprintf(file_out, "%lld \012", header->extended_number_of_point_records); #endif } else { fprintf(file_out, "%u \012", header->number_of_point_records); } if (parse_string && strcmp(parse_string, "xyz") && strcmp(parse_string, "xyzi") && strcmp(parse_string, "xyziRGB") && strcmp(parse_string, "xyzRGB")) { fprintf(stderr, "WARNING: the parse string for PTS should be 'xyz', 'xyzi', 'xyziRGB', or 'xyzRGB'\n"); } if (separator_sign != ' ') { fprintf(stderr, "WARNING: the separator for PTS should be 'space' not '%s'\n", separator); } } else if (optx) { // look for VRL with PTX info const LASvlr* ptxVLR = header->get_vlr("LAStools", 2001); if (ptxVLR && (ptxVLR->record_length_after_header == 272)) { U8* payload = ptxVLR->data; if ((parse_string == 0) || (strcmp(parse_string, "original") == 0)) { if (parse_string) free(parse_string); parse_string = strdup((CHAR*)(payload + 16)); } fprintf(file_out, "%u \012", (U32)((I64*)payload)[4]); // ncols fprintf(file_out, "%u \012", (U32)((I64*)payload)[5]); // nrows fprintf(file_out, "%g %g %g\012", ((F64*)payload)[6], ((F64*)payload)[7], ((F64*)payload)[8]); // translation fprintf(file_out, "%g %g %g\012", ((F64*)payload)[9], ((F64*)payload)[10], ((F64*)payload)[11]); // rotation_row_0 fprintf(file_out, "%g %g %g\012", ((F64*)payload)[12], ((F64*)payload)[13], ((F64*)payload)[14]); // rotation_row_1 fprintf(file_out, "%g %g %g\012", ((F64*)payload)[15], ((F64*)payload)[16], ((F64*)payload)[17]); // rotation_row_2 fprintf(file_out, "%g %g %g %g\012", ((F64*)payload)[18], ((F64*)payload)[19], ((F64*)payload)[20], ((F64*)payload)[21]); // transformation_row_0 fprintf(file_out, "%g %g %g %g\012", ((F64*)payload)[22], ((F64*)payload)[23], ((F64*)payload)[24], ((F64*)payload)[25]); // transformation_row_0 fprintf(file_out, "%g %g %g %g\012", ((F64*)payload)[26], ((F64*)payload)[27], ((F64*)payload)[28], ((F64*)payload)[29]); // transformation_row_0 fprintf(file_out, "%g %g %g %g\012", ((F64*)payload)[30], ((F64*)payload)[31], ((F64*)payload)[32], ((F64*)payload)[33]); // transformation_row_0 } else { if (ptxVLR) { fprintf(stderr, "WARNING: found VLR for PTX with wrong payload size of %d.\n", ptxVLR->record_length_after_header); } else { fprintf(stderr, "WARNING: found no VLR with PTX info.\n"); } fprintf(stderr, " outputting PTS instead ...\n"); if (header->version_minor >= 4) { #ifdef _WIN32 fprintf(file_out, "%I64d \012", header->extended_number_of_point_records); #else fprintf(file_out, "%lld \012", header->extended_number_of_point_records); #endif } else { fprintf(file_out, "%u \012", header->number_of_point_records); } } if (parse_string && strcmp(parse_string, "xyz") && strcmp(parse_string, "xyzi") && strcmp(parse_string, "xyziRGB") && strcmp(parse_string, "xyzRGB")) { fprintf(stderr, "WARNING: the parse string for PTX should be 'xyz', 'xyzi', 'xyziRGB', or 'xyzRGB'\n"); } if (separator_sign != ' ') { fprintf(stderr, "WARNING: the separator for PTX should be 'space' not '%s'\n", separator); } } else if (header_comment_sign) { // output header info fprintf(file_out, "%c file signature: '%.4s'\012", header_comment_sign, header->file_signature); fprintf(file_out, "%c file source ID: %d\012", header_comment_sign, header->file_source_ID); fprintf(file_out, "%c reserved (global encoding):%d\012", header_comment_sign, header->global_encoding); fprintf(file_out, "%c project ID GUID data 1-4: %d %d %d '%.8s'\012", header_comment_sign, header->project_ID_GUID_data_1, header->project_ID_GUID_data_2, header->project_ID_GUID_data_3, header->project_ID_GUID_data_4); fprintf(file_out, "%c version major.minor: %d.%d\012", header_comment_sign, header->version_major, header->version_minor); fprintf(file_out, "%c system_identifier: '%.32s'\012", header_comment_sign, header->system_identifier); fprintf(file_out, "%c generating_software: '%.32s'\012", header_comment_sign, header->generating_software); fprintf(file_out, "%c file creation day/year: %d/%d\012", header_comment_sign, header->file_creation_day, header->file_creation_year); fprintf(file_out, "%c header size %d\012", header_comment_sign, header->header_size); fprintf(file_out, "%c offset to point data %u\012", header_comment_sign, header->offset_to_point_data); fprintf(file_out, "%c number var. length records %u\012", header_comment_sign, header->number_of_variable_length_records); fprintf(file_out, "%c point data format %d\012", header_comment_sign, header->point_data_format); fprintf(file_out, "%c point data record length %d\012", header_comment_sign, header->point_data_record_length); fprintf(file_out, "%c number of point records %u\012", header_comment_sign, header->number_of_point_records); fprintf(file_out, "%c number of points by return %u %u %u %u %u\012", header_comment_sign, header->number_of_points_by_return[0], header->number_of_points_by_return[1], header->number_of_points_by_return[2], header->number_of_points_by_return[3], header->number_of_points_by_return[4]); fprintf(file_out, "%c scale factor x y z %g %g %g\012", header_comment_sign, header->x_scale_factor, header->y_scale_factor, header->z_scale_factor); fprintf(file_out, "%c offset x y z ", header_comment_sign); lidardouble2string(printstring, header->x_offset); fprintf(file_out, "%s ", printstring); lidardouble2string(printstring, header->y_offset); fprintf(file_out, "%s ", printstring); lidardouble2string(printstring, header->z_offset); fprintf(file_out, "%s\012", printstring); fprintf(file_out, "%c min x y z ", header_comment_sign); lidardouble2string(printstring, header->min_x, header->x_scale_factor); fprintf(file_out, "%s ", printstring); lidardouble2string(printstring, header->min_y, header->y_scale_factor); fprintf(file_out, "%s ", printstring); lidardouble2string(printstring, header->min_z, header->z_scale_factor); fprintf(file_out, "%s\012", printstring); fprintf(file_out, "%c max x y z ", header_comment_sign); lidardouble2string(printstring, header->max_x, header->x_scale_factor); fprintf(file_out, "%s ", printstring); lidardouble2string(printstring, header->max_y, header->y_scale_factor); fprintf(file_out, "%s ", printstring); lidardouble2string(printstring, header->max_z, header->z_scale_factor); fprintf(file_out, "%s\012", printstring); } // maybe create default parse string if (parse_string == 0) parse_string = strdup("xyz"); // check requested fields and print warnings of necessary i = 0; while (parse_string[i]) { switch (parse_string[i]) { case 'x': // the x coordinate case 'y': // the y coordinate case 'z': // the z coordinate case 'X': // the unscaled raw integer X coordinate case 'Y': // the unscaled raw integer Y coordinate case 'Z': // the unscaled raw integer Z coordinate case 'i': // the intensity case 'a': // the scan angle case 'r': // the number of the return case 'c': // the classification case 'u': // the user data case 'n': // the number of returns of given pulse case 'p': // the point source ID case 'e': // the edge of flight line flag case 'd': // the direction of scan flag case 'm': // the index of the point (count starts at 0) case 'M': // the index of the point (count starts at 0) break; case 't': // the gps-time if (lasreader->point.have_gps_time == false) fprintf (stderr, "WARNING: requested 't' but points do not have gps time\n"); break; case 'R': // the red channel of the RGB field if (lasreader->point.have_rgb == false) fprintf (stderr, "WARNING: requested 'R' but points do not have rgb\n"); break; case 'G': // the green channel of the RGB field if (lasreader->point.have_rgb == false) fprintf (stderr, "WARNING: requested 'G' but points do not have rgb\n"); break; case 'B': // the blue channel of the RGB field if (lasreader->point.have_rgb == false) fprintf (stderr, "WARNING: requested 'B' but points do not have rgb\n"); break; case 'w': // the wavepacket index if (lasreader->point.have_wavepacket == false) fprintf (stderr, "WARNING: requested 'w' but points do not have wavepacket\n"); break; case 'W': // all wavepacket attributes if (lasreader->point.have_wavepacket == false) fprintf (stderr, "WARNING: requested 'W' but points do not have wavepacket\n"); break; case 'V': // the waveform data if (laswaveform13reader == 0) { fprintf (stderr, "WARNING: requested 'V' but no waveform data available\n"); fprintf (stderr, " omitting ...\n"); } break; case ')': case '!': case '@': case '#': case '$': case '%': case '^': case '&': case '*': case '(': diff = true; break; case 'E': if (extra_string == 0) { fprintf (stderr, "WARNING: requested 'E' but no '-extra' specified\n"); parse_string[i] = 's'; } break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if ((parse_string[i] - '0') >= lasreader->header.number_attributes) { fprintf(stderr, "WARNING: attribute '%d' does not exist.\n", (parse_string[i] - '0')); parse_string[i] = 's'; } else { attribute_starts[(parse_string[i] - '0')] = lasreader->header.get_attribute_start((parse_string[i] - '0')); } break; default: fprintf (stderr, "WARNING: requested unknown parse item '%c'\n", parse_string[i]); } i++; } // in case diff is requested int last_XYZ[3] = {0,0,0}; unsigned short last_RGB[4] = {0,0,0}; double last_GPSTIME = 0; // read and convert the points to ASCII #ifdef _WIN32 if (verbose) fprintf(stderr,"processing %I64d points with '%s'.\n", lasreader->npoints, parse_string); #else if (verbose) fprintf(stderr,"processing %lld points with '%s'.\n", lasreader->npoints, parse_string); #endif while (lasreader->read_point()) { i = 0; while (true) { switch (parse_string[i]) { case 'x': // the x coordinate lidardouble2string(printstring, lasreader->point.get_x(), lasreader->header.x_scale_factor); fprintf(file_out, "%s", printstring); break; case 'y': // the y coordinate lidardouble2string(printstring, lasreader->point.get_y(), lasreader->header.y_scale_factor); fprintf(file_out, "%s", printstring); break; case 'z': // the z coordinate lidardouble2string(printstring, lasreader->point.get_z(), lasreader->header.z_scale_factor); fprintf(file_out, "%s", printstring); break; case 'X': // the unscaled raw integer X coordinate fprintf(file_out, "%d", lasreader->point.get_X()); break; case 'Y': // the unscaled raw integer Y coordinate fprintf(file_out, "%d", lasreader->point.get_Y()); break; case 'Z': // the unscaled raw integer Z coordinate fprintf(file_out, "%d", lasreader->point.get_Z()); break; case 't': // the gps-time fprintf(file_out, "%.6f", lasreader->point.get_gps_time()); break; case 'i': // the intensity if (opts) fprintf(file_out, "%d", -2048 + lasreader->point.get_intensity()); else if (optx) { int len; len = sprintf(printstring, "%.3f", 1.0f/4095.0f * lasreader->point.get_intensity()) - 1; while (printstring[len] == '0') len--; if (printstring[len] != '.') len++; printstring[len] = '\0'; fprintf(file_out, "%s", printstring); } else fprintf(file_out, "%d", lasreader->point.get_intensity()); break; case 'a': // the scan angle fprintf(file_out, "%d", lasreader->point.get_scan_angle_rank()); break; case 'r': // the number of the return fprintf(file_out, "%d", lasreader->point.get_return_number()); break; case 'c': // the classification fprintf(file_out, "%d", lasreader->point.get_classification()); break; case 'u': // the user data fprintf(file_out, "%d", lasreader->point.get_user_data()); break; case 'n': // the number of returns of given pulse fprintf(file_out, "%d", lasreader->point.get_number_of_returns()); break; case 'p': // the point source ID fprintf(file_out, "%d", lasreader->point.get_point_source_ID()); break; case 'e': // the edge of flight line flag fprintf(file_out, "%d", lasreader->point.get_edge_of_flight_line()); break; case 'd': // the direction of scan flag fprintf(file_out, "%d", lasreader->point.get_scan_direction_flag()); break; case 'R': // the red channel of the RGB field fprintf(file_out, "%d", lasreader->point.rgb[0]); break; case 'G': // the green channel of the RGB field fprintf(file_out, "%d", lasreader->point.rgb[1]); break; case 'B': // the blue channel of the RGB field fprintf(file_out, "%d", lasreader->point.rgb[2]); break; case 'm': // the index of the point (count starts at 0) #ifdef _WIN32 fprintf(file_out, "%I64d", lasreader->p_count-1); #else fprintf(file_out, "%lld", lasreader->p_count-1); #endif break; case 'M': // the index of the point (count starts at 1) #ifdef _WIN32 fprintf(file_out, "%I64d", lasreader->p_count); #else fprintf(file_out, "%lld", lasreader->p_count); #endif break; case ')': // the raw integer X difference to the last point fprintf(file_out, "%d", lasreader->point.get_X()-last_XYZ[0]); break; case '!': // the raw integer Y difference to the last point fprintf(file_out, "%d", lasreader->point.get_Y()-last_XYZ[1]); break; case '@': // the raw integer Z difference to the last point fprintf(file_out, "%d", lasreader->point.get_Z()-last_XYZ[2]); break; case '#': // the gps-time difference to the last point lidardouble2string(printstring,lasreader->point.gps_time-last_GPSTIME); fprintf(file_out, "%s", printstring); break; case '$': // the R difference to the last point fprintf(file_out, "%d", lasreader->point.rgb[0]-last_RGB[0]); break; case '%': // the G difference to the last point fprintf(file_out, "%d", lasreader->point.rgb[1]-last_RGB[1]); break; case '^': // the B difference to the last point fprintf(file_out, "%d", lasreader->point.rgb[2]-last_RGB[2]); break; case '&': // the byte-wise R difference to the last point fprintf(file_out, "%d%c%d", (lasreader->point.rgb[0]>>8)-(last_RGB[0]>>8), separator_sign, (lasreader->point.rgb[0]&255)-(last_RGB[0]&255)); break; case '*': // the byte-wise G difference to the last point fprintf(file_out, "%d%c%d", (lasreader->point.rgb[1]>>8)-(last_RGB[1]>>8), separator_sign, (lasreader->point.rgb[1]&255)-(last_RGB[1]&255)); break; case '(': // the byte-wise B difference to the last point fprintf(file_out, "%d%c%d", (lasreader->point.rgb[2]>>8)-(last_RGB[2]>>8), separator_sign, (lasreader->point.rgb[2]&255)-(last_RGB[2]&255)); break; case 'w': // the wavepacket index fprintf(file_out, "%d", lasreader->point.wavepacket.getIndex()); break; case 'W': // all wavepacket attributes fprintf(file_out, "%d%c%d%c%d%c%g%c%g%c%g%c%g", lasreader->point.wavepacket.getIndex(), separator_sign, (U32)lasreader->point.wavepacket.getOffset(), separator_sign, lasreader->point.wavepacket.getSize(), separator_sign, lasreader->point.wavepacket.getLocation(), separator_sign, lasreader->point.wavepacket.getXt(), separator_sign, lasreader->point.wavepacket.getYt(), separator_sign, lasreader->point.wavepacket.getZt()); break; case 'V': // the waVeform if (laswaveform13reader && laswaveform13reader->read_waveform(&lasreader->point)) { output_waveform(file_out, separator_sign, laswaveform13reader); } else { fprintf(file_out, "no_waveform"); } break; case 'E': // the extra string fprintf(file_out, "%s", extra_string); break; default: print_attribute(file_out, &lasreader->header, &lasreader->point, (I32)(parse_string[i]-'0'), printstring); } i++; if (parse_string[i]) { fprintf(file_out, "%c", separator_sign); } else { fprintf(file_out, "\012"); break; } } if (diff) { last_XYZ[0] = lasreader->point.get_X(); last_XYZ[1] = lasreader->point.get_Y(); last_XYZ[2] = lasreader->point.get_Z(); last_GPSTIME = lasreader->point.gps_time; last_RGB[0] = lasreader->point.rgb[0]; last_RGB[1] = lasreader->point.rgb[1]; last_RGB[2] = lasreader->point.rgb[2]; } } #ifdef _WIN32 if (verbose) fprintf(stderr,"converting %I64d points of '%s' took %g sec.\n", lasreader->p_count, lasreadopener.get_file_name(), taketime()-start_time); #else if (verbose) fprintf(stderr,"converting %lld points of '%s' took %g sec.\n", lasreader->p_count, lasreadopener.get_file_name(), taketime()-start_time); #endif // close the reader lasreader->close(); delete lasreader; // (maybe) close the waveform reader if (laswaveform13reader) { laswaveform13reader->close(); delete laswaveform13reader; } // close the files if (file_out != stdout) fclose(file_out); } free(parse_string); byebye(false, argc==1); return 0; }
int main(int argc, char *argv[]) { MPI_Init(&argc, &argv); int i; #ifdef COMPILE_WITH_GUI bool gui = false; #endif bool verbose = false; bool keep_lastiling = false; U32 chopchop = 0; bool projection_was_set = false; double start_time = 0; LASreadOpener lasreadopener; GeoProjectionConverter geoprojectionconverter; LASwriteOpener laswriteopener; if (argc == 1) { #ifdef COMPILE_WITH_GUI return lasmerge_gui(argc, argv, 0); #else fprintf(stderr,"%s is better run in the command line\n", argv[0]); char file_name[256]; fprintf(stderr,"enter input file 1: "); fgets(file_name, 256, stdin); file_name[strlen(file_name)-1] = '\0'; lasreadopener.add_file_name(file_name); fprintf(stderr,"enter input file 2: "); fgets(file_name, 256, stdin); file_name[strlen(file_name)-1] = '\0'; lasreadopener.add_file_name(file_name); fprintf(stderr,"enter output file: "); fgets(file_name, 256, stdin); file_name[strlen(file_name)-1] = '\0'; laswriteopener.set_file_name(file_name); #endif } else { for (i = 1; i < argc; i++) { if (argv[i][0] == '�') argv[i][0] = '-'; } if (!geoprojectionconverter.parse(argc, argv)) byebye(true); if (!lasreadopener.parse(argc, argv)) byebye(true); if (lasreadopener.get_file_name_number()<2) { fprintf(stderr,"Must specify more than one input file.\n"); byebye(true); // only support merging more than one file } if (!laswriteopener.parse(argc, argv)) byebye(true); } for (i = 1; i < argc; i++) { if (argv[i][0] == '\0') { continue; } else if (strcmp(argv[i],"-h") == 0 || strcmp(argv[i],"-help") == 0) { fprintf(stderr, "LAStools (by [email protected]) version %d\n", LAS_TOOLS_VERSION); usage(); } else if (strcmp(argv[i],"-v") == 0 || strcmp(argv[i],"-verbose") == 0) { verbose = true; } else if (strcmp(argv[i],"-version") == 0) { fprintf(stderr, "LAStools (by [email protected]) version %d\n", LAS_TOOLS_VERSION); byebye(); } else if (strcmp(argv[i],"-gui") == 0) { #ifdef COMPILE_WITH_GUI gui = true; #else fprintf(stderr, "WARNING: not compiled with GUI support. ignoring '-gui' ...\n"); #endif } else if (strcmp(argv[i],"-split") == 0) { if ((i+1) >= argc) { fprintf(stderr,"ERROR: '%s' needs 1 argument: size\n", argv[i]); byebye(true); } i++; chopchop = atoi(argv[i]); } else if (strcmp(argv[i],"-keep_lastiling") == 0) { keep_lastiling = true; } else if ((argv[i][0] != '-') && (lasreadopener.get_file_name_number() == 0)) { lasreadopener.add_file_name(argv[i]); argv[i][0] = '\0'; } else { fprintf(stderr, "ERROR: cannot understand argument '%s'\n", argv[i]); byebye(true); } } #ifdef COMPILE_WITH_GUI if (gui) { return lasmerge_gui(argc, argv, &lasreadopener); } #endif // read all the input files merged lasreadopener.set_merged(TRUE); // maybe we want to keep the lastiling if (keep_lastiling) { lasreadopener.set_keep_lastiling(TRUE); } // we need to precompute the bounding box lasreadopener.set_populate_header(TRUE); // check input and output if (!lasreadopener.active()) { fprintf(stderr, "ERROR: no input specified\n"); byebye(true, argc==1); } if (!laswriteopener.active()) { fprintf(stderr, "ERROR: no output specified\n"); byebye(true, argc==1); } // make sure we do not corrupt the input file if (lasreadopener.get_file_name() && laswriteopener.get_file_name() && (strcmp(lasreadopener.get_file_name(), laswriteopener.get_file_name()) == 0)) { fprintf(stderr, "ERROR: input and output file name are identical\n"); usage(true); } // check if projection info was set in the command line int number_of_keys; GeoProjectionGeoKeys* geo_keys = 0; int num_geo_double_params; double* geo_double_params = 0; if (geoprojectionconverter.has_projection()) { projection_was_set = geoprojectionconverter.get_geo_keys_from_projection(number_of_keys, &geo_keys, num_geo_double_params, &geo_double_params); } if (verbose) start_time = taketime(); LASreader* lasreader = lasreadopener.open(); lasreader->populate_rank_points(); LASreaderMerged *lasreadermerged = (LASreaderMerged *)lasreader; I32 process_count = lasreadermerged->get_process_count(); dbg(3, "rank %i, lasreadermerged->npoints %lli", lasreadermerged->get_rank(), lasreadermerged->npoints); for (i=0; i<process_count; i++) { dbg(3, "rank %i, rank_begin_point %lli", lasreadermerged->get_rank(), lasreadermerged->get_rank_begin_index()[i]); for(int j=lasreadermerged->get_file_name_start(); j< lasreadermerged->get_file_name_number(); j++) { dbg(3, "rank %i, number %i name %s count %lli, begin", lasreadermerged->get_rank(), j, lasreadermerged->get_file_names()[j], lasreadermerged->get_file_point_counts()[j]); } } dbg(3,"type of reader returned: class %s and declared name %s", typeid(*lasreader).name(), quote(*lasreader)); if (lasreader == 0) { fprintf(stderr, "ERROR: could not open lasreader\n"); byebye(true, argc==1); } #ifdef _WIN32 if (verbose) { fprintf(stderr,"merging headers took %g sec. there are %I64d points in total.\n", taketime()-start_time, lasreader->npoints); start_time = taketime(); } #else if (verbose) { fprintf(stderr,"merging headers took %g sec. there are %lld points in total.\n", taketime()-start_time, lasreader->npoints); start_time = taketime(); } #endif // prepare the header for the surviving points strncpy(lasreader->header.system_identifier, "LAStools (c) by rapidlasso GmbH", 32); lasreader->header.system_identifier[31] = '\0'; char temp[64]; sprintf(temp, "lasmerge (version %d)", LAS_TOOLS_VERSION); strncpy(lasreader->header.generating_software, temp, 32); lasreader->header.generating_software[31] = '\0'; if (projection_was_set) { lasreader->header.set_geo_keys(number_of_keys, (LASvlr_key_entry*)geo_keys); free(geo_keys); if (geo_double_params) { lasreader->header.set_geo_double_params(num_geo_double_params, geo_double_params); free(geo_double_params); } else { lasreader->header.del_geo_double_params(); } lasreader->header.del_geo_ascii_params(); } if (chopchop) { I32 file_number = 0; LASwriter* laswriter = 0; // loop over the points while (lasreader->read_point()) { if (laswriter == 0) { // open the next writer laswriteopener.make_file_name(0, file_number); file_number++; laswriter = laswriteopener.open(&lasreader->header); } laswriter->write_point(&lasreader->point); laswriter->update_inventory(&lasreader->point); if (laswriter->p_count == chopchop) { // close the current writer laswriter->update_header(&lasreader->header, TRUE); laswriter->close(); if (verbose) { fprintf(stderr,"splitting file '%s' took %g sec.\n", laswriteopener.get_file_name(), taketime()-start_time); start_time = taketime(); } delete laswriter; laswriter = 0; } } if (laswriter && laswriter->p_count) { // close the current writer laswriter->update_header(&lasreader->header, TRUE); laswriter->close(); if (verbose) { fprintf(stderr,"splitting file '%s' took %g sec.\n", laswriteopener.get_file_name(), taketime()-start_time); start_time = taketime(); } delete laswriter; laswriter = 0; } } else { // wait for all processes to open their input files MPI_Barrier(MPI_COMM_WORLD); // all processes open a writer LASwriter* laswriter = laswriteopener.open (&lasreader->header); // set the write file pointer... no filter support, assumes all input file's points are written to output file //ByteStreamOutFileLE *bs = (ByteStreamOutFileLE*) laswriter->get_stream (); <-- this is the ByteStreamOut type for las files ByteStreamOut *bs = laswriter->get_stream (); I64 begin_index = (lasreadermerged->get_rank_begin_index())[lasreadermerged->get_rank ()]; bs->seek (lasreader->header.point_data_record_length * begin_index + lasreader->header.offset_to_point_data); if (laswriter == 0) { fprintf (stderr, "ERROR: could not open laswriter\n"); byebye (true, argc == 1); } // wait for all processes to open the output file and set their write file pointers. MPI_Barrier(MPI_COMM_WORLD); // loop over the points while (lasreader->read_point()) { laswriter->write_point(&lasreader->point); laswriter->update_inventory(&lasreader->point); } int rank = lasreadermerged->get_rank(); if(rank!=0) { laswriter->close(FALSE); } MPI_Barrier(MPI_COMM_WORLD); // not needed since reduce causes barrier, used for testing // this whole MPI_Reduce section is not technically needed since we don't yet support point filtering, // It was implemented now to ensure that it will work when point filtering of input files is supported MPI_Reduce(&(laswriter->inventory.extended_number_of_point_records), &extended_number_of_point_records, 1, MPI_LONG_LONG_INT, MPI_SUM, 0, MPI_COMM_WORLD); int i; for(i=0; i<16; i++) { MPI_Reduce(&(laswriter->inventory.extended_number_of_points_by_return[i]), &extended_number_of_points_by_return[i], 1, MPI_LONG_LONG_INT, MPI_SUM, 0, MPI_COMM_WORLD); } MPI_Reduce(&(laswriter->inventory.max_X), &max_X, 1, MPI_INT, MPI_MAX, 0, MPI_COMM_WORLD); MPI_Reduce(&(laswriter->inventory.min_X), &min_X, 1, MPI_INT, MPI_MIN, 0, MPI_COMM_WORLD); MPI_Reduce(&(laswriter->inventory.max_Y), &max_Y, 1, MPI_INT, MPI_MAX, 0, MPI_COMM_WORLD); MPI_Reduce(&(laswriter->inventory.min_Y), &min_Y, 1, MPI_INT, MPI_MIN, 0, MPI_COMM_WORLD); MPI_Reduce(&(laswriter->inventory.max_Z), &max_Z, 1, MPI_INT, MPI_MAX, 0, MPI_COMM_WORLD); MPI_Reduce(&(laswriter->inventory.min_Z), &min_Z, 1, MPI_INT, MPI_MIN, 0, MPI_COMM_WORLD); if(rank==0) { dbg(3, "extended_number_of_point_records %lli", extended_number_of_point_records); laswriter->inventory.extended_number_of_point_records = extended_number_of_point_records; for(i=0; i<16; i++) { laswriter->inventory.extended_number_of_points_by_return[i] = extended_number_of_points_by_return[i]; } laswriter->inventory.max_X = max_X; laswriter->inventory.min_X = min_X; laswriter->inventory.max_Y = max_Y; laswriter->inventory.min_Y = min_Y; laswriter->inventory.max_Z = max_Z; laswriter->inventory.min_Z = min_Z; } dbg(3, "rank %i, point data record length %i", lasreadermerged->get_rank(), lasreader->header.point_data_record_length); // close the writer if(rank==0) { // update header should only be called with TRUE when using the MPI_Reduce calls above, // lasreadopener.open(), called above, generates a correct header for the output file, provided no points are filtered during the read laswriter->update_header(&lasreader->header, TRUE); laswriter->close(FALSE); } if (verbose) fprintf(stderr,"merging files took %g sec.\n", taketime()-start_time); delete laswriter; } MPI_Finalize(); lasreader->close(); delete lasreader; byebye(false, argc==1); return 0; }
BOOL LASindex::append(const char* file_name) const { #ifdef LASZIPDLL_EXPORTS return FALSE; #else LASreadOpener lasreadopener; if (file_name == 0) return FALSE; // open reader LASreader* lasreader = lasreadopener.open(file_name); if (lasreader == 0) return FALSE; if (lasreader->header.laszip == 0) return FALSE; // close reader lasreader->close(); FILE* file = fopen(file_name, "rb"); ByteStreamIn* bytestreamin = 0; if (IS_LITTLE_ENDIAN()) bytestreamin = new ByteStreamInFileLE(file); else bytestreamin = new ByteStreamInFileBE(file); // maybe write LASindex EVLR start position into LASzip VLR I64 offset_laz_vlr = -1; // where to write LASindex EVLR that will contain the LAX file I64 number_of_special_evlrs = lasreader->header.laszip->number_of_special_evlrs; I64 offset_to_special_evlrs = lasreader->header.laszip->offset_to_special_evlrs; if ((number_of_special_evlrs == -1) && (offset_to_special_evlrs == -1)) { bytestreamin->seekEnd(); number_of_special_evlrs = 1; offset_to_special_evlrs = bytestreamin->tell(); // find LASzip VLR I64 total = lasreader->header.header_size + 2; U32 number_of_variable_length_records = lasreader->header.number_of_variable_length_records + 1 + (lasreader->header.vlr_lastiling != 0) + (lasreader->header.vlr_lasoriginal != 0); for (U32 u = 0; u < number_of_variable_length_records; u++) { bytestreamin->seek(total); CHAR user_id[16]; try { bytestreamin->getBytes((U8*)user_id, 16); } catch(...) { fprintf(stderr,"ERROR: reading header.vlrs[%d].user_id\n", u); return FALSE; } if (strcmp(user_id, "laszip encoded") == 0) { offset_laz_vlr = bytestreamin->tell() - 18; break; } U16 record_id; try { bytestreamin->get16bitsLE((U8*)&record_id); } catch(...) { fprintf(stderr,"ERROR: reading header.vlrs[%d].record_id\n", u); return FALSE; } U16 record_length_after_header; try { bytestreamin->get16bitsLE((U8*)&record_length_after_header); } catch(...) { fprintf(stderr,"ERROR: reading header.vlrs[%d].record_length_after_header\n", u); return FALSE; } total += (54 + record_length_after_header); } if (number_of_special_evlrs == -1) return FALSE; } delete bytestreamin; fclose(file); ByteStreamOut* bytestreamout; file = fopen(file_name, "rb+"); if (IS_LITTLE_ENDIAN()) bytestreamout = new ByteStreamOutFileLE(file); else bytestreamout = new ByteStreamOutFileBE(file); bytestreamout->seek(offset_to_special_evlrs); LASevlr lax_evlr; sprintf(lax_evlr.user_id, "LAStools"); lax_evlr.record_id = 30; sprintf(lax_evlr.description, "LAX spatial indexing (LASindex)"); bytestreamout->put16bitsLE((U8*)&(lax_evlr.reserved)); bytestreamout->putBytes((U8*)lax_evlr.user_id, 16); bytestreamout->put16bitsLE((U8*)&(lax_evlr.record_id)); bytestreamout->put64bitsLE((U8*)&(lax_evlr.record_length_after_header)); bytestreamout->putBytes((U8*)lax_evlr.description, 32); if (!write(bytestreamout)) { fprintf(stderr,"ERROR (LASindex): cannot append LAX to '%s'\n", file_name); delete bytestreamout; fclose(file); delete lasreader; return FALSE; } // update LASindex EVLR lax_evlr.record_length_after_header = bytestreamout->tell() - offset_to_special_evlrs - 60; bytestreamout->seek(offset_to_special_evlrs + 20); bytestreamout->put64bitsLE((U8*)&(lax_evlr.record_length_after_header)); // maybe update LASzip VLR if (number_of_special_evlrs != -1) { bytestreamout->seek(offset_laz_vlr + 54 + 16); bytestreamout->put64bitsLE((U8*)&number_of_special_evlrs); bytestreamout->put64bitsLE((U8*)&offset_to_special_evlrs); } // close writer bytestreamout->seekEnd(); delete bytestreamout; fclose(file); // delete reader delete lasreader; return TRUE; #endif }
int main(int argc, char *argv[]) { int i; bool dry = false; #ifdef COMPILE_WITH_GUI bool gui = false; #endif #ifdef COMPILE_WITH_MULTI_CORE I32 cores = 1; #endif bool verbose = false; bool waveform = false; bool waveform_with_map = false; bool report_file_size = false; I32 end_of_points = -1; bool projection_was_set = false; bool lax = false; U32 tile_size = 100; U32 threshold = 1000; U32 minimum_points = 100000; I32 maximum_intervals = -20; double start_time = 0.0; LASreadOpener lasreadopener; GeoProjectionConverter geoprojectionconverter; LASwriteOpener laswriteopener; if (argc == 1) { #ifdef COMPILE_WITH_GUI return laszip_gui(argc, argv, 0); #else fprintf(stderr,"laszip.exe is better run in the command line or via the lastool.exe GUI\n"); char file_name[256]; fprintf(stderr,"enter input file: "); fgets(file_name, 256, stdin); file_name[strlen(file_name)-1] = '\0'; lasreadopener.set_file_name(file_name); fprintf(stderr,"enter output file: "); fgets(file_name, 256, stdin); file_name[strlen(file_name)-1] = '\0'; laswriteopener.set_file_name(file_name); #endif } else { for (i = 1; i < argc; i++) { if (argv[i][0] == '–') argv[i][0] = '-'; } if (!geoprojectionconverter.parse(argc, argv)) byebye(true); if (!lasreadopener.parse(argc, argv)) byebye(true); if (!laswriteopener.parse(argc, argv)) byebye(true); } for (i = 1; i < argc; i++) { if (argv[i][0] == '\0') { continue; } else if (strcmp(argv[i],"-h") == 0 || strcmp(argv[i],"-help") == 0) { fprintf(stderr, "LAStools (by [email protected]) version %d\n", LAS_TOOLS_VERSION); usage(); } else if (strcmp(argv[i],"-v") == 0 || strcmp(argv[i],"-verbose") == 0) { verbose = true; } else if (strcmp(argv[i],"-version") == 0) { fprintf(stderr, "LAStools (by [email protected]) version %d\n", LAS_TOOLS_VERSION); byebye(); } else if (strcmp(argv[i],"-gui") == 0) { #ifdef COMPILE_WITH_GUI gui = true; #else fprintf(stderr, "WARNING: not compiled with GUI support. ignoring '-gui' ...\n"); #endif } else if (strcmp(argv[i],"-cores") == 0) { #ifdef COMPILE_WITH_MULTI_CORE if ((i+1) >= argc) { fprintf(stderr,"ERROR: '%s' needs 1 argument: number\n", argv[i]); usage(true); } argv[i][0] = '\0'; i++; cores = atoi(argv[i]); argv[i][0] = '\0'; #else fprintf(stderr, "WARNING: not compiled with multi-core batching. ignoring '-cores' ...\n"); #endif } else if (strcmp(argv[i],"-dry") == 0) { dry = true; } else if (strcmp(argv[i],"-lax") == 0) { lax = true; } else if (strcmp(argv[i],"-eop") == 0) { if ((i+1) >= argc) { fprintf(stderr,"ERROR: '%s' needs 1 argument: char\n", argv[i]); usage(true); } i++; end_of_points = atoi(argv[i]); if ((end_of_points < 0) || (end_of_points > 255)) { fprintf(stderr,"ERROR: end of points value needs to be between 0 and 255\n"); usage(true); } } else if (strcmp(argv[i],"-tile_size") == 0) { if ((i+1) >= argc) { fprintf(stderr,"ERROR: '%s' needs 1 argument: size\n", argv[i]); usage(true); } i++; tile_size = atoi(argv[i]); } else if (strcmp(argv[i],"-maximum") == 0) { if ((i+1) >= argc) { fprintf(stderr,"ERROR: '%s' needs 1 argument: number\n", argv[i]); usage(true); } i++; maximum_intervals = atoi(argv[i]); } else if (strcmp(argv[i],"-minimum") == 0) { if ((i+1) >= argc) { fprintf(stderr,"ERROR: '%s' needs 1 argument: number\n", argv[i]); usage(true); } i++; minimum_points = atoi(argv[i]); } else if (strcmp(argv[i],"-threshold") == 0) { if ((i+1) >= argc) { fprintf(stderr,"ERROR: '%s' needs 1 argument: value\n", argv[i]); usage(true); } i++; threshold = atoi(argv[i]); } else if (strcmp(argv[i],"-size") == 0) { report_file_size = true; } else if (strcmp(argv[i],"-waveform") == 0 || strcmp(argv[i],"-waveforms") == 0) { waveform = true; } else if (strcmp(argv[i],"-waveform_with_map") == 0 || strcmp(argv[i],"-waveforms_with_map") == 0) { waveform = true; waveform_with_map = true; } else if ((argv[i][0] != '-') && (lasreadopener.get_file_name_number() == 0)) { lasreadopener.add_file_name(argv[i]); argv[i][0] = '\0'; } else { fprintf(stderr, "ERROR: cannot understand argument '%s'\n", argv[i]); usage(true); } } #ifdef COMPILE_WITH_GUI if (gui) { return laszip_gui(argc, argv, &lasreadopener); } #endif #ifdef COMPILE_WITH_MULTI_CORE if ((cores > 1) && (lasreadopener.get_file_name_number() > 1) && (!lasreadopener.get_merged())) { return laszip_multi_core(argc, argv, &geoprojectionconverter, &lasreadopener, &laswriteopener, cores); } #endif // check input if (!lasreadopener.active()) { fprintf(stderr,"ERROR: no input specified\n"); usage(true, argc==1); } // make sure we do not corrupt the input file if (lasreadopener.get_file_name() && laswriteopener.get_file_name() && (strcmp(lasreadopener.get_file_name(), laswriteopener.get_file_name()) == 0)) { fprintf(stderr, "ERROR: input and output file name are identical\n"); usage(true); } // check if projection info was set in the command line int number_of_keys; GeoProjectionGeoKeys* geo_keys = 0; int num_geo_double_params; double* geo_double_params = 0; if (geoprojectionconverter.has_projection()) { projection_was_set = geoprojectionconverter.get_geo_keys_from_projection(number_of_keys, &geo_keys, num_geo_double_params, &geo_double_params); } // loop over multiple input files while (lasreadopener.active()) { if (verbose) start_time = taketime(); // open lasreader LASreader* lasreader = lasreadopener.open(); if (lasreader == 0) { fprintf(stderr, "ERROR: could not open lasreader\n"); usage(true, argc==1); } // switch if (report_file_size) { // maybe only report uncompressed file size I64 uncompressed_file_size = (I64)lasreader->header.number_of_point_records * (I64)lasreader->header.point_data_record_length + lasreader->header.offset_to_point_data; if (uncompressed_file_size == (I64)((U32)uncompressed_file_size)) fprintf(stderr,"uncompressed file size is %u bytes or %.2f MB for '%s'\n", (U32)uncompressed_file_size, (F64)uncompressed_file_size/1024.0/1024.0, lasreadopener.get_file_name()); else fprintf(stderr,"uncompressed file size is %.2f MB or %.2f GB for '%s'\n", (F64)uncompressed_file_size/1024.0/1024.0, (F64)uncompressed_file_size/1024.0/1024.0/1024.0, lasreadopener.get_file_name()); } else if (dry) { // maybe only a dry read pass start_time = taketime(); while (lasreader->read_point()); fprintf(stderr,"needed %g secs to read '%s'\n", taketime()-start_time, lasreadopener.get_file_name()); } else { I64 start_of_waveform_data_packet_record = 0; // create output file name if no output was specified if (!laswriteopener.active()) { if (lasreadopener.get_file_name() == 0) { fprintf(stderr,"ERROR: no output specified\n"); usage(true, argc==1); } laswriteopener.set_force(TRUE); laswriteopener.make_file_name(lasreadopener.get_file_name(), -2); if (!laswriteopener.format_was_specified()) { char* file_name_out = strdup(laswriteopener.get_file_name()); int len = strlen(file_name_out); if (lasreader->get_format() == LAS_TOOLS_FORMAT_LAZ) { file_name_out[len-3] = 'l'; file_name_out[len-2] = 'a'; file_name_out[len-1] = 's'; } else { file_name_out[len-3] = 'l'; file_name_out[len-2] = 'a'; file_name_out[len-1] = 'z'; } laswriteopener.set_file_name(file_name_out); free(file_name_out); } } // maybe set projection if (projection_was_set) { lasreader->header.set_geo_keys(number_of_keys, (LASvlr_key_entry*)geo_keys); if (geo_double_params) { lasreader->header.set_geo_double_params(num_geo_double_params, geo_double_params); } else { lasreader->header.del_geo_double_params(); } lasreader->header.del_geo_ascii_params(); } // almost never open laswaveform13reader and laswaveform13writer (-: LASwaveform13reader* laswaveform13reader = 0; LASwaveform13writer* laswaveform13writer = 0; if (waveform) { laswaveform13reader = lasreadopener.open_waveform13(&lasreader->header); if (laswaveform13reader) { // switch compression on/off U8 compression_type = (laswriteopener.get_format() == LAS_TOOLS_FORMAT_LAZ ? 1 : 0); for (i = 0; i < 255; i++) if (lasreader->header.vlr_wave_packet_descr[i]) lasreader->header.vlr_wave_packet_descr[i]->setCompressionType(compression_type); // create laswaveform13writer laswaveform13writer = laswriteopener.open_waveform13(&lasreader->header); if (laswaveform13writer == 0) { delete [] laswaveform13reader; laswaveform13reader = 0; waveform = 0; // switch compression on/off back U8 compression_type = (laswriteopener.get_format() == LAS_TOOLS_FORMAT_LAZ ? 0 : 1); for (i = 0; i < 255; i++) if (lasreader->header.vlr_wave_packet_descr[i]) lasreader->header.vlr_wave_packet_descr[i]->setCompressionType(compression_type); } } else { waveform = false; } } // special check for LAS 1.3+ files that contain waveform data if ((lasreader->header.version_major == 1) && (lasreader->header.version_minor >= 3)) { if (lasreader->header.global_encoding & 2) // if bit # 1 is set we have internal waveform data { lasreader->header.global_encoding &= ~((U16)2); // remove internal bit if (lasreader->header.start_of_waveform_data_packet_record) // offset to { start_of_waveform_data_packet_record = lasreader->header.start_of_waveform_data_packet_record; lasreader->header.start_of_waveform_data_packet_record = 0; lasreader->header.global_encoding |= ((U16)4); // set external bit } } } // open laswriter LASwriter* laswriter = laswriteopener.open(&lasreader->header); if (laswriter == 0) { fprintf(stderr, "ERROR: could not open laswriter\n"); usage(true, argc==1); } // should we also deal with waveform data if (waveform) { U8 compression_type = (laswaveform13reader->is_compressed() ? 1 : 0); for (i = 0; i < 255; i++) if (lasreader->header.vlr_wave_packet_descr[i]) lasreader->header.vlr_wave_packet_descr[i]->setCompressionType(compression_type); U64 last_offset = 0; U32 last_size = 60; U64 new_offset = 0; U32 new_size = 0; U32 waves_written = 0; U32 waves_referenced = 0; my_offset_size_map offset_size_map; LASindex lasindex; if (lax) // should we also create a spatial indexing file { // setup the quadtree LASquadtree* lasquadtree = new LASquadtree; lasquadtree->setup(lasreader->header.min_x, lasreader->header.max_x, lasreader->header.min_y, lasreader->header.max_y, tile_size); // create lax index lasindex.prepare(lasquadtree, threshold); } // loop over points while (lasreader->read_point()) { if (lasreader->point.wavepacket.getIndex()) // if point is attached to a waveform { waves_referenced++; if (lasreader->point.wavepacket.getOffset() == last_offset) { lasreader->point.wavepacket.setOffset(new_offset); lasreader->point.wavepacket.setSize(new_size); } else if (lasreader->point.wavepacket.getOffset() > last_offset) { if (lasreader->point.wavepacket.getOffset() > (last_offset + last_size)) { if (!waveform_with_map) { fprintf(stderr,"WARNING: gap in waveform offsets.\n"); #ifdef _WIN32 fprintf(stderr,"WARNING: last offset plus size was %I64d but new offset is %I64d (for point %I64d)\n", (last_offset + last_size), lasreader->point.wavepacket.getOffset(), lasreader->p_count); #else fprintf(stderr,"WARNING: last offset plus size was %lld but new offset is %lld (for point %lld)\n", (last_offset + last_size), lasreader->point.wavepacket.getOffset(), lasreader->p_count); #endif } } waves_written++; last_offset = lasreader->point.wavepacket.getOffset(); last_size = lasreader->point.wavepacket.getSize(); laswaveform13reader->read_waveform(&lasreader->point); laswaveform13writer->write_waveform(&lasreader->point, laswaveform13reader->samples); new_offset = lasreader->point.wavepacket.getOffset(); new_size = lasreader->point.wavepacket.getSize(); if (waveform_with_map) { offset_size_map.insert(my_offset_size_map::value_type(last_offset, OffsetSize(new_offset,new_size))); } } else { if (waveform_with_map) { my_offset_size_map::iterator map_element; map_element = offset_size_map.find(lasreader->point.wavepacket.getOffset()); if (map_element == offset_size_map.end()) { waves_written++; last_offset = lasreader->point.wavepacket.getOffset(); last_size = lasreader->point.wavepacket.getSize(); laswaveform13reader->read_waveform(&lasreader->point); laswaveform13writer->write_waveform(&lasreader->point, laswaveform13reader->samples); new_offset = lasreader->point.wavepacket.getOffset(); new_size = lasreader->point.wavepacket.getSize(); offset_size_map.insert(my_offset_size_map::value_type(last_offset, OffsetSize(new_offset,new_size))); } else { lasreader->point.wavepacket.setOffset((*map_element).second.offset); lasreader->point.wavepacket.setSize((*map_element).second.size); } } else { fprintf(stderr,"ERROR: waveform offsets not in monotonically increasing order.\n"); #ifdef _WIN32 fprintf(stderr,"ERROR: last offset was %I64d but new offset is %I64d (for point %I64d)\n", last_offset, lasreader->point.wavepacket.getOffset(), lasreader->p_count); #else fprintf(stderr,"ERROR: last offset was %lld but new offset is %lld (for point %lld)\n", last_offset, lasreader->point.wavepacket.getOffset(), lasreader->p_count); #endif fprintf(stderr,"ERROR: use option '-waveforms_with_map' to compress.\n"); byebye(true, argc==1); } } } laswriter->write_point(&lasreader->point); if (lax) { lasindex.add(&lasreader->point, (U32)(laswriter->p_count)); } if (!lasreadopener.has_populated_header()) { laswriter->update_inventory(&lasreader->point); } } if (verbose && ((laswriter->p_count % 1000000) == 0)) fprintf(stderr,"written %d referenced %d of %d points\n", waves_written, waves_referenced, (I32)laswriter->p_count); if (!lasreadopener.has_populated_header()) { laswriter->update_header(&lasreader->header, TRUE); } if (lax) { // adaptive coarsening lasindex.complete(minimum_points, maximum_intervals); // write lax to file lasindex.write(laswriteopener.get_file_name()); } } else { // loop over points if (lasreadopener.has_populated_header()) { if (lax) // should we also create a spatial indexing file { // setup the quadtree LASquadtree* lasquadtree = new LASquadtree; lasquadtree->setup(lasreader->header.min_x, lasreader->header.max_x, lasreader->header.min_y, lasreader->header.max_y, tile_size); // create lax index LASindex lasindex; lasindex.prepare(lasquadtree, threshold); // compress points and add to index while (lasreader->read_point()) { lasindex.add(&lasreader->point, (U32)(laswriter->p_count)); laswriter->write_point(&lasreader->point); } // adaptive coarsening lasindex.complete(minimum_points, maximum_intervals); // write lax to file lasindex.write(laswriteopener.get_file_name()); } else { if (end_of_points > -1) { U8 point10[20]; memset(point10, end_of_points, 20); if (verbose) fprintf(stderr, "writing with end_of_points value %d\n", end_of_points); while (lasreader->read_point()) { if (memcmp(point10, &lasreader->point, 20) == 0) { break; } laswriter->write_point(&lasreader->point); laswriter->update_inventory(&lasreader->point); } laswriter->update_header(&lasreader->header, TRUE); } else { while (lasreader->read_point()) { laswriter->write_point(&lasreader->point); } } } } else { if (lax && (lasreader->header.min_x < lasreader->header.max_x) && (lasreader->header.min_y < lasreader->header.max_y)) { // setup the quadtree LASquadtree* lasquadtree = new LASquadtree; lasquadtree->setup(lasreader->header.min_x, lasreader->header.max_x, lasreader->header.min_y, lasreader->header.max_y, tile_size); // create lax index LASindex lasindex; lasindex.prepare(lasquadtree, threshold); // compress points and add to index while (lasreader->read_point()) { lasindex.add(&lasreader->point, (U32)(laswriter->p_count)); laswriter->write_point(&lasreader->point); laswriter->update_inventory(&lasreader->point); } // adaptive coarsening lasindex.complete(minimum_points, maximum_intervals); // write lax to file lasindex.write(laswriteopener.get_file_name()); } else { if (end_of_points > -1) { U8 point10[20]; memset(point10, end_of_points, 20); if (verbose) fprintf(stderr, "writing with end_of_points value %d\n", end_of_points); while (lasreader->read_point()) { if (memcmp(point10, &lasreader->point, 20) == 0) { break; } laswriter->write_point(&lasreader->point); laswriter->update_inventory(&lasreader->point); } } else { while (lasreader->read_point()) { laswriter->write_point(&lasreader->point); laswriter->update_inventory(&lasreader->point); } } } laswriter->update_header(&lasreader->header, TRUE); } } I64 total_bytes = laswriter->close(); delete laswriter; #ifdef _WIN32 if (verbose) fprintf(stderr,"%g secs to write %I64d bytes for '%s' with %I64d points of type %d\n", taketime()-start_time, total_bytes, laswriteopener.get_file_name(), lasreader->p_count, lasreader->header.point_data_format); #else if (verbose) fprintf(stderr,"%g secs to write %lld bytes for '%s' with %lld points of type %d\n", taketime()-start_time, total_bytes, laswriteopener.get_file_name(), lasreader->p_count, lasreader->header.point_data_format); #endif if (start_of_waveform_data_packet_record && !waveform) { lasreader->close(FALSE); ByteStreamIn* stream = lasreader->get_stream(); stream->seek(start_of_waveform_data_packet_record); char* wave_form_file_name; if (laswriteopener.get_file_name()) { wave_form_file_name = strdup(laswriteopener.get_file_name()); int len = strlen(wave_form_file_name); if (wave_form_file_name[len-3] == 'L') { wave_form_file_name[len-3] = 'W'; wave_form_file_name[len-2] = 'D'; wave_form_file_name[len-1] = 'P'; } else { wave_form_file_name[len-3] = 'w'; wave_form_file_name[len-2] = 'd'; wave_form_file_name[len-1] = 'p'; } } else { wave_form_file_name = strdup("wave_form.wdp"); } FILE* file = fopen(wave_form_file_name, "wb"); if (file) { if (verbose) fprintf(stderr,"writing waveforms to '%s'\n", wave_form_file_name); try { int byte; while (true) { byte = stream->getByte(); fputc(byte, file); } } catch (...) { fclose(file); } } } laswriteopener.set_file_name(0); } lasreader->close(); delete lasreader; } if (projection_was_set) { free(geo_keys); if (geo_double_params) { free(geo_double_params); } } byebye(false, argc==1); return 0; }
int main(int argc, char *argv[]) { int i; int is_mpi = 1; int debug = 0; bool verbose = false; bool force = false; // fixed header changes int set_version_major = -1; int set_version_minor = -1; int set_point_data_format = -1; int set_point_data_record_length = -1; int set_gps_time_endcoding = -1; // variable header changes bool remove_extra_header = false; bool remove_all_variable_length_records = false; int remove_variable_length_record = -1; int remove_variable_length_record_from = -1; int remove_variable_length_record_to = -1; bool remove_tiling_vlr = false; bool remove_original_vlr = false; // extract a subsequence //unsigned int subsequence_start = 0; //unsigned int subsequence_stop = U32_MAX; I64 subsequence_start = 0; I64 subsequence_stop = I64_MAX; // fix files with corrupt points bool clip_to_bounding_box = false; double start_time = 0; time_t wall_start_time; time_t wall_end_time; LASreadOpener lasreadopener; //if(is_mpi)lasreadopener.setIsMpi(TRUE); GeoProjectionConverter geoprojectionconverter; LASwriteOpener laswriteopener; if(is_mpi)laswriteopener.setIsMpi(TRUE); int process_count = 1; int rank = 0; start_time = taketime(); time(&wall_start_time); if (is_mpi){ MPI_Init(&argc,&argv); MPI_Comm_size(MPI_COMM_WORLD,&process_count); MPI_Comm_rank(MPI_COMM_WORLD,&rank); if(debug) printf ("MPI task %d has started...\n", rank); } if (argc == 1) { fprintf(stderr,"las2las.exe is better run in the command line or via the lastool.exe GUI\n"); char file_name[256]; fprintf(stderr,"enter input file: "); fgets(file_name, 256, stdin); file_name[strlen(file_name)-1] = '\0'; lasreadopener.set_file_name(file_name); fprintf(stderr,"enter output file: "); fgets(file_name, 256, stdin); file_name[strlen(file_name)-1] = '\0'; laswriteopener.set_file_name(file_name); } else { for (i = 1; i < argc; i++) { //if (argv[i][0] == '�') argv[i][0] = '-'; if (strcmp(argv[i],"-week_to_adjusted") == 0) { set_gps_time_endcoding = 1; } else if (strcmp(argv[i],"-adjusted_to_week") == 0) { set_gps_time_endcoding = 0; } } if (!geoprojectionconverter.parse(argc, argv)) byebye(true); if (!lasreadopener.parse(argc, argv)) byebye(true); if (!laswriteopener.parse(argc, argv)) byebye(true); } for (i = 1; i < argc; i++) { if (argv[i][0] == '\0') { continue; } else if (strcmp(argv[i],"-h") == 0 || strcmp(argv[i],"-help") == 0) { fprintf(stderr, "LAStools (by [email protected]) version %d\n", LAS_TOOLS_VERSION); usage(); } else if (strcmp(argv[i],"-v") == 0 || strcmp(argv[i],"-verbose") == 0) { verbose = true; } else if (strcmp(argv[i],"-version") == 0) { fprintf(stderr, "LAStools (by [email protected]) version %d\n", LAS_TOOLS_VERSION); byebye(); } else if (strcmp(argv[i],"-gui") == 0) { fprintf(stderr, "WARNING: not compiled with GUI support. ignoring '-gui' ...\n"); } else if (strcmp(argv[i],"-cores") == 0) { fprintf(stderr, "WARNING: not compiled with multi-core batching. ignoring '-cores' ...\n"); i++; } else if (strcmp(argv[i],"-force") == 0) { force = true; } else if (strcmp(argv[i],"-subseq") == 0) { if ((i+2) >= argc) { fprintf(stderr,"ERROR: '%s' needs 2 arguments: start stop\n", argv[i]); byebye(true); } subsequence_start = (unsigned int)atoi(argv[i+1]); subsequence_stop = (unsigned int)atoi(argv[i+2]); i+=2; } else if (strcmp(argv[i],"-start_at_point") == 0) { if ((i+1) >= argc) { fprintf(stderr,"ERROR: '%s' needs 1 argument: start\n", argv[i]); byebye(true); } subsequence_start = (unsigned int)atoi(argv[i+1]); i+=1; } else if (strcmp(argv[i],"-stop_at_point") == 0) { if ((i+1) >= argc) { fprintf(stderr,"ERROR: '%s' needs 1 argument: stop\n", argv[i]); byebye(true); } subsequence_stop = (unsigned int)atoi(argv[i+1]); i+=1; } else if (strcmp(argv[i],"-set_version") == 0) { if ((i+1) >= argc) { fprintf(stderr,"ERROR: '%s' needs 1 argument: major.minor\n", argv[i]); byebye(true); } if (sscanf(argv[i+1],"%d.%d",&set_version_major,&set_version_minor) != 2) { fprintf(stderr, "ERROR: cannot understand argument '%s' for '%s'\n", argv[i+1], argv[i]); usage(true); } i+=1; } else if (strcmp(argv[i],"-set_version_major") == 0) { if ((i+1) >= argc) { fprintf(stderr,"ERROR: '%s' needs 1 argument: major\n", argv[i]); byebye(true); } set_version_major = atoi(argv[i+1]); i+=1; } else if (strcmp(argv[i],"-set_version_minor") == 0) { if ((i+1) >= argc) { fprintf(stderr,"ERROR: '%s' needs 1 argument: minor\n", argv[i]); byebye(true); } set_version_minor = atoi(argv[i+1]); i+=1; } else if (strcmp(argv[i],"-remove_extra") == 0) { remove_extra_header = true; } else if (strcmp(argv[i],"-remove_all_vlrs") == 0) { remove_all_variable_length_records = true; } else if (strcmp(argv[i],"-remove_vlr") == 0) { if ((i+1) >= argc) { fprintf(stderr,"ERROR: '%s' needs 1 argument: number\n", argv[i]); byebye(true); } remove_variable_length_record = atoi(argv[i+1]); remove_variable_length_record_from = -1; remove_variable_length_record_to = -1; i++; } else if (strcmp(argv[i],"-remove_vlrs_from_to") == 0) { if ((i+2) >= argc) { fprintf(stderr,"ERROR: '%s' needs 2 arguments: start end\n", argv[i]); byebye(true); } remove_variable_length_record = -1; remove_variable_length_record_from = atoi(argv[i+1]); remove_variable_length_record_to = atoi(argv[i+2]); i+=2; } else if (strcmp(argv[i],"-remove_tiling_vlr") == 0) { remove_tiling_vlr = true; i++; } else if (strcmp(argv[i],"-remove_original_vlr") == 0) { remove_original_vlr = true; i++; } else if (strcmp(argv[i],"-set_point_type") == 0 || strcmp(argv[i],"-set_point_data_format") == 0 || strcmp(argv[i],"-point_type") == 0) { if ((i+1) >= argc) { fprintf(stderr,"ERROR: '%s' needs 1 argument: type\n", argv[i]); byebye(true); } set_point_data_format = atoi(argv[i+1]); i++; } else if (strcmp(argv[i],"-set_point_data_record_length") == 0 || strcmp(argv[i],"-set_point_size") == 0 || strcmp(argv[i],"-point_size") == 0) { if ((i+1) >= argc) { fprintf(stderr,"ERROR: '%s' needs 1 argument: size\n", argv[i]); byebye(true); } set_point_data_record_length = atoi(argv[i+1]); i++; } else if (strcmp(argv[i],"-clip_to_bounding_box") == 0 || strcmp(argv[i],"-clip_to_bb") == 0) { clip_to_bounding_box = true; } else if ((argv[i][0] != '-') && (lasreadopener.get_file_name_number() == 0)) { lasreadopener.add_file_name(argv[i]); argv[i][0] = '\0'; } else { fprintf(stderr, "ERROR: cannot understand argument '%s'\n", argv[i]); usage(true); } } // check input if (!lasreadopener.active()) { fprintf(stderr,"ERROR: no input specified\n"); usage(true, argc==1); } BOOL extra_pass = laswriteopener.is_piped(); // for piped output we need an extra pass if (extra_pass) { if (lasreadopener.is_piped()) { fprintf(stderr, "ERROR: input and output cannot both be piped\n"); usage(true); } } // make sure we do not corrupt the input file if (lasreadopener.get_file_name() && laswriteopener.get_file_name() && (strcmp(lasreadopener.get_file_name(), laswriteopener.get_file_name()) == 0)) { fprintf(stderr, "ERROR: input and output file name are identical\n"); usage(true); } // possibly loop over multiple input files while (lasreadopener.active()) { // if (verbose) start_time = taketime(); // open lasreader LASreader* lasreader = lasreadopener.open(); if (lasreader == 0) { fprintf(stderr, "ERROR: could not open lasreader\n"); usage(true, argc==1); } // store the inventory for the header LASinventory lasinventory; // the point we write sometimes needs to be copied LASpoint* point = 0; // prepare the header for output if (set_gps_time_endcoding != -1) { if (set_gps_time_endcoding == 0) { if ((lasreader->header.global_encoding & 1) == 0) { fprintf(stderr, "WARNING: global encoding indicates file already in GPS week time\n"); if (force) { fprintf(stderr, " forced conversion.\n"); } else { fprintf(stderr, " use '-force' to force conversion.\n"); byebye(true); } } else { lasreader->header.global_encoding &= ~1; } } else if (set_gps_time_endcoding == 1) { if ((lasreader->header.global_encoding & 1) == 1) { fprintf(stderr, "WARNING: global encoding indicates file already in Adjusted Standard GPS time\n"); if (force) { fprintf(stderr, " forced conversion.\n"); } else { fprintf(stderr, " use '-force' to force conversion.\n"); byebye(true); } } else { lasreader->header.global_encoding |= 1; } } } if (set_version_major != -1) { if (set_version_major != 1) { fprintf(stderr, "ERROR: unknown version_major %d\n", set_version_major); byebye(true); } lasreader->header.version_major = (U8)set_version_major; } if (set_version_minor >= 0) { if (set_version_minor > 4) { fprintf(stderr, "ERROR: unknown version_minor %d\n", set_version_minor); byebye(true); } if (set_version_minor < 3) { if (lasreader->header.version_minor == 3) { lasreader->header.header_size -= 8; lasreader->header.offset_to_point_data -= 8; } else if (lasreader->header.version_minor >= 4) { lasreader->header.header_size -= (8 + 140); lasreader->header.offset_to_point_data -= (8 + 140); } } else if (set_version_minor == 3) { if (lasreader->header.version_minor < 3) { lasreader->header.header_size += 8; lasreader->header.offset_to_point_data += 8; lasreader->header.start_of_waveform_data_packet_record = 0; } else if (lasreader->header.version_minor >= 4) { lasreader->header.header_size -= 140; lasreader->header.offset_to_point_data -= 140; } } else if (set_version_minor == 4) { if (lasreader->header.version_minor < 3) { lasreader->header.header_size += (8 + 140); lasreader->header.offset_to_point_data += (8 + 140); lasreader->header.start_of_waveform_data_packet_record = 0; } else if (lasreader->header.version_minor == 3) { lasreader->header.header_size += 140; lasreader->header.offset_to_point_data += 140; } } if ((set_version_minor <= 3) && (lasreader->header.version_minor >= 4)) { if (lasreader->header.point_data_format > 5) { switch (lasreader->header.point_data_format) { case 6: fprintf(stderr, "WARNING: downgrading point_data_format from %d to 1\n", lasreader->header.point_data_format); lasreader->header.point_data_format = 1; fprintf(stderr, " and point_data_record_length from %d to %d\n", lasreader->header.point_data_record_length, lasreader->header.point_data_record_length - 2); lasreader->header.point_data_record_length -= 2; break; case 7: fprintf(stderr, "WARNING: downgrading point_data_format from %d to 3\n", lasreader->header.point_data_format); lasreader->header.point_data_format = 3; fprintf(stderr, " and point_data_record_length from %d to %d\n", lasreader->header.point_data_record_length, lasreader->header.point_data_record_length - 2); lasreader->header.point_data_record_length -= 2; break; case 8: fprintf(stderr, "WARNING: downgrading point_data_format from %d to 3\n", lasreader->header.point_data_format); lasreader->header.point_data_format = 3; fprintf(stderr, " and point_data_record_length from %d to %d\n", lasreader->header.point_data_record_length, lasreader->header.point_data_record_length - 4); lasreader->header.point_data_record_length -= 4; break; case 9: fprintf(stderr, "WARNING: downgrading point_data_format from %d to 4\n", lasreader->header.point_data_format); lasreader->header.point_data_format = 4; fprintf(stderr, " and point_data_record_length from %d to %d\n", lasreader->header.point_data_record_length, lasreader->header.point_data_record_length - 2); lasreader->header.point_data_record_length -= 2; break; case 10: fprintf(stderr, "WARNING: downgrading point_data_format from %d to 5\n", lasreader->header.point_data_format); lasreader->header.point_data_format = 5; fprintf(stderr, " and point_data_record_length from %d to %d\n", lasreader->header.point_data_record_length, lasreader->header.point_data_record_length - 4); lasreader->header.point_data_record_length -= 4; break; default: fprintf(stderr, "ERROR: unknown point_data_format %d\n", lasreader->header.point_data_format); byebye(true); } } point = new LASpoint; point->init(&lasreader->header, lasreader->header.point_data_format, lasreader->header.point_data_record_length); } lasreader->header.version_minor = (U8)set_version_minor; } // are we supposed to change the point data format if (set_point_data_format != -1) { if (set_point_data_format < 0 || set_point_data_format > 10) { fprintf(stderr, "ERROR: unknown point_data_format %d\n", set_point_data_format); byebye(true); } // depending on the conversion we may need to copy the point if (convert_point_type_from_to[lasreader->header.point_data_format][set_point_data_format]) { if (point == 0) point = new LASpoint; } lasreader->header.point_data_format = (U8)set_point_data_format; lasreader->header.clean_laszip(); switch (lasreader->header.point_data_format) { case 0: lasreader->header.point_data_record_length = 20; break; case 1: lasreader->header.point_data_record_length = 28; break; case 2: lasreader->header.point_data_record_length = 26; break; case 3: lasreader->header.point_data_record_length = 34; break; case 4: lasreader->header.point_data_record_length = 57; break; case 5: lasreader->header.point_data_record_length = 63; break; case 6: lasreader->header.point_data_record_length = 30; break; case 7: lasreader->header.point_data_record_length = 36; break; case 8: lasreader->header.point_data_record_length = 38; break; case 9: lasreader->header.point_data_record_length = 59; break; case 10: lasreader->header.point_data_record_length = 67; break; } } // are we supposed to change the point data record length if (set_point_data_record_length != -1) { I32 num_extra_bytes = 0; switch (lasreader->header.point_data_format) { case 0: num_extra_bytes = set_point_data_record_length - 20; break; case 1: num_extra_bytes = set_point_data_record_length - 28; break; case 2: num_extra_bytes = set_point_data_record_length - 26; break; case 3: num_extra_bytes = set_point_data_record_length - 34; break; case 4: num_extra_bytes = set_point_data_record_length - 57; break; case 5: num_extra_bytes = set_point_data_record_length - 63; break; case 6: num_extra_bytes = set_point_data_record_length - 30; break; case 7: num_extra_bytes = set_point_data_record_length - 36; break; case 8: num_extra_bytes = set_point_data_record_length - 38; break; case 9: num_extra_bytes = set_point_data_record_length - 59; break; case 10: num_extra_bytes = set_point_data_record_length - 67; break; } if (num_extra_bytes < 0) { fprintf(stderr, "ERROR: point_data_format %d needs record length of at least %d\n", lasreader->header.point_data_format, set_point_data_record_length - num_extra_bytes); byebye(true); } if (lasreader->header.point_data_record_length < set_point_data_record_length) { if (!point) point = new LASpoint; } lasreader->header.point_data_record_length = (U16)set_point_data_record_length; lasreader->header.clean_laszip(); } // if the point needs to be copied set up the data fields if (point) { point->init(&lasreader->header, lasreader->header.point_data_format, lasreader->header.point_data_record_length); } // maybe we should remove some stuff if (remove_extra_header) { lasreader->header.clean_user_data_in_header(); lasreader->header.clean_user_data_after_header(); } if (remove_all_variable_length_records) { lasreader->header.clean_vlrs(); } else { if (remove_variable_length_record != -1) { lasreader->header.remove_vlr(remove_variable_length_record); } if (remove_variable_length_record_from != -1) { for (i = remove_variable_length_record_to; i >= remove_variable_length_record_from; i--) { lasreader->header.remove_vlr(i); } } } if (remove_tiling_vlr) { lasreader->header.clean_lastiling(); } if (remove_original_vlr) { lasreader->header.clean_lasoriginal(); } // maybe we should add / change the projection information LASquantizer* reproject_quantizer = 0; LASquantizer* saved_quantizer = 0; if (geoprojectionconverter.has_projection(true) || geoprojectionconverter.has_projection(false)) { if (!geoprojectionconverter.has_projection(true) && lasreader->header.vlr_geo_keys) { geoprojectionconverter.set_projection_from_geo_keys(lasreader->header.vlr_geo_keys[0].number_of_keys, (GeoProjectionGeoKeys*)lasreader->header.vlr_geo_key_entries, lasreader->header.vlr_geo_ascii_params, lasreader->header.vlr_geo_double_params); } if (geoprojectionconverter.has_projection(true) && geoprojectionconverter.has_projection(false)) { reproject_quantizer = new LASquantizer(); double point[3]; point[0] = (lasreader->header.min_x+lasreader->header.max_x)/2; point[1] = (lasreader->header.min_y+lasreader->header.max_y)/2; point[2] = (lasreader->header.min_z+lasreader->header.max_z)/2; geoprojectionconverter.to_target(point); reproject_quantizer->x_scale_factor = geoprojectionconverter.get_target_precision(); reproject_quantizer->y_scale_factor = geoprojectionconverter.get_target_precision(); reproject_quantizer->z_scale_factor = lasreader->header.z_scale_factor; reproject_quantizer->x_offset = ((I64)((point[0]/reproject_quantizer->x_scale_factor)/10000000))*10000000*reproject_quantizer->x_scale_factor; reproject_quantizer->y_offset = ((I64)((point[1]/reproject_quantizer->y_scale_factor)/10000000))*10000000*reproject_quantizer->y_scale_factor; reproject_quantizer->z_offset = ((I64)((point[2]/reproject_quantizer->z_scale_factor)/10000000))*10000000*reproject_quantizer->z_scale_factor; } int number_of_keys; GeoProjectionGeoKeys* geo_keys = 0; int num_geo_double_params; double* geo_double_params = 0; if (geoprojectionconverter.get_geo_keys_from_projection(number_of_keys, &geo_keys, num_geo_double_params, &geo_double_params, !geoprojectionconverter.has_projection(false))) { lasreader->header.set_geo_keys(number_of_keys, (LASvlr_key_entry*)geo_keys); free(geo_keys); if (geo_double_params) { lasreader->header.set_geo_double_params(num_geo_double_params, geo_double_params); free(geo_double_params); } else { lasreader->header.del_geo_double_params(); } lasreader->header.del_geo_ascii_params(); } } // do we need an extra pass BOOL extra_pass = laswriteopener.is_piped(); // for piped output we need an extra pass if (extra_pass) { if (lasreadopener.is_piped()) { fprintf(stderr, "ERROR: input and output cannot both be piped\n"); usage(true); } if (verbose) fprintf(stderr, "extra pass for piped output: reading %lld points ...\n", lasreader->npoints); // maybe seek to start position if (subsequence_start) lasreader->seek(subsequence_start); while (lasreader->read_point()) { if (lasreader->p_count > subsequence_stop) break; if (clip_to_bounding_box) { if (!lasreader->point.inside_box(lasreader->header.min_x, lasreader->header.min_y, lasreader->header.min_z, lasreader->header.max_x, lasreader->header.max_y, lasreader->header.max_z)) { continue; } } if (reproject_quantizer) { lasreader->point.compute_coordinates(); geoprojectionconverter.to_target(lasreader->point.coordinates); lasreader->point.compute_XYZ(reproject_quantizer); } lasinventory.add(&lasreader->point); } lasreader->close(); lasreader->header.number_of_point_records = lasinventory.number_of_point_records; for (i = 0; i < 5; i++) lasreader->header.number_of_points_by_return[i] = lasinventory.number_of_points_by_return[i+1]; if (reproject_quantizer) lasreader->header = *reproject_quantizer; lasreader->header.max_x = lasreader->header.get_x(lasinventory.max_X); lasreader->header.min_x = lasreader->header.get_x(lasinventory.min_X); lasreader->header.max_y = lasreader->header.get_y(lasinventory.max_Y); lasreader->header.min_y = lasreader->header.get_y(lasinventory.min_Y); lasreader->header.max_z = lasreader->header.get_z(lasinventory.max_Z); lasreader->header.min_z = lasreader->header.get_z(lasinventory.min_Z); // if (verbose) { fprintf(stderr,"extra pass took %g sec.\n", taketime()-start_time); start_time = taketime(); } if (verbose) fprintf(stderr, "piped output: reading %lld and writing %d points ...\n", lasreader->npoints, lasinventory.number_of_point_records); } else { if (reproject_quantizer) { saved_quantizer = new LASquantizer(); *saved_quantizer = lasreader->header; lasreader->header = *reproject_quantizer; } //if (verbose) fprintf(stderr, "reading %lld and writing all surviving points ...\n", lasreader->npoints); } // check output if (!laswriteopener.active()) { // create name from input name laswriteopener.make_file_name(lasreadopener.get_file_name()); } // prepare the header for the surviving points strncpy(lasreader->header.system_identifier, "LAStools (c) by rapidlasso GmbH", 32); lasreader->header.system_identifier[31] = '\0'; char temp[64]; sprintf(temp, "las2las (version %d)", LAS_TOOLS_VERSION); strncpy(lasreader->header.generating_software, temp, 32); lasreader->header.generating_software[31] = '\0'; LASwriter* laswriter = 0; // open laswriter if(is_mpi){ // remove any existing out file, before opening with MPI_File_open if(rank==0){ remove(laswriteopener.get_file_name()); } MPI_Barrier(MPI_COMM_WORLD); } laswriter = laswriteopener.open(&lasreader->header); if (laswriter == 0) { fprintf(stderr, "ERROR: could not open laswriter\n"); byebye(true, argc==1); } // ************************************************************************************************** if(is_mpi == 1){ // jdw, we do this because only rank 0 now writes the header in laswriter_las.cpp MPI_File fh = laswriter->get_MPI_File(); MPI_Offset offset; //MPI_File_get_position(fh, &offset); //printf ("offset %lld, rank %i fh %lld\n", offset, rank, fh); if(rank==0){ MPI_File_get_position(fh, &offset); } MPI_Bcast(&offset, 1, MPI_OFFSET, 0, MPI_COMM_WORLD); MPI_Barrier(MPI_COMM_WORLD); MPI_File_seek(fh, offset, MPI_SEEK_SET); } // **************************************************************************************************** // for piped output we need to re-open the input file if (extra_pass) { if (!lasreadopener.reopen(lasreader)) { fprintf(stderr, "ERROR: could not re-open lasreader\n"); byebye(true); } } else { if (reproject_quantizer) { lasreader->header = *saved_quantizer; delete saved_quantizer; } } // maybe seek to start position if (subsequence_start) lasreader->seek(subsequence_start); // loop over points if (point) { while (lasreader->read_point()) { if (lasreader->p_count > subsequence_stop) break; if (clip_to_bounding_box) { if (!lasreader->point.inside_box(lasreader->header.min_x, lasreader->header.min_y, lasreader->header.min_z, lasreader->header.max_x, lasreader->header.max_y, lasreader->header.max_z)) { continue; } } if (reproject_quantizer) { lasreader->point.compute_coordinates(); geoprojectionconverter.to_target(lasreader->point.coordinates); lasreader->point.compute_XYZ(reproject_quantizer); } *point = lasreader->point; laswriter->write_point(point); // without extra pass we need inventory of surviving points if (!extra_pass) laswriter->update_inventory(point); } delete point; point = 0; } else // ***************************** MPI ******************************************************** { // ***** Determine the start and stop points for this process ***** I64 left_over_count = lasreader->npoints % process_count; I64 process_points = lasreader->npoints / process_count; subsequence_start = rank*process_points; subsequence_stop = subsequence_start + process_points; if(rank == process_count-1) subsequence_stop += left_over_count; // ***** Set the input stream file offset for this process ***** // subsequence_start parameter gets cast to U32 in the implementation of seek and overflows for large files // manually set the file offset instead for now //((LASreaderLAS*)lasreader)->stream->seek(subsequence_start); I64 header_end_read_position = lasreader->get_Stream()->tell(); //printf("header end %lld subseqence_start * 28 %lld rank %i\n", header_end_read_position, subsequence_start*28, rank); lasreader->p_count = subsequence_start; lasreader->get_Stream()->seek(header_end_read_position + subsequence_start*28); //printf("seek pos first loop %lld rank %i\n", lasreader->get_Stream()->tell(), rank); if (verbose) fprintf(stderr, "reading %lli points, rank %i\n", subsequence_stop - subsequence_start, rank); // *****Read the file for the first time ***** // this first read and filter of the file is to gather a count of points that pass the filter so that // write offsets can be set. I64 filtered_count = 0; //while (lasreader->read_point()){ lasreader->MPI_END_POINT = subsequence_stop; while (lasreader->read_point()) { filtered_count++; } // ***** Gather and set the write offset for this process ***** I64* filtered_counts = (I64*)malloc(process_count * sizeof(I64)); if(is_mpi)MPI_Barrier(MPI_COMM_WORLD); filtered_counts[rank] = filtered_count; if(is_mpi)MPI_Allgather(&filtered_count, 1, MPI_LONG_LONG, filtered_counts, 1, MPI_LONG_LONG, MPI_COMM_WORLD); if(is_mpi)MPI_Barrier(MPI_COMM_WORLD); if(debug) printf("filtered count %lli rank %i\n", filtered_counts[rank], rank); if(is_mpi)MPI_Barrier(MPI_COMM_WORLD); I64 write_point_offset = 0; for (int k=0; k < rank; k++){ write_point_offset += filtered_counts[k]; } if(is_mpi){ MPI_File fh = laswriter->get_MPI_File(); MPI_Offset cur = 0; // jdw, todo, remove the hardcoding by adding methods to read point size from reader MPI_File_seek(fh, write_point_offset*28, MPI_SEEK_CUR); if(debug){ MPI_File_get_position(fh, &cur); printf ("rank %i, write offset %lld\n", rank, write_point_offset*28); } } if(is_mpi)MPI_Barrier(MPI_COMM_WORLD); // ***** Read and filter the input file again, this time write the filtered point since output file offset in now known amd set ***** //lasreader->seek(subsequence_start); // subsequence_start parameter gets cast to U32 in the implementation and overflows for large files // manually set the file offset instead for now //printf("header end %lld subseqence_start * 28 %lld rank %i\n", header_end_read_position, subsequence_start*28, rank); lasreader->p_count = subsequence_start; lasreader->get_Stream()->seek(header_end_read_position + subsequence_start*28); //printf("seek pos second loop %lld rank %i\n", lasreader->get_Stream()->tell(), rank); lasreader->MPI_END_POINT = subsequence_stop; while (lasreader->read_point()) { //if (lasreader->p_count > subsequence_stop) break; //if (clip_to_bounding_box) //{ // if (!lasreader->point.inside_box(lasreader->header.min_x, lasreader->header.min_y, lasreader->header.min_z, lasreader->header.max_x, lasreader->header.max_y, lasreader->header.max_z)) // { // continue; // } // } if (reproject_quantizer) { lasreader->point.compute_coordinates(); geoprojectionconverter.to_target(lasreader->point.coordinates); lasreader->point.compute_XYZ(reproject_quantizer); } laswriter->write_point(&lasreader->point); // without extra pass we need inventory of surviving points if (!extra_pass){ laswriter->update_inventory(&lasreader->point); } } //***** this is part of an mpi write optimization ***** laswriter->get_Stream()->flushBytes(); } // without the extra pass we need to fix the header now // ***** do the inventory reconciliation ***** // ***** Reduce inventory information in rank 0 ***** if (is_mpi){ U32 number_of_point_records = 0; U32 number_of_points_by_return[8]; for(int i = 0; i<8; i++)number_of_points_by_return[i] = 0; I32 max_X = 0; I32 min_X = 0; I32 max_Y = 0; I32 min_Y = 0; I32 max_Z = 0; I32 min_Z = 0; MPI_Reduce(&laswriter->inventory.number_of_point_records, &number_of_point_records, 1, MPI_UNSIGNED, MPI_SUM, 0, MPI_COMM_WORLD); MPI_Reduce(laswriter->inventory.number_of_points_by_return, number_of_points_by_return, 8, MPI_UNSIGNED, MPI_SUM, 0, MPI_COMM_WORLD); MPI_Reduce(&laswriter->inventory.max_X, &max_X, 1, MPI_INT, MPI_MAX, 0, MPI_COMM_WORLD); MPI_Reduce(&laswriter->inventory.min_X, &min_X, 1, MPI_INT, MPI_MIN, 0, MPI_COMM_WORLD); MPI_Reduce(&laswriter->inventory.max_Y, &max_Y, 1, MPI_INT, MPI_MAX, 0, MPI_COMM_WORLD); MPI_Reduce(&laswriter->inventory.min_Y, &min_Y, 1, MPI_INT, MPI_MIN, 0, MPI_COMM_WORLD); MPI_Reduce(&laswriter->inventory.max_Z, &max_Z, 1, MPI_INT, MPI_MAX, 0, MPI_COMM_WORLD); MPI_Reduce(&laswriter->inventory.min_Z, &min_Z, 1, MPI_INT, MPI_MIN, 0, MPI_COMM_WORLD); if (rank ==0){ laswriter->inventory.number_of_point_records = number_of_point_records; for(int i=0; i<8; i++)laswriter->inventory.number_of_points_by_return[i] = number_of_points_by_return[i]; laswriter->inventory.max_X = max_X; laswriter->inventory.min_X = min_X; laswriter->inventory.max_Y = max_Y; laswriter->inventory.min_Y = min_Y; laswriter->inventory.max_Z = max_Z; laswriter->inventory.min_Z = min_Z; } } if(rank == 0){ if (!extra_pass) { if (reproject_quantizer) lasreader->header = *reproject_quantizer; laswriter->update_header(&lasreader->header, TRUE); } } if(is_mpi)MPI_Barrier(MPI_COMM_WORLD); if (verbose) { fprintf(stderr,"%lli surviving points written by rank: %i\n", laswriter->p_count, rank); } laswriter->close(FALSE); if(is_mpi)MPI_Barrier(MPI_COMM_WORLD); delete laswriter; lasreader->close(); delete lasreader; if (reproject_quantizer) delete reproject_quantizer; } if(is_mpi)MPI_Finalize(); time(&wall_end_time); if (verbose) { fprintf(stderr,"total time %.f sec, cpu time: %g sec. rank: %i\n", difftime(wall_end_time, wall_start_time), taketime()-start_time, rank); } return 0; }
int main(int argc, char *argv[]) { int i; #ifdef COMPILE_WITH_GUI bool gui = false; #endif #ifdef COMPILE_WITH_MULTI_CORE I32 cores = 1; #endif bool verbose = false; bool force = false; // fixed header changes int set_version_major = -1; int set_version_minor = -1; int set_point_data_format = -1; int set_point_data_record_length = -1; int set_gps_time_endcoding = -1; // variable header changes bool remove_extra_header = false; bool remove_all_variable_length_records = false; int remove_variable_length_record = -1; bool remove_tiling_vlr = false; bool remove_original_vlr = false; // extract a subsequence unsigned int subsequence_start = 0; unsigned int subsequence_stop = U32_MAX; // fix files with corrupt points bool clip_to_bounding_box = false; double start_time = 0; LASreadOpener lasreadopener; GeoProjectionConverter geoprojectionconverter; LASwriteOpener laswriteopener; if (argc == 1) { #ifdef COMPILE_WITH_GUI return las2las_gui(argc, argv, 0); #else fprintf(stderr,"las2las.exe is better run in the command line or via the lastool.exe GUI\n"); char file_name[256]; fprintf(stderr,"enter input file: "); fgets(file_name, 256, stdin); file_name[strlen(file_name)-1] = '\0'; lasreadopener.set_file_name(file_name); fprintf(stderr,"enter output file: "); fgets(file_name, 256, stdin); file_name[strlen(file_name)-1] = '\0'; laswriteopener.set_file_name(file_name); #endif } else { for (i = 1; i < argc; i++) { if (argv[i][0] == '–') argv[i][0] = '-'; if (strcmp(argv[i],"-week_to_adjusted") == 0) { set_gps_time_endcoding = 1; } else if (strcmp(argv[i],"-adjusted_to_week") == 0) { set_gps_time_endcoding = 0; } } if (!geoprojectionconverter.parse(argc, argv)) byebye(true); if (!lasreadopener.parse(argc, argv)) byebye(true); if (!laswriteopener.parse(argc, argv)) byebye(true); } for (i = 1; i < argc; i++) { if (argv[i][0] == '\0') { continue; } else if (strcmp(argv[i],"-h") == 0 || strcmp(argv[i],"-help") == 0) { fprintf(stderr, "LAStools (by [email protected]) version %d\n", LAS_TOOLS_VERSION); usage(); } else if (strcmp(argv[i],"-v") == 0 || strcmp(argv[i],"-verbose") == 0) { verbose = true; } else if (strcmp(argv[i],"-version") == 0) { fprintf(stderr, "LAStools (by [email protected]) version %d\n", LAS_TOOLS_VERSION); byebye(); } else if (strcmp(argv[i],"-gui") == 0) { #ifdef COMPILE_WITH_GUI gui = true; #else fprintf(stderr, "WARNING: not compiled with GUI support. ignoring '-gui' ...\n"); #endif } else if (strcmp(argv[i],"-cores") == 0) { #ifdef COMPILE_WITH_MULTI_CORE if ((i+1) >= argc) { fprintf(stderr,"ERROR: '%s' needs 1 argument: number\n", argv[i]); usage(true); } argv[i][0] = '\0'; i++; cores = atoi(argv[i]); argv[i][0] = '\0'; #else fprintf(stderr, "WARNING: not compiled with multi-core batching. ignoring '-cores' ...\n"); #endif } else if (strcmp(argv[i],"-force") == 0) { force = true; } else if (strcmp(argv[i],"-subseq") == 0) { if ((i+2) >= argc) { fprintf(stderr,"ERROR: '%s' needs 2 arguments: start stop\n", argv[i]); byebye(true); } subsequence_start = (unsigned int)atoi(argv[i+1]); subsequence_stop = (unsigned int)atoi(argv[i+2]); i+=2; } else if (strcmp(argv[i],"-start_at_point") == 0) { if ((i+1) >= argc) { fprintf(stderr,"ERROR: '%s' needs 1 argument: start\n", argv[i]); byebye(true); } subsequence_start = (unsigned int)atoi(argv[i+1]); i+=1; } else if (strcmp(argv[i],"-stop_at_point") == 0) { if ((i+1) >= argc) { fprintf(stderr,"ERROR: '%s' needs 1 argument: stop\n", argv[i]); byebye(true); } subsequence_stop = (unsigned int)atoi(argv[i+1]); i+=1; } else if (strcmp(argv[i],"-set_version") == 0) { if ((i+1) >= argc) { fprintf(stderr,"ERROR: '%s' needs 1 argument: major.minor\n", argv[i]); byebye(true); } if (sscanf(argv[i+1],"%d.%d",&set_version_major,&set_version_minor) != 2) { fprintf(stderr, "ERROR: cannot understand argument '%s' for '%s'\n", argv[i+1], argv[i]); usage(true); } i+=1; } else if (strcmp(argv[i],"-set_version_major") == 0) { if ((i+1) >= argc) { fprintf(stderr,"ERROR: '%s' needs 1 argument: major\n", argv[i]); byebye(true); } set_version_major = atoi(argv[i+1]); i+=1; } else if (strcmp(argv[i],"-set_version_minor") == 0) { if ((i+1) >= argc) { fprintf(stderr,"ERROR: '%s' needs 1 argument: minor\n", argv[i]); byebye(true); } set_version_minor = atoi(argv[i+1]); i+=1; } else if (strcmp(argv[i],"-remove_extra") == 0) { remove_extra_header = true; } else if (strcmp(argv[i],"-remove_all_vlrs") == 0 || strcmp(argv[i],"-remove_all_vlr") == 0) { remove_all_variable_length_records = true; } else if (strcmp(argv[i],"-remove_vlr") == 0) { if ((i+1) >= argc) { fprintf(stderr,"ERROR: '%s' needs 1 argument: number\n", argv[i]); byebye(true); } remove_variable_length_record = atoi(argv[i+1]); i++; } else if (strcmp(argv[i],"-remove_tiling_vlr") == 0) { remove_tiling_vlr = true; i++; } else if (strcmp(argv[i],"-remove_original_vlr") == 0) { remove_original_vlr = true; i++; } else if (strcmp(argv[i],"-point_type") == 0) { if ((i+1) >= argc) { fprintf(stderr,"ERROR: '%s' needs 1 argument: type\n", argv[i]); byebye(true); } set_point_data_format = atoi(argv[i+1]); i++; } else if (strcmp(argv[i],"-point_size") == 0) { if ((i+1) >= argc) { fprintf(stderr,"ERROR: '%s' needs 1 argument: size\n", argv[i]); byebye(true); } set_point_data_record_length = atoi(argv[i+1]); i++; } else if (strcmp(argv[i],"-clip_to_bounding_box") == 0 || strcmp(argv[i],"-clip_to_bbox") == 0) { clip_to_bounding_box = true; } else if ((argv[i][0] != '-') && (lasreadopener.get_file_name_number() == 0)) { lasreadopener.add_file_name(argv[i]); argv[i][0] = '\0'; } else { fprintf(stderr, "ERROR: cannot understand argument '%s'\n", argv[i]); usage(true); } } #ifdef COMPILE_WITH_GUI if (gui) { return las2las_gui(argc, argv, &lasreadopener); } #endif #ifdef COMPILE_WITH_MULTI_CORE if ((cores > 1) && (lasreadopener.get_file_name_number() > 1) && (!lasreadopener.get_merged())) { return las2las_multi_core(argc, argv, &geoprojectionconverter, &lasreadopener, &laswriteopener, cores); } #endif // check input if (!lasreadopener.active()) { fprintf(stderr,"ERROR: no input specified\n"); usage(true, argc==1); } BOOL extra_pass = laswriteopener.is_piped(); // for piped output we need an extra pass if (extra_pass) { if (lasreadopener.is_piped()) { fprintf(stderr, "ERROR: input and output cannot both be piped\n"); usage(true); } } // make sure we do not corrupt the input file if (lasreadopener.get_file_name() && laswriteopener.get_file_name() && (strcmp(lasreadopener.get_file_name(), laswriteopener.get_file_name()) == 0)) { fprintf(stderr, "ERROR: input and output file name are identical\n"); usage(true); } // possibly loop over multiple input files while (lasreadopener.active()) { if (verbose) start_time = taketime(); // open lasreader LASreader* lasreader = lasreadopener.open(); if (lasreader == 0) { fprintf(stderr, "ERROR: could not open lasreader\n"); usage(true, argc==1); } // store the inventory for the header LASinventory lasinventory; // the point we write sometimes needs to be copied LASpoint* point = 0; // prepare the header for output if (set_gps_time_endcoding != -1) { if (set_gps_time_endcoding == 0) { if ((lasreader->header.global_encoding & 1) == 0) { fprintf(stderr, "WARNING: global encoding indicates file already in GPS week time\n"); if (force) { fprintf(stderr, " forced conversion.\n"); } else { fprintf(stderr, " use '-force' to force conversion.\n"); byebye(true); } } else { lasreader->header.global_encoding &= ~1; } } else if (set_gps_time_endcoding == 1) { if ((lasreader->header.global_encoding & 1) == 1) { fprintf(stderr, "WARNING: global encoding indicates file already in Adjusted Standard GPS time\n"); if (force) { fprintf(stderr, " forced conversion.\n"); } else { fprintf(stderr, " use '-force' to force conversion.\n"); byebye(true); } } else { lasreader->header.global_encoding |= 1; } } } if (set_version_major != -1) { if (set_version_major != 1) { fprintf(stderr, "ERROR: unknown version_major %d\n", set_version_major); byebye(true); } lasreader->header.version_major = (U8)set_version_major; } if (set_version_minor >= 0) { if (set_version_minor > 4) { fprintf(stderr, "ERROR: unknown version_minor %d\n", set_version_minor); byebye(true); } if (set_version_minor < 3) { if (lasreader->header.version_minor == 3) { lasreader->header.header_size -= 8; lasreader->header.offset_to_point_data -= 8; } else if (lasreader->header.version_minor >= 4) { lasreader->header.header_size -= (8 + 140); lasreader->header.offset_to_point_data -= (8 + 140); } } else if (set_version_minor == 3) { if (lasreader->header.version_minor < 3) { lasreader->header.header_size += 8; lasreader->header.offset_to_point_data += 8; lasreader->header.start_of_waveform_data_packet_record = 0; } else if (lasreader->header.version_minor >= 4) { lasreader->header.header_size -= 140; lasreader->header.offset_to_point_data -= 140; } } else if (set_version_minor == 4) { if (lasreader->header.version_minor < 3) { lasreader->header.header_size += (8 + 140); lasreader->header.offset_to_point_data += (8 + 140); lasreader->header.start_of_waveform_data_packet_record = 0; } else if (lasreader->header.version_minor == 3) { lasreader->header.header_size += 140; lasreader->header.offset_to_point_data += 140; } } lasreader->header.version_minor = (U8)set_version_minor; } // are we supposed to change the point data format if (set_point_data_format != -1) { if (set_point_data_format < 0 || set_point_data_format >= 6) { fprintf(stderr, "ERROR: unknown point_data_format %d\n", set_point_data_format); byebye(true); } // depending on the conversion we may need to copy the point if (convert_point_type_from_to[lasreader->header.point_data_format][set_point_data_format]) { point = new LASpoint; } lasreader->header.point_data_format = (U8)set_point_data_format; lasreader->header.clean_laszip(); switch (lasreader->header.point_data_format) { case 0: lasreader->header.point_data_record_length = 20; break; case 1: lasreader->header.point_data_record_length = 28; break; case 2: lasreader->header.point_data_record_length = 26; break; case 3: lasreader->header.point_data_record_length = 34; break; case 4: lasreader->header.point_data_record_length = 57; break; case 5: lasreader->header.point_data_record_length = 63; break; } } // are we supposed to change the point data record length if (set_point_data_record_length != -1) { I32 num_extra_bytes = 0; switch (lasreader->header.point_data_format) { case 0: num_extra_bytes = set_point_data_record_length - 20; break; case 1: num_extra_bytes = set_point_data_record_length - 28; break; case 2: num_extra_bytes = set_point_data_record_length - 26; break; case 3: num_extra_bytes = set_point_data_record_length - 34; break; case 4: num_extra_bytes = set_point_data_record_length - 57; break; case 5: num_extra_bytes = set_point_data_record_length - 63; break; } if (num_extra_bytes < 0) { fprintf(stderr, "ERROR: point_data_format %d needs record length of at least %d\n", lasreader->header.point_data_format, set_point_data_record_length - num_extra_bytes); byebye(true); } if (lasreader->header.point_data_record_length < set_point_data_record_length) { if (!point) point = new LASpoint; } lasreader->header.point_data_record_length = (U16)set_point_data_record_length; lasreader->header.clean_laszip(); } // if the point needs to be copied set up the data fields if (point) { point->init(&lasreader->header, lasreader->header.point_data_format, lasreader->header.point_data_record_length); } // maybe we should remove some stuff if (remove_extra_header) { lasreader->header.clean_user_data_in_header(); lasreader->header.clean_user_data_after_header(); } if (remove_all_variable_length_records) { lasreader->header.clean_vlrs(); } if (remove_variable_length_record != -1) { lasreader->header.remove_vlr(remove_variable_length_record); } if (remove_tiling_vlr) { lasreader->header.clean_lastiling(); } if (remove_original_vlr) { lasreader->header.clean_lasoriginal(); } // maybe we should add / change the projection information LASquantizer* reproject_quantizer = 0; LASquantizer* saved_quantizer = 0; if (geoprojectionconverter.has_projection(true) || geoprojectionconverter.has_projection(false)) { if (!geoprojectionconverter.has_projection(true) && lasreader->header.vlr_geo_keys) { geoprojectionconverter.set_projection_from_geo_keys(lasreader->header.vlr_geo_keys[0].number_of_keys, (GeoProjectionGeoKeys*)lasreader->header.vlr_geo_key_entries, lasreader->header.vlr_geo_ascii_params, lasreader->header.vlr_geo_double_params); } if (geoprojectionconverter.has_projection(true) && geoprojectionconverter.has_projection(false)) { reproject_quantizer = new LASquantizer(); double point[3]; point[0] = (lasreader->header.min_x+lasreader->header.max_x)/2; point[1] = (lasreader->header.min_y+lasreader->header.max_y)/2; point[2] = (lasreader->header.min_z+lasreader->header.max_z)/2; geoprojectionconverter.to_target(point); reproject_quantizer->x_scale_factor = geoprojectionconverter.get_target_precision(); reproject_quantizer->y_scale_factor = geoprojectionconverter.get_target_precision(); reproject_quantizer->z_scale_factor = lasreader->header.z_scale_factor; reproject_quantizer->x_offset = ((I64)((point[0]/reproject_quantizer->x_scale_factor)/10000000))*10000000*reproject_quantizer->x_scale_factor; reproject_quantizer->y_offset = ((I64)((point[1]/reproject_quantizer->y_scale_factor)/10000000))*10000000*reproject_quantizer->y_scale_factor; reproject_quantizer->z_offset = ((I64)((point[2]/reproject_quantizer->z_scale_factor)/10000000))*10000000*reproject_quantizer->z_scale_factor; } int number_of_keys; GeoProjectionGeoKeys* geo_keys = 0; int num_geo_double_params; double* geo_double_params = 0; if (geoprojectionconverter.get_geo_keys_from_projection(number_of_keys, &geo_keys, num_geo_double_params, &geo_double_params, !geoprojectionconverter.has_projection(false))) { lasreader->header.set_geo_keys(number_of_keys, (LASvlr_key_entry*)geo_keys); free(geo_keys); if (geo_double_params) { lasreader->header.set_geo_double_params(num_geo_double_params, geo_double_params); free(geo_double_params); } else { lasreader->header.del_geo_double_params(); } lasreader->header.del_geo_ascii_params(); } } // do we need an extra pass BOOL extra_pass = laswriteopener.is_piped(); // for piped output we need an extra pass if (extra_pass) { if (lasreadopener.is_piped()) { fprintf(stderr, "ERROR: input and output cannot both be piped\n"); usage(true); } #ifdef _WIN32 if (verbose) fprintf(stderr, "extra pass for piped output: reading %I64d points ...\n", lasreader->npoints); #else if (verbose) fprintf(stderr, "extra pass for piped output: reading %lld points ...\n", lasreader->npoints); #endif // maybe seek to start position if (subsequence_start) lasreader->seek(subsequence_start); while (lasreader->read_point()) { if (lasreader->p_count > subsequence_stop) break; if (clip_to_bounding_box) { if (!lasreader->point.inside_box(lasreader->header.min_x, lasreader->header.min_y, lasreader->header.min_z, lasreader->header.max_x, lasreader->header.max_y, lasreader->header.max_z)) { continue; } } if (reproject_quantizer) { lasreader->point.compute_coordinates(); geoprojectionconverter.to_target(lasreader->point.coordinates); lasreader->point.compute_xyz(reproject_quantizer); } lasinventory.add(&lasreader->point); } lasreader->close(); lasreader->header.number_of_point_records = lasinventory.number_of_point_records; for (i = 0; i < 5; i++) lasreader->header.number_of_points_by_return[i] = lasinventory.number_of_points_by_return[i+1]; if (reproject_quantizer) lasreader->header = *reproject_quantizer; lasreader->header.max_x = lasreader->header.get_x(lasinventory.raw_max_x); lasreader->header.min_x = lasreader->header.get_x(lasinventory.raw_min_x); lasreader->header.max_y = lasreader->header.get_y(lasinventory.raw_max_y); lasreader->header.min_y = lasreader->header.get_y(lasinventory.raw_min_y); lasreader->header.max_z = lasreader->header.get_z(lasinventory.raw_max_z); lasreader->header.min_z = lasreader->header.get_z(lasinventory.raw_min_z); if (verbose) { fprintf(stderr,"extra pass took %g sec.\n", taketime()-start_time); start_time = taketime(); } #ifdef _WIN32 if (verbose) fprintf(stderr, "piped output: reading %I64d and writing %u points ...\n", lasreader->npoints, lasinventory.number_of_point_records); #else if (verbose) fprintf(stderr, "piped output: reading %lld and writing %u points ...\n", lasreader->npoints, lasinventory.number_of_point_records); #endif } else { if (reproject_quantizer) { saved_quantizer = new LASquantizer(); *saved_quantizer = lasreader->header; lasreader->header = *reproject_quantizer; } #ifdef _WIN32 if (verbose) fprintf(stderr, "reading %I64d and writing all surviving points ...\n", lasreader->npoints); #else if (verbose) fprintf(stderr, "reading %lld and writing all surviving points ...\n", lasreader->npoints); #endif } // check output if (!laswriteopener.active()) { // create name from input name laswriteopener.make_file_name(lasreadopener.get_file_name()); } // prepare the header for the surviving points strncpy(lasreader->header.system_identifier, "LAStools (c) by Martin Isenburg", 32); lasreader->header.system_identifier[31] = '\0'; char temp[64]; sprintf(temp, "las2las (version %d)", LAS_TOOLS_VERSION); strncpy(lasreader->header.generating_software, temp, 32); lasreader->header.generating_software[31] = '\0'; // open laswriter LASwriter* laswriter = laswriteopener.open(&lasreader->header); if (laswriter == 0) { fprintf(stderr, "ERROR: could not open laswriter\n"); byebye(true, argc==1); } // for piped output we need to re-open the input file if (extra_pass) { if (!lasreadopener.reopen(lasreader)) { fprintf(stderr, "ERROR: could not re-open lasreader\n"); byebye(true); } } else { if (reproject_quantizer) { lasreader->header = *saved_quantizer; delete saved_quantizer; } } // maybe seek to start position if (subsequence_start) lasreader->seek(subsequence_start); // loop over points if (point) { while (lasreader->read_point()) { if (lasreader->p_count > subsequence_stop) break; if (clip_to_bounding_box) { if (!lasreader->point.inside_box(lasreader->header.min_x, lasreader->header.min_y, lasreader->header.min_z, lasreader->header.max_x, lasreader->header.max_y, lasreader->header.max_z)) { continue; } } if (reproject_quantizer) { lasreader->point.compute_coordinates(); geoprojectionconverter.to_target(lasreader->point.coordinates); lasreader->point.compute_xyz(reproject_quantizer); } *point = lasreader->point; laswriter->write_point(point); // without extra pass we need inventory of surviving points if (!extra_pass) laswriter->update_inventory(point); } delete point; point = 0; } else { while (lasreader->read_point()) { if (lasreader->p_count > subsequence_stop) break; if (clip_to_bounding_box) { if (!lasreader->point.inside_box(lasreader->header.min_x, lasreader->header.min_y, lasreader->header.min_z, lasreader->header.max_x, lasreader->header.max_y, lasreader->header.max_z)) { continue; } } if (reproject_quantizer) { lasreader->point.compute_coordinates(); geoprojectionconverter.to_target(lasreader->point.coordinates); lasreader->point.compute_xyz(reproject_quantizer); } laswriter->write_point(&lasreader->point); // without extra pass we need inventory of surviving points if (!extra_pass) laswriter->update_inventory(&lasreader->point); } } // without the extra pass we need to fix the header now if (!extra_pass) { if (reproject_quantizer) lasreader->header = *reproject_quantizer; laswriter->update_header(&lasreader->header, TRUE); if (verbose) { fprintf(stderr,"total time: %g sec. written %u surviving points.\n", taketime()-start_time, (U32)laswriter->p_count); } } else { if (verbose) { fprintf(stderr,"main pass took %g sec.\n", taketime()-start_time); } } laswriter->close(); delete laswriter; lasreader->close(); delete lasreader; if (reproject_quantizer) delete reproject_quantizer; laswriteopener.set_file_name(0); } byebye(false, argc==1); return 0; }
int main(int argc, char *argv[]) { int i; BOOL verbose = TRUE; BOOL very_verbose = TRUE; F64 start_time = 0.0; F64 full_start_time = 0.0; const CHAR* xml_output_file = 0; BOOL one_report_per_file = FALSE; U32 num_pass = 0; U32 num_fail = 0; U32 num_warning = 0; fprintf(stderr, "This is version '%s' of the LAS validator. Please contact\n", "GRiD-1"); fprintf(stderr, "me at '*****@*****.**' if you disagree with\n"); fprintf(stderr, "validation reports, want additional checks, or find bugs as\n"); fprintf(stderr, "the software is still under development. Your feedback will\n"); fprintf(stderr, "help to finish it sooner.\n"); LASreadOpener lasreadopener; if (argc == 1) { fprintf(stderr,"lasvalidate.exe is best run with arguments in the command line\n"); char file_name[256]; fprintf(stderr,"enter input LAS file name: "); fgets(file_name, 256, stdin); file_name[strlen(file_name)-1] = '\0'; lasreadopener.set_file_name(file_name); fprintf(stderr,"enter output XML file name: "); fgets(file_name, 256, stdin); file_name[strlen(file_name)-1] = '\0'; xml_output_file = strdup(file_name); } for (i = 1; i < argc; i++) { if (strcmp(argv[i],"-version") == 0) { fprintf(stderr, "\nlasvalidate %d with LASread (v %d.%d %d) and LAScheck (v %d.%d %d) by rapidlasso GmbH\n", VALIDATE_VERSION, LASREAD_VERSION_MAJOR, LASREAD_VERSION_MINOR, LASREAD_BUILD_DATE, LASCHECK_VERSION_MAJOR, LASCHECK_VERSION_MINOR, LASCHECK_BUILD_DATE); byebye(LAS_VALIDATE_SUCCESS); } else if (strcmp(argv[i],"-h") == 0 || strcmp(argv[i],"-help") == 0) { lasreadopener.usage(); usage(LAS_VALIDATE_SUCCESS); } else if (strcmp(argv[i],"-v") == 0 || strcmp(argv[i],"-verbose") == 0) { verbose = TRUE; } else if (strcmp(argv[i],"-vv") == 0 || strcmp(argv[i],"-very_verbose") == 0) { verbose = TRUE; very_verbose = TRUE; } else if (strcmp(argv[i],"-i") == 0) { if ((i+1) >= argc) { fprintf(stderr,"ERROR: '%s' needs at least 1 argument: file_name or wild_card\n", argv[i]); usage(LAS_VALIDATE_WRONG_COMMAND_LINE_SYNTAX); } i+=1; do { lasreadopener.add_file_name(argv[i]); i+=1; } while (i < argc && *argv[i] != '-'); i-=1; } else if (strcmp(argv[i],"-irec") == 0) { if ((i+1) >= argc) { fprintf(stderr,"ERROR: '%s' needs at least 1 argument: directory_name\n", argv[i]); usage(LAS_VALIDATE_WRONG_COMMAND_LINE_SYNTAX); } i+=1; do { lasreadopener.add_directory(argv[i], TRUE); i+=1; } while (i < argc && *argv[i] != '-'); i-=1; } else if (strcmp(argv[i],"-stdin") == 0) { lasreadopener.set_piped(TRUE); } else if (strcmp(argv[i],"-lof") == 0) { if ((i+1) >= argc) { fprintf(stderr,"ERROR: '%s' needs 1 argument: list_of_files\n", argv[i]); usage(LAS_VALIDATE_WRONG_COMMAND_LINE_SYNTAX); } FILE* file = fopen(argv[i+1], "r"); if (file == 0) { fprintf(stderr, "ERROR: cannot open '%s'\n", argv[i+1]); return FALSE; } char line[1024]; while (fgets(line, 1024, file)) { // find end of line int len = strlen(line) - 1; // remove extra white spaces and line return at the end while (len > 0 && ((line[len] == '\n') || (line[len] == ' ') || (line[len] == '\t') || (line[len] == '\012'))) { line[len] = '\0'; len--; } lasreadopener.add_file_name(line); } fclose(file); i+=1; } else if (strcmp(argv[i],"-o") == 0) { i++; xml_output_file = argv[i]; } else if (strcmp(argv[i],"-oxml") == 0) { one_report_per_file = TRUE; } else { fprintf(stderr, "ERROR: cannot understand argument '%s'\n", argv[i]); usage(LAS_VALIDATE_WRONG_COMMAND_LINE_SYNTAX); } } // in verbose mode we measure the total time if (verbose) full_start_time = taketime(); // check input if (!lasreadopener.is_active()) { fprintf(stderr,"ERROR: no input specified\n"); byebye(LAS_VALIDATE_NO_INPUT_SPECIFIED, argc == 1); } // output logging XMLwriter xmlwriter; if (lasreadopener.is_active()) { if (xml_output_file) { one_report_per_file = FALSE; } else if (!one_report_per_file) { xml_output_file = "validate.xml"; } } // maybe we are doing one summary report if (xml_output_file) { if (!xmlwriter.open(xml_output_file, "LASvalidator")) { byebye(LAS_VALIDATE_WRITE_PERMISSION_ERROR, argc == 1); } } // accumulated pass U32 total_pass = VALIDATE_PASS; // possibly loop over multiple input files while (lasreadopener.is_active()) { // in very verbose mode we measure the time for each file if (very_verbose) start_time = taketime(); // open lasreader LASreader* lasreader = lasreadopener.open(); if (lasreader == 0) { fprintf(stderr, "ERROR: could not open lasreader\n"); byebye(LAS_VALIDATE_INPUT_FILE_NOT_FOUND, argc == 1); } // get a pointer to the header LASheader* lasheader = &lasreader->header; // maybe we are doing one report per file if (one_report_per_file) { int len = strlen(lasreadopener.get_path()); CHAR* current_xml_output_file = (CHAR*)malloc(len + 5); strcpy(current_xml_output_file, lasreadopener.get_path()); current_xml_output_file[len-4] = '_'; current_xml_output_file[len-3] = 'L'; current_xml_output_file[len-2] = 'V'; current_xml_output_file[len-1] = 'S'; current_xml_output_file[len ] = '.'; current_xml_output_file[len+1] = 'x'; current_xml_output_file[len+2] = 'm'; current_xml_output_file[len+3] = 'l'; current_xml_output_file[len+4] = '\0'; if (!xmlwriter.open(current_xml_output_file, "LASvalidator")) { byebye(LAS_VALIDATE_WRITE_PERMISSION_ERROR, argc == 1); } free(current_xml_output_file); } // start a new report xmlwriter.begin("report"); // report description of file xmlwriter.beginsub("file"); xmlwriter.write("name", lasreadopener.get_file_name()); xmlwriter.write("path", lasreadopener.get_path()); CHAR temp[32]; sprintf(temp, "%d.%d", lasheader->version_major, lasheader->version_minor); xmlwriter.write("version", temp); strncpy(temp, lasheader->system_identifier, 32); temp[31] = '\0'; xmlwriter.write("system_identifier", temp); strncpy(temp, lasheader->generating_software, 32); temp[31] = '\0'; xmlwriter.write("generating_software", temp); xmlwriter.write("point_data_format", lasheader->point_data_format); CHAR crsdescription[512]; strcpy(crsdescription, "not valid or not specified"); if (lasheader->fails == 0) { // header was loaded. now parse and check. LAScheck lascheck(lasheader); while (lasreader->read_point()) { lascheck.parse(&lasreader->point); } // check header and points and get CRS description lascheck.check(lasheader, crsdescription); } xmlwriter.write("CRS", crsdescription); xmlwriter.endsub("file"); // report the verdict U32 pass = (lasheader->fails ? VALIDATE_FAIL : VALIDATE_PASS); if (lasheader->warnings) pass |= VALIDATE_WARNING; xmlwriter.beginsub("summary"); xmlwriter.write((pass == VALIDATE_PASS ? "pass" : ((pass & VALIDATE_FAIL) ? "fail" : "warning"))); xmlwriter.endsub("summary"); // report details (if necessary) if (pass != VALIDATE_PASS) { xmlwriter.beginsub("details"); for (i = 0; i < lasheader->fail_num; i+=2) { xmlwriter.write(lasheader->fails[i], "fail", lasheader->fails[i+1]); } for (i = 0; i < lasheader->warning_num; i+=2) { xmlwriter.write(lasheader->warnings[i], "warning", lasheader->warnings[i+1]); } xmlwriter.endsub("details"); total_pass |= pass; if (pass & VALIDATE_FAIL) { num_fail++; } else { num_warning++; } } else { num_pass++; } // end the report xmlwriter.end("report"); // maybe we are doing one report per file if (one_report_per_file) { // report the total verdict xmlwriter.begin("total"); xmlwriter.write((total_pass == VALIDATE_PASS ? "pass" : ((total_pass & VALIDATE_FAIL) ? "fail" : "warning"))); xmlwriter.beginsub("details"); xmlwriter.write("pass", num_pass); xmlwriter.write("warning", num_warning); xmlwriter.write("fail", num_fail); xmlwriter.endsub("details"); xmlwriter.end("total"); num_pass = 0; num_warning = 0; num_fail = 0; // write which validator was used write_version(xmlwriter); // write which command line was used write_command_line(xmlwriter, argc, argv); // close the LASvalidator XML output file xmlwriter.close("LASvalidator"); } lasreader->close(); delete lasreader; // in very verbose mode we report the time for each file if (very_verbose) { fprintf(stderr,"needed %.2f sec for '%s'\n", taketime()-start_time, lasreadopener.get_file_name()); start_time = taketime(); } } // maybe we are doing one summary report if (!one_report_per_file) { // report the total verdict xmlwriter.begin("total"); xmlwriter.write((total_pass == 0 ? "pass" : ((total_pass & 1) ? "fail" : "warning"))); xmlwriter.beginsub("details"); xmlwriter.write("pass", num_pass); xmlwriter.write("warning", num_warning); xmlwriter.write("fail", num_fail); xmlwriter.endsub("details"); xmlwriter.end("total"); // write which validator was used write_version(xmlwriter); // write which command line was used write_command_line(xmlwriter, argc, argv); // close the LASvalidator XML output file xmlwriter.close("LASvalidator"); } // in verbose mode we report the total time if (verbose && (lasreadopener.get_file_name_number() > 1)) { fprintf(stderr,"done. total time %.2f sec.\n", taketime()-full_start_time); } byebye(argc==1); return 0; }