/* ================================== LoadWorker::run() Starts the worker. ================================== */ void LoadWorker::run() { int num_files = filenames.size(); // Has a new quadtree been created? bool newQuadtree = false; try { // For each file for (int i = 0; i < num_files; ++i) { std::string filename = filenames[i]; send_message(filename); if (filename != "") { filetype_t file_type = test_filename(filename); if (file_type == UNKNOWN_FILE) { send_message( "Unrecognised file type. Supported formats: las, txt, csv."); sig_fail(); return; } LASreadOpener lasreadopener; lasreadopener.set_file_name(filename.c_str()); // ASCII files if (file_type == ASCII_FILE) { lasreadopener.set_parse_string(ascii_code.c_str()); if (!use_default_scale_factors) { lasreadopener.set_scale_factor(scale_factor); } } // Point filter if (point_filter.argc != 0) { std::vector<char*> argv; std::transform(point_filter.args.begin(), point_filter.args.end(), std::back_inserter(argv), convert_string); argv.push_back(0); if (!lasreadopener.parse(point_filter.argc, &argv[0])) { for (size_t i = 0; i < argv.size(); ++i) delete[] argv[i]; send_message("Error parsing filter parameters."); sig_fail(); return; } for (size_t i = 0; i < argv.size(); ++i) delete[] argv[i]; } reader = lasreadopener.open(); if (reader == NULL) { send_message("Error opening the file."); sig_fail(); return; } // Check if we have a latlong file latlong = is_latlong(reader); // If we have latlong convert to UTM if (latlong) convert_projection(); // Get file boundary Boundary boundary = get_boundary(); fileopener->set_utm_zone(get_utm_zone()); // If refreshing if ((i == 0 && (create_new_quadtree || !fileopener->get_loadedanyfiles())) || fileopener->get_lidardata() == NULL) { // Delete old quadtree fileopener->delete_lidardata(); // Create new quadree Quadtree* qt; if (!usearea) qt = new Quadtree(&boundary, bucketlimit, cachelimit, bucketLevels, resolutionbase, resolutiondepth, cache_path); else { qt = new Quadtree(fence.get_min_x(), fence.get_min_y(), fence.get_max_x(), fence.get_max_y(), bucketlimit, cachelimit, bucketLevels, resolutionbase, resolutiondepth, cache_path); } // Load points int points_loaded = 0; if (has_waveform(reader)) points_loaded = load_points_wf(qt); else points_loaded = load_points(qt); // Add flightline to quadtree's flight table qt->addFlightline(filename); if (points_loaded == 0) { std::cout << "LoadWorker: " << filename << " - no points loaded from file. Possibly because of fence." << std::endl; } // Set lidardata fileopener->set_lidardata(qt); newQuadtree = true; qt = NULL; } else { Quadtree* qt = fileopener->get_lidardata(); // Adjust boundary if (!usearea) qt->adjustBoundary(boundary); // Load points int points_loaded = 0; if (has_waveform(reader)) points_loaded = load_points_wf(qt); else points_loaded = load_points(qt); qt->addFlightline(filename); if (points_loaded == 0) { std::cout << "LoadWorker: " << filename << " - no points loaded from file. Possibly because of fence." << std::endl; } qt = NULL; } if (reader->header.min_z < fileopener->get_minZ() || i == 0) fileopener->set_minZ(reader->header.min_z); if (reader->header.max_z > fileopener->get_maxZ() || i == 0) fileopener->set_maxZ(reader->header.max_z); } sig_file_loaded(); if (stopped) break; } } catch (DescriptiveException& e) { if (reproject_quantizer) delete reproject_quantizer; if (saved_quantizer) delete saved_quantizer; std::cout << "LoadWorker: Error loading file.\n"; std::cout << e.what() << "\n" << e.why() << std::endl; send_message(e.why()); fileopener->delete_lidardata(); fileopener->set_loadedanyfiles(false); newQuadtree = false; sig_fail(); return; } // Delete quantizers somewhere if (latlong) { delete reproject_quantizer; delete saved_quantizer; } fileopener->set_newQuadtree(newQuadtree); sig_done(); }
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; }