Exemple #1
0
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;
}
Exemple #4
0
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;
    }
}
Exemple #5
0
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;

  }
}
Exemple #6
0
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;
}
Exemple #7
0
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;
}
Exemple #10
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,
		   &center_lat, &center_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;
}
Exemple #11
0
/* 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);
}