void update_location_block(meta_parameters *meta) { if (!meta->projection) asfPrintWarning("Image does not have a projection block.\n" "Not updating location block!\n"); else asfPrintWarning("Location block is updated based on the projection " "information.\nThis might no reflect the actual corner " "coordinates as it could\ninclude background values.\n"); double startX = meta->projection->startX; double startY = meta->projection->startY; double endX = startX + meta->general->sample_count*meta->projection->perX; double endY = startY + meta->general->line_count*meta->projection->perY; double lat, lon, height; proj_to_latlon(meta->projection, startX, startY, 0.0, &lat, &lon, &height); meta->location->lat_start_near_range = lat*R2D; meta->location->lon_start_near_range = lon*R2D; proj_to_latlon(meta->projection, startX, endY, 0.0, &lat, &lon, &height); meta->location->lat_end_near_range = lat*R2D; meta->location->lon_end_near_range = lon*R2D; proj_to_latlon(meta->projection, endX, startY, 0.0, &lat, &lon, &height); meta->location->lat_start_far_range = lat*R2D; meta->location->lon_start_far_range = lon*R2D; proj_to_latlon(meta->projection, endX, endY, 0.0, &lat, &lon, &height); meta->location->lat_end_far_range = lat*R2D; meta->location->lon_end_far_range = lon*R2D; }
void EQR2latLon(double projX, double projY, double *lat, double *lon) { project_parameters_t pps; projection_type_t proj_type; meta_projection *meta_proj; double h; proj_type = EQUI_RECTANGULAR; pps.eqr.central_meridian = 0.0; pps.eqr.orig_latitude = 0.0; pps.eqr.false_easting = 0.0; pps.eqr.false_northing = 0.0; // Initialize meta_projection block meta_proj = meta_projection_init(); meta_proj->type = proj_type; meta_proj->datum = WGS84_DATUM; // assumed... meta_proj->param = pps; proj_to_latlon(meta_proj, projX, projY, 0.0, lat, lon, &h); *lat *= R2D; *lon *= R2D; free(meta_proj); }
void UTM2latLon(double projX, double projY, double elev, int zone, double *lat, double *lon) { project_parameters_t pps; projection_type_t proj_type; meta_projection *meta_proj; double h; proj_type = UNIVERSAL_TRANSVERSE_MERCATOR; pps.utm.zone = zone; pps.utm.scale_factor = 0.9996; pps.utm.lon0 = (double) (zone - 1) * 6.0 - 177.0; pps.utm.lat0 = 0.0; pps.utm.false_easting = 500000.0; pps.utm.false_northing = 0.0; // Initialize meta_projection block meta_proj = meta_projection_init(); meta_proj->type = proj_type; meta_proj->datum = WGS84_DATUM; // assumed... meta_proj->param = pps; proj_to_latlon(meta_proj, projX, projY, elev, lat, lon, &h); *lat *= R2D; *lon *= R2D; }
static void test_p2ll(meta_projection *mp, const char *proj_name, double projY, double projX, double height, int zone, double lon, double lat, datum_type_t datum) { double testLat, testLon, z; proj_to_latlon(mp, projX, projY, height, &testLat, &testLon, &z); testLat *= R2D; testLon *= R2D; CU_ASSERT(double_equals(lat, testLat, 5)); CU_ASSERT(double_equals(lon, testLon, 5)); if (double_equals(lat, testLat, 5) && double_equals(lon, testLon, 5)) { //asfPrintStatus("%s proj_to_latlon Testing: %f, %f ... OK\n", // proj_name, projX, projY); ++n_ok; } else { asfPrintStatus("%s proj_to_latlon Testing: %f, %f ... ERROR\n", proj_name, projX, projY); asfPrintStatus("Result: %.10f %.10f (%.10f)\n", testLat, testLon, z); asfPrintStatus("Expected: %.10f %.10f\n", lat, lon); ++n_bad; } double x, y; latlon_to_proj(mp, '?', lat*D2R, lon*D2R, height, &x, &y, &z); CU_ASSERT(double_equals(x, projX, 5)); CU_ASSERT(double_equals(y, projY, 5)); if (double_equals(x, projX, 5) && double_equals(y, projY, 5)) { //asfPrintStatus("%s latlon_to_proj Testing: %f, %f ... OK\n", // proj_name, lat, lon); ++n_ok; } else { asfPrintStatus("%s latlon_to_proj Testing: %f, %f ... ERROR\n", proj_name, lat, lon); asfPrintStatus("Result: %.10f %.10f (%.10f)\n", x, y, z); asfPrintStatus("Expected: %.10f %.10f\n", projX, projY); ++n_bad; } }
static int proj_getls(double *line, double *samp) { meta_parameters *meta = curr->meta; if (meta->projection || (meta->sar&&meta->state_vectors) || meta->transform || meta->airsar) { double x = get_double_from_entry("go_to_projx_entry"); double y = get_double_from_entry("go_to_projy_entry"); double lat, lon; if (curr->meta->projection) { double h; proj_to_latlon(curr->meta->projection, x, y, 0, &lat, &lon, &h); if (lat==y && lon==x) { // this is usually indicative of failure... an error will have // been printed out already by libproj return FALSE; } lat *= R2D; lon *= R2D; } else { int zone = utm_zone(curr->meta->general->center_longitude); asfPrintStatus("Unprojected data -- assuming UTM (zone: %d)\n", zone); UTM2latLon(x, y, 0, zone, &lat, &lon); if (lat==y*R2D && lon==x*R2D) { // this is usually indicative of failure... an error will have // been printed out already by libproj return FALSE; } } int bad = meta_get_lineSamp(curr->meta, lat, lon, 0, line, samp); return !bad; } else { asfPrintWarning("No geolocation information available -- GoTo will only\n" "work for GoTo by Line/Sample.\n"); return FALSE; } }
void pr2ll(double projX, double projY, int zone, double *lat, double *lon) { meta_projection *meta_proj = meta_projection_init(); meta_proj->datum = WGS84_DATUM; project_parameters_t pps; if (zone == 999 || zone == -999) { pps.ps.is_north_pole = zone>0 ? 1 : 0; pps.ps.slat = zone>0 ? 70 : -70; pps.ps.slon = 150; pps.ps.false_easting = 0; pps.ps.false_northing = 0; meta_proj->type = POLAR_STEREOGRAPHIC; } else { pps.utm.zone = zone; pps.utm.scale_factor = 0.9996; pps.utm.lon0 = (double) (zone - 1) * 6.0 - 177.0; pps.utm.lat0 = 0.0; pps.utm.false_easting = 500000.0; pps.utm.false_northing = 0.0; meta_proj->type = UNIVERSAL_TRANSVERSE_MERCATOR; } meta_proj->param = pps; double h; proj_to_latlon(meta_proj, projX, projY, 0, lat, lon, &h); FREE(meta_proj); *lat *= R2D; *lon *= R2D; }
int main(int argc, char **argv) { char *listFile, *projFile, *key, line[255]; FILE *fp; project_parameters_t pps; projection_type_t proj_type; datum_type_t datum; spheroid_type_t spheroid; meta_projection *meta_proj; double lat, lon, projX, projY; int listFlag = FALSE; extern int currArg; /* from cla.h in asf.h... initialized to 1 */ currArg = 1; if (argc < 4) { printf("Insufficient arguments.\n"); usage(argv[0]); } key = argv[currArg]; if (strmatches(key,"-list","--list",NULL)) { currArg++; CHECK_ARG(1); listFile = GET_ARG(1); projFile = argv[currArg]; listFlag = TRUE; } else { projX = atof(argv[currArg++]); projY = atof(argv[currArg++]); projFile = argv[currArg]; } system("date"); printf("Program: proj2latLon\n\n"); // Read projection file read_proj_file(projFile, &pps, &proj_type, &datum, &spheroid); // Check whether UTM projection has a zone defined if (proj_type == UNIVERSAL_TRANSVERSE_MERCATOR && (pps.utm.zone < 0 || pps.utm.zone > 60)) asfPrintError("Undefined zone for UTM projection\n"); // Report the conversion type if (proj_type == ALBERS_EQUAL_AREA) printf("Albers Equal Area to Lat/Lon\n\n"); else if (proj_type == LAMBERT_AZIMUTHAL_EQUAL_AREA) printf("Lambert Azimuthal Equal Area to Lat/Lon\n\n"); else if (proj_type == LAMBERT_CONFORMAL_CONIC) printf("Lambert Conformal Conic to Lat/Lon\n\n"); else if (proj_type == POLAR_STEREOGRAPHIC) printf("Polar Stereographic to Lat/Lon\n\n"); else if (proj_type == UNIVERSAL_TRANSVERSE_MERCATOR) printf("UTM to Lat/Lon\n\n"); // Initialize meta_projection block meta_proj = meta_projection_init(); meta_proj->type = proj_type; meta_proj->datum = datum; meta_proj->param = pps; // Read coordinates from list if needed and convert to map coordinates if (listFlag) { fp = FOPEN(listFile, "r"); while (fgets(line, 255, fp) != NULL) { if (strlen(line) > 1) { double junk_height; sscanf(line, "%lf %lf", &projX, &projY); proj_to_latlon(meta_proj, projX, projY, 0.0, &lat, &lon, &junk_height); printf("%.3lf\t%.3lf\t%.4lf\t%.4lf\n", projX, projY, lat*R2D, lon*R2D); } } FCLOSE(fp); } else { double junk_height; proj_to_latlon(meta_proj, projX, projY, 0.0, &lat, &lon, &junk_height); printf("%.3lf\t%.3lf\t%.4lf\t%.4lf\n", projX, projY, lat*R2D, lon*R2D); } printf("\n"); return 0; }
/******************************************************************* * meta_get_latLon: * Converts given line and sample to geodetic latitude and longitude. * Works with all image types.*/ int meta_get_latLon(meta_parameters *meta, double yLine, double xSample,double elev, double *lat,double *lon) { double hgt; if (meta->projection) { /*Map-Projected. Use projection information to calculate lat & lon.*/ double px,py,pz=0.0; px = meta->projection->startX + ((xSample + meta->general->start_sample) * meta->projection->perX); py = meta->projection->startY + ((yLine + meta->general->start_line) * meta->projection->perY); /*Currently have to handle scansar separately, because it depends on a lot more info than the other projections */ if (meta->projection->type == SCANSAR_PROJECTION) { scan_to_latlon(meta, px, py, elev, lat, lon, &hgt); } else { proj_to_latlon(meta->projection, px, py, pz, lat, lon, &hgt); *lat *= R2D; *lon *= R2D; } } else if (meta->airsar) { double l = yLine, s = xSample; if (meta->sar) { l = meta->general->start_line + meta->general->line_scaling * yLine; s = meta->general->start_sample + meta->general->sample_scaling * xSample; } airsar_to_latlon(meta, s, l, elev, lat, lon); } else if (meta->uavsar) { double l = yLine, s = xSample; if (meta->sar) { l = meta->general->start_line + meta->general->line_scaling * yLine; s = meta->general->start_sample + meta->general->sample_scaling * xSample; } uavsar_to_latlon(meta, s, l, elev, lat, lon); } else if (meta->latlon) { int nLine = (int)(yLine + 0.5); int nSample = (int)(xSample + 0.5); int sample_count = meta->general->sample_count; *lat = meta->latlon->lat[nLine*sample_count + nSample]; *lon = meta->latlon->lon[nLine*sample_count + nSample]; } else if (meta->transform) { /* ALOS data (not projected) -- use transform block */ double l = yLine, s = xSample; if (meta->sar) { s = meta->general->start_sample + meta->general->sample_scaling * s; l = meta->general->start_line + meta->general->line_scaling * l; } if (meta->sar && meta->sar->image_type == 'G' && strcmp_case(meta->transform->type, "slant") == 0) { // map s (sample) value from Ground to Slant double new_s = map_gr2sr(meta, l, s); //printf("meta_get_latLon -- mapped gr to sr: %f -> %f\n", s, new_s); s = new_s; } else if (meta->sar && meta->sar->image_type == 'S' && strcmp_case(meta->transform->type, "ground") == 0) { // not implemented, don't think we need this? asfPrintError("meta_get_latLon: ground transform block " "with a slant range image.\n"); double new_s = map_sr2gr(meta, l, s); //printf("meta_get_latLon -- mapped sr to gr: %f -> %f\n", s, new_s); s = new_s; } alos_to_latlon(meta, s, l, elev, lat, lon, &hgt); //printf("alos_to_latlon: %f, %f ==> %f, %f\n", l, s, *lat, *lon); } else if (meta->sar && (meta->sar->image_type=='S' || meta->sar->image_type=='G')) { /*Slant or ground range. Use state vectors and doppler.*/ double slant,doppler,time; meta_get_timeSlantDop(meta,yLine,xSample,&time,&slant,&doppler); meta_timeSlantDop2latLon(meta, time,slant,doppler,elev, lat,lon); } else if (meta->location) { double l = yLine, s = xSample; if (meta->sar) { l = meta->general->start_line + meta->general->line_scaling * yLine; s = meta->general->start_sample + meta->general->sample_scaling * xSample; } location_to_latlon(meta, s, l, elev, lat, lon, &hgt); } else { /*Bogus image type.*/ asfPrintError( "meta_get_latLon: Couldn't figure out what kind of image this is!\n" "meta->transform = %p, so it isn't ALOS.\n" "meta->sar = %p, and it isn't Slant/Ground range.\n" "meta->projection = %p, so it isn't Projected, or Scansar.\n" "meta->location = %p, so doesn't have location information.\n" "meta->general->name: %s\n", meta->transform, meta->sar, meta->projection, meta->location, meta->general ? meta->general->basename : "(null)"); return 1; /* Not Reached */ } //if (*lon < -180) *lon += 360; //if (*lon > 180) *lon -= 360; return 0; }
int main(int argc, char **argv) { FILE *fpIn, *fpOut, *fpInList, *fpOutList, *fpXml; meta_parameters *meta; extern int currArg; /* from cla.h in asf.h... initialized to 1 */ logflag = 0; // Parse command line args while (currArg < (argc-2)) { char *key=argv[currArg++]; if (strmatch(key,"-log")) { sprintf(logFile, "%s", argv[currArg]); logflag = 1; } else { printf("\n ***Invalid option: %s\n\n", argv[currArg-1]); usage(argv[0]); } } if ((argc-currArg) < 2) { printf("Insufficient arguments.\n"); usage(argv[0]); } asfSplashScreen(argc, argv); char *listInFile = (char *) MALLOC(sizeof(char)*(strlen(argv[1])+1)); strcpy(listInFile, argv[1]); char *outFile = (char *) MALLOC(sizeof(char)*(strlen(argv[2])+1)); strcpy(outFile, argv[2]); // Setup file names char outDirName[512], outFileName[512]; split_dir_and_file(outFile, outDirName, outFileName); char *tmpDir = (char *) MALLOC(sizeof(char)*512); sprintf(tmpDir, "%smeasures-", outDirName); char *tsdir = time_stamp_dir(); strcat(tmpDir, tsdir); FREE(tsdir); create_clean_dir(tmpDir); char *isoStr = iso_date(); // Read header information char inFile[512], imgFile[768], metaFile[768]; char listOutFile[768], citation[50], start[30], end[30], first[30]; char header[120], baseName[512], dirName[512], ext[5]; float x_pix, y_pix, x_map_ll, y_map_ll, x_map_ur, y_map_ur, inc, cat; double lat, lon, height, x, y, z; int ii, kk, nFiles=0, num = 1, sample_count, line_count; image_data_type_t image_data_type; sprintf(listOutFile, "%s%crgps.xml", tmpDir, DIR_SEPARATOR); // Preparing map projection information project_parameters_t pps; projection_type_t proj_type; datum_type_t datum; spheroid_type_t spheroid; read_proj_file("polar_stereographic_north_ssmi.proj", &pps, &proj_type, &datum, &spheroid); pps.ps.false_easting = 0.0; pps.ps.false_northing = 0.0; meta_projection *proj = meta_projection_init(); proj->type = proj_type; proj->datum = HUGHES_DATUM; proj->spheroid = HUGHES_SPHEROID; proj->param = pps; strcpy(proj->units, "meters"); proj->hem = 'N'; spheroid_axes_lengths(spheroid, &proj->re_major, &proj->re_minor); FREE(proj); // Set up supplemental file names: water mask, lat/lon, x/y grids char maskFile[768], latFile[768], lonFile[768], xFile[768], yFile[768]; sprintf(maskFile, "%s%cwater_mask.img", tmpDir, DIR_SEPARATOR); sprintf(latFile, "%s%clatitude.img", tmpDir, DIR_SEPARATOR); sprintf(lonFile, "%s%clongitude.img", tmpDir, DIR_SEPARATOR); sprintf(xFile, "%s%cxgrid.img", tmpDir, DIR_SEPARATOR); sprintf(yFile, "%s%cygrid.img", tmpDir, DIR_SEPARATOR); // Generating output XML file fpInList = FOPEN(listInFile, "r"); fpOutList = FOPEN(listOutFile, "w"); fprintf(fpOutList, "<netcdf>\n"); fprintf(fpOutList, " <data>\n"); fprintf(fpOutList, " <latitude>%s</latitude>\n", latFile); fprintf(fpOutList, " <longitude>%s</longitude>\n", lonFile); fprintf(fpOutList, " <xgrid>%s</xgrid>\n", xFile); fprintf(fpOutList, " <ygrid>%s</ygrid>\n", yFile); fprintf(fpOutList, " <mask>%s</mask>\n", maskFile); julian_date jdStart, jdEnd, jdRef; hms_time hms; hms.hour = 0; hms.min = 0; hms.sec = 0.0; asfPrintStatus("Working through the file list:\n"); int myrFlag=FALSE, divFlag=FALSE, vrtFlag=FALSE, shrFlag=FALSE; int firstYear, firstDay, startYear, startDay, endYear, endDay; double westBoundLon, eastBoundLon, northBoundLat, southBoundLat; double minLat=90.0, maxLat=-90.0, minLon=180.0, maxLon=-180.0; while (fgets(inFile, 512, fpInList)) { chomp(inFile); char inDirName[512], inFileName[512]; split_dir_and_file(inFile, inDirName, inFileName); // Preparing map projection information project_parameters_t pps; projection_type_t proj_type; datum_type_t datum; spheroid_type_t spheroid; read_proj_file("polar_stereographic_north_ssmi.proj", &pps, &proj_type, &datum, &spheroid); pps.ps.false_easting = 0.0; pps.ps.false_northing = 0.0; meta_projection *proj = meta_projection_init(); proj->type = proj_type; proj->datum = HUGHES_DATUM; proj->spheroid = HUGHES_SPHEROID; proj->param = pps; strcpy(proj->units, "meters"); proj->hem = 'N'; spheroid_axes_lengths(spheroid, &proj->re_major, &proj->re_minor); // Sort out dates startYear = subInt(inFileName, 0, 4); startDay = subInt(inFileName, 4, 3); endYear = subInt(inFileName, 8, 4); endDay = subInt(inFileName, 12, 3); if (nFiles == 0) { firstYear = startYear; firstDay = startDay; } sprintf(citation, "%d%03d to %d%03d", startYear, startDay, endYear, endDay); rgps2iso_date(startYear, (double) startDay, start); rgps2iso_date(endYear, (double) endDay, end); rgps2iso_date(firstYear, (double) firstDay, first); // Read header information FILE *fpIn = FOPEN(inFile, "r"); fgets(header, 100, fpIn); sscanf(header, "%f %f %f %f %f %f", &x_pix, &y_pix, &x_map_ll, &y_map_ll, &x_map_ur, &y_map_ur); fgets(header, 100, fpIn); int params = sscanf(header, "%f %f %d %d", &inc, &cat, &sample_count, &line_count); if (params == 3) { sscanf(header, "%f %d %d", &cat, &sample_count, &line_count); inc = 0; } else if (params == 2) { sscanf(header, "%d %d", &sample_count, &line_count); inc = 0; cat = 1; } num = (int) cat; if (num > 1) asfPrintError("Multiband imagery (%s) not supported for netCDF " "generation!\n", inFile); /* printf("x_pix: %f, y_pix: %f\n", x_pix, y_pix); printf("x_map_ll: %f, y_map_ll: %f\n", x_map_ll, y_map_ll); printf("x_map_ur: %f, y_map_ur: %f\n", x_map_ur, y_map_ur); printf("sample_count: %d, line_count: %d\n\n", sample_count, line_count); */ // Check extension split_base_and_ext(inFileName, 1, '.', baseName, ext); asfPrintStatus("Processing %s ...\n", inFileName); sprintf(imgFile, "%s%c%s_%s.img", tmpDir, DIR_SEPARATOR, baseName, &ext[1]); sprintf(metaFile, "%s%c%s_%s.meta", tmpDir, DIR_SEPARATOR, baseName, &ext[1]); jdRef.year = firstYear; jdRef.jd = 1; jdStart.year = startYear; jdStart.jd = startDay; jdEnd.year = endYear; jdEnd.jd = endDay; double startSec = date2sec(&jdStart, &hms) - date2sec(&jdRef, &hms); double endSec = date2sec(&jdEnd, &hms) - date2sec(&jdRef, &hms); if (strcmp_case(ext, ".MYR") == 0) { fprintf(fpOutList, " <multiyear_ice_fraction start=\"%.0f\" end=\"%.0f" "\">%s</multiyear_ice_fraction>\n", startSec, endSec, imgFile); image_data_type = MULTIYEAR_ICE_FRACTION; myrFlag = TRUE; } else if (strcmp_case(ext, ".DIV") == 0) { fprintf(fpOutList, " <divergence start=\"%.0f\" end=\"%.0f\">%s" "</divergence>\n", startSec, endSec, imgFile); image_data_type = DIVERGENCE; divFlag = TRUE; } else if (strcmp_case(ext, ".VRT") == 0) { fprintf(fpOutList, " <vorticity start=\"%.0f\" end=\"%.0f\">%s" "</vorticity>\n", startSec, endSec, imgFile); image_data_type = VORTICITY; vrtFlag = TRUE; } else if (strcmp_case(ext, ".SHR") == 0) { fprintf(fpOutList, " <shear start=\"%.0f\" end=\"%.0f\">%s</shear>", startSec, endSec, imgFile); image_data_type = SHEAR; shrFlag = TRUE; } // Generate basic metadata meta = raw_init(); meta->general->line_count = line_count; meta->general->sample_count = sample_count; meta->general->band_count = 1; meta->general->data_type = REAL32; meta->general->image_data_type = image_data_type; strcpy(meta->general->basename, inFile); meta->general->x_pixel_size = x_pix*1000.0; meta->general->y_pixel_size = y_pix*1000.0; meta->general->start_line = 0; meta->general->start_sample = 0; meta->general->no_data = MAGIC_UNSET_DOUBLE; strcpy(meta->general->sensor, "RGPS MEaSUREs"); char *tmp = image_data_type2str(meta->general->image_data_type); sprintf(meta->general->bands, "%s", lc(tmp)); FREE(tmp); sprintf(meta->general->acquisition_date, "%s", baseName); // Sort out map projection proj->startX = x_map_ll*1000.0; proj->startY = y_map_ur*1000.0; proj->perX = x_pix*1000.0; proj->perY = -y_pix*1000.0; meta->projection = proj; meta_write(meta, metaFile); strcpy(meta->general->bands, "water mask"); sprintf(metaFile, "%s%cwater_mask.meta", tmpDir, DIR_SEPARATOR); meta_write(meta, metaFile); sprintf(metaFile, "%s%c%s_%s.meta", tmpDir, DIR_SEPARATOR, baseName, &ext[1]); float *floatBuf = (float *) MALLOC(sizeof(float)*sample_count); // Write gridded data to ASF internal format fpOut = FOPEN(imgFile, "wb"); for (ii=0; ii<line_count; ii++) { for (kk=0; kk<sample_count; kk++) { ASF_FREAD(&floatBuf[kk], sizeof(float), 1, fpIn); ieee_big32(floatBuf[kk]); if (floatBuf[kk] > 10000000000.0 || FLOAT_EQUIVALENT(floatBuf[kk], 10000000000.0)) floatBuf[kk] = MAGIC_UNSET_DOUBLE; } put_float_line(fpOut, meta, line_count-ii-1, floatBuf); } FCLOSE(fpOut); FREE(floatBuf); double lat1, lon1, lat2, lon2, lat3, lon3, lat4, lon4; proj_to_latlon(proj, x_map_ll*1000.0, y_map_ll*1000.0, 0.0, &lat1, &lon1, &height); proj_to_latlon(proj, x_map_ll*1000.0, y_map_ur*1000.0, 0.0, &lat2, &lon2, &height); proj_to_latlon(proj, x_map_ur*1000.0, y_map_ur*1000.0, 0.0, &lat3, &lon3, &height); proj_to_latlon(proj, x_map_ur*1000.0, y_map_ll*1000.0, 0.0, &lat4, &lon4, &height); westBoundLon = minValue(lon1*R2D, lon2*R2D, lon3*R2D, lon4*R2D); eastBoundLon = maxValue(lon1*R2D, lon2*R2D, lon3*R2D, lon4*R2D); northBoundLat = maxValue(lat1*R2D, lat2*R2D, lat3*R2D, lat4*R2D); southBoundLat = minValue(lat1*R2D, lat2*R2D, lat3*R2D, lat4*R2D); if (westBoundLon < minLon) minLon = westBoundLon; if (eastBoundLon > maxLon) maxLon = eastBoundLon; if (southBoundLat < minLat) minLat = southBoundLat; if (northBoundLat > maxLat) maxLat = northBoundLat; meta_free(meta); nFiles++; } FCLOSE(fpInList); fprintf(fpOutList, " </data>\n"); fprintf(fpOutList, " <metadata>\n"); fprintf(fpOutList, " <time>\n"); fprintf(fpOutList, " <axis type=\"string\" definition=\"name of axis\">T" "</axis>\n"); fprintf(fpOutList, " <long_name type=\"string\" definition=\"long " "descriptive name\">serial date</long_name>\n"); fprintf(fpOutList, " <references type=\"string\" definition=\"reference " "of the value\">start time of 3-day average</references>\n"); fprintf(fpOutList, " <standard_name type=\"string\" definition=\"name " "used to identify the physical quantity\">time</standard_name>\n"); fprintf(fpOutList, " <units type=\"string\" definition=\"unit of " "dimensional quantity\">seconds since %d-01-01T00:00:00Z</units>\n", firstYear); fprintf(fpOutList, " <bounds type=\"string\" definition=\"variable " "containing data range\">time_bounds</bounds>\n"); fprintf(fpOutList, " <FillValue type=\"double\" definition=\"default " "value\">0</FillValue>\n"); fprintf(fpOutList, " </time>\n"); fprintf(fpOutList, " <time_bounds>\n"); fprintf(fpOutList, " <long_name type=\"string\" definition=\"long " "descriptive name\">serial date</long_name>\n"); fprintf(fpOutList, " <references type=\"string\" definition=\"reference " "of the value\">start and end time of 3-day average</references>\n"); fprintf(fpOutList, " <standard_name type=\"string\" definition=\"name " "used to identify the physical quantity\">time</standard_name>\n"); fprintf(fpOutList, " <units type=\"string\" definition=\"unit of " "dimensional quantity\">seconds since %d-01-01T00:00:00Z</units>\n", firstYear); fprintf(fpOutList, " <FillValue type=\"double\" definition=\"default " "value\">0</FillValue>\n"); fprintf(fpOutList, " </time_bounds>\n"); fprintf(fpOutList, " <latitude>\n"); fprintf(fpOutList, " <long_name type=\"string\" definition=\"long " "descriptive name\">latitude</long_name>\n"); fprintf(fpOutList, " <standard_name type=\"string\" definition=\"name " "used to identify the physical quantity\">latitude</standard_name>\n"); fprintf(fpOutList, " <units type=\"string\" definition=\"unit of " "dimensional quantity\">degrees_north</units>\n"); fprintf(fpOutList, " <FillValue type=\"float\" definition=\"default " "value\">-999</FillValue>\n"); fprintf(fpOutList, " <valid_min type=\"float\" definition=\"minimum " "valid value\">-90.0</valid_min>\n"); fprintf(fpOutList, " <valid_max type=\"float\" definition=\"minimum " "valid value\">90.0</valid_max>\n"); fprintf(fpOutList, " </latitude>\n"); fprintf(fpOutList, " <longitude>\n"); fprintf(fpOutList, " <long_name type=\"string\" definition=\"long " "descriptive name\">longitude</long_name>\n"); fprintf(fpOutList, " <standard_name type=\"string\" definition=\"name " "used to identify the physical quantity\">longitude</standard_name>\n"); fprintf(fpOutList, " <units type=\"string\" definition=\"unit of " "dimensional quantity\">degrees_east</units>\n"); fprintf(fpOutList, " <FillValue type=\"float\" definition=\"default " "value\">-999</FillValue>\n"); fprintf(fpOutList, " <valid_min type=\"float\" definition=\"minimum " "valid value\">-180.0</valid_min>\n"); fprintf(fpOutList, " <valid_max type=\"float\" definition=\"minimum " "valid value\">180.0</valid_max>\n"); fprintf(fpOutList, " </longitude>\n"); fprintf(fpOutList, " <xgrid>\n"); fprintf(fpOutList, " <axis type=\"string\" definition=\"name of axis\">X" "</axis>\n"); fprintf(fpOutList, " <long_name type=\"string\" definition=\"long " "descriptive name\">projection_grid_x_center</long_name>\n"); fprintf(fpOutList, " <standard_name type=\"string\" definition=\"name " "used to identify the physical quantity\">projection_x_coordinate" "</standard_name>\n"); fprintf(fpOutList, " <units type=\"string\" definition=\"unit of " "dimensional quantity\">meters</units>\n"); fprintf(fpOutList, " <FillValue type=\"float\" definition=\"default " "value\">NaN</FillValue>\n"); fprintf(fpOutList, " </xgrid>\n"); fprintf(fpOutList, " <ygrid>\n"); fprintf(fpOutList, " <axis type=\"string\" definition=\"name of axis\">Y" "</axis>\n"); fprintf(fpOutList, " <long_name type=\"string\" definition=\"long " "descriptive name\">projection_grid_y_center</long_name>\n"); fprintf(fpOutList, " <standard_name type=\"string\" definition=\"name " "used to identify the physical quantity\">projection_y_coordinate" "</standard_name>\n"); fprintf(fpOutList, " <units type=\"string\" definition=\"unit of " "dimensional quantity\">meters</units>\n"); fprintf(fpOutList, " <FillValue type=\"float\" definition=\"default " "value\">NaN</FillValue>\n"); fprintf(fpOutList, " </ygrid>\n"); fprintf(fpOutList, " <Polar_Stereographic>\n"); fprintf(fpOutList, " <grid_mapping_name>polar_stereographic" "</grid_mapping_name>\n"); fprintf(fpOutList, " <straight_vertical_longitude_from_pole>%.1f" "</straight_vertical_longitude_from_pole>\n", pps.ps.slon); fprintf(fpOutList, " <longitude_of_central_meridian>90.0" "</longitude_of_central_meridian>\n"); fprintf(fpOutList, " <standard_parallel>%.1f</standard_parallel>\n", pps.ps.slat); fprintf(fpOutList, " <false_easting>%.1f</false_easting>\n", pps.ps.false_easting); fprintf(fpOutList, " <false_northing>%.1f</false_northing>\n", pps.ps.false_northing); fprintf(fpOutList, " <projection_x_coordinate>xgrid" "</projection_x_coordinate>\n"); fprintf(fpOutList, " <projection_y_coordinate>ygrid" "</projection_y_coordinate>\n"); fprintf(fpOutList, " <units>meters</units>\n"); fprintf(fpOutList, " </Polar_Stereographic>\n"); fprintf(fpOutList, " <mask>\n"); fprintf(fpOutList, " <coordinates type=\"string\" definition=\"" "coordinate reference\">ygrid xgrid</coordinates>\n"); fprintf(fpOutList, " <grid_mapping type=\"string\" definition=\"\">" "Polar_Stereographic</grid_mapping>\n"); fprintf(fpOutList, " <long_name type=\"string\" definition=\"long " "descriptive name\">projection_grid_y_center</long_name>\n"); fprintf(fpOutList, " <units type=\"string\" definition=\"unit of " "dimensional quantity\">1</units>\n"); fprintf(fpOutList, " <units_description type=\"string\" definition=\"" "descriptive information about dimensionless quantity\">unitless" "</units_description>\n"); fprintf(fpOutList, " <FillValue type=\"int\" definition=\"default " "value\">0</FillValue>\n"); fprintf(fpOutList, " </mask>\n"); if (myrFlag) { fprintf(fpOutList, " <multiyear_ice_fraction>\n"); fprintf(fpOutList, " <cell_methods type=\"string\" definition=\"" "characteristic of a field that is represented by cell values\">area: " "multiyear ice fraction value</cell_methods>\n"); fprintf(fpOutList, " <coordinates type=\"string\" definition=\"" "coordinate reference\">ygrid xgrid</coordinates>\n"); fprintf(fpOutList, " <grid_mapping type=\"string\" definition=\"\">" "Polar_Stereographic</grid_mapping>\n"); fprintf(fpOutList, " <long_name type=\"string\" definition=\"long " "descriptive name\">RGPS MEaSUREs multiyear ice fraction</long_name>\n"); fprintf(fpOutList, " <units type=\"string\" definition=\"unit of " "dimensional quantity\">1</units>\n"); fprintf(fpOutList, " <units_description type=\"string\" definition=\"" "descriptive information about dimensionless quantity\">unitless" "</units_description>\n"); fprintf(fpOutList, " <FillValue type=\"float\" definition=\"default " "value\">NaN</FillValue>\n"); fprintf(fpOutList, " </multiyear_ice_fraction>\n"); } if (divFlag) { fprintf(fpOutList, " <divergence>\n"); fprintf(fpOutList, " <cell_methods type=\"string\" definition=\"" "characteristic of a field that is represented by cell values\">area: " "divergence value</cell_methods>\n"); fprintf(fpOutList, " <coordinates type=\"string\" definition=\"" "coordinate reference\">ygrid xgrid</coordinates>\n"); fprintf(fpOutList, " <grid_mapping type=\"string\" definition=\"\">" "Polar_Stereographic</grid_mapping>\n"); fprintf(fpOutList, " <long_name type=\"string\" definition=\"long " "descriptive name\">RGPS MEaSUREs divergence</long_name>\n"); fprintf(fpOutList, " <units type=\"string\" definition=\"unit of " "dimensional quantity\">1</units>\n"); fprintf(fpOutList, " <units_description type=\"string\" definition=\"" "descriptive information about dimensionless quantity\">unitless" "</units_description>\n"); fprintf(fpOutList, " <FillValue type=\"float\" definition=\"default " "value\">NaN</FillValue>\n"); fprintf(fpOutList, " </divergence>\n"); } if (vrtFlag) { fprintf(fpOutList, " <vorticity>\n"); fprintf(fpOutList, " <cell_methods type=\"string\" definition=\"" "characteristic of a field that is represented by cell values\">area: " "vorticity value</cell_methods>\n"); fprintf(fpOutList, " <coordinates type=\"string\" definition=\"" "coordinate reference\">ygrid xgrid</coordinates>\n"); fprintf(fpOutList, " <grid_mapping type=\"string\" definition=\"\">" "Polar_Stereographic</grid_mapping>\n"); fprintf(fpOutList, " <long_name type=\"string\" definition=\"long " "descriptive name\">RGPS MEaSUREs vorticity</long_name>\n"); fprintf(fpOutList, " <units type=\"string\" definition=\"unit of " "dimensional quantity\">1</units>\n"); fprintf(fpOutList, " <units_description type=\"string\" definition=\"" "descriptive information about dimensionless quantity\">unitless" "</units_description>\n"); fprintf(fpOutList, " <FillValue type=\"float\" definition=\"default " "value\">NaN</FillValue>\n"); fprintf(fpOutList, " </vorticity>\n"); } if (shrFlag) { fprintf(fpOutList, " <shear>\n"); fprintf(fpOutList, " <cell_methods type=\"string\" definition=\"" "characteristic of a field that is represented by cell values\">area: " "shear value</cell_methods>\n"); fprintf(fpOutList, " <coordinates type=\"string\" definition=\"" "coordinate reference\">ygrid xgrid</coordinates>\n"); fprintf(fpOutList, " <grid_mapping type=\"string\" definition=\"\">" "Polar_Stereographic</grid_mapping>\n"); fprintf(fpOutList, " <long_name type=\"string\" definition=\"long " "descriptive name\">RGPS MEaSUREs shear</long_name>\n"); fprintf(fpOutList, " <units type=\"string\" definition=\"unit of " "dimensional quantity\">1</units>\n"); fprintf(fpOutList, " <units_description type=\"string\" definition=\"" "descriptive information about dimensionless quantity\">unitless" "</units_description>\n"); fprintf(fpOutList, " <FillValue type=\"float\" definition=\"default " "value\">NaN</FillValue>\n"); fprintf(fpOutList, " </shear>\n"); } fprintf(fpOutList, " </metadata>\n"); fprintf(fpOutList, " <parameter>\n"); if (myrFlag) fprintf(fpOutList, " <multiyear_ice_fraction type=\"float\"/>\n"); if (divFlag) fprintf(fpOutList, " <divergence type=\"float\"/>\n"); if (vrtFlag) fprintf(fpOutList, " <vorticity type=\"float\"/>\n"); if (shrFlag) fprintf(fpOutList, " <shear type=\"float\"/>\n"); fprintf(fpOutList, " </parameter>\n"); char startStr[15], endStr[15]; jdStart.year = firstYear; jdStart.jd = firstDay; jdEnd.year = endYear; jdEnd.jd = endDay; jd2date(&jdStart, startStr); jd2date(&jdEnd, endStr); if (firstYear != endYear || firstDay != endDay) sprintf(citation, "%s to %s", startStr, endStr); else sprintf(citation, "%s", startStr); fprintf(fpOutList, " <root>\n"); fprintf(fpOutList, " <Conventions>CF-1.6</Conventions>\n"); fprintf(fpOutList, " <institution>Alaska Satellite Facility</institution>\n"); fprintf(fpOutList, " <title>Kwok, Ron. 2008. MEaSUREs Small-Scale Kinematics" " of Arctic Ocean Sea Ice, Version 01, %s. Jet Propulsion Laboratory " "Pasadena, CA USA and Alaska Satellite Facility Fairbanks, AK USA. " "Digital media.</title>\n", citation); fprintf(fpOutList, " <source>Products derived from RADARSAT-1 SWB imagery at " "100 m resolution</source>\n"); fprintf(fpOutList, " <comment>Imagery the products are derived from: Copyright " "Canadian Space Agency (1996 to 2008)</comment>\n"); fprintf(fpOutList, " <reference>Documentation available at: www.asf.alaska.edu" "</reference>\n"); fprintf(fpOutList, " <history>%s: netCDF file created.</history>\n", isoStr); fprintf(fpOutList, " </root>\n"); fprintf(fpOutList, "</netcdf>\n"); FCLOSE(fpOutList); // Generate supplemental files: water mask, lat/lon, x/y grids asfPrintStatus("Generating supplemental files ...\n"); float *floatBuf = (float *) MALLOC(sizeof(float)*sample_count); float *maskBuf = (float *) MALLOC(sizeof(float)*sample_count); float *latBuf = (float *) MALLOC(sizeof(float)*sample_count); float *lonBuf = (float *) MALLOC(sizeof(float)*sample_count); float *xBuf = (float *) MALLOC(sizeof(float)*sample_count); float *yBuf = (float *) MALLOC(sizeof(float)*sample_count); meta = meta_read(metaFile); fpIn = FOPEN(inFile, "r"); fgets(header, 100, fpIn); sscanf(header, "%f %f %f %f %f %f", &x_pix, &y_pix, &x_map_ll, &y_map_ll, &x_map_ur, &y_map_ur); fgets(header, 100, fpIn); sscanf(header, "%d %d", &sample_count, &line_count); FILE *fpMask = FOPEN(maskFile, "wb"); FILE *fpLat = FOPEN(latFile, "wb"); FILE *fpLon = FOPEN(lonFile, "wb"); FILE *fpXgrid = FOPEN(xFile, "wb"); FILE *fpYgrid = FOPEN(yFile, "wb"); for (ii=0; ii<line_count; ii++) { for (kk=0; kk<sample_count; kk++) { ASF_FREAD(&floatBuf[kk], sizeof(float), 1, fpIn); ieee_big32(floatBuf[kk]); } for (kk=0; kk<sample_count; kk++) { meta_get_latLon(meta, line_count-ii-1, kk, 0.0, &lat, &lon); latlon_to_proj(meta->projection, 'R', lat*D2R, lon*D2R, 0.0, &x, &y, &z); latBuf[kk] = lat; lonBuf[kk] = lon; xBuf[kk] = x; yBuf[kk] = y; if (floatBuf[kk] < 10000000000.0) { maskBuf[kk] = 1.0; } else if (floatBuf[kk] > 10000000000.0) { maskBuf[kk] = 1.0; } else { maskBuf[kk] = 0.0; } } put_float_line(fpMask, meta, line_count-ii-1, maskBuf); put_float_line(fpLat, meta, line_count-ii-1, latBuf); put_float_line(fpLon, meta, line_count-ii-1, lonBuf); put_float_line(fpXgrid, meta, line_count-ii-1, xBuf); put_float_line(fpYgrid, meta, line_count-ii-1, yBuf); } FCLOSE(fpIn); FCLOSE(fpMask); FCLOSE(fpLat); FCLOSE(fpLon); FREE(floatBuf); FREE(maskBuf); FREE(latBuf); FREE(lonBuf); FREE(xBuf); FREE(yBuf); meta_write(meta, latFile); meta_write(meta, lonFile); meta_write(meta, xFile); meta_write(meta, yFile); // Write ISO meatadata for netCDF asfPrintStatus("Generating metadata for netCDF file ...\n"); char *ncXmlBase = get_basename(outFile); char *ncXmlFile = appendExt(outFile, ".xml"); fpXml = FOPEN(ncXmlFile, "w"); fprintf(fpXml, "<rgps>\n"); fprintf(fpXml, " <granule>%s</granule>\n", ncXmlBase); fprintf(fpXml, " <metadata_creation>%s</metadata_creation>\n", isoStr); fprintf(fpXml, " <metadata>\n"); fprintf(fpXml, " <product>\n"); fprintf(fpXml, " <file type=\"string\" definition=\"name of product " "file\">%s.nc</file>\n", ncXmlBase); if (divFlag && vrtFlag && shrFlag) fprintf(fpXml, " <type type=\"string\" definition=\"product type\">" "divergence, vorticity, shear</type>\n"); else if (myrFlag) fprintf(fpXml, " <type type=\"string\" definition=\"product type\">" "multiyear ice fraction</type>\n"); fprintf(fpXml, " <format type=\"string\" definition=\"name of the data " "format\">netCDF</format>\n"); fpInList = FOPEN(listInFile, "r"); while (fgets(inFile, 512, fpInList)) { chomp(inFile); split_dir_and_file(inFile, dirName, baseName); fprintf(fpXml, " <source type=\"string\" definition=\"name of the data" " source\">%s</source>\n", baseName); } FCLOSE(fpInList); fprintf(fpXml, " <cell_size_x type=\"double\" definition=\"cell size " "in x direction\" units=\"m\">%.2f</cell_size_x>\n", x_pix*1000.0); fprintf(fpXml, " <cell_size_y type=\"double\" definition=\"cell size " "in y direction\" units=\"m\">%.2f</cell_size_y>\n", y_pix*1000.0); fprintf(fpXml, " <map_x_lower_left type=\"double\" definition=\"x " "coordinate of lower left corner\" units=\"m\">%.6f</map_x_lower_left>\n", x_map_ll*1000.0); fprintf(fpXml, " <map_y_lower_left type=\"double\" definition=\"y " "coordinate of lower left corner\" units=\"m\">%.6f</map_y_lower_left>\n", y_map_ll*1000.0); fprintf(fpXml, " <map_x_upper_right type=\"double\" definition=\"x " "coordinate of upper right corner\" units=\"m\">%.6f</map_x_upper_right>" "\n", x_map_ur*1000.0); fprintf(fpXml, " <map_y_upper_right type=\"double\" definition=\"y " "coordinate of upper right corner\" units=\"m\">%.6f</map_y_upper_right>" "\n", y_map_ur*1000.0); fprintf(fpXml, " <cell_dimension_x type=\"int\" definition=\"cell " "dimension in x direction\">%d</cell_dimension_x>\n", sample_count); fprintf(fpXml, " <cell_dimension_y type=\"int\" definition=\"cell " "dimension in y direction\">%d</cell_dimension_y>\n", line_count); fprintf(fpXml, " <projection_string type=\"string\" definition=\"map " "projection information as well known text\">%s</projection_string>\n", meta2esri_proj(meta, NULL)); fprintf(fpXml, " </product>\n"); fprintf(fpXml, " </metadata>\n"); fprintf(fpXml, " <extent>\n"); fprintf(fpXml, " <product>\n"); fprintf(fpXml, " <westBoundLongitude>%.5f</westBoundLongitude>\n", minLon); fprintf(fpXml, " <eastBoundLongitude>%.5f</eastBoundLongitude>\n", maxLon); fprintf(fpXml, " <northBoundLatitude>%.5f</northBoundLatitude>\n", maxLat); fprintf(fpXml, " <southBoundLatitude>%.5f</southBoundLatitude>\n", minLat); fprintf(fpXml, " <start_datetime>%s</start_datetime>\n", first); fprintf(fpXml, " <end_datetime>%s</end_datetime>\n", end); fprintf(fpXml, " </product>\n"); fprintf(fpXml, " </extent>\n"); fprintf(fpXml, "</rgps>\n"); FCLOSE(fpXml); FREE(ncXmlBase); FREE(ncXmlFile); meta_free(meta); // Export to netCDF asfPrintStatus("Exporting to netCDF file ...\n"); export_netcdf_xml(listOutFile, outFile); // Clean up remove_dir(tmpDir); FREE(tmpDir); FREE(outFile); FREE(listInFile); FREE(isoStr); return 0; }
meta_parameters* envi2meta(envi_header *envi) { meta_parameters *meta; /* Allocate memory for metadata structure */ meta = raw_init(); /* Fill metadata with valid ENVI header data */ strcpy(meta->general->basename, envi->description); strcpy(meta->general->sensor, envi->sensor_type); meta->general->line_count = envi->lines; meta->general->sample_count = envi->samples; // We have to assume that we are not dealing with a subset. // Hence, the start line/sample are set to 0. meta->general->start_line = 0; meta->general->start_sample = 0; meta->general->band_count = envi->bands; strcpy(meta->general->bands, envi->band_name); meta->general->re_major = envi->semimajor_axis; meta->general->re_minor = envi->semiminor_axis; // Another assumption is that we are dealing with geocoded data that has // regular zero fill. meta->general->no_data = 0.0; switch (envi->data_type) { case 1: meta->general->data_type = ASF_BYTE; break; case 2: meta->general->data_type = INTEGER16; break; case 3: meta->general->data_type = INTEGER32; break; case 4: meta->general->data_type = REAL32; break; case 5: meta->general->data_type = REAL64; break; case 6: meta->general->data_type = COMPLEX_REAL32; break; default: sprintf(errbuf,"\n ERROR: Unsupported data type\n\n"); printErr(errbuf); break; } if (strncmp(envi->sensor_type, "RADARSAT", 8)==0) sprintf(meta->general->sensor, "RSAT-1"); else sprintf(meta->general->sensor, "%s", envi->sensor_type); if (strcmp(envi->projection, "not map projected") != 0) { if (!meta->projection) meta->projection = meta_projection_init(); if (strncmp(envi->projection, "UTM", 3)==0) { meta->projection->type = UNIVERSAL_TRANSVERSE_MERCATOR; meta->projection->param.utm.zone = envi->projection_zone; // Fill in the default values for UTM meta->projection->param.utm.false_easting = 500000.0; if (strcmp_case(envi->hemisphere, "NORTH") == 0) meta->projection->param.utm.false_northing = 0.0; else meta->projection->param.utm.false_northing = 10000000.0; meta->projection->param.utm.lat0 = 0.0; meta->projection->param.utm.lon0 = (double) (envi->projection_zone - 1) * 6.0 - 177.0; meta->projection->param.utm.scale_factor = 0.9996; } else if (strncmp(envi->projection, "Polar Stereographic", 18)==0) { meta->projection->type = POLAR_STEREOGRAPHIC; meta->projection->param.ps.slat = envi->center_lat; meta->projection->param.ps.slon = envi->center_lon; meta->projection->param.ps.is_north_pole = (envi->center_lat > 0) ? 1 : 0; meta->projection->param.ps.false_easting = envi->false_easting; meta->projection->param.ps.false_northing = envi->false_northing; } else if (strncmp(envi->projection, "Albers Conical Equal Area", 25)==0) { meta->projection->type = ALBERS_EQUAL_AREA; meta->projection->param.albers.std_parallel1 = envi->standard_parallel1; meta->projection->param.albers.std_parallel2 = envi->standard_parallel2; meta->projection->param.albers.center_meridian = envi->center_lon; meta->projection->param.albers.orig_latitude = envi->center_lat; meta->projection->param.albers.false_easting = envi->false_easting; meta->projection->param.albers.false_northing = envi->false_northing; } else if (strncmp(envi->projection, "Lambert Conformal Conic", 23)==0) { meta->projection->type = LAMBERT_CONFORMAL_CONIC; meta->projection->param.lamcc.plat1 = envi->standard_parallel1; meta->projection->param.lamcc.plat2 = envi->standard_parallel2; meta->projection->param.lamcc.lat0 = envi->center_lat; meta->projection->param.lamcc.lon0 = envi->center_lon; meta->projection->param.lamcc.false_easting = envi->false_easting; meta->projection->param.lamcc.false_northing = envi->false_northing; } else if (strncmp(envi->projection, "Lambert Azimuthal Equal Area", 28)==0) { meta->projection->type = LAMBERT_AZIMUTHAL_EQUAL_AREA; meta->projection->param.lamaz.center_lat = envi->center_lat; meta->projection->param.lamaz.center_lon = envi->center_lon; meta->projection->param.lamaz.false_easting = envi->false_easting; meta->projection->param.lamaz.false_northing = envi->false_northing; } else if (strncmp(envi->projection, "Geographic Lat/Lon", 18)==0) meta->projection->type = LAT_LONG_PSEUDO_PROJECTION; else { sprintf(errbuf,"\n ERROR: Unsupported projection type\n\n"); printErr(errbuf); } meta->projection->startX = envi->pixel_easting; meta->projection->startY = envi->pixel_northing; meta->projection->perX = envi->proj_dist_x; meta->projection->perY = -envi->proj_dist_y; if (strncmp(envi->hemisphere, "North", 5)==0) meta->projection->hem = 'N'; else if (strncmp(envi->hemisphere, "South", 5)==0) meta->projection->hem = 'S'; if (strcmp(envi->datum, "North America 1927") == 0) meta->projection->datum = NAD27_DATUM; else if (strcmp(envi->datum, "North America 1983") == 0) meta->projection->datum = NAD83_DATUM; else if (strcmp(envi->datum, "European 1950") == 0) meta->projection->datum = ED50_DATUM; else if (strcmp(envi->datum, "WGS-72") == 0) meta->projection->datum = WGS72_DATUM; else if (strcmp(envi->datum, "WGS-84") == 0) meta->projection->datum = WGS84_DATUM; else if (strcmp(envi->datum, "Hughes") == 0) meta->projection->datum = HUGHES_DATUM; meta->projection->spheroid = datum_spheroid(meta->projection->datum); meta->projection->re_major = envi->semimajor_axis; meta->projection->re_minor = envi->semiminor_axis; if (meta->projection->type == UNIVERSAL_TRANSVERSE_MERCATOR) { double re_major, re_minor; if (meta->projection->datum == WGS72_DATUM) datum2earth_radius(5, &re_major, &re_minor); else if (meta->projection->datum == WGS84_DATUM) datum2earth_radius(8, &re_major, &re_minor); meta->general->re_major = re_major; meta->general->re_minor = re_minor; meta->projection->re_major = re_major; meta->projection->re_minor = re_minor; } sprintf(meta->projection->units, "meters"); double center_x = meta->projection->startX + meta->general->sample_count/2.0 * meta->projection->perX; double center_y = meta->projection->startY + meta->general->line_count/2.0 * meta->projection->perY; double center_lat, center_lon, height; proj_to_latlon(meta->projection, center_x, center_y, 0.0, ¢er_lat, ¢er_lon, &height); meta->general->center_latitude = center_lat * R2D; meta->general->center_longitude = center_lon * R2D; if (meta->projection->hem == MAGIC_UNSET_CHAR) { if (center_lat > 0.0) meta->projection->hem = 'N'; else meta->projection->hem = 'S'; } } if (meta->sar) meta->sar->wavelength = envi->wavelength; meta->general->x_pixel_size = envi->pixel_size_x; meta->general->y_pixel_size = envi->pixel_size_y; return meta; }
/* Main program */ int main(int argc, char *argv[]) { FILE *fpLook=NULL, *fpIncid=NULL, *fpRange=NULL, *fpIn=NULL, *fpMask=NULL; meta_parameters *meta; stateVector stVec; int ii, kk, ll; char inFile[255], metaFile[255], dataFile[255], outLook[255], outIncid[255]; char outRange[255], outBase[255], outFile[255], *maskFile=NULL; char cmd[255], *bufMask=NULL; float *bufImage=NULL, *bufLook=NULL, *bufIncid=NULL, *bufRange=NULL; double latitude, longitude, time, doppler, earth_radius=0, satellite_height, range; double look_angle, incidence_angle, height; double line, sample, re=6378144.0, rp=6356754.9, px, py; double firstLook=0.0, firstIncid=0.0, firstRange=0.0; flag_indices_t flags[NUM_FLAGS]; /* Set all flags to 'not set' */ for (ii=0; ii<NUM_FLAGS; ii++) { flags[ii] = FLAG_NOT_SET; } /**********************BEGIN COMMAND LINE PARSING STUFF**********************/ /* Check to see if any options were provided */ if (checkForOption("-help", argc, argv) != -1) /* Most important */ help_page(); flags[f_LOOK] = checkForOption("-look", argc, argv); flags[f_INCIDENCE] = checkForOption("-incidence", argc, argv); flags[f_RANGE] = checkForOption("-range", argc, argv); flags[f_LINE] = checkForOption("-line", argc, argv); flags[f_SAMPLE] = checkForOption("-sample", argc, argv); flags[f_MIN] = checkForOption("-min", argc, argv); flags[f_MAX] = checkForOption("-max", argc, argv); flags[f_BINS] = checkForOption("-bins", argc, argv); flags[f_INTERVAL] = checkForOption("-interval", argc, argv); /* Make sure to set log & quiet flags (for use in our libraries) */ logflag = (flags[f_LOG]!=FLAG_NOT_SET) ? TRUE : FALSE; quietflag = (flags[f_QUIET]!=FLAG_NOT_SET) ? TRUE : FALSE; { /* We need to make sure the user specified the proper number of arguments */ int needed_args = 4;/*command & in_base & out_base */ if (flags[f_MIN] != FLAG_NOT_SET) needed_args += 2; /* option & value */ if (flags[f_MAX] != FLAG_NOT_SET) needed_args += 2; /* option & value */ if (flags[f_BINS] != FLAG_NOT_SET) needed_args += 2; /* option & value */ if (flags[f_INTERVAL] != FLAG_NOT_SET) needed_args += 2; /* option & value */ /*Make sure we have enough arguments*/ if (argc != needed_args) usage();/*This exits with a failure*/ } /* We must be close to good enough at this point...start filling in fields as needed */ if (flags[f_MIN] != FLAG_NOT_SET) min = atof(argv[flags[f_MIN] + 1]); if (flags[f_MAX] != FLAG_NOT_SET) max = atof(argv[flags[f_MAX] + 1]); if (flags[f_BINS] != FLAG_NOT_SET) bins = atoi(argv[flags[f_BINS] + 1]); if (flags[f_INTERVAL] != FLAG_NOT_SET) interval = atof(argv[flags[f_INTERVAL] + 1]); if (flags[f_QUIET] == FLAG_NOT_SET) /* display splash screen if not quiet */ print_splash_screen(argc, argv); if (flags[f_LOG] != FLAG_NOT_SET) strcpy(logFile, argv[flags[f_LOG] + 1]); else /* default behavior: log to tmp<pid>.log */ sprintf(logFile, "tmp%i.log", (int)getpid()); fLog = FOPEN(logFile, "a"); /* Fetch required arguments */ strcpy(inFile,argv[argc - 2]); strcpy(outBase,argv[argc - 1]); /***********************END COMMAND LINE PARSING STUFF***********************/ create_name(metaFile, inFile, ".meta"); create_name(dataFile, inFile, ".img"); /* Read metadata */ meta = meta_read(inFile); lines = meta->general->line_count; samples = meta->general->sample_count; /* Set some values */ doppler = 0.0; /* Determine what kind of image it is */ if (meta->sar->image_type=='P') { if (meta->projection->type==SCANSAR_PROJECTION) printf(" Detected ScanSAR "); } else if (meta->sar->image_type=='S') printf(" Detected slant range "); else if (meta->sar->image_type=='G') printf(" Detected ground range "); /* switch (meta->general->image_data_type) { case AMPLITUDE_IMAGE: printf("amplitude image ...\n"); break; case SIGMA_IMAGE: printf("sigma image ...\n"); break; case GAMMA_IMAGE: printf("gamma image ...\n"); break; case BETA_IMAGE: printf("beta image ...\n"); break; case RAW_IMAGE: case COMPLEX_IMAGE: case PHASE_IMAGE: case POWER_IMAGE: case COHERENCE_IMAGE: case GEOREFERENCED_IMAGE: case GEOCODED_IMAGE: case POLARIMETRIC_IMAGE: case LUT_IMAGE: case ELEVATION: case DEM: case IMAGE: case MASK: break; } */ /* Create a mask file for background fill - required only for ScanSAR */ if (meta->sar->image_type=='P') { if (meta->projection->type==SCANSAR_PROJECTION) { fpIn = fopenImage(inFile, "rb"); bufImage = (float *) MALLOC(samples * sizeof(float)); printf(" Generating mask file ...\n"); maskFile = (char *) MALLOC(255*sizeof(char)); sprintf(maskFile, "tmp%i.mask", (int)getpid()); fpMask = fopenImage(maskFile, "wb"); bufMask = (unsigned char *) MALLOC(samples * sizeof(char)); for (ii=0; ii<lines; ii++) { get_float_line(fpIn, meta, ii, bufImage); for (kk=0; kk<samples; kk++) { if (bufImage[kk]>0.0) bufMask[kk] = 1; else bufMask[kk] = 0; } ASF_FWRITE(bufMask, sizeof(char), samples, fpMask); } FCLOSE(fpMask); FREE(bufMask); FCLOSE(fpIn); FREE(bufImage); } } /* Create grid for least square approach */ printf(" Initialization ...\n"); if (flags[f_LOOK] != FLAG_NOT_SET) { sprintf(outLook, "tmp%i.look", (int)getpid()); fpLook = FOPEN(outLook, "w"); } if (flags[f_INCIDENCE] != FLAG_NOT_SET) { sprintf(outIncid, "tmp%i.incid", (int)getpid()); fpIncid = FOPEN(outIncid, "w"); } if (flags[f_RANGE] != FLAG_NOT_SET) { sprintf(outRange, "tmp%i.range", (int)getpid()); fpRange = FOPEN(outRange, "w"); } if (flags[f_LOOK] != FLAG_NOT_SET || flags[f_INCIDENCE] != FLAG_NOT_SET || flags[f_RANGE] != FLAG_NOT_SET) { for (ll=0; ll<=RES_X; ll++) for (kk=0; kk<=RES_Y; kk++) { line = ll * lines / RES_Y; sample = kk * samples / RES_X; if (meta->sar->image_type=='P') { px = meta->projection->startX + meta->projection->perX * sample; py = meta->projection->startY + meta->projection->perY * line; proj_to_latlon(meta->projection, px, py, 0.0, &latitude, &longitude, &height); latLon2timeSlant(meta, latitude, longitude, &time, &range, &doppler); } else time = meta_get_time(meta, line, sample); stVec = meta_get_stVec(meta, time); if (meta->sar->image_type=='P') { if (meta->projection->type==SCANSAR_PROJECTION) earth_radius = meta->projection->param.atct.rlocal; else asfPrintError("Unable to determine earth radius.\n"); } else earth_radius = my_get_earth_radius(time, stVec, re, rp); satellite_height = my_get_satellite_height(time, stVec); range = my_get_slant_range(meta, earth_radius, satellite_height, line, sample); look_angle = my_get_look_angle(earth_radius, satellite_height, range); incidence_angle = my_get_incidence_angle(earth_radius, satellite_height, range); if (ll==0 && kk==0) { firstLook = look_angle * R2D; firstIncid = incidence_angle * R2D; firstRange = range; } if (flags[f_LOOK] != FLAG_NOT_SET) fprintf(fpLook, "%.18f %.12f %.12f\n", (float)look_angle*R2D, line, sample); if (flags[f_INCIDENCE] != FLAG_NOT_SET) fprintf(fpIncid, "%.18f %.12f %.12f\n", (float)incidence_angle*R2D, line, sample); if (flags[f_RANGE] != FLAG_NOT_SET) fprintf(fpRange, "%.18f %.12f %.12f\n", (float)range, line, sample); } } /* Close files for now */ if (flags[f_LOOK] != FLAG_NOT_SET) { FCLOSE(fpLook); FREE(bufLook); } if (flags[f_INCIDENCE] != FLAG_NOT_SET) { FCLOSE(fpIncid); FREE(bufIncid); } if (flags[f_RANGE] != FLAG_NOT_SET) { FCLOSE(fpRange); FREE(bufRange); } /* Calculate plots */ if (flags[f_LOOK] != FLAG_NOT_SET) { create_name(outFile, outBase, "_look.plot"); calculate_plot("Look angle", outLook, dataFile, maskFile, outFile, meta, firstLook); } if (flags[f_INCIDENCE] != FLAG_NOT_SET) { create_name(outFile, outBase, "_incid.plot"); calculate_plot("Incidence angle", outIncid, dataFile, maskFile, outFile, meta, firstIncid); } if (flags[f_RANGE] != FLAG_NOT_SET) { create_name(outFile, outBase, "_range.plot"); calculate_plot("Range", outRange, dataFile, maskFile, outFile, meta, firstRange); } if (flags[f_LINE] != FLAG_NOT_SET) { create_name(outFile, outBase, "_line.plot"); calculate_plot("Line", NULL, dataFile, maskFile, outFile, meta, 0.0); } if (flags[f_SAMPLE] != FLAG_NOT_SET) { create_name(outFile, outBase, "_sample.plot"); calculate_plot("Sample", NULL, dataFile, maskFile, outFile, meta, 0.0); } /* Clean up */ sprintf(cmd, "rm -rf tmp*"); system(cmd); exit(0); }