/* ---------------------------------------------------------------------------------- */ void print_header(LASHeaderH header, int bSkipVLR) { char *pszSignature = NULL; char *pszProjectId = NULL; char *pszSystemId = NULL; char *pszSoftwareId = NULL; /*char *pszProj4 = NULL;*/ char *pszVLRUser = NULL; char *pszVLRDescription = NULL; uint16_t nVLRLength = 0; uint16_t nVLRRecordId = 0; LASVLRH pVLR = NULL; LASSRSH pSRS = NULL; uint32_t nVLR = 0; int i = 0; #ifdef HAVE_GEOTIFF const GTIF* pGTIF = NULL; #else const void* pGTIF = NULL; #endif pszSignature = LASHeader_GetFileSignature(header); pszProjectId = LASHeader_GetProjectId(header); pszSystemId = LASHeader_GetSystemId(header); pszSoftwareId = LASHeader_GetSoftwareId(header); pSRS = LASHeader_GetSRS(header); /*pszProj4 = LASSRS_GetProj4(pSRS);*/ pGTIF = LASSRS_GetGTIF(pSRS); nVLR = LASHeader_GetRecordsCount(header); mexPrintf("\n---------------------------------------------------------\n"); mexPrintf(" Header Summary\n"); mexPrintf("---------------------------------------------------------\n"); if (strcmp(pszSignature,"LASF") !=0) { LASError_Print("File signature is not 'LASF'... aborting"); return; } mexPrintf(" Version: %d.%d\n", LASHeader_GetVersionMajor(header), LASHeader_GetVersionMinor(header)); mexPrintf(" Source ID: %d\n", LASHeader_GetFileSourceId(header) ) ; mexPrintf(" Reserved: %d\n", LASHeader_GetReserved(header) ); mexPrintf(" Project ID/GUID: '%s'\n", pszProjectId); mexPrintf(" System Identifier: '%s'\n", pszSystemId); mexPrintf(" Generating Software: '%s'\n", pszSoftwareId); mexPrintf(" File Creation Day/Year: %d/%d\n", LASHeader_GetCreationDOY(header), LASHeader_GetCreationYear(header)); mexPrintf(" Header Size %d\n", LASHeader_GetHeaderSize(header)); mexPrintf(" Offset to Point Data %d\n", LASHeader_GetDataOffset(header)); mexPrintf(" Number Var. Length Records %d\n", LASHeader_GetRecordsCount(header)); mexPrintf(" Point Data Format %d\n", LASHeader_GetDataFormatId(header)); mexPrintf(" Point Data Record Length %d\n", LASHeader_GetDataRecordLength(header)); mexPrintf(" Number of Point Records %d\n", LASHeader_GetPointRecordsCount(header)); mexPrintf(" Number of Points by Return %d %d %d %d %d\n", LASHeader_GetPointRecordsByReturnCount(header, 0), LASHeader_GetPointRecordsByReturnCount(header, 1), LASHeader_GetPointRecordsByReturnCount(header, 2), LASHeader_GetPointRecordsByReturnCount(header, 3), LASHeader_GetPointRecordsByReturnCount(header, 4)); mexPrintf(" Scale Factor X Y Z %.6g %.6g %.6g\n", LASHeader_GetScaleX(header), LASHeader_GetScaleY(header), LASHeader_GetScaleZ(header)); mexPrintf(" Offset X Y Z %.6f %.6f %.6f\n", LASHeader_GetOffsetX(header), LASHeader_GetOffsetY(header), LASHeader_GetOffsetZ(header)); mexPrintf(" Min X Y Z %.6f %.6f %.6f\n", LASHeader_GetMinX(header), LASHeader_GetMinY(header), LASHeader_GetMinZ(header)); mexPrintf(" Max X Y Z %.6f %.6f %.6f\n", LASHeader_GetMaxX(header), LASHeader_GetMaxY(header), LASHeader_GetMaxZ(header)); /*mexPrintf(" Spatial Reference %s\n", pszProj4);*/ #ifdef HAVE_LIBGEOTIFF if (pGTIF) GTIFPrint((GTIF*)pGTIF, 0, 0); #endif if (nVLR && !bSkipVLR) { mexPrintf("\n---------------------------------------------------------\n"); mexPrintf(" VLR Summary\n"); mexPrintf("---------------------------------------------------------\n"); for (i = 0; i < (int)nVLR; i++) { pVLR = LASHeader_GetVLR(header, i); if (LASError_GetLastErrorNum()) { LASError_Print("Unable to fetch VLR"); return; } pszVLRUser = LASVLR_GetUserId(pVLR); pszVLRDescription = LASVLR_GetDescription(pVLR); nVLRLength = LASVLR_GetRecordLength(pVLR); nVLRRecordId = LASVLR_GetRecordId(pVLR); mexPrintf(" User: '******' - Description: '%s'\n", pszVLRUser, pszVLRDescription); mexPrintf(" ID: %d Length: %d\n\n", nVLRRecordId, nVLRLength); LASVLR_Destroy(pVLR); pVLR = NULL; LASString_Free(pszVLRUser); LASString_Free(pszVLRDescription); } } LASString_Free(pszSignature); LASString_Free(pszProjectId); LASString_Free(pszSystemId); LASString_Free(pszSoftwareId); /*LASString_Free(pszProj4);*/ }
int main(int argc, char *argv[]) { int i; int dry = FALSE; int verbose = FALSE; char* file_name_in = 0; char* file_name_out = 0; double xyz_min[3] = {0.0, 0.0, 0.0}; double xyz_max[3] = {0.0, 0.0, 0.0}; double xyz_scale[3] = {0.01,0.01,0.01}; double xyz_offset[3] = {0.0,0.0,0.0}; unsigned int number_of_point_records = 0; unsigned int number_of_points_by_return[8] = {0,0,0,0,0,0,0,0}; char* parse_string = "xyz"; int file_creation_day = 0; int file_creation_year = 0; char* system_identifier = 0; char* generating_software = 0; #define MAX_CHARACTERS_PER_LINE 512 char line[MAX_CHARACTERS_PER_LINE]; double xyz[3]; LASPointH point = NULL; double gps_time; FILE* file_in = NULL; char* parse_less = NULL; LASHeaderH header = NULL; LASWriterH writer = NULL; LASError err; int format = LAS_FORMAT_12; int xyz_min_quant[3] = {0, 0, 0}; int xyz_max_quant[3] = {0, 0, 0}; double xyz_min_dequant[3] = {0.0, 0.0, 0.0}; double xyz_max_dequant[3] = {0.0, 0.0, 0.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],"-d") == 0 || strcmp(argv[i],"-dry") == 0 || strcmp(argv[i],"--dry") == 0 ) { dry = TRUE; } else if ( strcmp(argv[i],"--parse") == 0 || strcmp(argv[i],"-parse") == 0 || strcmp(argv[i],"-p") == 0 ) { i++; parse_string = argv[i]; } else if ( strcmp(argv[i],"--scale") == 0 || strcmp(argv[i],"-scale") == 0 || strcmp(argv[i],"-s") == 0 ) { i++; sscanf(argv[i], "%lf", &(xyz_scale[2])); xyz_scale[0] = xyz_scale[1] = xyz_scale[2]; } else if ( strcmp(argv[i],"--xyz_scale") == 0 || strcmp(argv[i],"-xyz_scale") == 0 ) { i++; sscanf(argv[i], "%lf", &(xyz_scale[0])); i++; sscanf(argv[i], "%lf", &(xyz_scale[1])); i++; sscanf(argv[i], "%lf", &(xyz_scale[2])); } else if ( strcmp(argv[i],"--xyz_offset") == 0 || strcmp(argv[i],"-xyz_offset") == 0 ) { i++; sscanf(argv[i], "%lf", &(xyz_offset[0])); i++; sscanf(argv[i], "%lf", &(xyz_offset[1])); i++; sscanf(argv[i], "%lf", &(xyz_offset[2])); } 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 ( strcmp(argv[i],"--format") == 0 || strcmp(argv[i],"-f") == 0 || strcmp(argv[i],"-format") == 0 ) { i++; if (strcmp(argv[i], "1.0") == 0) { format = LAS_FORMAT_10; } else if (strcmp(argv[i], "1.1") == 0) { format = LAS_FORMAT_11; } else if (strcmp(argv[i], "1.2") == 0) { format = LAS_FORMAT_12; } else { LASError_Print("Format must be specified as 1.0, 1.1, or 1.2"); } } else if ( strcmp(argv[i],"--system_identifier") == 0 || strcmp(argv[i],"-system_identifier") == 0 || strcmp(argv[i],"-s") == 0 || strcmp(argv[i],"-sys_id") == 0) { i++; system_identifier = (char*) malloc(31 * sizeof(char)); strcpy(system_identifier, argv[i]); } else if ( strcmp(argv[i],"--generating_software") == 0 || strcmp(argv[i],"-generating_software") == 0 || strcmp(argv[i],"-g") == 0 || strcmp(argv[i],"-gen_soft") == 0) { i++; generating_software = (char*) malloc(31*sizeof(char)); strcpy(generating_software, argv[i]); } else if ( strcmp(argv[i],"--file_creation") == 0 || strcmp(argv[i],"-file_creation") == 0) { i++; file_creation_day = (unsigned short)atoi(argv[i]); i++; file_creation_year = (unsigned short)atoi(argv[i]); } else if ( i == argc - 2 && file_name_in == NULL && file_name_out == NULL ) { file_name_in = argv[i]; } else if ( i == argc - 1 && file_name_in == NULL && file_name_out == NULL ) { file_name_in = argv[i]; } else if ( i == argc - 1 && file_name_in && file_name_out == NULL ) { file_name_out = argv[i]; } else { fprintf(stderr, "ERROR: unknown argument '%s'\n",argv[i]); usage(); exit(1); } } /* create output file name if none specified and no piped output requested */ if (file_name_out == NULL && file_name_in != NULL) { int len = (int)strlen(file_name_in); file_name_out = strdup(file_name_in); while (len > 0 && file_name_out[len] != '.') { len--; } file_name_out[len] = '.'; file_name_out[len+1] = 'l'; file_name_out[len+2] = 'a'; file_name_out[len+3] = 's'; file_name_out[len+4] = '\0'; } /* make sure that input and output are not *both* piped */ if (file_name_in == NULL && file_name_out == NULL) { LASError_Print("both input and output filenames are null!"); usage(); exit(1); } file_in = fopen(file_name_in, "r"); if (file_in == NULL) { LASError_Print("could not open file to read for first pass"); exit(1); } /* create a cheaper parse string that only looks for 'x' 'y' 'z' and 'r' */ parse_less = strdup(parse_string); for (i = 0; i < (int)strlen(parse_string); i++) { if (parse_less[i] != 'x' && parse_less[i] != 'y' && parse_less[i] != 'z' && parse_less[i] != 'r') { parse_less[i] = 's'; } } do { parse_less[i] = '\0'; printf("nuking %d for %c\n", i, parse_less[i]); i--; } while (parse_less[i] == 's'); /* first pass to figure out the bounding box and number of returns */ if (verbose) { fprintf(stderr, "first pass over file '%s' with parse '%s'\n", file_name_in, parse_less); } /* read the first line */ while (fgets(line, sizeof(char) * MAX_CHARACTERS_PER_LINE, file_in)) { point = LASPoint_Create(); if (parse(parse_less, line, xyz, point, &gps_time)) { /* init the bounding box */ VecCopy3dv(xyz_min, xyz); VecCopy3dv(xyz_max, xyz); /* mark that we found the first point */ number_of_point_records = 1; /* create return histogram */ number_of_points_by_return[LASPoint_GetReturnNumber(point)]++; /* we can stop this loop */ break; } else { fprintf(stderr, "WARNING: cannot parse '%s' with '%s'. skipping ...\n", line, parse_less); } LASPoint_Destroy(point); point = NULL; } /* did we manage to parse a line? */ if (number_of_point_records != 1) { fprintf(stderr, "ERROR: could not parse any lines with '%s'\n", parse_less); exit(1); } /* loop over the remaining lines */ while (fgets(line, sizeof(char) * MAX_CHARACTERS_PER_LINE, file_in)) { point = LASPoint_Create(); if (parse(parse_less, line, xyz, point, &gps_time)) { /* update bounding box */ VecUpdateMinMax3dv(xyz_min, xyz_max, xyz); /* count points */ number_of_point_records++; /* create return histogram */ number_of_points_by_return[LASPoint_GetReturnNumber(point)]++; } else { fprintf(stderr, "WARNING: cannot parse '%s' with '%s'. skipping ...\n", line, parse_less); } LASPoint_Destroy(point); point = NULL; } /* output some stats */ if (verbose) { fprintf(stderr, "npoints %d min %g %g %g max %g %g %g\n", number_of_point_records, xyz_min[0], xyz_min[1], xyz_min[2], xyz_max[0], xyz_max[1], xyz_max[2] ); fprintf(stderr, "return histogram %d %d %d %d %d %d %d %d\n", number_of_points_by_return[0], number_of_points_by_return[1], number_of_points_by_return[2], number_of_points_by_return[3], number_of_points_by_return[4], number_of_points_by_return[5], number_of_points_by_return[6], number_of_points_by_return[7] ); } /* close the input file */ fclose(file_in); /* compute bounding box after quantization */ for (i = 0; i < 3; i++) { xyz_min_quant[i] = (int)(0.5 + (xyz_min[i] - xyz_offset[i]) / xyz_scale[i]); xyz_max_quant[i] = (int)(0.5 + (xyz_max[i] - xyz_offset[i]) / xyz_scale[i]); } for (i = 0; i < 3; i++) { xyz_min_dequant[i] = xyz_offset[i] + (xyz_min_quant[i] * xyz_scale[i]); xyz_max_dequant[i] = xyz_offset[i] + (xyz_max_quant[i] * xyz_scale[i]); } #define log_xor !=0==! /* make sure there is not sign flip */ for (i = 0; i < 3; i++) { if ((xyz_min[i] > 0) log_xor (xyz_min_dequant[i] > 0)) { fprintf(stderr, "WARNING: quantization sign flip for %s min coord %g -> %g. use offset or scale up\n", (i ? (i == 1 ? "y" : "z") : "x"), xyz_min[i], xyz_min_dequant[i] ); } if ((xyz_max[i] > 0) log_xor (xyz_max_dequant[i] > 0)) { fprintf(stderr, "WARNING: quantization sign flip for %s max coord %g -> %g. use offset or scale up\n", (i ? (i == 1 ? "y" : "z") : "x"), xyz_max[i], xyz_max_dequant[i] ); } } #undef log_xor /* populate the header */ header = LASHeader_Create(); if (system_identifier) LASHeader_SetSystemId(header, system_identifier); if (generating_software) LASHeader_SetSoftwareId(header, generating_software); LASHeader_SetCreationDOY(header, file_creation_day); LASHeader_SetCreationYear(header, file_creation_year); if (format == LAS_FORMAT_10) { LASHeader_SetVersionMinor(header, 0); } else if (format == LAS_FORMAT_11){ LASHeader_SetVersionMinor(header, 1); } else if (format == LAS_FORMAT_12) { LASHeader_SetVersionMinor(header, 2); } if (strstr(parse_string,"t") && (strstr(parse_string, "R") || strstr(parse_string, "G") ||strstr(parse_string, "B") ) ) { fprintf(stderr, "Setting point format to 3, overriding version to 1.2 -- RGB + time\n"); LASHeader_SetDataFormatId(header, 3); LASHeader_SetVersionMinor(header, 2); } else if ((strstr(parse_string, "R") || strstr(parse_string, "G") ||strstr(parse_string, "B") ) ) { fprintf(stderr, "Setting point format to 2, overriding version to 1.2 -- RGB\n"); LASHeader_SetDataFormatId(header, 2); LASHeader_SetVersionMinor(header, 2); } else if (strstr(parse_string,"t")) { fprintf(stderr, "Setting point format to 1\n"); LASHeader_SetDataFormatId(header, 1); } else { LASHeader_SetDataFormatId(header, 0); } LASHeader_SetPointRecordsCount(header, number_of_point_records); LASHeader_SetScale(header, xyz_scale[0], xyz_scale[1], xyz_scale[2]); LASHeader_SetOffset(header, xyz_offset[0], xyz_offset[1], xyz_offset[2]); LASHeader_SetMin(header, xyz_min_dequant[0], xyz_min_dequant[1], xyz_min_dequant[2]); LASHeader_SetMax(header, xyz_max_dequant[0], xyz_max_dequant[1], xyz_max_dequant[2]); LASHeader_SetPointRecordsByReturnCount(header, 0, number_of_points_by_return[1]); LASHeader_SetPointRecordsByReturnCount(header, 1, number_of_points_by_return[2]); LASHeader_SetPointRecordsByReturnCount(header, 2, number_of_points_by_return[3]); LASHeader_SetPointRecordsByReturnCount(header, 3, number_of_points_by_return[4]); LASHeader_SetPointRecordsByReturnCount(header, 4, number_of_points_by_return[5]); /* reopen input file for the second pass */ file_in = fopen(file_name_in, "r"); if (file_in == 0) { fprintf(stderr, "ERROR: could not open '%s' for second pass\n",file_name_in); exit(1); } /* because the output goes to a file we can do everything in a single pass and compute the header information along the way */ /* open output file */ printf("Creating file...\n"); writer = LASWriter_Create(file_name_out, header, LAS_MODE_WRITE); if (!writer) { LASError_Print("Could not open file for write mode "); exit(1); } if (verbose) { fprintf(stderr, "scanning %s with parse '%s' writing to %s\n", file_name_in , parse_string, file_name_out ); } /* read the first line */ while (fgets(line, sizeof(char) * MAX_CHARACTERS_PER_LINE, file_in)) { point = LASPoint_Create(); if (parse(parse_string, line, xyz, point, &gps_time)) { /* init the bounding box */ VecCopy3dv(xyz_min, xyz); VecCopy3dv(xyz_max, xyz); /* mark that we found the first point */ number_of_point_records = 1; /* create return histogram */ number_of_points_by_return[LASPoint_GetReturnNumber(point)]++; /* compute the quantized x, y, and z values */ LASPoint_SetX(point, xyz[0]); LASPoint_SetY(point, xyz[1]); LASPoint_SetZ(point, xyz[2]); /* write the first point */ err = LASWriter_WritePoint(writer, point); if (err) { LASError_Print("could not write point"); exit(1); } /* we can stop this loop */ break; } else { fprintf(stderr, "WARNING: cannot parse '%s' with '%s'. skipping ...\n", line, parse_string); } LASPoint_Destroy(point); point = NULL; } /* did we manage to parse a line? */ if (number_of_point_records != 1) { fprintf(stderr, "ERROR: could not parse any lines with '%s'\n", parse_less); exit(1); } /* loop over the remaining lines */ while (fgets(line, sizeof(char) * MAX_CHARACTERS_PER_LINE, file_in)) { point = LASPoint_Create(); if (parse(parse_string, line, xyz, point, &gps_time)) { /* update bounding box */ VecUpdateMinMax3dv(xyz_min, xyz_max, xyz); /* count points */ number_of_point_records++; /* create return histogram */ number_of_points_by_return[LASPoint_GetReturnNumber(point)]++; /* compute the quantized x, y, and z values */ LASPoint_SetX(point, xyz[0]); LASPoint_SetY(point, xyz[1]); LASPoint_SetZ(point, xyz[2]); /* write the first point */ err = LASWriter_WritePoint(writer, point); if (err) { LASError_Print("could not write point"); exit(1); } } else { fprintf(stderr, "WARNING: cannot parse '%s' with '%s'. skipping ...\n", line, parse_string); } LASPoint_Destroy(point); point = NULL; } /* close up stuff */ fclose(file_in); LASWriter_Destroy(writer); if (verbose) { fprintf(stderr, "done.\n"); } return 0; }
int main(int argc, char *argv[]) { /*Initialize the catalog locks*/ MT_lock_init(&dataLock); MT_cond_init(&mainCond); MT_cond_init(&writeTCond); MT_cond_init(&readCond); char* file_name_in = 0; char* file_name_out = 0; char separator_sign = ' '; char* parse_string = "xyz"; char* buffer; char printstring[256]; LASReaderH reader = NULL; LASHeaderH header = NULL; LASPointH p = NULL; FILE** files_out = NULL; int len, j; int64_t mortonkey = 0; unsigned int index = 0; int num_files_in = 0, num_files_out = 0, num_files, num_of_entries=0, check = 0, num_read_threads = DEFAULT_NUM_READ_THREADS; int i; pthread_t *writeThreads = NULL; pthread_t *readThreads = NULL; struct readThreadArgs *dataRead = NULL; boolean input_file = FALSE; int64_t global_offset_x = 0; int64_t global_offset_y = 0; double scale_x; double scale_y; if (argc == 1) { usage(); exit(0); } /*Allocate space for input files*/ files_name_in = (char**) malloc(sizeof(char*)*DEFAULT_NUM_INPUT_FILES); 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],"--num_read_threads") == 0) { num_read_threads = atoi(argv[++i]); } 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], "--moffset") == 0 || strcmp(argv[i], "-moffset") == 0 ) { i++; buffer = strtok (argv[i], ","); j = 0; while (buffer) { if (j == 0) { global_offset_x = S64(buffer); } else if (j == 1) { global_offset_y = S64(buffer); } j++; buffer = strtok (NULL, ","); while (buffer && *buffer == '\040') buffer++; } if (j != 2){ fprintf(stderr, "Only two int64_t are required in moffset option!\n"); exit(1); } } else if ( strcmp(argv[i], "--check") == 0 || strcmp(argv[i], "-check") == 0 ) { i++; check = 1; buffer = strtok (argv[i], ","); j = 0; while (buffer) { if (j == 0) { sscanf(buffer, "%lf", &scale_x); } else if (j == 1) { sscanf(buffer, "%lf", &scale_y); } j++; buffer = strtok (NULL, ","); while (buffer && *buffer == '\040') buffer++; } if (j != 2){ fprintf(stderr, "Only two doubles are required in moffset option!\n"); exit(1); } } else if ( strcmp(argv[i],"--input") == 0 || strcmp(argv[i],"-input") == 0 || strcmp(argv[i],"-i") == 0 || strcmp(argv[i],"-in") == 0 ) { i++; files_name_in[num_files_in++] = argv[i]; if (num_files_in % DEFAULT_NUM_INPUT_FILES) files_name_in = (char**) realloc(files_name_in, (num_files_in*2)*sizeof(char*)); } else if (strcmp(argv[i],"--file") == 0 || strcmp(argv[i],"-file") == 0 || strcmp(argv[i],"-f") == 0 ) { i++; int read; char line_buffer[BUFSIZ]; FILE* in = NULL; in = fopen(argv[i], "r"); if (!in) { fprintf(stderr, "ERROR: the path for file containing the input files is invalid %s\n", argv[i]); exit(1); } while (fgets(line_buffer, sizeof(line_buffer), in)) { line_buffer[strlen(line_buffer)-1]='\0'; files_name_in[num_files_in++] = strdup(line_buffer); if (num_files_in % DEFAULT_NUM_INPUT_FILES) files_name_in = (char**) realloc(files_name_in, (num_files_in*2)*sizeof(char*)); } fclose(in); input_file = TRUE; } else if ((num_files_in != 0) && num_files_out == 0) { file_name_out = argv[i]; num_files_out++; } else { fprintf(stderr, "ERROR: unknown argument '%s'\n",argv[i]); usage(); exit(1); } } /* end looping through argc/argv */ num_of_entries = strlen(parse_string); if (num_files_in == 0) { LASError_Print("No input filename was specified"); usage(); exit(1); } num_files = num_files_in; /*Entries metadata*/ i = 0; for (;;) { switch (parse_string[i]) { /* // the morton code on xy */ case 'k': entries[i] = ENTRY_k; entriesType[i] = sizeof(int64_t); /*Changes for Oscar's new Morton code function*/ //entriesFunc[i] = (void*)morton2D_encode; entriesFunc[i] = (void*)morton2D_encodeOscar; break; /* // the x coordinate double*/ case 'x': entries[i] = ENTRY_x; entriesType[i] = sizeof(double); entriesFunc[i] = (void*)LASPoint_GetX; break; /* // the y coordinate double*/ case 'y': entries[i] = ENTRY_y; entriesType[i] = sizeof(double); entriesFunc[i] = (void*)LASPoint_GetY; break; /* // the z coordinate double*/ case 'z': entries[i] = ENTRY_z; entriesType[i] = sizeof(double); entriesFunc[i] = (void*)LASPoint_GetZ; break; /* // the X coordinate decimal*/ case 'X': entries[i] = ENTRY_X; entriesType[i] = sizeof(int); entriesFunc[i] = (void*)LASPoint_GetX; break; /* // the y coordinate decimal*/ case 'Y': entries[i] = ENTRY_Y; entriesType[i] = sizeof(int); entriesFunc[i] = (void*)LASPoint_GetY; break; /* // the z coordinate decimal*/ case 'Z': entries[i] = ENTRY_Z; entriesType[i] = sizeof(int); entriesFunc[i] = (void*)LASPoint_GetZ; break; /* // the gps-time */ case 't': entries[i] = ENTRY_t; entriesType[i] = sizeof(double); entriesFunc[i] = (void*)LASPoint_GetTime; break; /* // the intensity */ case 'i': entries[i] = ENTRY_i; entriesType[i] = sizeof(int); entriesFunc[i] = (void*)LASPoint_GetIntensity; break; /* the scan angle */ case 'a': entries[i] = ENTRY_a; entriesType[i] = sizeof(int); entriesFunc[i] = (void*)LASPoint_GetScanAngleRank; break; /* the number of the return */ case 'r': entries[i] = ENTRY_r; entriesType[i] = sizeof(int); entriesFunc[i] = (void*)LASPoint_GetReturnNumber; break; /* the classification */ case 'c': entries[i] = ENTRY_c; entriesType[i] = sizeof(int); entriesFunc[i] = (void*)LASPoint_GetClassification; break; /* the user data */ case 'u': entries[i] = ENTRY_u; entriesType[i] = sizeof(int); entriesFunc[i] = (void*)LASPoint_GetUserData; break; /* the number of returns of given pulse */ case 'n': entries[i] = ENTRY_n; entriesType[i] = sizeof(int); entriesFunc[i] = (void*)LASPoint_GetNumberOfReturns; break; /* the red channel color */ case 'R': entries[i] = ENTRY_R; entriesType[i] = sizeof(int); entriesFunc[i] = (void*)LASColor_GetRed; break; /* the green channel color */ case 'G': entries[i] = ENTRY_G; entriesType[i] = sizeof(int); entriesFunc[i] = (void*)LASColor_GetGreen; break; /* the blue channel color */ case 'B': entries[i] = ENTRY_B; entriesType[i] = sizeof(int); entriesFunc[i] = (void*)LASColor_GetBlue; break; case 'M': entries[i] = ENTRY_M; entriesType[i] = sizeof(unsigned int); break; case 'p': entries[i] = ENTRY_p; entriesType[i] = sizeof(int); entriesFunc[i] = (void*)LASPoint_GetPointSourceId; break; /* the edge of flight line flag */ case 'e': entries[i] = ENTRY_e; entriesType[i] = sizeof(int); entriesFunc[i] = (void*)LASPoint_GetFlightLineEdge; break; /* the direction of scan flag */ case 'd': entries[i] = ENTRY_d; entriesType[i] = sizeof(int); entriesFunc[i] = (void*)LASPoint_GetScanDirection; break; } i++; if (parse_string[i] == 0) { break; } } /*Prepare the output files*/ if (file_name_out == NULL) { len = (int)strlen(file_name_in); file_name_out = LASCopyString(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] = '\0'; } char *str = malloc(sizeof(char)*(strlen(file_name_out)+12)); files_out = (FILE**) malloc(sizeof(FILE*)*num_of_entries); for (i = 0; i < num_of_entries; i++) { sprintf(str, "%s_col_%c.dat", file_name_out, parse_string[i]); if(doesFileExist(str)) { remove(str); } files_out[i] = fopen(str, "wb"); if (files_out[i] == 0) { LASError_Print("Could not open file for write"); usage(); exit(1); } } free(str); /*Initialize structures for the reading threads*/ //data = (struct writeT**) malloc(num_read_threads*sizeof(struct writeT*)); //Malloc is more efficient than calloc data = (struct writeT**) calloc(num_read_threads, sizeof(struct writeT*)); dataRead = (struct readThreadArgs*) malloc(sizeof(struct readThreadArgs)*num_read_threads); /* Launch read Threads */ stop = 0; readThreads = (pthread_t*) malloc(sizeof(pthread_t)*num_read_threads); for (i=0; i < num_read_threads; i++) { dataRead[i].id = i; dataRead[i].num_read_threads = num_read_threads; dataRead[i].num_of_entries = num_of_entries; dataRead[i].check = check; dataRead[i].global_offset_x = global_offset_x; dataRead[i].global_offset_y = global_offset_y; dataRead[i].scale_x = scale_x; dataRead[i].scale_y = scale_y; pthread_create(&readThreads[i], NULL, readFile, (void*)dataRead); } int writeIndex = 0; writeThreads = (pthread_t*) malloc(sizeof(pthread_t)*num_of_entries); /* Launch Threads */ struct writeThreadArgs *dataWrite = (struct writeThreadArgs *) malloc(sizeof(struct writeThreadArgs) *num_of_entries); for (i = 0; i < num_of_entries; i++) { dataWrite[i].id = i; dataWrite[i].out = files_out[i]; pthread_create(&writeThreads[i], NULL, writeFile, (void*)(&dataWrite[i])); } sleep(1); //Do we need to comment this one out!? int done = 0; while (num_files) { /*Obtain lock over data to get the pointer*/ MT_set_lock(&dataLock); dataWriteT = data[writeIndex]; while (dataWriteT == NULL) { /*Sleep and wait for data to be read*/ MT_cond_wait(&mainCond,&dataLock); dataWriteT = data[writeIndex]; } data[writeIndex] = NULL; //Release the lock /*Tell the write threads there is new data*/ pthread_cond_broadcast(&writeTCond); /*Tell the read threads there is a new buf empty*/ pthread_cond_broadcast(&readCond); MT_unset_lock(&dataLock); /*Keep looping*/ writeIndex++; writeIndex = (writeIndex % num_read_threads); MT_set_lock(&dataLock); while (done == 0) { /*Sleep and wait for data to be read*/ MT_cond_wait(&mainCond,&dataLock); done = 1; for (i = 0; i < num_of_entries; i++) { if (dataWriteT[i].values != NULL) { done = 0; break; } } } num_files--; if (verbose) printf("Files to go %d\n", num_files); free(dataWriteT); dataWriteT = NULL; done = 0; MT_unset_lock(&dataLock); } /*Tell the write threads to exit*/ MT_set_lock(&dataLock); stop = 1; pthread_cond_broadcast(&writeTCond); MT_unset_lock(&dataLock); /* Wait for Threads to Finish */ for (i=0; i<num_of_entries; i++) { pthread_join(writeThreads[i], NULL); } free(dataWrite); free(writeThreads); MT_cond_destroy(&readCond); MT_cond_destroy(&writeTCond); MT_cond_destroy(&mainCond); MT_lock_destroy(&dataLock); for (i = 0; i < num_of_entries; i++) { fflush(files_out[i]); if (verbose) printf("close file %d\n", i); fsync(files_out[i]); fclose(files_out[i]); } free(files_out); if (input_file) { for (i=0 ; i < num_files_in; i++) free(files_name_in[i]); free(files_name_in); } free(dataRead); if (readThreads) free(readThreads); return 0; }
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 = 0; char* file_name = NULL; LASReaderH reader = NULL; LASHeaderH header = NULL; LASWriterH writer = NULL; int check_points = FALSE; int repair_header = FALSE; int change_header = FALSE; int repair_bounding_box = FALSE; int use_stdin = FALSE; int update_return_counts = FALSE; int skip_vlr = FALSE; int wkt = FALSE; char *system_identifier = NULL; char *generating_software = NULL; unsigned char file_creation_day = 0; unsigned char file_creation_year = 0; int err = 0; LASPointSummary* summary = NULL; for (i = 1; i < argc; i++) { if (strcmp(argv[i],"-v") == 0 || strcmp(argv[i],"--version") == 0) { char* ver = LAS_GetFullVersion(); fprintf(stderr,"%s", ver); LASString_Free(ver); exit(0); } else if (strcmp(argv[i],"-h") == 0 || strcmp(argv[i],"--help") == 0) { usage(); exit(0); } 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 = argv[i]; } else if (strcmp(argv[i], "--points") == 0 || strcmp(argv[i], "--check") == 0 || strcmp(argv[i], "--check_points") == 0 || strcmp(argv[i], "-c") == 0 || strcmp(argv[i], "-points") == 0 || strcmp(argv[i], "-check") == 0 || strcmp(argv[i], "-check_points") == 0) { check_points = TRUE; } else if (strcmp(argv[i], "--nocheck") == 0 || strcmp(argv[i], "-nocheck") == 0) { check_points = FALSE; } else if (strcmp(argv[i], "--stdin") == 0 || strcmp(argv[i], "-ilas") == 0) { use_stdin = TRUE; } else if (strcmp(argv[i], "--repair") == 0 || strcmp(argv[i], "-r") == 0 || strcmp(argv[i], "-repair_header") == 0 || strcmp(argv[i], "-repair") == 0) { repair_header = TRUE; check_points = TRUE; } else if (strcmp(argv[i], "--repair_bb") == 0 || strcmp(argv[i], "--repair_bounding_box") == 0 || strcmp(argv[i], "--repair_boundingbox") == 0 || strcmp(argv[i], "-repair_bb") == 0 || strcmp(argv[i], "-repair_bounding_box") == 0 || strcmp(argv[i], "-repair_boundingbox") == 0 || strcmp(argv[i], "-repair") == 0 || strcmp(argv[i], "-rb") == 0) { repair_bounding_box = TRUE; check_points = TRUE; } else if (strcmp(argv[i],"--system_identifier") == 0 || strcmp(argv[i],"-system_identifier") == 0 || strcmp(argv[i],"-s") == 0 || strcmp(argv[i],"-sys_id") == 0) { i++; system_identifier = (char*) malloc(31 * sizeof(char)); strcpy(system_identifier, argv[i]); change_header = TRUE; } else if (strcmp(argv[i],"--generating_software") == 0 || strcmp(argv[i],"-generating_software") == 0 || strcmp(argv[i],"-g") == 0 || strcmp(argv[i],"-gen_soft") == 0) { i++; generating_software = (char*) malloc(31*sizeof(char)); strcpy(generating_software, argv[i]); change_header = TRUE; } else if (strcmp(argv[i],"--file_creation") == 0 || strcmp(argv[i],"-file_creation") == 0) { /* XXX - mloskot: Consider replacing atoi with strtol, see http://www.iso-9899.info/wiki/Converting */ i++; file_creation_day = (unsigned char)atoi(argv[i]); i++; file_creation_year = (unsigned char)atoi(argv[i]); change_header = TRUE; } else if (strcmp(argv[i],"--skip_vlr") == 0 || strcmp(argv[i],"--no_vlr") == 0) { skip_vlr = TRUE; } else if (strcmp(argv[i],"--wkt") == 0) { wkt = TRUE; } else if (file_name == NULL) { file_name = argv[i]; } else { usage(); fprintf(stderr, "ERROR: unknown argument '%s'\n",argv[i]); exit(1); } } if (use_stdin) { file_name = "stdin"; } if (!file_name) { LASError_Print("No filename was provided to be opened"); usage(); exit(1); } reader = LASReader_Create(file_name); if (!reader) { LASError_Print("Could not open file "); exit(1); } header = LASReader_GetHeader(reader); if (!header) { LASError_Print("Could not get LASHeader "); exit(1); } print_header(stdout, header, file_name, skip_vlr, wkt); if (change_header) { if (system_identifier) { err = LASHeader_SetSystemId (header, system_identifier); if (err) LASError_Print("Could not set SystemId"); } if (generating_software) { err = LASHeader_SetSoftwareId(header, generating_software); if (err) LASError_Print("Could not set SoftwareId"); } if ( file_creation_day || file_creation_year) { err = LASHeader_SetCreationDOY(header, file_creation_day); if (err) LASError_Print("Could not set file creation day"); err = LASHeader_SetCreationYear(header, file_creation_year); if (err) LASError_Print("Could not set file creation year"); } /* We need to wipe out the reader and make a writer. */ if (reader) { LASReader_Destroy(reader); reader = NULL; } writer = LASWriter_Create(file_name, header, LAS_MODE_APPEND); if (!writer) { LASError_Print("Problem creating LASWriterH object"); LASHeader_Destroy(header); header = NULL; exit(1); } if (writer) LASWriter_Destroy(writer); writer = NULL; if (header) LASHeader_Destroy(header); header = NULL; } if (check_points) { if (!reader) { reader = LASReader_Create(file_name); if (!reader) { LASError_Print("Could not open file "); exit(1); } } if (! header) { header = LASReader_GetHeader(reader); if (!header) { LASError_Print("Could not get LASHeader "); exit(1); } } if (!summary) summary = SummarizePoints(reader); print_point_summary(stdout, summary, header); if (repair_header) { fprintf(stdout, "\n---------------------------------------------------------\n"); fprintf(stdout, " Repair Summary\n"); fprintf(stdout, "---------------------------------------------------------\n"); if (use_stdin) { LASError_Print("Cannot update header information on piped input!"); exit(1); } if (! header) { header = LASReader_GetHeader(reader); if (!header) { LASError_Print("Could not get LASHeader "); exit(1); } } if (! repair_bounding_box) { if ( LASHeader_GetMinX(header) != LASPoint_GetX(summary->pmin) ) repair_bounding_box = TRUE; if ( LASHeader_GetMinY(header) != LASPoint_GetY(summary->pmin) ) repair_bounding_box = TRUE; if ( LASHeader_GetMinZ(header) != LASPoint_GetZ(summary->pmin) ) repair_bounding_box = TRUE; if ( LASHeader_GetMaxX(header) != LASPoint_GetX(summary->pmax) ) repair_bounding_box = TRUE; if ( LASHeader_GetMaxY(header) != LASPoint_GetY(summary->pmax) ) repair_bounding_box = TRUE; if ( LASHeader_GetMaxZ(header) != LASPoint_GetZ(summary->pmax) ) repair_bounding_box = TRUE; } if (repair_bounding_box) { fprintf(stdout, " Reparing Bounding Box...\n"); err = LASHeader_SetMin( header, LASPoint_GetX(summary->pmin), LASPoint_GetY(summary->pmin), LASPoint_GetZ(summary->pmin) ); if (err) { LASError_Print("Could not set minimum for header "); exit(1); } err = LASHeader_SetMax( header, LASPoint_GetX(summary->pmax), LASPoint_GetY(summary->pmax), LASPoint_GetZ(summary->pmax) ); if (err) { LASError_Print("Could not set minimum for header "); exit(1); } } for (i = 0; i < 5; i++) { if (LASHeader_GetPointRecordsByReturnCount(header, i) != summary->number_of_points_by_return[i]) { update_return_counts = TRUE; break; } } if (update_return_counts) { fprintf(stdout, " Reparing Point Count by Return...\n"); for (i = 0; i < 5; i++) { LASHeader_SetPointRecordsByReturnCount( header, i, summary->number_of_points_by_return[i]); } } if (reader) { LASReader_Destroy(reader); reader = NULL; } writer = LASWriter_Create(file_name, header, LAS_MODE_APPEND); if (!writer) { LASError_Print("Problem creating LASWriterH object for append"); LASHeader_Destroy(header); header = NULL; exit(1); } LASWriter_Destroy(writer); writer = NULL; LASHeader_Destroy(header); header = NULL; } if (summary) { LASPoint_Destroy(summary->pmin); LASPoint_Destroy(summary->pmax); free(summary); } } if (reader) LASReader_Destroy(reader); if (header) LASHeader_Destroy(header); #ifdef HAVE_GDAL /* Various GDAL related cleanups */ #ifdef OSRCleanup OSRCleanup(); #endif CPLFinderClean(); CPLFreeConfig(); CPLCleanupTLS(); #endif return 0; }
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; }
int main(int argc, char *argv[]) { int i; int j; char* buffer; int use_stdout = FALSE; int skip_invalid = FALSE; int num_entries = 0; int verbose = FALSE; char* file_name_in = 0; char* file_name_out = 0; char separator_sign = ' '; char* parse_string = "xyz"; int64_t global_offset_x = 0; int64_t global_offset_y = 0; int check = FALSE; double scale_x; double scale_y; LASReaderH reader = NULL; LASHeaderH header = NULL; LASPointH p = NULL; FILE* file_out; int len; unsigned int index = 0; if (argc == 1) { usage(); exit(0); } for (i = 1; i < argc; i++) { if ( strcmp(argv[i],"-h") == 0 || strcmp(argv[i],"-help") == 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], "--moffset") == 0 || strcmp(argv[i], "-moffset") == 0 ) { i++; buffer = strtok (argv[i], ","); j = 0; while (buffer) { if (j == 0) { global_offset_x = S64(buffer); } else if (j == 1) { global_offset_y = S64(buffer); } j++; buffer = strtok (NULL, ","); while (buffer && *buffer == '\040') buffer++; } if (j != 2){ fprintf(stderr, "Only two int64_t are required in moffset option!\n"); exit(1); } } else if ( strcmp(argv[i], "--check") == 0 || strcmp(argv[i], "-check") == 0 ) { i++; check = TRUE; buffer = strtok (argv[i], ","); j = 0; while (buffer) { if (j == 0) { sscanf(buffer, "%lf", &scale_x); } else if (j == 1) { sscanf(buffer, "%lf", &scale_y); } j++; buffer = strtok (NULL, ","); while (buffer && *buffer == '\040') buffer++; } if (j != 2){ fprintf(stderr, "Only two doubles are required in moffset option!\n"); exit(1); } } 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 (file_name_in == 0 && file_name_out == 0) { file_name_in = argv[i]; } else if (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 */ num_entries = strlen(parse_string); if (use_stdout == TRUE && file_name_out){ LASError_Print("If an output file is specified, --stdout must not be used!"); exit(1); } 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 = LASCopyString(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] = '\0'; } file_out = fopen(file_name_out, "wb"); } if (file_out == 0) { LASError_Print("Could not open file for write"); usage(); exit(1); } if (verbose) { print_header(stderr, header, file_name_in); } // Compute factors to add to X and Y and check sanity of generated codes double file_scale_x = LASHeader_GetScaleX(header); double file_scale_y = LASHeader_GetScaleY(header); if (check) { // Check specified scales are like in the LAS file if (fabs(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, scale_x); exit(1); } if (fabs(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, 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) global_offset_x) * 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) global_offset_y) * 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) global_offset_x) * scale_x); if (check_max_x > (MAX_INT_31 * 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) global_offset_y) * scale_y); if (check_max_y > (MAX_INT_31 * scale_y)) { fprintf(stderr, "ERROR: Specied Y global offset is too small. (MaxY - (GlobalY*ScaleY)) > (2^31)*ScaleY\n"); exit(1); } } /*Write Postgres header*/ struct postHeader pgHeader; pgHeader.s = "PGCOPY\n\377\r\n\0"; int i1T = 0, i2T = 0; pgHeader.i1 = htonl(i1T); pgHeader.i2 = htonl(i2T); fwrite(pgHeader.s, 11, 1, file_out); fwrite(&pgHeader.i1, sizeof(uint32_t), 1, file_out); fwrite(&pgHeader.i2, sizeof(uint32_t), 1, file_out); /* declaration for morton*/ uint32_t rawx = 0; uint32_t rawy = 0; uint64_t mortonkey = 0; /* scaled offsets to add for the morton encoding */ int64_t factorX = ((int64_t) (LASHeader_GetOffsetX(header) / file_scale_x)) - global_offset_x; int64_t factorY = ((int64_t) (LASHeader_GetOffsetY(header) / file_scale_y)) - global_offset_y; 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; } struct postRow pgRow; uint32_t size; uint16_t hT = num_entries; pgRow.h = htons(hT); fwrite(& pgRow.h, 2, 1, file_out); size = sizeof(double); pgRow.vardSize = htonl(size); size = sizeof(uint32_t); pgRow.varSize = htonl(size); i = 0; for (;;) { LASColorH color = LASPoint_GetColor(p); double vard; int var; unsigned long long int vardL, varL; switch (parse_string[i]) { /* // the morton code on xy */ case 'k': rawx = (uint32_t) (((int64_t) LASPoint_GetRawX(p)) + factorX); rawy = (uint32_t) (((int64_t) LASPoint_GetRawY(p)) + factorY); mortonkey = EncodeMorton2D(rawx,rawy); varL = htobe64(mortonkey); fwrite(&pgRow.vardSize, sizeof(uint32_t), 1, file_out); fwrite(&varL, sizeof(uint64_t), 1, file_out); break; /* // the x coordinate */ case 'x': vard = LASPoint_GetX(p); fwrite(&pgRow.vardSize, sizeof(uint32_t), 1, file_out); vardL = bigEndian_double(vard); fwrite(&vardL, sizeof(double), 1, file_out); break; /* // the y coordinate */ case 'y': vard = LASPoint_GetY(p); fwrite(&pgRow.vardSize, sizeof(uint32_t), 1, file_out); vardL = bigEndian_double(vard); fwrite(&vardL, sizeof(double), 1, file_out); break; /* // the z coordinate */ case 'z': vard = LASPoint_GetZ(p); fwrite(&pgRow.vardSize, sizeof(uint32_t), 1, file_out); vardL = bigEndian_double(vard); fwrite(&vardL, sizeof(double), 1, file_out); break; /* // the gps-time */ case 't': vard = LASPoint_GetTime(p); fwrite(&pgRow.vardSize, sizeof(uint32_t), 1, file_out); vardL = bigEndian_double(vard); fwrite(&vardL, sizeof(double), 1, file_out); break; /* // the intensity */ case 'i': var = LASPoint_GetIntensity(p); fwrite(&pgRow.varSize, sizeof(uint32_t), 1, file_out); varL = htonl(var); fwrite(&varL, sizeof(uint32_t), 1, file_out); break; /* the scan angle */ case 'a': var = LASPoint_GetScanAngleRank(p); fwrite(&pgRow.varSize, sizeof(uint32_t), 1, file_out); varL = htonl(var); fwrite(&varL, sizeof(uint32_t), 1, file_out); break; /* the number of the return */ case 'r': var = LASPoint_GetReturnNumber(p); fwrite(&pgRow.varSize, sizeof(uint32_t), 1, file_out); varL = htonl(var); fwrite(&varL, sizeof(uint32_t), 1, file_out); break; /* the classification */ case 'c': var = LASPoint_GetClassification(p); fwrite(&pgRow.varSize, sizeof(uint32_t), 1, file_out); varL = htonl(var); fwrite(&varL, sizeof(uint32_t), 1, file_out); break; /* the user data */ case 'u': var = LASPoint_GetUserData(p); fwrite(&pgRow.varSize, sizeof(uint32_t), 1, file_out); varL = htonl(var); fwrite(&varL, sizeof(uint32_t), 1, file_out); break; /* the number of returns of given pulse */ case 'n': var = LASPoint_GetNumberOfReturns(p); fwrite(&pgRow.varSize, sizeof(uint32_t), 1, file_out); varL = htonl(var); fwrite(&varL, sizeof(uint32_t), 1, file_out); break; /* the red channel color */ case 'R': var = LASColor_GetRed(color); fwrite(&pgRow.varSize, sizeof(uint32_t), 1, file_out); varL = htonl(var); fwrite(&varL, sizeof(uint32_t), 1, file_out); break; /* the green channel color */ case 'G': var = LASColor_GetGreen(color); fwrite(&pgRow.varSize, sizeof(uint32_t), 1, file_out); varL = htonl(var); fwrite(&varL, sizeof(uint32_t), 1, file_out); break; /* the blue channel color */ case 'B': var = LASColor_GetBlue(color); fwrite(&pgRow.varSize, sizeof(uint32_t), 1, file_out); varL = htonl(var); fwrite(&varL, sizeof(uint32_t), 1, file_out); break; case 'M': var = index; fwrite(&pgRow.varSize, sizeof(uint32_t), 1, file_out); varL = htonl(var); fwrite(&varL, sizeof(uint32_t), 1, file_out); break; case 'p': var = LASPoint_GetPointSourceId(p); fwrite(&pgRow.varSize, sizeof(uint32_t), 1, file_out); varL = htonl(var); fwrite(&varL, sizeof(uint32_t), 1, file_out); break; /* the edge of flight line flag */ case 'e': var = LASPoint_GetFlightLineEdge(p); fwrite(&pgRow.varSize, sizeof(uint32_t), 1, file_out); varL = htonl(var); fwrite(&varL, sizeof(uint32_t), 1, file_out); break; /* the direction of scan flag */ case 'd': var = LASPoint_GetScanDirection(p); fwrite(&pgRow.varSize, sizeof(uint32_t), 1, file_out); varL = htonl(var); fwrite(&varL, sizeof(uint32_t), 1, file_out); break; } i++; if (!parse_string[i]) { break; } LASColor_Destroy(color); } p = LASReader_GetNextPoint(reader); index +=1; } short endT = -1; short end = htons(endT); fwrite(&end, sizeof(end), 1, file_out); fflush(file_out); fclose(file_out); LASReader_Destroy(reader); LASHeader_Destroy(header); return 0; }