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; }
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; }