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