void* readFile(void *arg) { struct readThreadArgs *rTA = (struct readThreadArgs*) arg; LASReaderH reader = NULL; LASHeaderH header = NULL; LASPointH p = NULL; unsigned int index = 0; int read_index = 0; char *file_name_in = NULL; int i, j; while(1) { file_name_in = NULL; /*Get next file to read*/ MT_set_lock(&dataLock); file_name_in = files_name_in[files_in_index]; if (file_name_in == NULL) { MT_unset_lock(&dataLock); return NULL; } read_index = (files_in_index % rTA->num_read_threads); files_in_index++; struct writeT *dataWriteTT = (struct writeT*) malloc(sizeof(struct writeT)*rTA->num_of_entries); /*Lets read the data*/ reader = LASReader_Create(file_name_in); if (!reader) { LASError_Print("Unable to read file"); MT_unset_lock(&dataLock); exit(1); } MT_unset_lock(&dataLock); header = LASReader_GetHeader(reader); if (!header) { LASError_Print("Unable to fetch header for file"); exit(1); } if (verbose) { print_header(stderr, header, file_name_in); } /*Allocate arrays for the columns*/ long num_points = LASHeader_GetPointRecordsCount(header); for (i = 0; i < rTA->num_of_entries; i++) { dataWriteTT[i].num_points = num_points; dataWriteTT[i].values = malloc(entriesType[i]*num_points); dataWriteTT[i].type = entriesType[i]; } /*Changes for Oscar's new Morton code function*/ //unsigned int factorX = (unsigned int) (LASHeader_GetOffsetX(header) / LASHeader_GetScaleX(header)); //unsigned int factorY = (unsigned int) (LASHeader_GetOffsetY(header) / LASHeader_GetScaleY(header)); /*Compute factors to add to X and Y and cehck sanity of generated codes*/ double file_scale_x = LASHeader_GetScaleX(header); double file_scale_y = LASHeader_GetScaleY(header); double file_scale_z = LASHeader_GetScaleZ(header); //printf("The scales are x:%lf y:%lf z:%lf\n", file_scale_x, file_scale_y, file_scale_z); /* scaled offsets to add for the morton encoding */ int64_t factorX = ((int64_t) (LASHeader_GetOffsetX(header) / file_scale_x)) - rTA->global_offset_x; int64_t factorY = ((int64_t) (LASHeader_GetOffsetY(header) / file_scale_y)) - rTA->global_offset_y; if (rTA->check) { // Check specified scales are like in the LAS file if (fabs(rTA->scale_x - file_scale_x) > TOLERANCE){ fprintf(stderr, "ERROR: x scale in input file (%lf) does not match specified x scale (%lf)\n",file_scale_x, rTA->scale_x); exit(1); } if (fabs(rTA->scale_y - file_scale_y) > TOLERANCE){ fprintf(stderr, "ERROR: y scale in input file (%lf) does not match specified y scale (%lf)\n",file_scale_y, rTA->scale_y); exit(1); } /* Check that the extent of the file (taking into account the global offset) * is within 0,2^31 */ double check_min_x = 1.0 + LASHeader_GetMinX(header) - (((double) rTA->global_offset_x) * rTA->scale_x); if (check_min_x < TOLERANCE) { fprintf(stderr, "ERROR: Specied X global offset is too large. (MinX - (GlobalX*ScaleX)) < 0\n"); exit(1); } double check_min_y = 1.0 + LASHeader_GetMinY(header) - (((double) rTA->global_offset_y) * rTA->scale_y); if (check_min_y < TOLERANCE) { fprintf(stderr, "ERROR: Specied Y global offset is too large. (MinY - (GlobalY*ScaleY)) < 0\n"); exit(1); } double check_max_x = LASHeader_GetMaxX(header) - (((double) rTA->global_offset_x) * rTA->scale_x); if (check_max_x > (MAX_INT_31 * rTA->scale_x)) { fprintf(stderr, "ERROR: Specied X global offset is too small. (MaxX - (GlobalX*ScaleX)) > (2^31)*ScaleX\n"); exit(1); } double check_max_y = LASHeader_GetMaxY(header) - (((double) rTA->global_offset_y) * rTA->scale_y); if (check_max_y > (MAX_INT_31 * rTA->scale_y)) { fprintf(stderr, "ERROR: Specied Y global offset is too small. (MaxY - (GlobalY*ScaleY)) > (2^31)*ScaleY\n"); exit(1); } } p = LASReader_GetNextPoint(reader); index = 0; while (p) { if (skip_invalid && !LASPoint_IsValid(p)) { if (verbose) { LASError_Print("Skipping writing invalid point..."); } p = LASReader_GetNextPoint(reader); index -=1; continue; } LASColorH color = NULL; for (j = 0; j < rTA->num_of_entries; j++) { uint64_t res; switch (entries[j]) { case ENTRY_x: case ENTRY_y: case ENTRY_z: ((double*) dataWriteTT[j].values)[index] = entriesFunc[j](p); //printf(" Point is:%lf\n", ((double*) dataWriteTT[j].values)[index]); break; case ENTRY_X: ((int*) dataWriteTT[j].values)[index] = entriesFunc[j](p) / file_scale_x; break; case ENTRY_Y: ((int*) dataWriteTT[j].values)[index] = entriesFunc[j](p) / file_scale_y; break; case ENTRY_Z: ((int*) dataWriteTT[j].values)[index] = entriesFunc[j](p) / file_scale_z; break; case ENTRY_k: entriesFunc[j](&res, p, factorX, factorY); ((int64_t*)dataWriteTT[j].values)[index] = res; break; case ENTRY_R: case ENTRY_G: case ENTRY_B: color = (color == NULL) ? LASPoint_GetColor(p) : color; dataWriteTT[j].values[index] = (double) entriesFunc[j](color); break; case ENTRY_M: dataWriteTT[j].values[index] = index; break; default: LASError_Print("las2col:readFile: Invalid Entry."); } } if (color != NULL) LASColor_Destroy(color); p = LASReader_GetNextPoint(reader); index +=1; } if (verbose) printf("Num of points:%d %ld for file:%s \n", index, num_points, file_name_in); /*Give the data to the writer threads*/ MT_set_lock(&dataLock); LASHeader_Destroy(header); header = NULL; LASReader_Destroy(reader); reader = NULL; /*TODO: make sure you are not overtaking other reading threads*/ while (data[read_index] != NULL) { MT_cond_wait(&readCond, &dataLock); } data[read_index] = dataWriteTT; /*Wake up the main*/ pthread_cond_broadcast(&mainCond); MT_unset_lock(&dataLock); } return NULL; }
int main(int argc, char *argv[]) { int i; int use_stdin = FALSE; int use_stdout = FALSE; int skip_invalid = FALSE; int verbose = FALSE; char* file_name_in = 0; char* file_name_out = 0; char separator_sign = ' '; char header_comment_sign = '\0'; char* parse_string = "xyz"; char printstring[256]; LASReaderH reader = NULL; LASHeaderH header = NULL; LASPointH p = NULL; FILE* file_out = NULL; int len; uint32_t index = 0; for (i = 1; i < argc; i++) { if ( strcmp(argv[i],"-h") == 0 || strcmp(argv[i],"--help") == 0 ) { usage(); exit(0); } else if ( strcmp(argv[i],"-v") == 0 || strcmp(argv[i],"--verbose") == 0 ) { verbose = TRUE; } else if ( strcmp(argv[i],"-s") == 0 || strcmp(argv[i],"--skip_invalid") == 0 ) { skip_invalid = TRUE; } else if ( strcmp(argv[i], "--parse") == 0 || strcmp(argv[i], "-parse") == 0 ) { i++; parse_string = argv[i]; } else if ( strcmp(argv[i], "--sep") == 0 || strcmp(argv[i], "-sep") == 0 ) { i++; if (strcmp(argv[i],"komma") == 0) { separator_sign = ','; } else if (strcmp(argv[i],"tab") == 0) { separator_sign = '\t'; } else if ( strcmp(argv[i],"dot") == 0 || strcmp(argv[i],"period") == 0 ) { separator_sign = '.'; } else if (strcmp(argv[i],"colon") == 0) { separator_sign = ':'; } else if ( strcmp(argv[i],"scolon") == 0 || strcmp(argv[i],"semicolon") == 0 ) { separator_sign = ';'; } else if ( strcmp(argv[i],"hyphen") == 0 || strcmp(argv[i],"minus") == 0 ) { separator_sign = '-'; } else if (strcmp(argv[i],"space") == 0) { separator_sign = ' '; } else { fprintf(stderr, "ERROR: unknown seperator '%s'\n",argv[i]); usage(); exit(1); } } else if ( strcmp(argv[i], "--header") == 0 || strcmp(argv[i], "--comment") == 0 || strcmp(argv[i], "-header") == 0 || strcmp(argv[i], "-comment") == 0 || strcmp(argv[i], "-head") == 0 ) { i++; if (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 comment symbol '%s'\n",argv[i]); usage(); exit(1); } } else if ( strcmp(argv[i], "--stdin") == 0 || strcmp(argv[i], "-ilas") == 0 ) { use_stdin = TRUE; } else if ( strcmp(argv[i], "--stdout") == 0 ) { use_stdout = TRUE; } else if ( strcmp(argv[i],"--input") == 0 || strcmp(argv[i],"-input") == 0 || strcmp(argv[i],"-i") == 0 || strcmp(argv[i],"-in") == 0 ) { i++; file_name_in = argv[i]; } else if ( strcmp(argv[i],"--output") == 0 || strcmp(argv[i],"--out") == 0 || strcmp(argv[i],"-out") == 0 || strcmp(argv[i],"-o") == 0 ) { i++; file_name_out = argv[i]; } else if (i == argc - 2 && file_name_in == 0 && file_name_out == 0) { file_name_in = argv[i]; } else if (i == argc - 1 && file_name_in == 0 && file_name_out == 0) { file_name_in = argv[i]; } else if (i == argc - 1 && file_name_in && file_name_out == 0) { file_name_out = argv[i]; } else { fprintf(stderr, "ERROR: unknown argument '%s'\n",argv[i]); usage(); exit(1); } } /* end looping through argc/argv */ if (use_stdin) file_name_in = "stdin"; reader = LASReader_Create(file_name_in); if (!reader) { LASError_Print("Unable to read file"); exit(1); } header = LASReader_GetHeader(reader); if (!header) { LASError_Print("Unable to fetch header for file"); exit(1); } if (use_stdout) { file_out = stdout; } else { if (file_name_out == NULL) { if (file_name_in == NULL) { LASError_Print("No input filename was specified"); usage(); exit(1); } len = (int)strlen(file_name_in); file_name_out = strdup(file_name_in); if (file_name_out[len-3] == '.' && file_name_out[len-2] == 'g' && file_name_out[len-1] == 'z') { len = len - 4; } while (len > 0 && file_name_out[len] != '.') { len--; } file_name_out[len] = '.'; file_name_out[len+1] = 't'; file_name_out[len+2] = 'x'; file_name_out[len+3] = 't'; file_name_out[len+4] = '\0'; } file_out = fopen(file_name_out, "w"); if (file_out == 0) { LASError_Print("Could not open file for write"); usage(); exit(1); } } if (verbose) { print_header(stderr, header, file_name_in); } if (header_comment_sign) { fprintf(file_out, "%c file signature: '%s'\012", header_comment_sign, LASHeader_GetFileSignature(header) ); fprintf(file_out, "%c file source ID: %d\012", header_comment_sign, LASHeader_GetFileSourceId(header) ); fprintf(file_out, "%c reserved: %d\012", header_comment_sign, LASHeader_GetReserved(header) ); fprintf(file_out, "%c project ID GUID: %s\012", header_comment_sign, LASHeader_GetProjectId(header) ); fprintf(file_out, "%c version major.minor: %d.%d\012", header_comment_sign, LASHeader_GetVersionMajor(header), LASHeader_GetVersionMinor(header) ); fprintf(file_out, "%c system_identifier: '%s'\012", header_comment_sign, LASHeader_GetSystemId(header) ); fprintf(file_out, "%c generating_software: '%s'\012", header_comment_sign, LASHeader_GetSoftwareId(header) ); fprintf(file_out, "%c file creation day/year: %d/%d\012", header_comment_sign, LASHeader_GetCreationDOY(header), LASHeader_GetCreationYear(header) ); fprintf(file_out, "%c header size %d\012", header_comment_sign, LASHeader_GetHeaderSize(header) ); fprintf(file_out, "%c offset to point data %d\012", header_comment_sign, LASHeader_GetDataOffset(header) ); fprintf(file_out, "%c number var. length records %d\012", header_comment_sign, LASHeader_GetRecordsCount(header) ); fprintf(file_out, "%c point data format %d\012", header_comment_sign, LASHeader_GetDataFormatId(header) ); fprintf(file_out, "%c point data record length %d\012", header_comment_sign, LASHeader_GetDataRecordLength(header) ); fprintf(file_out, "%c number of point records %d\012", header_comment_sign, LASHeader_GetPointRecordsCount(header) ); fprintf(file_out, "%c number of points by return %d %d %d %d %d\012", header_comment_sign, LASHeader_GetPointRecordsByReturnCount(header, 0), LASHeader_GetPointRecordsByReturnCount(header, 1), LASHeader_GetPointRecordsByReturnCount(header, 2), LASHeader_GetPointRecordsByReturnCount(header, 3), LASHeader_GetPointRecordsByReturnCount(header, 4) ); fprintf(file_out, "%c scale factor x y z %.6f %.6f %.6f\n", header_comment_sign, LASHeader_GetScaleX(header), LASHeader_GetScaleY(header), LASHeader_GetScaleZ(header) ); fprintf(file_out, "%c offset x y z %.6f %.6f %.6f\n", header_comment_sign, LASHeader_GetOffsetX(header), LASHeader_GetOffsetY(header), LASHeader_GetOffsetZ(header) ); fprintf(file_out, "%c min x y z %.6f %.6f %.6f\n", header_comment_sign, LASHeader_GetMinX(header), LASHeader_GetMinY(header), LASHeader_GetMinZ(header) ); fprintf(file_out, "%c max x y z %.6f %.6f %.6f\n", header_comment_sign, LASHeader_GetMaxX(header), LASHeader_GetMaxY(header), LASHeader_GetMaxZ(header) ); } p = LASReader_GetNextPoint(reader); while (p) { if (skip_invalid && !LASPoint_IsValid(p)) { if (verbose) { LASError_Print("Skipping writing invalid point..."); } p = LASReader_GetNextPoint(reader); index -=1; continue; } i = 0; for (;;) { LASColorH color = LASPoint_GetColor(p); switch (parse_string[i]) { /* // the x coordinate */ case 'x': lidardouble2string(printstring, LASPoint_GetX(p)); fprintf(file_out, printstring); break; /* // the y coordinate */ case 'y': lidardouble2string(printstring, LASPoint_GetY(p)); fprintf(file_out, printstring); break; /* // the z coordinate */ case 'z': lidardouble2string(printstring, LASPoint_GetZ(p)); fprintf(file_out, printstring); break; /* // the gps-time */ case 't': lidardouble2string(printstring,LASPoint_GetTime(p)); fprintf(file_out, printstring); break; /* // the intensity */ case 'i': fprintf(file_out, "%d", LASPoint_GetIntensity(p)); break; /* the scan angle */ case 'a': fprintf(file_out, "%d", LASPoint_GetScanAngleRank(p)); break; /* the number of the return */ case 'r': fprintf(file_out, "%d", LASPoint_GetReturnNumber(p)); break; /* the classification */ case 'c': fprintf(file_out, "%d", LASPoint_GetClassification(p)); break; /* the user data */ case 'u': fprintf(file_out, "%d", LASPoint_GetUserData(p)); break; /* the number of returns of given pulse */ case 'n': fprintf(file_out, "%d", LASPoint_GetNumberOfReturns(p)); break; /* the red channel color */ case 'R': fprintf(file_out, "%d", LASColor_GetRed(color)); break; /* the green channel color */ case 'G': fprintf(file_out, "%d", LASColor_GetGreen(color)); break; /* the blue channel color */ case 'B': fprintf(file_out, "%d", LASColor_GetBlue(color)); break; case 'M': fprintf(file_out, "%d", index); break; /* case 'p': // the point source ID fprintf(file_out, "%d", lasreader->point.point_source_ID); break; */ /* the edge of flight line flag */ case 'e': fprintf(file_out, "%d", LASPoint_GetFlightLineEdge(p)); break; /* the direction of scan flag */ case 'd': fprintf(file_out, "%d", LASPoint_GetScanDirection(p)); break; } i++; if (parse_string[i]) { fprintf(file_out, "%c", separator_sign); } else { fprintf(file_out, "\012"); break; } LASColor_Destroy(color); } p = LASReader_GetNextPoint(reader); index +=1; } LASReader_Destroy(reader); LASHeader_Destroy(header); fclose(file_out); return 0; }