static void ingest_polarimetry_data(char *inFile, char *inBaseName, char *outFile, char band, int create) { FILE *fpIn, *fpOut; meta_parameters *meta = NULL; char tmp[10]; int ii, kk; float *power = NULL; char *byteBuf = NULL; fpIn = FOPEN(inFile, "rb"); append_ext_if_needed(outFile, ".img", NULL); if (create) fpOut = FOPEN(outFile, "wb"); else fpOut = FOPEN(outFile, "ab"); if (create) { meta = import_airsar_meta(inFile, inBaseName, TRUE); meta->general->data_type = REAL32; meta->general->band_count = 1; sprintf(meta->general->bands, "AMP-%c", band); meta->general->image_data_type = IMAGE_LAYER_STACK; } else { meta = meta_read(outFile); meta->general->band_count += 1; sprintf(tmp, ",AMP-%c", band); strcat(meta->general->bands, tmp); } power = (float *) MALLOC(sizeof(float)*meta->general->sample_count); byteBuf = (char *) MALLOC(sizeof(char)*10); airsar_header *header = read_airsar_header(inFile); long offset = header->first_data_offset; FSEEK(fpIn, offset, SEEK_SET); for (ii=0; ii<meta->general->line_count; ii++) { for (kk=0; kk<meta->general->sample_count; kk++) { FREAD(byteBuf, sizeof(char), 10, fpIn); power[kk] = sqrt(((float)byteBuf[1]/254.0 + 1.5) * pow(2, byteBuf[0])); } put_float_line(fpOut, meta, ii, power); asfLineMeter(ii, meta->general->line_count); } FCLOSE(fpIn); FCLOSE(fpOut); meta_write(meta, outFile); if (power) FREE(power); if (byteBuf) FREE(byteBuf); if (meta) meta_free(meta); }
int asf_windspeed(platform_type_t platform_type, char *band_id, double wind_dir, int cmod4, double landmaskHeight, char *landmaskFile, char *demFile, char *inBaseName, char *colormapName, char *outBaseName) { char *inDataName, outDataName[1024], outMetaName[1024]; FILE *in = NULL, *out = NULL; asfPrintStatus("\n Determining windspeeds in: %s\n", inBaseName); strcpy(outDataName, outBaseName); strcpy(outMetaName, outBaseName); inDataName = (char *)MALLOC(sizeof(char) * (strlen(inBaseName) + 10)); strcpy(inDataName, inBaseName); append_ext_if_needed(inDataName, ".img", NULL); append_ext_if_needed(outDataName, ".img", NULL); append_ext_if_needed(outMetaName, ".meta", NULL); // New images for processing in to out meta_parameters *imd = meta_read(inBaseName); meta_general *img = imd->general; // convenience ptr meta_parameters *omd = meta_read(inBaseName); meta_general *omg = omd->general; // convenience ptr meta_sar *oms = omd->sar; // convenience ptr omg->band_count = 0; strcpy(omg->bands, ""); strcpy(oms->polarization, ""); if (strstr(img->bands, "VV") == NULL && strstr(img->bands, "HH") == NULL) { asfPrintError("Cannot find any VV or HH polarized bands in this data. Available\n" "bands are %s). Wind speeds can only be determined on Sigma0-\n" "calibrated SAR data in HH or VV polarizations.\n", img->bands); } in = (FILE *)FOPEN(inDataName, "rb"); out = (FILE *)FOPEN(outDataName, "wb"); FREE(inDataName); // For each band double alpha = 1.0; // Default for VV polarization; int band_num; float *data = (float *)MALLOC(sizeof(float) * img->sample_count); for (band_num = 0; band_num < img->band_count; band_num++) { // Get band name, check for proper polarization, and create new output bandname, set alpha char *band_name = get_band_name(img->bands, img->band_count, band_num); long offset = img->line_count * band_num; char polarization[2]=""; if (strncmp_case(band_name, "SIGMA-VV", 8) == 0 || strncmp_case(band_name, "SIGMA-HH", 8) == 0) { asfPrintStatus("\nProcessing wind speed calculations on band %s...\n\n", band_name); (omg->band_count)++; strcpy(polarization, (strstr(band_name, "VV") != NULL) ? "VV" : "HH"); strcpy(oms->polarization, polarization); sprintf(&omg->bands[strlen(omg->bands)], "%s%s%s", WINDSPEED_BAND_BASENAME, polarization, (band_num < img->band_count - 1 && img->band_count > 0) ? ", " : ""); alpha = (strcmp(polarization, "VV") == 0) ? 1.0 : DEFAULT_HH_POL_ALPHA; // For CMODx } else { asfPrintStatus("\nFound band: %s (Cannot calculate wind speed on this type of band)\n\n", band_name); continue; // Skip this band } // Calculate average r_look for entire image (r_look is the angle between the NADIR line // and a line point directly north, the 'look angle' of the platform.) double r_look = asf_r_look(imd); double phi_diff = wind_dir - r_look; // Pre-populate incidence angles (as a function of sample) and get min/max incidence angle // as well int line, sample; double *incids = (double *)MALLOC(img->sample_count * sizeof(double)); double min_incid = DBL_MAX; double max_incid = DBL_MIN; for (sample = 0; sample < img->sample_count; sample++) { incids[sample] = R2D * meta_incid(imd, img->line_count / 2, sample); min_incid = (incids[sample] < min_incid) ? incids[sample] : min_incid; max_incid = (incids[sample] > max_incid) ? incids[sample] : max_incid; } // Get min/max radar cross-sections asfPrintStatus("\nFinding min/max radar cross-sections...\n\n"); double rcs_min = DBL_MAX; double rcs_max = DBL_MIN; for (line = 0; line < img->line_count; line++) { // Get a line get_float_line(in, imd, line+offset, data); for (sample = 0; sample < img->sample_count; sample++) { if (meta_is_valid_double(data[sample]) && data[sample] >= 0.0) { rcs_min = (data[sample] < rcs_min) ? data[sample] : rcs_min; rcs_max = (data[sample] > rcs_max) ? data[sample] : rcs_max; } } asfLineMeter(line, img->line_count); } // FIXME: Generate 2D array of windspeeds here. One dimension is incidence angle and // the other is radar cross-section. The values in the table are wind speed as a function // of incidence angle and radar cross-section (given the provided wind direction.) The idea // is to more-quickly populate a grid of results and then to interpolate results for each // pixel of the image rather then perform the full calculation (very sloooow) double windspeed1 = 0.0, windspeed2 = 0.0; for (line = 0; line < img->line_count; line++) { // Get a line get_float_line(in, imd, line+offset, data); for (sample = 0; sample < img->sample_count; sample++) { // FIXME: Here is where we should apply a land mask ...in this if-statement expression if (meta_is_valid_double(data[sample]) && data[sample] >= 0.0) { // Calculate windspeed // FIXME: This returns the angle, at the target pixel location, between straight up // and the line to the satellite. Make sure Frank's code doesn't assume the angle // between the line to the satellite and a horizontal line, i.e. 90 degrees minus // this angle. double incidence_angle = incids[sample]; switch (platform_type) { case p_RSAT1: if (!cmod4) { // Use CMOD5 to calculate windspeeds double hh = alpha; ws_inv_cmod5((double)data[sample], phi_diff, incidence_angle, &windspeed1, &windspeed2, (double)MIN_CMOD5_WINDSPEED, (double)MAX_CMOD5_WINDSPEED, 25, hh); data[sample] = windspeed1; // When 2 answers exist, take the lower (per Frank Monaldo) } else { // Use CMOD4 to calculate windspeeds asfPrintError("The CMOD4 algorithm is not yet supported. Avoid the -cmod4\n" "option for now and let %s default to using the CMOD5 algorithm\n" "instead.\n"); } break; case p_PALSAR: case p_TERRASARX: case p_ERS1: case p_ERS2: default: asfPrintError("Found a platform type (%s) that is not yet supported.\n", (platform_type == p_PALSAR) ? "PALSAR" : (platform_type == p_TERRASARX) ? "TerraSAR-X" : (platform_type == p_ERS1) ? "ERS-1" : (platform_type == p_ERS2) ? "ERS-2" : "UNKNOWN PLATFORM"); } } } put_float_line(out, omd, line+offset, data); asfLineMeter(line, img->line_count); } } // end for (each band) FREE(data); // Insert colormap into metadata meta_write(omd, outMetaName); meta_free(imd); meta_free(omd); asfPrintStatus("Windspeed calculation complete.\n\n"); return EXIT_SUCCESS; }
int asf_export_bands(output_format_t format, scale_t sample_mapping, int rgb, int true_color, int false_color, char *look_up_table_name, int use_pixel_is_point, char *in_base_name, char *output_name, char **band_name, int *noutputs, char ***output_names) { char *in_meta_name=NULL, *in_data_name=NULL, *out_name=NULL; asfPrintStatus("Exporting ...\n"); meta_parameters *md = NULL; int i, nouts = 0, is_polsarpro = 0, is_matrix = 0; char **outs = NULL; if (format != HDF && format != NC) { in_data_name = appendExt(in_base_name, ".img"); in_meta_name = appendExt(in_base_name, ".meta"); md = meta_read(in_meta_name); is_polsarpro = (md->general->image_data_type == POLARIMETRIC_SEGMENTATION) ? 1 : 0; is_matrix = ((md->general->image_data_type >= POLARIMETRIC_C2_MATRIX && md->general->image_data_type <= POLARIMETRIC_STOKES_MATRIX) || md->general->image_data_type == POLARIMETRIC_DECOMPOSITION) ? 1 : 0; if (md->general->image_data_type == RGB_STACK) rgb = TRUE; } // Do that exporting magic! if ( format == ENVI ) { //in_data_name = appendExt(in_base_name, ".img"); //in_meta_name = appendExt(in_base_name, ".meta"); out_name = appendExt(output_name, ".bsq"); export_as_envi (in_meta_name, in_data_name, out_name); } else if ( format == ESRI ) { //in_data_name = appendExt(in_base_name, ".img"); //in_meta_name = appendExt(in_base_name, ".meta"); out_name = appendExt(output_name, ".esri"); export_as_esri (in_meta_name, in_data_name, out_name); } else if ( format == TIF ) { //in_data_name = appendExt(in_base_name, ".img"); //in_meta_name = appendExt(in_base_name, ".meta"); out_name = MALLOC(sizeof(char)*(strlen(output_name)+32)); strcpy(out_name, output_name); if (!is_matrix) append_ext_if_needed(out_name, ".tif", ".tiff"); export_band_image(in_meta_name, in_data_name, out_name, sample_mapping, band_name, rgb, true_color, false_color, look_up_table_name, TIF, 0, &nouts, &outs); } else if ( format == GEOTIFF ) { //in_data_name = appendExt(in_base_name, ".img"); //in_meta_name = appendExt(in_base_name, ".meta"); out_name = MALLOC(sizeof(char)*(strlen(output_name)+32)); strcpy(out_name, output_name); if (!is_matrix) append_ext_if_needed(out_name, ".tif", ".tiff"); export_band_image(in_meta_name, in_data_name, out_name, sample_mapping, band_name, rgb, true_color, false_color, look_up_table_name, GEOTIFF, use_pixel_is_point, &nouts, &outs); } else if ( format == JPEG ) { //in_data_name = appendExt(in_base_name, ".img"); //in_meta_name = appendExt(in_base_name, ".meta"); out_name = MALLOC(sizeof(char)*(strlen(output_name)+32)); strcpy(out_name, output_name); if (!is_matrix) append_ext_if_needed(out_name, ".jpg", ".jpeg"); export_band_image(in_meta_name, in_data_name, out_name, sample_mapping, band_name, rgb, true_color, false_color, look_up_table_name, JPEG, 0, &nouts, &outs); } else if ( format == PNG ) { //in_data_name = appendExt(in_base_name, ".img"); //in_meta_name = appendExt(in_base_name, ".meta"); out_name = MALLOC(sizeof(char)*(strlen(output_name)+32)); strcpy(out_name, output_name); if (!is_matrix) append_ext_if_needed(out_name, ".png", NULL); export_band_image(in_meta_name, in_data_name, out_name, sample_mapping, band_name, rgb, true_color, false_color, look_up_table_name, PNG, 0, &nouts, &outs); } else if ( format == PNG_ALPHA ) { //in_data_name = appendExt(in_base_name, ".img"); //in_meta_name = appendExt(in_base_name, ".meta"); out_name = MALLOC(sizeof(char)*(strlen(output_name)+32)); strcpy(out_name, output_name); if (!is_matrix) append_ext_if_needed(out_name, ".png", NULL); export_band_image(in_meta_name, in_data_name, out_name, sample_mapping, band_name, rgb, true_color, false_color, look_up_table_name, PNG_ALPHA, 0, &nouts, &outs); } else if ( format == PNG_GE ) { //in_data_name = appendExt(in_base_name, ".img"); //in_meta_name = appendExt(in_base_name, ".meta"); out_name = MALLOC(sizeof(char)*(strlen(output_name)+32)); strcpy(out_name, output_name); if (!is_matrix) append_ext_if_needed(out_name, ".png", NULL); export_band_image(in_meta_name, in_data_name, out_name, sample_mapping, band_name, rgb, true_color, false_color, look_up_table_name, PNG_GE, 0, &nouts, &outs); } else if ( format == PGM ) { //in_data_name = appendExt(in_base_name, ".img"); //in_meta_name = appendExt(in_base_name, ".meta"); if (rgb || true_color || false_color || is_polsarpro) { asfPrintWarning( "Greyscale PGM output is not compatible with color options:\n" "(RGB, True Color, False Color, color look-up tables, PolSARpro\n" "classifications, etc) ...\n" "Defaulting to producing separate greyscale PGM files for " "available bands.\n"); rgb = 0; true_color = 0; false_color = 0; } out_name = MALLOC(sizeof(char)*(strlen(output_name)+32)); strcpy(out_name, output_name); if (!is_matrix) append_ext_if_needed(out_name, ".pgm", NULL); export_band_image(in_meta_name, in_data_name, out_name, sample_mapping, band_name, rgb, true_color, false_color, look_up_table_name, 0, PGM, &nouts, &outs); } else if ( format == POLSARPRO_HDR ) { out_name = MALLOC(sizeof(char)*(strlen(output_name)+32)); strcpy(out_name, output_name); export_polsarpro(in_meta_name, in_data_name, out_name, &nouts, &outs); } else if ( format == HDF ) { out_name = MALLOC(sizeof(char)*(strlen(output_name)+32)); strcpy(out_name, output_name); export_hdf(in_base_name, out_name, &nouts, &outs); } else if ( format == NC ) { out_name = MALLOC(sizeof(char)*(strlen(output_name)+32)); strcpy(out_name, output_name); export_netcdf(in_base_name, out_name, &nouts, &outs); } if (format != HDF && format != NC) { if (should_write_insar_rgb(md->general->bands)) { write_insar_rgb(format, in_meta_name, in_data_name, out_name); } if (should_write_insar_xml_meta(md)) { char *xml_meta = get_insar_xml_string(md, FALSE); char *xml_output_file_name = (char *) MALLOC(sizeof(char)*(strlen(out_name)+10)); sprintf(xml_output_file_name, "%s.xml", stripExt(out_name)); write_insar_xml_to_file(xml_output_file_name, xml_meta); FREE(xml_meta); FREE(xml_output_file_name); } else if (should_write_dem_xml_meta(md)) { char *xml_meta = get_dem_xml_string(md, FALSE); char *xml_output_file_name = (char *) MALLOC(sizeof(char)*(strlen(out_name)+10)); sprintf(xml_output_file_name, "%s.xml", stripExt(out_name)); write_dem_xml_to_file(xml_output_file_name, xml_meta); FREE(xml_meta); FREE(xml_output_file_name); } } if (noutputs && output_names) { asfPrintStatus("\n\nExport complete.\nGenerated %d output file%s:\n", nouts, nouts==1?"":"s"); for (i=0; i<nouts; ++i) asfPrintStatus(" %s\n", outs[i]); asfPrintStatus("\n"); *noutputs = nouts; *output_names = outs; } else { for (i=0; i<nouts; ++i) FREE(outs[i]); FREE(outs); } if (in_data_name) FREE(in_data_name); if (in_meta_name) FREE(in_meta_name); if (out_name) FREE(out_name); if (md) meta_free(md); asfPrintStatus("Export successful!\n\n"); return (EXIT_SUCCESS); }
void asf_airsar_import(char *inFile, char *outFile, int insar, int polar) { airsar_header *header = NULL; meta_parameters *metaIn = NULL, *metaOut = NULL; FILE *fpIn, *fpOut; float *floatBuf; char dataName[1024], *airsar_basename=NULL; int ii, kk, create=TRUE, line_count; int dem=FALSE, amp=FALSE, coh=FALSE; long line_offset; // First check for the existence of the input file. In this case we ingest // a single AirSAR file and ignore any other option that is passed in. if (fileExists(inFile) && strstr(inFile, "_meta.airsar") == NULL) { // Check what kind of data it is if (strstr(inFile, ".demi2")) dem = TRUE; else if (strstr(inFile, ".vvi2")) amp = TRUE; else if (strstr(inFile, ".corgr")) coh = TRUE; // FIX ME: Does not deal with polarimetric data yet header = read_airsar_header(inFile); metaIn = import_airsar_meta(inFile, airsar_basename, TRUE); line_offset = header->first_data_offset/metaIn->general->sample_count/2; metaIn->general->line_count += line_offset; metaOut = import_airsar_meta(inFile, airsar_basename, TRUE); // Assign appropriate data type if (dem || amp) metaIn->general->data_type = INTEGER16; else metaIn->general->data_type = ASF_BYTE; metaOut->general->data_type = REAL32; floatBuf = (float *) MALLOC(sizeof(float)*metaIn->general->sample_count); fpIn = FOPEN(inFile, "rb"); append_ext_if_needed(outFile, ".img", NULL); fpOut = FOPEN(outFile, "wb"); for (ii=0; ii<metaOut->general->line_count; ii++) { // Interferometric data can be read using get_float_line if (dem || amp || coh) get_float_line(fpIn, metaIn, ii+line_offset, floatBuf); // DEM needs some additional treatment if (dem) { for (kk=0; kk<metaIn->general->sample_count; kk++) floatBuf[kk] = floatBuf[kk]*metaIn->airsar->elevation_increment + metaIn->airsar->elevation_offset; } // Writing away should work the same way put_float_line(fpOut, metaOut, ii, floatBuf); asfLineMeter(ii, metaOut->general->line_count); } FCLOSE(fpIn); FCLOSE(fpOut); if (dem) { metaOut->general->image_data_type = DEM; strcpy(metaOut->general->bands, "DEM"); } else if (amp) { metaOut->general->image_data_type = AMPLITUDE_IMAGE; strcpy(metaOut->general->bands, "AMPLITUDE"); } else if (coh) { metaOut->general->image_data_type = COHERENCE_IMAGE; strcpy(metaOut->general->bands, "COHERENCE"); } meta_write(metaOut, outFile); } // Take care of interferometric layer stack else if (insar) { // Check for DEM sprintf(dataName, "%s.demi2", inFile); if (!fileExists(dataName)) asfPrintError("Could not find DEM (%s)\nDEM is required for reliable" "geometry and geolocation\n", dataName); else { printf("Ingesting DEM (%s) ...\n", dataName); metaIn = import_airsar_meta(dataName, inFile, TRUE); line_count = metaIn->general->line_count; ingest_insar_data(dataName, inFile, "DEM", sizeof(short), line_count, outFile, create); create = FALSE; } // Check for amplitude image sprintf(dataName, "%s.vvi2", inFile); if (!fileExists(dataName)) asfPrintWarning("Could not find amplitude image (%s)\n", dataName); else { printf("Ingesting amplitude image (%s) ...\n", dataName); ingest_insar_data(dataName, inFile, "AMPLITUDE", sizeof(short), line_count, outFile, create); create = FALSE; } // Check for coherence image sprintf(dataName, "%s.corgr", inFile); if (!fileExists(dataName)) asfPrintWarning("Could not find coherence image (%s)\n", dataName); else { printf("Ingesting coherence image (%s) ...\n", dataName); ingest_insar_data(dataName, inFile, "COHERENCE", sizeof(char), line_count, outFile, create); create = FALSE; } } // Take care of polarimetric layer stack // We will just put all available power images into a multiband image else if (polar) { // Check for C-band data sprintf(dataName, "%s_c.datgr", inFile); if (!fileExists(dataName)) sprintf(dataName, "%s_c.dat", inFile); if (!fileExists(dataName)) asfPrintWarning("Could not find polarimetric data set (%s)\n", dataName); else { printf("Ingesting C band data (%s) ...\n", dataName); ingest_polarimetry_data(dataName, inFile, outFile, 'C', create); create = FALSE; } // Check for L-band data sprintf(dataName, "%s_l.datgr", inFile); if (!fileExists(dataName)) sprintf(dataName, "%s_l.dat", inFile); if (!fileExists(dataName)) asfPrintWarning("Could not find polarimetric data set (%s)\n", dataName); else { printf("Ingesting L band data (%s) ...\n", dataName); ingest_polarimetry_data(dataName, inFile, outFile, 'L', create); create = FALSE; } // Check for P-band data sprintf(dataName, "%s_p.datgr", inFile); if (!fileExists(dataName)) sprintf(dataName, "%s_p.dat", inFile); if (!fileExists(dataName)) asfPrintWarning("Could not find polarimetric data set (%s)\n", dataName); else { printf("Ingesting P band data (%s) ...\n", dataName); ingest_polarimetry_data(dataName, inFile, outFile, 'P', create); create = FALSE; } } // Regular ingest else import_airsar(inFile, r_AMP, outFile); // Clean up time if (metaIn) meta_free(metaIn); if (metaOut) meta_free(metaOut); }
static void ingest_insar_data(char *inFile, char *inBaseName, char *band, int size, int line_count, char *outFile, int create) { airsar_header *header; meta_parameters *metaIn = NULL, *metaOut = NULL; FILE *fpIn, *fpOut; int ii, kk, line_offset; float *floatBuf; char tmp[10]; fpIn = FOPEN(inFile, "rb"); append_ext_if_needed(outFile, ".img", NULL); if (create) fpOut = FOPEN(outFile, "wb"); else fpOut = FOPEN(outFile, "ab"); if (create) { metaOut = import_airsar_meta(inFile, inBaseName, TRUE); metaOut->general->data_type = REAL32; metaOut->general->band_count = 1; sprintf(metaOut->general->bands, "%s", band); metaOut->general->image_data_type = IMAGE_LAYER_STACK; } else { metaOut = meta_read(outFile); metaOut->general->band_count += 1; sprintf(tmp, ",%s", band); strcat(metaOut->general->bands, tmp); } header = read_airsar_header(inFile); metaIn = import_airsar_meta(inFile, inBaseName, TRUE); line_offset = header->first_data_offset/metaIn->general->sample_count/size; metaIn->general->line_count = line_count + line_offset; if (size == 2) metaIn->general->data_type = INTEGER16; else if (size == 1) metaIn->general->data_type = ASF_BYTE; floatBuf = (float *) MALLOC(sizeof(float)*metaIn->general->sample_count); for (ii=0; ii<line_count; ii++) { get_float_line(fpIn, metaIn, ii+line_offset, floatBuf); if (strcmp_case(band, "DEM") == 0) { for (kk=0; kk<metaIn->general->sample_count; kk++) floatBuf[kk] = floatBuf[kk]*metaIn->airsar->elevation_increment + metaIn->airsar->elevation_offset; } put_float_line(fpOut, metaOut, ii, floatBuf); asfLineMeter(ii, line_count); } FCLOSE(fpIn); FCLOSE(fpOut); meta_write(metaOut, outFile); if (floatBuf) FREE(floatBuf); if (metaIn) meta_free(metaIn); if (metaOut) meta_free(metaOut); }