Exemplo n.º 1
0
static void get_bounding_box_linesamp(meta_parameters *metaSAR,
                                      meta_parameters *metaDEM,
                                      double *line_lo, double *line_hi,
                                      double *samp_lo, double *samp_hi,
                                      int h_padding, int v_padding)
{
    *line_lo = metaDEM->general->line_count;
    *samp_lo = metaDEM->general->sample_count;
    *line_hi = *samp_hi = 0;

    // must call meta_get_latLon for each corner
    int nl = metaSAR->general->line_count;
    int ns = metaSAR->general->sample_count;
    double lat, lon, line, samp;

    meta_get_latLon(metaSAR, 0, 0, 0, &lat, &lon);
    meta_get_lineSamp(metaDEM, lat, lon, 0, &line, &samp);
    if (meta_is_valid_double(line) && meta_is_valid_double(samp))
        update_extents(line, samp, line_lo, line_hi, samp_lo, samp_hi);

    meta_get_latLon(metaSAR, 0, ns-1, 0, &lat, &lon);
    meta_get_lineSamp(metaDEM, lat, lon, 0, &line, &samp);
    if (meta_is_valid_double(line) && meta_is_valid_double(samp))
        update_extents(line, samp, line_lo, line_hi, samp_lo, samp_hi);

    meta_get_latLon(metaSAR, nl-1, 0, 0, &lat, &lon);
    meta_get_lineSamp(metaDEM, lat, lon, 0, &line, &samp);
    if (meta_is_valid_double(line) && meta_is_valid_double(samp))
        update_extents(line, samp, line_lo, line_hi, samp_lo, samp_hi);

    meta_get_latLon(metaSAR, nl-1, ns-1, 0, &lat, &lon);
    meta_get_lineSamp(metaDEM, lat, lon, 0, &line, &samp);
    if (meta_is_valid_double(line) && meta_is_valid_double(samp))
        update_extents(line, samp, line_lo, line_hi, samp_lo, samp_hi);

    // Add a little bit of fudge to each -- we want there to be some room
    // for adjustment via the co-registration.

    // Add about some pixels worth to each top/left/bottom/right.
    nl = metaDEM->general->line_count;
    ns = metaDEM->general->sample_count;

    *line_lo -= v_padding;
    if (*line_lo < 0) *line_lo = 0;
    if (*line_lo > nl-1) *line_lo = nl-1;

    *line_hi += v_padding;
    if (*line_hi < 0) *line_hi = 0;
    if (*line_hi > nl-1) *line_hi = nl-1;

    *samp_lo -= h_padding;
    if (*samp_lo < 0) *samp_lo = 0;
    if (*samp_lo > ns-1) *samp_lo = ns-1;

    *samp_hi += h_padding;
    if (*samp_hi < 0) *samp_hi = 0;
    if (*samp_hi > ns-1) *samp_hi = ns-1;
}
Exemplo n.º 2
0
static void line_samp_to_proj(ImageInfo *ii, double line, double samp,
                              double *x, double *y)
{
  meta_parameters *meta = ii->meta;
  if (meta_supports_meta_get_latLon(meta))
  {
    double lat, lon, projZ;
    meta_get_latLon(meta, line, samp, 0, &lat, &lon);
    if (meta->projection &&
        meta->projection->type != LAT_LONG_PSEUDO_PROJECTION)
    {
      latlon_to_proj(meta->projection, 'R', lat*D2R, lon*D2R, 0,
                     x, y, &projZ);
    }
    else {
      int zone;
      if (meta_is_valid_double(meta->general->center_longitude) &&
          meta->general->center_longitude > -180 &&
          meta->general->center_longitude < 180)
      {
        zone = utm_zone(meta->general->center_longitude);
      }
      else {
        zone = utm_zone(lon);
      }
      latLon2UTM_zone(lat, lon, 0, zone, x, y);
    }
  } else {
    *x = samp;
    *y = line;
  }
}
Exemplo n.º 3
0
static void
img_to_latlon(meta_parameters *meta,
              double line, double samp,
              double *lat, double *lon)
{
  int ret = meta_get_latLon(meta, line, samp, 0, lat, lon);
  if (ret != 0) {
    asfPrintError("meta_get_latLon error: line = %f, samp = %f\n",
                  line, samp);
  }
}
Exemplo n.º 4
0
/*******************************************************************
 * meta_get_timeSlantDop:
 * Converts a given line and sample in image into time, slant-range,
 * and doppler.  Works with all image types.*/
void meta_get_timeSlantDop(meta_parameters *meta,
  double yLine,double xSample,double *time,double *slant,double *dop)
{
  // No effort has been made to make this routine work with
  // pseudoprojected images.
  assert (meta->projection == NULL
    || meta->projection->type != LAT_LONG_PSEUDO_PROJECTION);

  if (meta->transform)
  {
    double lat,lon;
    meta_get_latLon(meta,yLine,xSample,0.0,&lat,&lon);
    latLon2timeSlant(meta,lat,lon,time,slant,dop);
  }
  // just for testing
  else if (meta->sar->image_type=='S'||meta->sar->image_type=='G')
  { /*Slant or ground range.  These are easy.*/
    *slant = meta_get_slant(meta,yLine,xSample);
    *time  = meta_get_time(meta,yLine,xSample);
    if (dop != NULL)
    {
      if (meta->sar->deskewed == 1)
        *dop=0.0;
      else
        *dop=meta_get_dop(meta,yLine,xSample);
    }
  } else if (meta->sar->image_type=='P' ||
           meta->sar->image_type=='R')
  {
    double lat,lon;
    meta_get_latLon(meta,yLine,xSample,0.0,&lat,&lon);
    latLon2timeSlant(meta,lat,lon,time,slant,dop);
  } else
  {  /*Bogus image type.*/
    printf("Error! Invalid image type '%c' passed to meta_get_timeSlantDop!\n",
      meta->sar->image_type);
    exit(1);
  }
}
Exemplo n.º 5
0
double errorVsTimeRng(double x,imgLocRec *loc)
{
	int i;
	double saved_timeOffset=loc->meta->sar->time_shift;
	double saved_slant=loc->meta->sar->slant_shift;
	loc->meta->sar->time_shift=loc->offT;
	loc->meta->sar->slant_shift=x;
	for (i=0;i<loc->nPts;i++)
	{
		int y=(int)loc->y[i],x=(int)loc->x[i];
		meta_get_original_line_sample(loc->meta,y,x,&y,&x);
		meta_get_latLon(loc->meta,y,x,loc->elev[i],
				&loc->est[i].lat,&loc->est[i].lon);
	}
	loc->meta->sar->time_shift  = saved_timeOffset;
	loc->meta->sar->slant_shift = saved_slant;
	return errorVsLoc(loc);
}
Exemplo n.º 6
0
static void
sar_to_dem(meta_parameters *meta_sar, meta_parameters *meta_dem,
           double line_sar, double samp_sar,
           double *line_dem, double *samp_dem)
{
  double lat, lon;
  int ret;

  ret = meta_get_latLon(meta_sar, line_sar, samp_sar, 0, &lat, &lon);
  if (ret != 0) {
    asfPrintError("meta_get_latLon error: line = %f, samp = %f\n",
                  line_sar, samp_sar);
  }
  ret = meta_get_lineSamp(meta_dem, lat, lon, 0, line_dem, samp_dem);
  if (ret != 0) {
    asfPrintError("meta_get_lineSamp error: lat = %f, lon = %f\n",
                  lat, lon);
  }
}
Exemplo n.º 7
0
iso_meta *meta2iso(meta_parameters *meta)
{
  int ii, kk, numAnnotations=0, numLayers=0, numAuxRasterFiles=0;
  iso_polLayer_t *polLayer;
  char **beamID, errorMessage[1024];
  int line_count = meta->general->line_count;
  int sample_count = meta->general->sample_count;

  strcpy(errorMessage, "");
  if (!meta->sar)
    strcat(errorMessage, "Missing SAR block. Can't generate ISO metadata\n");
  else if (!meta->state_vectors)
    strcat(errorMessage, 
	   "Missing state vector block. Cant't generate ISO metadata\n");
  if (strlen(errorMessage) > 0)
    asfPrintError(errorMessage);

  if (strcmp_case(meta->general->sensor, "SEASAT") == 0) {
    numAnnotations = 1;
    numLayers = 1;
    numAuxRasterFiles = 0;
    polLayer = (iso_polLayer_t *) CALLOC(1, sizeof(iso_polLayer_t));
    polLayer[0] = HH_POL;
    beamID = (char **) CALLOC(1, sizeof(char *));
    beamID[0] = (char *) CALLOC(20, sizeof(char));
    strcpy(beamID[0], meta->general->sensor_name);
  }

  iso_meta *iso = iso_meta_init();
  iso_generalHeader *header = iso->generalHeader;
  iso_productComponents *comps = iso->productComponents;
  iso_productInfo *info = iso->productInfo;
  iso_productSpecific *spec = iso->productSpecific;
  iso_setup *setup = iso->setup;
  iso_processing *proc = iso->processing;
  iso_instrument *inst = iso->instrument;
  iso_platform *platform = iso->platform;
  iso_productQuality *quality = iso->productQuality;

  // General Header  
  strcpy(header->itemName, "LEVEL 1 PRODUCT");
  if (strcmp_case(meta->general->sensor, "SEASAT") == 0)  
    strcpy(header->mission, "SEASAT");
  strcpy(header->source, "(seasat tape)");
  strcpy(header->destination, "DATAPOOL");
  strncpy(header->generationSystem, meta->general->processor, 20);
  utcDateTime(&header->generationTime);
  // header->referenceDocument: needs to be generated
  header->revision = (char *) CALLOC(20, sizeof(char));
  strcpy(header->revision, "OPERATIONAL");

  // Product Components
  comps->numAnnotations = numAnnotations;
  comps->numLayers = numLayers;
  comps->numAuxRasterFiles = numAuxRasterFiles;
  comps->annotation = 
    (iso_filesType *) CALLOC(numAnnotations, sizeof(iso_filesType));
  for (ii=0; ii<numAnnotations; ii++) {
    comps->annotation[ii].type = MAIN_TYPE;
    strcpy(comps->annotation[ii].file.host, ".");
    strcpy(comps->annotation[ii].file.path, ".");
    sprintf(comps->annotation[ii].file.name, "%s.xml", meta->general->basename);
    comps->annotation[ii].file.size = -1;
  }
  if (strcmp_case(meta->general->sensor, "SEASAT") == 0) {
    // only one HDF5 file that contains everything
    comps->imageData = (iso_filesPol *) CALLOC(1,sizeof(iso_filesPol));
    comps->imageData[0].polLayer = HH_POL;
    strcpy(comps->imageData[0].beamID, meta->general->sensor_name);
    strcpy(comps->imageData[0].file.host, ".");
    strcpy(comps->imageData[0].file.path, ".");
    sprintf(comps->imageData[0].file.name, "%s.h5", meta->general->basename);
    comps->imageData[0].file.size = -1;
  }
  comps->quicklooks = 
    (iso_filesPol *) CALLOC(numLayers, sizeof(iso_filesPol));
  for (ii=0; ii<numLayers; ii++) {
    comps->quicklooks[ii].polLayer = polLayer[ii];
    strcpy(comps->quicklooks[ii].beamID, beamID[ii]);
    strcpy(comps->quicklooks[ii].file.host, ".");
    strcpy(comps->quicklooks[ii].file.path, ".");
    sprintf(comps->quicklooks[ii].file.name, "%s.jpg", 
	    meta->general->basename);
    // comps->quicklooks[ii].file.size: calculated after being generated
  }
  strcpy(comps->browseImage.host, ".");
  strcpy(comps->browseImage.path, ".");
  sprintf(comps->browseImage.name, "%s.jpg", meta->general->basename);
  // comps->browseImage.size: calculated after being generated
  strcpy(comps->mapPlot.host, ".");
  strcpy(comps->mapPlot.path, ".");
  sprintf(comps->mapPlot.name, "%s.kml", meta->general->basename);
  // comps->mapPlat.size: calculated after being generated

  // Product Info
  strcpy(info->logicalProductID, "not applicable");
  strcpy(info->receivingStation, meta->general->receiving_station);
  //strcpy(info->receivingStation, MAGIC_UNSET_STRING);
  if (strcmp_case(meta->general->sensor, "SEASAT") == 0) {
    strcpy(info->level0ProcessingFacility, "ASF");
    strcpy(info->level1ProcessingFacility, "ASF");
  }
  info->groundOperationsType = OPERATIONAL;
  strcpy(info->deliveryInfo, "NOMINAL");
  if (strcmp_case(meta->general->sensor, "SEASAT") == 0)   
    strcpy(info->copyrightInfo, "Copyright NASA (1978)");
  // FIXME: need to decide whether quality inspection is constant or
  //        information comes from somewhere else
  info->qualityInspection = UNDEF_QUALITY; 
  strcpy(info->mission, meta->general->sensor);
  info->orbitPhase = 1; // nominal orbit
  if (strcmp_case(meta->general->sensor, "SEASAT") == 0) {
    // FIXME: mid-Aug 1978 the orbit was changed to 244 revolution cycles
    info->numOrbitsInCycle = 43;
  }
  info->absOrbit = meta->general->orbit;
  info->orbitCycle = (info->absOrbit / info->numOrbitsInCycle) + 1;
  info->relOrbit = 
    info->absOrbit - (info->orbitCycle - 1)*info->numOrbitsInCycle; 
  if (meta->general->orbit_direction == 'A')
    info->orbitDirection = ASCENDING;
  else if (meta->general->orbit_direction == 'D')
    info->orbitDirection = DESCENDING;
  strncpy(info->sensor, meta->general->sensor_name, 20);
  if (strcmp_case(meta->general->sensor, "SEASAT") == 0)   
    info->imageMode = STANDARD_BEAM;
  if (meta->sar->look_direction == 'R')
    info->lookDirection = RIGHT_LOOK;
  else if (meta->sar->look_direction == 'L')
    info->lookDirection = LEFT_LOOK;
  if (strcmp_case(meta->general->sensor, "SEASAT") == 0) {
    info->polarizationMode = SINGLE_POL;
    info->polLayer = (iso_polLayer_t *) CALLOC(1,sizeof(iso_polLayer_t));
    info->polLayer[0] = HH_POL;
    strcpy(info->elevationBeamConfiguration, meta->general->mode);
  }
  strcpy(info->azimuthBeamID, "boresightAzimuth");
  /* ScanSAR and spotlight
  info->numberOfBeams = MAGIC_UNSET_INT;
  info->beamID = NULL;
  info->numberOfBursts = MAGIC_UNSET_INT;
  info->numberOfAzimuthBeams = MAGIC_UNSET_INT;
  strcpy(info->azimuthBeamIDFirst, MAGIC_UNSET_STRING);
  strcpy(info->azimuthBeamIDLast, MAGIC_UNSET_STRING);
  info->azimuthSteeringAngleFirst = MAGIC_UNSET_DOUBLE;
  info->azimuthSteeringAngleLast = MAGIC_UNSET_DOUBLE;
  */
  // FIXME: work out naming scheme for productType
  strcpy(info->productType, "STANDARD PRODUCT");
  if (meta->general->data_type >= COMPLEX_BYTE)
    info->productVariant = SLC_PRODUCT;
  else
    info->productVariant = STD_PRODUCT;
  if (meta->sar->image_type == 'S')
    info->projection = SLANTRANGE_PROJ;
  else if (meta->sar->image_type == 'G')
    info->projection = GROUNDRANGE_PROJ;
  info->mapProjection = UNDEF_MAP;
  info->resolutionVariant = UNDEF_RES;
  info->radiometricCorrection = NOTCALIBRATED;
  // FIXME: needs to updated when calibration is done
  strcpy(info->pixelValueID, "RADAR BRIGHTNESS");
  if (meta->general->data_type >= COMPLEX_BYTE)
    info->imageDataType = COMPLEX_DATA_TYPE;
  else
    info->imageDataType = DETECTED_DATA_TYPE;
  if (strcmp_case(meta->general->sensor, "SEASAT") == 0)   
    info->imageDataFormat = HDF5_DATA_FORMAT;
  info->numberOfLayers = meta->general->band_count;
  if (meta->general->data_type == ASF_BYTE ||
      meta->general->data_type == COMPLEX_BYTE)
    info->imageDataDepth = 8;
  else if (meta->general->data_type == INTEGER16 ||
	   meta->general->data_type == COMPLEX_INTEGER16)
    info->imageDataDepth = 16;
  else if (meta->general->data_type == REAL32 ||
	   meta->general->data_type == INTEGER32 ||
	   meta->general->data_type == COMPLEX_REAL32 ||
	   meta->general->data_type == COMPLEX_INTEGER32)
    info->imageDataDepth = 32;
  else if (meta->general->data_type == REAL64 ||
	   meta->general->data_type == COMPLEX_REAL64)
    info->imageDataDepth = 64;
  info->imageStorageOrder = ROWBYROW;
  strcpy(info->rowContent, "RANGELINES");
  strcpy(info->columnContent, "AZIMUTHLINES");
  info->numberOfRows = meta->general->line_count;
  info->numberOfColumns = meta->general->sample_count;
  info->startRow = meta->general->start_line;
  info->startColumn = meta->general->start_sample;
  info->rowScaling = meta->general->line_scaling;
  info->columnScaling = meta->general->sample_scaling;
  info->rowSpacing = (float) meta->sar->azimuth_time_per_pixel;
  info->columnSpacing = (float) meta->sar->range_time_per_pixel;
  if (meta->sar->image_type == 'S') {
    spec->slantRangeResolution = meta->general->x_pixel_size;
    // FIXME: calculate groundRangeResolution for slant range
    info->groundRangeResolution = meta->general->x_pixel_size;
  }
  if (meta->sar->image_type == 'G') {
    // FIXME: calculate slantRangeResolution for ground range
    spec->slantRangeResolution = meta->general->x_pixel_size;
    info->groundRangeResolution = meta->general->x_pixel_size;
  }
  info->azimuthResolution = meta->general->y_pixel_size;
  info->azimuthLooks = (float) meta->sar->azimuth_look_count;
  info->rangeLooks = (float) meta->sar->range_look_count;
  strcpy(info->sceneID, meta->general->basename);
  if (meta->sar->azimuth_time_per_pixel < 0) {
    dateTimeStamp(meta, line_count, &info->startTimeUTC);
    dateTimeStamp(meta, 0, &info->stopTimeUTC);
  }
  else {
    dateTimeStamp(meta, 0, &info->startTimeUTC);
    dateTimeStamp(meta, line_count, &info->stopTimeUTC);
  }
  info->rangeTimeFirstPixel = rangeTime(meta, 0);
  info->rangeTimeLastPixel = rangeTime(meta, sample_count);
  info->sceneAzimuthExtent = line_count * meta->general->y_pixel_size;
  info->sceneRangeExtent = sample_count * meta->general->x_pixel_size;
  int *x = (int *) CALLOC(4, sizeof(int));
  int *y = (int *) CALLOC(4, sizeof(int));
  double lat, lon;
  y[0] = meta->general->line_count / 2;
  info->sceneCenterCoord.refRow = y[0];
  x[0] = meta->general->sample_count / 2;
  info->sceneCenterCoord.refColumn = x[0];
  if (meta->general->center_latitude == MAGIC_UNSET_DOUBLE ||
      meta->general->center_longitude == MAGIC_UNSET_DOUBLE) {
    info->sceneCenterCoord.lat = meta->general->center_latitude;
    info->sceneCenterCoord.lon = meta->general->center_longitude;
  }
  else {
    meta_get_latLon(meta, (double) y[0], (double) x[0], 0.0, &lat, &lon);
    info->sceneCenterCoord.lat = lat;
    info->sceneCenterCoord.lon = lon;    
  }
  dateTimeStamp(meta, y[0], &info->sceneCenterCoord.azimuthTimeUTC);
  info->sceneCenterCoord.rangeTime = rangeTime(meta, x[0]);
  if (ISNAN(meta->sar->incid_a[0]))
    info->sceneCenterCoord.incidenceAngle = meta_incid(meta, y[0], x[0])*R2D;
  else
    info->sceneCenterCoord.incidenceAngle = meta->sar->incid_a[0];
  info->sceneAverageHeight = MAGIC_UNSET_DOUBLE;
  x[0] = 0; y[0] = 0;
  x[1] = meta->general->sample_count; y[1] = 0;
  x[2] = 0; y[2] = meta->general->line_count;
  x[3] = meta->general->sample_count; y[3] = meta->general->line_count;
  for (ii=0; ii<4; ii++) {
    info->sceneCornerCoord[ii].refRow = y[ii];
    info->sceneCornerCoord[ii].refColumn = x[ii];
    meta_get_latLon(meta, (double) y[ii], (double) x[ii], 0.0, &lat, &lon);
    info->sceneCornerCoord[ii].lat = (float) lat;
    info->sceneCornerCoord[ii].lon = (float) lon;
    dateTimeStamp(meta, y[ii], &info->sceneCornerCoord[ii].azimuthTimeUTC);
    info->sceneCornerCoord[ii].rangeTime = rangeTime(meta, x[ii]);
    info->sceneCornerCoord[ii].incidenceAngle = 
      meta_incid(meta, (double) y[ii], (double) x[ii])*R2D;
  }
  info->yaw = meta->sar->yaw;
  info->pitch = meta->sar->pitch;
  info->roll = meta->sar->roll;
  info->earthRadius = meta->sar->earth_radius;
  info->satelliteHeight = meta->sar->satellite_height;
  info->headingAngle = meta->sar->heading_angle;
  strcpy(info->quicklooks.imageDataFormat,"JPEG");
  info->quicklooks.imageDataDepth = 8;
  info->quicklooks.numberOfRows = 1000;
  info->quicklooks.numberOfColumns = 1000;
  info->quicklooks.columnBlockLength = MAGIC_UNSET_DOUBLE;
  info->quicklooks.rowBlockLength = MAGIC_UNSET_DOUBLE;
  info->quicklooks.rowSpacing = MAGIC_UNSET_DOUBLE;
  info->quicklooks.columnSpacing = MAGIC_UNSET_DOUBLE;
  strcpy(info->browseImageDataFormat, "JPEG"); // assumption
  info->browseImageDataDepth = 8;
  strcpy(info->mapPlotFormat, "KML"); // assumption

  // Product Specific
  spec->commonPRF = meta->sar->prf;
  spec->commonRSF = meta->sar->range_sampling_rate;
  // FIXME: calculate properly for different geometry
  spec->slantRangeResolution = meta->general->x_pixel_size;
  spec->projectedSpacingAzimuth = meta->general->y_pixel_size;
  spec->projectedSpacingGroundNearRange = meta->general->x_pixel_size;
  spec->projectedSpacingGroundFarRange = meta->general->x_pixel_size;
  spec->projectedSpacingSlantRange = meta->sar->slant_range_first_pixel;
  spec->slantRangeShift = meta->sar->slant_shift;
  if (strcmp_case(meta->general->sensor, "SEASAT") == 0) {
    spec->imageCoordinateType = RAW_COORD;
    spec->imageDataStartWith = EARLYAZNEARRG; // assumption
    spec->quicklookDataStartWith = EARLYAZNEARRG; // assumption
  }
  // FIXME: deal with map projected data later
  if (meta->projection) {
    spec->geocodedImageInfoFlag = TRUE;

    // mapProjection
    strcpy(spec->geodeticDatumID, MAGIC_UNSET_STRING);
    strcpy(spec->projectionID, MAGIC_UNSET_STRING);
    strcpy(spec->zoneID, MAGIC_UNSET_STRING);
    spec->projectionCenterLatitude = MAGIC_UNSET_DOUBLE;
    spec->projectionCenterLongitude = MAGIC_UNSET_DOUBLE;
    spec->mapOriginEasting = MAGIC_UNSET_DOUBLE;
    spec->mapOriginNorthing = MAGIC_UNSET_DOUBLE;
    spec->scaleFactor = MAGIC_UNSET_DOUBLE;
    
    // geoParameter
    spec->pixelSpacingEasting = MAGIC_UNSET_DOUBLE;
    spec->pixelSpacingNorthing = MAGIC_UNSET_DOUBLE;
    spec->frameCoordsGeographic.upperLeftLatitude = MAGIC_UNSET_DOUBLE;
    spec->frameCoordsGeographic.upperLeftLongitude = MAGIC_UNSET_DOUBLE;
    spec->frameCoordsGeographic.upperRightLatitude = MAGIC_UNSET_DOUBLE;
    spec->frameCoordsGeographic.upperRightLongitude = MAGIC_UNSET_DOUBLE;
    spec->frameCoordsGeographic.lowerLeftLatitude = MAGIC_UNSET_DOUBLE;
    spec->frameCoordsGeographic.lowerLeftLongitude = MAGIC_UNSET_DOUBLE;
    spec->frameCoordsGeographic.lowerRightLatitude = MAGIC_UNSET_DOUBLE;
    spec->frameCoordsGeographic.lowerRightLongitude = MAGIC_UNSET_DOUBLE;
    spec->frameCoordsCartographic.upperLeftEasting = MAGIC_UNSET_DOUBLE;
    spec->frameCoordsCartographic.upperLeftNorthing = MAGIC_UNSET_DOUBLE;
    spec->frameCoordsCartographic.upperRightEasting = MAGIC_UNSET_DOUBLE;
    spec->frameCoordsCartographic.upperRightNorthing = MAGIC_UNSET_DOUBLE;
    spec->frameCoordsCartographic.lowerRightEasting = MAGIC_UNSET_DOUBLE;
    spec->frameCoordsCartographic.lowerRightNorthing = MAGIC_UNSET_DOUBLE;
    spec->frameCoordsCartographic.lowerLeftEasting = MAGIC_UNSET_DOUBLE;
    spec->frameCoordsCartographic.lowerLeftNorthing = MAGIC_UNSET_DOUBLE;
    spec->sceneCoordsGeographic.upperLeftLatitude = MAGIC_UNSET_DOUBLE;
    spec->sceneCoordsGeographic.upperLeftLongitude = MAGIC_UNSET_DOUBLE;
    spec->sceneCoordsGeographic.upperRightLatitude = MAGIC_UNSET_DOUBLE;
    spec->sceneCoordsGeographic.upperRightLongitude = MAGIC_UNSET_DOUBLE;
    spec->sceneCoordsGeographic.lowerLeftLatitude = MAGIC_UNSET_DOUBLE;
    spec->sceneCoordsGeographic.lowerLeftLongitude = MAGIC_UNSET_DOUBLE;
    spec->sceneCoordsGeographic.lowerRightLatitude = MAGIC_UNSET_DOUBLE;
    spec->sceneCoordsGeographic.lowerRightLongitude = MAGIC_UNSET_DOUBLE;
    spec->sceneCoordsCartographic.upperLeftEasting = MAGIC_UNSET_DOUBLE;
    spec->sceneCoordsCartographic.upperLeftNorthing = MAGIC_UNSET_DOUBLE;
    spec->sceneCoordsCartographic.upperRightEasting = MAGIC_UNSET_DOUBLE;
    spec->sceneCoordsCartographic.upperRightNorthing = MAGIC_UNSET_DOUBLE;
    spec->sceneCoordsCartographic.lowerRightEasting = MAGIC_UNSET_DOUBLE;
    spec->sceneCoordsCartographic.lowerRightNorthing = MAGIC_UNSET_DOUBLE;
    spec->sceneCoordsCartographic.lowerLeftEasting = MAGIC_UNSET_DOUBLE;
    spec->sceneCoordsCartographic.lowerLeftNorthing = MAGIC_UNSET_DOUBLE;
    spec->sceneCenterCoordLatitude = MAGIC_UNSET_DOUBLE;
    spec->sceneCenterCoordLongitude = MAGIC_UNSET_DOUBLE;
    spec->sceneCenterCoordEasting = MAGIC_UNSET_DOUBLE;
    spec->sceneCenterCoordNorthing = MAGIC_UNSET_DOUBLE;
    spec->imageResamplingMethod = UNDEF_RESAMPLE;
    
    // elevationData
    spec->elevationDataFlag = FALSE;
    strcpy(spec->elevationDataSource, MAGIC_UNSET_STRING);
    spec->elevationMinimumHeight = MAGIC_UNSET_DOUBLE;
    spec->elevationMeanHeight = MAGIC_UNSET_DOUBLE;
    spec->elevationMaximumHeight = MAGIC_UNSET_DOUBLE;
    
    // incidenceAngleMaskDescription
    spec->incidenceAngleMaskDescriptionFlag = FALSE;
    strcpy(spec->incidenceAnglePixelValueID, MAGIC_UNSET_STRING);
    spec->incidenceAngleImageDataFormat = UNDEF_DATA_FORMAT;
    spec->incidenceAngleImageDataDepth = MAGIC_UNSET_INT;
    spec->incidenceAngleNumberOfRows = MAGIC_UNSET_INT;
    spec->incidenceAngleNumberOfColumns = MAGIC_UNSET_INT;
    spec->incidenceAngleRowSpacing = MAGIC_UNSET_DOUBLE;
    spec->incidenceAngleColumnSpacing = MAGIC_UNSET_DOUBLE;
  }

  // Setup
  strcpy(setup->orderType, "L1 STD");
  strcpy(setup->processingPriority, "NOMINAL");
  if (strcmp_case(meta->general->sensor, "SEASAT") == 0)
    setup->orbitAccuracy = RESTITUTED_ORBIT;
  setup->sceneSpecification = FRAME_SPEC;
  setup->frameID = meta->general->frame;
  dateTimeStamp(meta, 0, &setup->sceneStartTimeUTC);
  dateTimeStamp(meta, line_count, &setup->sceneStopTimeUTC);
  setup->sceneCenterLatitude = MAGIC_UNSET_DOUBLE;
  setup->sceneCenterLongitude = MAGIC_UNSET_DOUBLE;
  if (strcmp_case(meta->general->sensor, "SEASAT") == 0) {
    setup->imagingMode = STANDARD_BEAM;
    setup->lookDirection = RIGHT_LOOK;
    setup->polarizationMode = SINGLE_POL;
    setup->polLayer = HH_POL;
    strcpy(setup->elevationBeamConfiguration, "STD");
  }
  if (meta->general->data_type >= COMPLEX_BYTE)  
    setup->productVariant = SLC_PRODUCT;
  else
    setup->productVariant = STD_PRODUCT;
  setup->resolutionVariant = UNDEF_RES;
  if (meta->sar->image_type == 'S')
    setup->projection = SLANTRANGE_PROJ;
  else if (meta->sar->image_type == 'G')
    setup->projection = GROUNDRANGE_PROJ;
  strcpy(setup->logicalDataTakeID, MAGIC_UNSET_STRING);
  strcpy(setup->level0ProductID, MAGIC_UNSET_STRING);
  setup->L0SARGenerationTimeUTC.year = MAGIC_UNSET_INT;
  setup->L0SARGenerationTimeUTC.month = MAGIC_UNSET_INT;
  setup->L0SARGenerationTimeUTC.day = MAGIC_UNSET_INT;
  setup->L0SARGenerationTimeUTC.hour = MAGIC_UNSET_INT;
  setup->L0SARGenerationTimeUTC.min = MAGIC_UNSET_INT;
  setup->L0SARGenerationTimeUTC.second = MAGIC_UNSET_DOUBLE;
  if (strcmp_case(meta->general->sensor, "SEASAT") == 0) {
    setup->numProcessingSteps = 2;
    setup->processingStep = 
      (iso_procStep *) CALLOC(1,sizeof(iso_procStep)*setup->numProcessingSteps);
    strcpy(setup->processingStep[0].softwareID, "prep_raw");
    strcpy(setup->processingStep[0].softwareVersion, "1.2");
    strcpy(setup->processingStep[0].description, "pre-processing of raw data");
    strcpy(setup->processingStep[0].algorithm, 
	   "various level for cleaning up the header information");
    setup->processingStep[0].processingLevel = PRE_PROCESSING;
    setup->processingStep[0].processingTimeUTC.year = MAGIC_UNSET_INT;
    setup->processingStep[0].processingTimeUTC.month = MAGIC_UNSET_INT;
    setup->processingStep[0].processingTimeUTC.day = MAGIC_UNSET_INT;
    setup->processingStep[0].processingTimeUTC.hour = MAGIC_UNSET_INT;
    setup->processingStep[0].processingTimeUTC.min = MAGIC_UNSET_INT;
    setup->processingStep[0].processingTimeUTC.second = MAGIC_UNSET_DOUBLE;

    sprintf(setup->processingStep[1].softwareID, "%s", TOOL_SUITE_NAME);
    sprintf(setup->processingStep[1].softwareVersion, "%s", 
	    TOOL_SUITE_VERSION_STRING);
    strcpy(setup->processingStep[1].description, 
	   "processing of raw data to detected imagery");
    strcpy(setup->processingStep[1].algorithm, 
	   "customized ROI processing of raw data; "
	   "conversion of data from ROI to ASF format; "
	   "conversion of data from ASF to HDF5 format.");
    setup->processingStep[1].processingLevel = LEVEL_ONE;
    setup->processingStep[1].processingTimeUTC.year = MAGIC_UNSET_INT;
    setup->processingStep[1].processingTimeUTC.month = MAGIC_UNSET_INT;
    setup->processingStep[1].processingTimeUTC.day = MAGIC_UNSET_INT;
    setup->processingStep[1].processingTimeUTC.hour = MAGIC_UNSET_INT;
    setup->processingStep[1].processingTimeUTC.min = MAGIC_UNSET_INT;
    setup->processingStep[1].processingTimeUTC.second = MAGIC_UNSET_DOUBLE;
  }

  // Processing
  strcpy(proc->dopplerBasebandEstimationMethod, "azimuth cross correlation");
  if (strcmp_case(meta->general->sensor, "SEASAT") == 0)
    proc->dopplerCentroidCoordinateType = RAW_COORD;
  proc->doppler = (iso_dopplerCentroid *) CALLOC(1,sizeof(iso_dopplerCentroid));
  if (strcmp_case(meta->general->sensor, "SEASAT") == 0) {
    proc->doppler[0].polLayer = HH_POL;
    proc->doppler[0].numberOfBlocks = MAGIC_UNSET_INT;
    proc->doppler[0].numberOfRejectedBlocks = MAGIC_UNSET_INT;
    proc->doppler[0].numberOfDopperRecords = 1;
    proc->doppler[0].timeUTC.year = MAGIC_UNSET_INT;
    proc->doppler[0].timeUTC.month = MAGIC_UNSET_INT;
    proc->doppler[0].timeUTC.day = MAGIC_UNSET_INT;
    proc->doppler[0].timeUTC.hour = MAGIC_UNSET_INT;
    proc->doppler[0].timeUTC.min = MAGIC_UNSET_INT;
    proc->doppler[0].timeUTC.second = MAGIC_UNSET_DOUBLE;
    proc->doppler[0].dopplerAtMidRange =
      meta_get_dop(meta, (double) line_count/2, (double) sample_count/2);
    proc->doppler[0].polynomialDegree = 2;
    proc->doppler[0].coefficient = (double *) CALLOC(3, sizeof(double));
    proc->doppler[0].coefficient[0] = meta->sar->range_doppler_coefficients[0];
    proc->doppler[0].coefficient[1] = meta->sar->range_doppler_coefficients[1];
    proc->doppler[0].coefficient[2] = meta->sar->range_doppler_coefficients[2];
  }
  // FIXME: ScanSAR will need processing parameters per beam
  proc->processingParameter = 
    (iso_processingParameter *) CALLOC(1, sizeof(iso_processingParameter));
  proc->processingParameter[0].processingInfoCoordinateType = RAW_COORD;
  proc->processingParameter[0].rangeLooks = (float) meta->sar->range_look_count;
  proc->processingParameter[0].azimuthLooks = 
    (float) meta->sar->azimuth_look_count;
  proc->processingParameter[0].rangeLookBandwidth = 0;
  proc->processingParameter[0].azimuthLookBandwidth =
    meta->sar->azimuth_processing_bandwidth;
  proc->processingParameter[0].totalProcessedRangeBandwidth = 0;
  proc->processingParameter[0].totalProcessedAzimuthBandwidth =
    meta->sar->azimuth_processing_bandwidth;
  proc->processingParameter[0].chirpRate = meta->sar->chirp_rate;
  proc->processingParameter[0].pulseDuration = meta->sar->pulse_duration;
  // rangeCompression ???
  // FIXME: check all the flags
  proc->chirpReplicaUsedFlag = TRUE;
  proc->geometricDopplerUsedFlag = FALSE;
  proc->azimuthPatternCorrectedFlag = FALSE;
  proc->elevationPatternCorrectedFlag = FALSE;
  if (meta->sar->image_type == 'S')
    proc->detectedFlag = FALSE;
  else if (meta->sar->image_type == 'G')
    proc->detectedFlag = TRUE;
  proc->multiLookedFlag = meta->sar->multilook;
  proc->polarimetricProcessedFlag = FALSE;
  proc->terrainCorrectedFlag = FALSE;
  proc->layoverShadowMaskGeneratedFlag = FALSE;
  proc->geocodedFlag = FALSE;
  proc->nominalProcessingPerformedFlag = TRUE;

  // Instrument
  if (strcmp_case(meta->general->sensor, "SEASAT") == 0)
    inst->instrumentInfoCoordinateType = RAW_COORD;
  inst->centerFrequency = SPD_LIGHT / meta->sar->wavelength;
  inst->settings = (iso_settings *) CALLOC(numLayers, sizeof(iso_settings));
  for (ii=0; ii<numLayers; ii++) {
    iso_settings set;
    if (strcmp_case(meta->general->sensor, "SEASAT") == 0) {
      set.polLayer = polLayer[ii];
      strcpy(set.beamID, beamID[ii]);
    }
    set.rxBandwidth = MAGIC_UNSET_DOUBLE;
    set.rsf = meta->sar->range_sampling_rate;
    set.numberOfPRFChanges = MAGIC_UNSET_INT;
    set.numberOfEchoWindowPositionChanges = MAGIC_UNSET_INT;
    set.numberOfEchoWindowLengthChanges = MAGIC_UNSET_INT;
    set.numberOfSettingRecords = MAGIC_UNSET_INT;
    int numRec = set.numberOfSettingRecords;
    numRec = 1;
    set.settingRecord = 
      (iso_settingRecord *) CALLOC(numRec, sizeof(iso_settingRecord));
    for (kk=0; kk<numRec; kk++) {
      iso_settingRecord rec;
      rec.startTimeUTC.year = MAGIC_UNSET_INT;
      rec.startTimeUTC.month = MAGIC_UNSET_INT;
      rec.startTimeUTC.day = MAGIC_UNSET_INT;
      rec.startTimeUTC.hour = MAGIC_UNSET_INT;
      rec.startTimeUTC.min = MAGIC_UNSET_INT;
      rec.startTimeUTC.second = MAGIC_UNSET_DOUBLE;
      rec.stopTimeUTC.year = MAGIC_UNSET_INT;
      rec.stopTimeUTC.month = MAGIC_UNSET_INT;
      rec.stopTimeUTC.day = MAGIC_UNSET_INT;
      rec.stopTimeUTC.hour = MAGIC_UNSET_INT;
      rec.stopTimeUTC.min = MAGIC_UNSET_INT;
      rec.stopTimeUTC.second = MAGIC_UNSET_DOUBLE;
      rec.numberOfRows = MAGIC_UNSET_INT;
      rec.prf = MAGIC_UNSET_DOUBLE;
      rec.echoWindowPosition = MAGIC_UNSET_DOUBLE;
      rec.echoWindowLength = MAGIC_UNSET_DOUBLE;
      strcpy(rec.pulseType, "standard");
      set.settingRecord[kk] = rec;
    }
    inst->settings[ii] = set;
  }

  // Platform
  platform->sensor = PREDICTED_SENSOR;
  platform->accuracy = RESTITUTED_ORBIT;
  strcpy(platform->stateVectorRefFrame, "WGS84");
  platform->stateVectorTimeSpacing = meta->state_vectors->vecs[1].time;
  platform->numStateVectors = meta->state_vectors->vector_count;
  platform->stateVec = 
    (iso_stateVec *) CALLOC(platform->numStateVectors, sizeof(iso_stateVec));
  hms_time hms;
  ymd_date ymd;
  if (meta->sar->azimuth_time_per_pixel > 0) {
    dateTimeStamp(meta, 0, &platform->firstStateTimeUTC); 
    dateTimeStamp(meta, meta->general->line_count, &platform->lastStateTimeUTC);
  }
  else {
    dateTimeStamp(meta, meta->general->line_count, &platform->firstStateTimeUTC); 
    dateTimeStamp(meta, 0, &platform->lastStateTimeUTC);
  }
  ymd.year = platform->firstStateTimeUTC.year;
  ymd.month = platform->firstStateTimeUTC.month;
  ymd.day = platform->firstStateTimeUTC.day;
  hms.hour = platform->firstStateTimeUTC.hour;
  hms.min = platform->firstStateTimeUTC.min;
  hms.sec = platform->firstStateTimeUTC.second;
  for (ii=0; ii<platform->numStateVectors; ii++) {
    if (ii > 0)
      add_time(platform->stateVectorTimeSpacing, &ymd, &hms);
    else
      add_time(meta->state_vectors->vecs[0].time, &ymd, &hms);
    platform->stateVec[ii].timeUTC.year = ymd.year;
    platform->stateVec[ii].timeUTC.month = ymd.month;
    platform->stateVec[ii].timeUTC.day = ymd.day;
    platform->stateVec[ii].timeUTC.hour = hms.hour;
    platform->stateVec[ii].timeUTC.min = hms.min;
    platform->stateVec[ii].timeUTC.second = hms.sec;
    platform->stateVec[ii].posX = meta->state_vectors->vecs[ii].vec.pos.x;
    platform->stateVec[ii].posY = meta->state_vectors->vecs[ii].vec.pos.y;
    platform->stateVec[ii].posZ = meta->state_vectors->vecs[ii].vec.pos.z;
    platform->stateVec[ii].velX = meta->state_vectors->vecs[ii].vec.vel.x;
    platform->stateVec[ii].velY = meta->state_vectors->vecs[ii].vec.vel.y;
    platform->stateVec[ii].velZ = meta->state_vectors->vecs[ii].vec.vel.z;
  }

  // Product Quality
  quality->rawDataQuality = 
    (iso_rawDataQuality *) CALLOC(numLayers, sizeof(iso_rawDataQuality));  
  for (ii=0; ii<numLayers; ii++) {
    quality->rawDataQuality[ii].polLayer = polLayer[ii];
    strcpy(quality->rawDataQuality[0].beamID, beamID[ii]);
    quality->rawDataQuality[ii].numGaps = 0;

    /* Information is now passed as gap file into iso_meta_write
    // need to get this information from somewhere else
    quality->rawDataQuality[ii].numGaps = 1;
    quality->rawDataQuality[ii].gap = (iso_gap *) CALLOC(1, sizeof(iso_gap));
    quality->rawDataQuality[ii].gap[0].start = 0;
    quality->rawDataQuality[ii].gap[0].length = MAGIC_UNSET_INT;
    quality->rawDataQuality[ii].gap[0].fill = RANDOM_FILL;
    quality->rawDataQuality[ii].gapSignificanceFlag = FALSE;
    quality->rawDataQuality[ii].missingLinesSignificanceFlag = FALSE;
    quality->rawDataQuality[ii].bitErrorSignificanceFlag = FALSE;
    quality->rawDataQuality[ii].timeReconstructionSignificanceFlag = FALSE;
    */
  }
  quality->dopplerAmbiguityNotZeroFlag = FALSE;
  quality->dopplerOutsideLimitsFlag = FALSE;
  quality->geolocationQualityLowFlag = FALSE;
  quality->imageDataQuality = 
    (iso_imageDataQuality *) CALLOC(numLayers, sizeof(iso_imageDataQuality));  
  for (ii=0; ii<numLayers; ii++) {
    quality->imageDataQuality[ii].polLayer = polLayer[ii];
    strcpy(quality->imageDataQuality[0].beamID, beamID[ii]);
    // need to get this information from somewhere else
    quality->imageDataQuality[ii].min = MAGIC_UNSET_DOUBLE;
    quality->imageDataQuality[ii].max = MAGIC_UNSET_DOUBLE;
    quality->imageDataQuality[ii].mean = MAGIC_UNSET_DOUBLE;
    quality->imageDataQuality[ii].stdDev = MAGIC_UNSET_DOUBLE;
    quality->imageDataQuality[ii].missingLines = meta->general->missing_lines;
    quality->imageDataQuality[ii].bitErrorRate = meta->general->bit_error_rate;
    quality->imageDataQuality[ii].noData = (double) meta->general->no_data;
  }
  quality->gapDefinition = 8;
  // These limits need to be defined per satellite
  if (strcmp_case(meta->general->sensor, "SEASAT") == 0) {
    quality->gapPercentageLimit = MAGIC_UNSET_DOUBLE;
    quality->missingLinePercentageLimit = MAGIC_UNSET_DOUBLE;
    quality->bitErrorLimit = MAGIC_UNSET_DOUBLE;
    quality->timeReconstructionPercentageLimit = MAGIC_UNSET_DOUBLE;
    quality->dopplerCentroidLimit = MAGIC_UNSET_DOUBLE;
    quality->geolocationQualityLimit = MAGIC_UNSET_DOUBLE;
  }

  return iso;
}
Exemplo n.º 8
0
meta_parameters* uavsar_polsar2meta(uavsar_polsar *params)
{
  meta_parameters *meta;

  // Allocate memory for metadata structure
  meta = raw_init();

  // General block
  sprintf(meta->general->basename, "%s", params->site);
  sprintf(meta->general->sensor, "UAVSAR");
  strcpy(meta->general->sensor_name, "PolSAR");
  strcpy(meta->general->processor, "JPL version ");
  strcat(meta->general->processor, params->processor);
  if (params->type == POLSAR_SLC) {
    strcpy(meta->general->mode, "SLC");
    meta->general->image_data_type = POLARIMETRIC_S2_MATRIX;
  }
  else if (params->type == POLSAR_MLC) {
    strcpy(meta->general->mode, "MLC");
    meta->general->image_data_type = POLARIMETRIC_C3_MATRIX;
  }
  else if (params->type == POLSAR_DAT) {
    strcpy(meta->general->mode, "DAT");
    meta->general->image_data_type = POLARIMETRIC_STOKES_MATRIX;
  }
  else if (params->type == POLSAR_GRD) {
    strcpy(meta->general->mode, "GRD");
    meta->general->image_data_type = POLARIMETRIC_C3_MATRIX;
    meta->general->no_data = 0;
  }
  else if (params->type == POLSAR_HGT) {
    strcpy(meta->general->mode, "HGT");
    meta->general->image_data_type = DEM;
  }
  else
    strcpy(meta->general->mode, "unknown");
  meta->general->radiometry = r_GAMMA;
  meta->general->data_type = REAL32;
  strcpy(meta->general->acquisition_date, params->acquisition_date);
  meta->general->band_count = 1;
  meta->general->line_count = params->row_count;
  meta->general->sample_count = params->column_count;
  meta->general->start_line = 0;
  meta->general->start_sample = 0;
  meta->general->x_pixel_size = params->range_pixel_spacing;
  meta->general->y_pixel_size = fabs(params->azimuth_pixel_spacing);
  meta->general->re_major = params->semi_major;
  double re = params->semi_major;
  double ecc2 = params->eccentricity;
  double rp = sqrt((1-ecc2)*re*re);
  meta->general->re_minor = rp;
  // no information on bit error rate, missing lines and no data

  // SAR block
  meta->sar = meta_sar_init();
  strcpy(meta->sar->polarization, "QUAD-POL");
  if (strcmp_case(params->projection, "SCX") == 0)
    meta->sar->image_type = 'S';
  else if (strcmp_case(params->projection, "EQA") == 0)
    meta->sar->image_type = 'P';
  if (strcmp_case(params->look_direction, "Left") == 0)
    meta->sar->look_direction = 'L';
  else if (strcmp_case(params->look_direction, "Right") == 0)
    meta->sar->look_direction = 'R';
  if (params->type == POLSAR_SLC) {
    meta->sar->azimuth_look_count = 1;
    meta->sar->range_look_count = 1;
    meta->sar->multilook = 0;
  }
  else {
    // FIXME: Update once range look count is introduced to metadata structure
    meta->sar->azimuth_look_count = params->azimuth_look_count;
    meta->sar->range_look_count = params->range_look_count;
    meta->sar->multilook = 1;
  }
  meta->sar->deskewed = 1;
  meta->sar->original_line_count = params->row_count;
  meta->sar->original_sample_count = params->column_count;
  meta->sar->line_increment = 1;
  meta->sar->sample_increment = 1;
  // no information on azimuth and range time per pixel
  meta->sar->time_shift = 0.0;
  meta->sar->slant_shift = 0.0;
  meta->sar->slant_range_first_pixel = params->slant_range_first_pixel * 1000.0;
  meta->sar->wavelength = params->wavelength / 100.0;
  // no information on pulse repetition frequency
  double tan_lat = params->lat_peg_point*D2R;
  meta->sar->earth_radius = rp*sqrt(1 + tan_lat*tan_lat) /
    sqrt(rp*rp/(re*re) + tan_lat*tan_lat);
  // no information on satellite height
  // no time information
  // no Doppler information
  meta->sar->yaw = params->yaw;
  meta->sar->pitch = params->pitch;
  meta->sar->roll = params->roll;
  meta->sar->azimuth_processing_bandwidth = params->bandwidth;
  // no chirp rate information
  meta->sar->pulse_duration = params->pulse_length / 1000.0;
  // no information on range sampling rate
  // FIXME: check polarizations for interferometric/polarimetric data
  // FIXME: multilook flag depends on data type
  
  // UAVSAR block
  meta->uavsar = meta_uavsar_init();
  strcpy(meta->uavsar->id, params->id);
  meta->uavsar->scale_factor = 1.0;
  meta->uavsar->gps_altitude = params->altitude;
  meta->uavsar->lat_peg_point = params->lat_peg_point;
  meta->uavsar->lon_peg_point = params->lon_peg_point;
  meta->uavsar->head_peg_point = params->head_peg_point;
  meta->uavsar->along_track_offset = params->along_track_offset;
  meta->uavsar->cross_track_offset = params->cross_track_offset;

  // Location block
  meta->location = meta_location_init();
  meta->location->lat_start_near_range = params->lat_upper_left;
  meta->location->lon_start_near_range = params->lon_upper_left;
  meta->location->lat_start_far_range = params->lat_upper_right;
  meta->location->lon_start_far_range = params->lon_upper_right;
  meta->location->lat_end_near_range = params->lat_lower_left;
  meta->location->lon_end_near_range = params->lon_lower_left;
  meta->location->lat_end_far_range = params->lat_lower_right;
  meta->location->lon_end_far_range = params->lon_lower_right;

  // Projection block
  if (params->type == POLSAR_GRD || params->type == POLSAR_HGT) {
    meta->projection = meta_projection_init();
    meta->projection->type = LAT_LONG_PSEUDO_PROJECTION;
    strcpy (meta->projection->units, "degrees");
    if (params->along_track_offset >= 0.0)
      meta->projection->hem = 'N';
    else
      meta->projection->hem = 'S';
    meta->projection->re_major = meta->general->re_major;
    meta->projection->re_minor = meta->general->re_minor;
    meta->projection->height = 0.0;
    meta->projection->spheroid = WGS84_SPHEROID;
    meta->projection->datum = WGS84_DATUM;

    // Coordinate reference: Point
    // UAVSAR lat/lon projected data is calculated from center
    // pixel.  Thus we have to add in a half-pixel shift.
    meta->projection->startX = 
      params->cross_track_offset - params->range_pixel_spacing / 2.0;
    meta->projection->startY = 
      params->along_track_offset - params->azimuth_pixel_spacing / 2.0;
    meta->projection->perX = params->range_pixel_spacing;
    meta->projection->perY = params->azimuth_pixel_spacing;

    meta->general->center_latitude = params->along_track_offset + 
      params->azimuth_pixel_spacing * params->row_count / 2.0;
    meta->general->center_longitude = params->cross_track_offset +
      params->range_pixel_spacing * params->column_count / 2.0;
  }
  else {
    meta_get_latLon(meta, meta->general->line_count/2, meta->general->sample_count/2, 0,
                    &meta->general->center_latitude, &meta->general->center_longitude);
  }

  return meta;
}
Exemplo n.º 9
0
void update_pixel_info(ImageInfo *ii)
{
    // update the left-hand "clicked pixel" information
    char buf[512];

    GtkWidget *img = get_widget_checked("big_image");
    GdkPixbuf *shown_pixbuf = gtk_image_get_pixbuf(GTK_IMAGE(img));

    double x = crosshair_samp;
    double y = crosshair_line;
    int nl = ii->meta->general->line_count;
    int ns = ii->meta->general->sample_count;
    CachedImage *data_ci = ii->data_ci;
    meta_parameters *meta = ii->meta;

    sprintf(buf, "Line: %.1f, Sample: %.1f\n", y, x);

    if (x < 0 || x >= ns || y < 0 || y >= nl)
    {
        // outside of the image
        sprintf(&buf[strlen(buf)], "Pixel Value: (outside image)\n");
    }
    else
    {
        assert(meta);
        assert(shown_pixbuf);

        if (data_ci->data_type == GREYSCALE_FLOAT) {
            float fval = cached_image_get_pixel(data_ci,
                crosshair_line, crosshair_samp);
            if (have_lut()) {
                unsigned char r, g, b;
                cached_image_get_rgb(data_ci, crosshair_line, crosshair_samp,
                                     &r, &g, &b);
                if (is_ignored(&ii->stats, fval)) {
                  sprintf(&buf[strlen(buf)], "Pixel Value: %f [ignored]\n",
                          fval);
                }
                else {
                  sprintf(&buf[strlen(buf)],
                          "Pixel Value: %f -> R:%d G:%d B:%d\n",
                          fval, (int)r, (int)g, (int)b);
                }
            }
            else {
                int uval = calc_scaled_pixel_value(&(ii->stats), fval);

                if (is_ignored(&ii->stats, fval)) {
                  sprintf(&buf[strlen(buf)], "Pixel Value: %f [ignored]\n",
                          fval);
                }
                else {
                  sprintf(&buf[strlen(buf)], "Pixel Value: %f -> %d\n",
                          fval, uval);
                }
            }
        }
        else if (data_ci->data_type == RGB_BYTE) {
            unsigned char r, g, b;
            float rf, gf, bf;
            cached_image_get_rgb(data_ci, crosshair_line, crosshair_samp,
                &r, &g, &b);
            cached_image_get_rgb_float(data_ci, crosshair_line, crosshair_samp,
                &rf, &gf, &bf);

            if (!is_ignored_rgb(&ii->stats_r, rf) &&
                !is_ignored_rgb(&ii->stats_g, gf) &&
                !is_ignored_rgb(&ii->stats_b, bf))
            {
              sprintf(&buf[strlen(buf)], "Pixel Value: R,G,B = %d, %d, %d\n",
                      (int)r, (int)g, (int)b);
            }
            else {
              sprintf(&buf[strlen(buf)],
                      "Pixel Value: R,G,B = %d,%d,%d [ignored]\n",
                      (int)rf, (int)gf, (int)bf);
            }
        }
        else if (data_ci->data_type == GREYSCALE_BYTE) {
            unsigned char r, g, b;
            cached_image_get_rgb(data_ci, crosshair_line, crosshair_samp,
                                 &r, &g, &b);
            if (have_lut()) {
                int gs = (int)cached_image_get_pixel(data_ci,
                             crosshair_line, crosshair_samp);
                if (is_ignored(&ii->stats, (float)gs))
                    sprintf(&buf[strlen(buf)],
                            "Pixel Value: %d [ignored]\n",
                            gs);
                else
                    sprintf(&buf[strlen(buf)],
                            "Pixel Value: %d -> R:%d G:%d B:%d\n",
                            gs, (int)r, (int)g, (int)b);
            }
            else {
                int gs = (int)cached_image_get_pixel(data_ci,
                             crosshair_line, crosshair_samp);
                if (is_ignored(&ii->stats, gs)) {
                    sprintf(&buf[strlen(buf)], "Pixel Value: %d [ignored]\n",
                            gs);
                }
                else if (ii->stats.truncate) {
                    sprintf(&buf[strlen(buf)], "Pixel Value: %d\n", gs);
                }
                else {
                    sprintf(&buf[strlen(buf)], "Pixel Value: %d -> %d\n",
                            gs, (int)r);
                }
            }
        }
        else if (data_ci->data_type == RGB_FLOAT) {
            unsigned char r, g, b;
            float rf, gf, bf;
            cached_image_get_rgb(data_ci, crosshair_line, crosshair_samp,
                &r, &g, &b);
            cached_image_get_rgb_float(data_ci, crosshair_line, crosshair_samp,
                &rf, &gf, &bf);

            if (is_ignored_rgb(&ii->stats_r, rf))
              sprintf(&buf[strlen(buf)],  "Red: %f [ignored]\n", rf);
            else
              sprintf(&buf[strlen(buf)],  "Red: %f -> %d\n", rf, (int)r);

            if (is_ignored_rgb(&ii->stats_g, gf))
              sprintf(&buf[strlen(buf)],  "Green: %f [ignored]\n", gf);
            else
              sprintf(&buf[strlen(buf)],  "Green: %f -> %d\n", gf, (int)g);

            if (is_ignored_rgb(&ii->stats_b, bf))
              sprintf(&buf[strlen(buf)],  "Blue: %f [ignored]\n", rf);
            else
              sprintf(&buf[strlen(buf)],  "Blue: %f -> %d\n", bf, (int)b);
        }
    }

    double lat=0, lon=0;
    if (meta_supports_meta_get_latLon(meta))
    {
        meta_get_latLon(meta, y, x, 0, &lat, &lon);
        sprintf(&buf[strlen(buf)], "Lat, Lon: %.5f, %.5f (deg)\n", lat, lon);

        //double px, py;
        //latLon2UTM(lat,lon,0,&px,&py);
        //printf("%14.7f %14.7f --> %13.2f %13.2f\n", lat, lon, px, py);
    }

    // skip projection coords if not projected, or lat/long pseudo (since
    // in that case the projection coords are just the lat/long values
    // we are already showing)
    if (meta->projection &&
        meta->projection->type != LAT_LONG_PSEUDO_PROJECTION)
    {
        double projX, projY, projZ;
        latlon_to_proj(meta->projection, 'R', lat*D2R, lon*D2R, 0,
            &projX, &projY, &projZ);
        sprintf(&buf[strlen(buf)], "Proj X,Y: %.1f, %.1f m\n",
            projX, projY);
    }

    if (!meta->projection && meta->state_vectors && meta->sar) {
        double s,t;
        meta_get_timeSlantDop(meta, y, x, &t, &s, NULL);
        sprintf(&buf[strlen(buf)],
            "Incid: %.4f, Look: %.4f (deg)\n"
            "Slant: %.1f m Time: %.3f s\n"
            "Yaw: %.4f (deg)\n",
            R2D*meta_incid(meta,y,x), R2D*meta_look(meta,y,x), s, t,
            R2D*meta_yaw(meta,y,x));
    }

    if (meta->projection &&
        meta->projection->type != LAT_LONG_PSEUDO_PROJECTION &&
	meta->projection->type != SCANSAR_PROJECTION) {
      distortion_t d;
      map_distortions(meta->projection, lat*D2R, lon*D2R, &d);
      sprintf(&buf[strlen(buf)], "Meridian scale factor: %.6f\n", d.h);
      sprintf(&buf[strlen(buf)], "Parallel scale factor: %.6f\n", d.k);
      sprintf(&buf[strlen(buf)], "Areal scale factor: %.6f\n", d.s);
      sprintf(&buf[strlen(buf)], "Angular distortion: %.4f (deg)\n", d.omega);
    }

    if (g_poly->n > 0) {
        // start distance measure at crosshair coords
        double cross_x, cross_y, prev_x, prev_y;
        line_samp_to_proj(ii, y, x, &cross_x, &cross_y);
        prev_x = cross_x; prev_y = cross_y;

        // iterate through ctrl-clicked coords
        int i;
        double d=0, A=0; // d=distance, A=area
        for (i=0; i<g_poly->n; ++i) {
            double proj_x, proj_y;       
            line_samp_to_proj(ii, g_poly->line[i], g_poly->samp[i],
                              &proj_x, &proj_y);

            d += hypot(proj_x-prev_x, proj_y-prev_y);
            A += prev_x * proj_y - proj_x * prev_y;

            prev_x = proj_x; prev_y = proj_y;

            // for the area calc, we close the polygon automatically
            if (i==g_poly->n-1)
                A += prev_x * cross_y - cross_x * prev_y;
        }
        A /= 2.;

        char *units = "m";
        if (!meta_supports_meta_get_latLon(meta))
            units = "pixels";

        if (g_poly->n == 1)
            sprintf(&buf[strlen(buf)], "Distance to %.1f,%.1f: %.1f %s",
                g_poly->line[0], g_poly->samp[0], d, units);
        else
            sprintf(&buf[strlen(buf)],
                "Total distance: %.1f %s (%d points)\n"
                "Area (of closure): %.1f %s^2",
                d, units, g_poly->n+1, fabs(A), units);
    } else {
        sprintf(&buf[strlen(buf)], "Distance: (ctrl-click to measure)");
    }

    put_text_in_textview(buf, "info_textview");
    //GtkWidget *lbl = get_widget_checked("upper_label");
    //gtk_label_set_text(GTK_LABEL(lbl), buf);
}
Exemplo n.º 10
0
/*
  writePatch:
  Outputs one full patch of data to the given file.
*/
void writePatch(const patch *p,const satellite *s,meta_parameters *meta,
    const file *f,int patchNo)
{
  int outLine;       /* Counter for line base output */
  FILE *fp_amp,*fp_cpx;  /* File pointers for the amplitude and  complex outputs*/
  FILE *fp_pwr,*fp_sig;  /* File pointers for the power and Sigma_0 outputs */
  FILE *fp_gam,*fp_bet;  /* File pointers for the Gamma_0 and Beta_0 outputs */
  complexFloat *outputBuf; /* Buffer for one line of patch = n_range    */
  complexFloat *mlBuf;   /* Buffer for multilooking the amplitude image */
  float *amps;           /* Output Amplitude  = n_az/nlooks X n_range */
  float *pwrs;       /* Output power */
  char *openMode="ab";   /* Normally append output.*/
  int mlCount=0;     /* Counter for setting up the multilook buffer */
  int writeNoiseTable=0; /* Flag to determine whether to write the noise table and
                antenna pattern */
  int off_slc = f->n_az_valid * (patchNo-1);
  int off_ml = f->n_az_valid * (patchNo-1) / (f->nlooks);

  if (patchNo==1)
    openMode="wb";   /* for first patch, truncate output. */

  if ((patchNo==1) && (s->vecLen!=0))
    writeNoiseTable=1;  /* If first patch AND antenna pattern correction,
               write the noise table */

  update_status("Range-doppler done");
  if (!quietflag) printf("   WRITING PATCH OUT...\n");
  elapse(0);

  /* Allocate buffer space  ------------------------*/
  amps = (float *) MALLOC(p->n_range*sizeof(float));
  pwrs = (float *) MALLOC(p->n_range*sizeof(float));

  outputBuf = (complexFloat *)MALLOC(p->n_range*sizeof(complexFloat));
  mlBuf = (complexFloat *)MALLOC(p->n_range*f->nlooks*sizeof(complexFloat));

  /* Fill in metadata */
  meta_get_latLon(meta, meta->general->line_count/2,
          meta->general->sample_count/2, 0.0,
          &(meta->general->center_latitude),
          &(meta->general->center_longitude));

  meta_parameters *metaCpx=meta_copy(meta);
  metaCpx->general->data_type = COMPLEX_REAL32;
  metaCpx->general->image_data_type = COMPLEX_IMAGE;
  metaCpx->general->radiometry = r_AMP;
  metaCpx->general->line_count = f->n_az_valid * patchNo;
  metaCpx->general->sample_count = p->n_range;
  meta_get_latLon(metaCpx, metaCpx->general->line_count/2,
          metaCpx->general->sample_count/2, 0.0,
          &(metaCpx->general->center_latitude),
          &(metaCpx->general->center_longitude));
  metaCpx->general->start_line = f->firstLineToProcess + s->dop_precomp + 1;
  metaCpx->general->start_sample = f->skipFile + 1;
  metaCpx->general->x_pixel_size = f->rngpix;
  metaCpx->general->y_pixel_size = f->azpix;
  meta_write(metaCpx, f->out_cpx);
  fp_cpx=fopenImage(f->out_cpx,openMode);

  meta_parameters *metaAmp=meta_copy(metaCpx);
  metaAmp->general->data_type = REAL32;
  metaAmp->general->image_data_type = AMPLITUDE_IMAGE;
  metaAmp->general->radiometry = r_AMP;
  metaAmp->general->line_count = f->n_az_valid / f->nlooks * patchNo;
  metaAmp->general->y_pixel_size *= f->nlooks;
  metaAmp->sar->azimuth_time_per_pixel *= f->nlooks;
  meta_write(metaAmp, f->out_amp);
  fp_amp=fopenImage(f->out_amp,openMode);

  meta_parameters *metaPower=0, *metaSigma=0, *metaGamma=0, *metaBeta=0;
  if (s->imageType.power) {
    metaPower=meta_copy(metaAmp);
    metaPower->general->image_data_type = AMPLITUDE_IMAGE;
    metaPower->general->radiometry = r_POWER;
    meta_write(metaPower, f->out_pwr);
    fp_pwr=fopenImage(f->out_pwr,openMode);
  }
  if (s->imageType.sigma) {
    metaSigma=meta_copy(metaAmp);
    metaSigma->general->image_data_type = AMPLITUDE_IMAGE;
    metaSigma->general->radiometry = r_SIGMA;
    meta_write(metaSigma, f->out_sig);
    fp_sig=fopenImage(f->out_sig,openMode);
  }
  if (s->imageType.gamma) {
    metaGamma=meta_copy(metaAmp);
    metaGamma->general->image_data_type = AMPLITUDE_IMAGE;
    metaGamma->general->image_data_type = r_GAMMA;
    meta_write(metaGamma, f->out_gam);
    fp_gam=fopenImage(f->out_gam,openMode);
  }
  if (s->imageType.beta) {
    metaBeta=meta_copy(metaAmp);
    metaBeta->general->image_data_type = AMPLITUDE_IMAGE;
    metaBeta->general->radiometry = r_BETA;
    meta_write(metaBeta, f->out_bet);
    fp_bet=fopenImage(f->out_bet,openMode);
  }

  /* This gets messy */
  for (outLine = 0; outLine < f->n_az_valid; outLine++)
  {
      int j; /* loop counter */
      int base = f->firstOutputLine+outLine; /* loop counter for transposed data */

      if(writeNoiseTable==1) {
          if (!quietflag) printf("   Writing .noise and .ant files\n");
      }

      /* Print statement for the antenna pattern correction option */
      if(s->vecLen==0) {
          if(!quietflag && (outLine % 1024 == 0)) {
              printf("   ...Writing Line %i\n",outLine);
          }
      }
      if(s->vecLen!=0) {
          if(!quietflag && (outLine % 1024 == 0)) {
              printf("   ...Writing Line %i and applying Antenna Pattern Correction\n",
                     outLine);
          }
      }

      /* Fill up the buffers */
      for (j=0; j<p->n_range; j++,base+=p->n_az)
      {
          outputBuf[j] = p->trans[base];

          /* For speed, if we aren't correcting the antenna pattern,
             write the multi-look buffer now */
          if(s->vecLen==0)
          {
              mlBuf[j+mlCount*p->n_range].real = outputBuf[j].real;
              mlBuf[j+mlCount*p->n_range].imag = outputBuf[j].imag;
          }
      }

      /* Apply the Antenna Pattern Correction if desired */
      if(s->vecLen!=0)
      {

          /* On the first time through, write out the noise table */
          if(writeNoiseTable==1)
          {
              writeTable(meta,s,p->n_range);
              writeNoiseTable=0;
          }

          antptn_correct(meta,outputBuf,base,p->n_range,s);
          if(!quietflag && (j==0)) printf("   Correcting Line %d\n",outLine);

          /* Otherwise, write the multi-look buffer now */
          for(j=0;j<p->n_range;j++)
          {
              mlBuf[j+mlCount*p->n_range].real = outputBuf[j].real;
              mlBuf[j+mlCount*p->n_range].imag = outputBuf[j].imag;
          }
      }

      put_complexFloat_line(fp_cpx, metaCpx, outLine+off_slc, outputBuf);
      mlCount+=1;
      /* Multilook takes f->nlooks lines of data and averages them together,
         and writes one line on return */
      if(mlCount==f->nlooks)
      {
          /* multilook on the power image, then use the power image to generate
             an amplitude, and all other detected images from the command line.
             Be careful because I recycle amps after writing out the line of
             amplitude data, and it gets used as the sigma_0, beta_0, and gamma_0
             line. It my be confusing, but it uses less memory.*/
          multilook(mlBuf,p->n_range,f->nlooks,pwrs);
          intensity(p->n_range,pwrs,amps);

          put_float_line(fp_amp, metaAmp, outLine/f->nlooks+off_ml, amps);

          if (s->imageType.power) {
              put_float_line(fp_pwr, metaPower, outLine/f->nlooks+off_ml, pwrs);
          }
          if (s->imageType.sigma)
          {
              calculateRCS(SIGMA_0, meta, pwrs, amps,
                           base-mlCount/2, p->n_range,s);
              put_float_line(fp_sig, metaSigma, outLine/f->nlooks+off_ml, amps);
          }
          if (s->imageType.gamma)
          {
              calculateRCS(GAMMA_0, meta, pwrs, amps,
                           base-mlCount/2, p->n_range,s);
              put_float_line(fp_gam, metaGamma, outLine/f->nlooks+off_ml, amps);
          }
          if (s->imageType.beta)
          {
              calculateRCS(BETA_0, meta, pwrs, amps,
                           base-mlCount/2, p->n_range,s);
              put_float_line(fp_bet, metaBeta, outLine/f->nlooks+off_ml, amps);
          }

          mlCount=0;
      }
  }
  FCLOSE(fp_cpx);
  FCLOSE(fp_amp);
  if (s->imageType.power)
    FCLOSE(fp_pwr);
  if (s->imageType.sigma)
    FCLOSE(fp_sig);
  if (s->imageType.gamma)
    FCLOSE(fp_gam);
  if (s->imageType.beta)
    FCLOSE(fp_bet);

  if (!quietflag) printf("\n");
  if (logflag) printLog("\n");
  if (!quietflag) {
    printf("   AMPLITUDE IMAGE FINISHED: Wrote %i lines and %i samples\n",
           f->n_az_valid/f->nlooks,p->n_range);
    printf("   PATCH FINISHED: Wrote %i lines of %i samples (float)\n\n",
           f->n_az_valid,p->n_range);
  }
  FREE((void *)amps);
  FREE((void *)pwrs);
  FREE((void *)outputBuf);
  FREE((void *)mlBuf);
  meta_free(metaAmp);
  meta_free(metaCpx);
  if (metaPower) meta_free(metaPower);
  if (metaSigma) meta_free(metaSigma);
  if (metaGamma) meta_free(metaGamma);
  if (metaBeta)  meta_free(metaBeta);
  if (!quietflag) elapse(1);
}
Exemplo n.º 11
0
int main(int argc, char **argv)
{
  FILE *fp;
  meta_parameters *metaSrc, *metaTrg;
  envi_header *envi;
  extern int currArg;          // Pre-initialized to 1
  radiometry_t radiometry=r_AMP;
  filter_type_t filter_type;
  char srcImage[255], trgImage[255], *inFile, outFile[255], filter_str[25];
  int startX_src, startY_src, startX_trg, startY_trg, lines, samples, size;
  int subset=FALSE, filter=FALSE, geotiff=FALSE, line_count, sample_count;
  double lat_UL, lon_UL, lat_LR, lon_LR, yLine, xSample;
  float mean, scale;
  register float *img, *filtered_img=NULL;
  register int x, y, l;

  /* parse command line */
  logflag=quietflag=FALSE;
  while (currArg < (argc-2)) {
    char *key = argv[currArg++];
    if (strmatch(key,"-startX")) {
      CHECK_ARG(1);
      startX_src = atoi(GET_ARG(1));
      subset = TRUE;
    }
    else if (strmatch(key,"-startY")) {
      CHECK_ARG(1);
      startY_src = atoi(GET_ARG(1));
      subset = TRUE;
    }
    else if (strmatch(key,"-lines")) {
      CHECK_ARG(1);
      lines = atoi(GET_ARG(1));
      subset = TRUE;
    }
    else if (strmatch(key,"-samples")) {
      CHECK_ARG(1);
      samples = atoi(GET_ARG(1));
      subset = TRUE;
    }
    else if (strmatch(key,"-filter")) {
      CHECK_ARG(2);
      strcpy(filter_str, GET_ARG(2));
      size = atoi(GET_ARG(1));
      filter = TRUE;
    }
    else if (strmatch(key,"-geotiff")) {
      geotiff = TRUE;
    }
    else {
      printf( "\n**Invalid option:  %s\n", argv[currArg-1]);
      usage(argv[0]);
    }
  }

  if ((argc-currArg)<2) {printf("Insufficient arguments.\n"); usage(argv[0]);}

  strcpy (srcImage, argv[currArg]);
  strcpy (trgImage, argv[currArg+1]);

  asfSplashScreen(argc, argv);

  // Ingesting CEOS files into ASF internal format
  asfPrintStatus("Ingesting source image: %s ...\n", srcImage);
  asf_import(radiometry, FALSE, FALSE, FALSE, "CEOS", "", "geocoded_image", NULL, NULL,
	     -99.0, -99.0, NULL, NULL, NULL, TRUE, NULL, srcImage, "", srcImage);
  metaSrc = meta_read(srcImage);

  asfPrintStatus("Ingesting target image: %s ...\n", trgImage);
  asf_import(radiometry, FALSE, FALSE, FALSE, "CEOS", "", "geocoded_image", NULL, NULL,
	     -99.0, -99.0, NULL, NULL, NULL, TRUE, NULL, trgImage, "", trgImage);
  metaTrg = meta_read(trgImage);

  // Check subset values for source image
  line_count = metaSrc->general->line_count;
  sample_count = metaSrc->general->sample_count;
  if (subset) {
    if (startX_src < 0 || startX_src > sample_count)
      startX_src = 0;
    if (startY_src < 0 || startY_src > line_count)
      startY_src = 0;
    if (lines < 0 || (lines-startY_src) > line_count)
      lines = line_count - startY_src;
    if (samples < 0 || (samples-startX_src) > sample_count)
      samples = sample_count - startX_src;
  }
  else {
    startX_src = startY_src = 0;
    lines = line_count;
    samples = sample_count;
  }

  // Assign filter
  if (filter) {
    if (strcmp(uc(filter_str), "AVERAGE") == 0)
      filter_type = AVERAGE;
    else if (strcmp(uc(filter_str), "SOBEL") == 0)
      filter_type = SOBEL;
    else if (strcmp(uc(filter_str), "FROST") == 0)
      filter_type = FROST;
    else if (strcmp(uc(filter_str), "LEE") == 0)
      filter_type = LEE;
    else if (strcmp(uc(filter_str), "GAMMA_MAP") == 0)
      filter_type = GAMMA_MAP;
    else {
      asfPrintWarning("Unsupported filter type '%s'- ignoring the filter"
		      " settings\n", filter_str);
      filter = FALSE;
    }
    if (size%2 == 0 && filter_type != AVERAGE) {
      size--;
      asfPrintWarning("Filter kernel must have an odd number of lines and"
		      "samples!\n");
    }
  }

  // Allocate some memory for the subsets
  line_count = metaTrg->general->line_count;
  sample_count = metaTrg->general->sample_count;
  img = (float *) MALLOC(sizeof(float)*lines*samples);
  if (filter)
    filtered_img = (float *) MALLOC(sizeof(float)*lines*samples);

  // Determine geographic location of subset
  meta_get_latLon(metaSrc, startY_src, startX_src, 0.0, &lat_UL, &lon_UL);
  meta_get_latLon(metaSrc, startY_src+lines, startX_src+samples, 0.0,
		  &lat_LR, &lon_LR);
  meta_get_lineSamp(metaTrg, lat_UL, lon_UL, 0.0, &yLine, &xSample);
  startX_trg = (int) (xSample + 0.5);
  startY_trg = (int) (yLine + 0.5);

  // READ IN SUBSETS
  // Read target image subset first to determine average brightness
  asfPrintStatus("\nGenerating subset for target image ...\n");
  asfPrintStatus("start line: %d, start sample: %d, lines: %d, samples: %d\n",
		 startY_trg, startX_trg, lines, samples);
  inFile = appendExt(trgImage, ".img");
  sprintf(outFile, "%s_sub.img", trgImage);
  fp = FOPEN(inFile, "rb");
  read_subset(fp, metaTrg, startX_trg, startY_trg, samples, lines, 0.0,
	      &mean, img);
  FCLOSE(fp);

  // Compute scale factor
  mean *= -1;
  scale = 1.0 / (lines * samples);

  // Subtract this average off of target image
  for (y=0; y<lines; y++) {
    l = samples * y;
    for (x=0; x<samples; x++)
      img[l+x] = (img[l+x] + mean) * scale;
  }

  if (filter) {
    asfPrintStatus("\nFiltering target image subset with %s (%dx%d) ...\n",
		   uc(filter_str), size, size);
    filter_image(img, filtered_img, filter_type, size, lines, samples);
  }

  // Update metadata and write target subset to file
  metaTrg->general->line_count = lines;
  metaTrg->general->sample_count = samples;
  metaTrg->general->start_line = startY_trg;
  metaTrg->general->start_sample = startX_trg;
  meta_write(metaTrg, outFile);
  envi = meta2envi(metaTrg);
  write_envi_header(outFile, outFile, metaTrg, envi);

  fp = FOPEN(outFile, "wb");
  if (filter)
    put_float_lines(fp, metaTrg, 0, lines, filtered_img);
  else
    put_float_lines(fp, metaTrg, 0, lines, img);
  FCLOSE(fp);

  // Read source image subset applying for brightness
  asfPrintStatus("\nGenerating subset for source image ...\n");
  asfPrintStatus("start line: %d, start sample: %d, lines: %d, samples: %d\n",
		 startY_src, startX_src, lines, samples);
  inFile = appendExt(srcImage, ".img");
  sprintf(outFile, "%s_sub.img", srcImage);
  fp = FOPEN(inFile, "rb");
  read_subset(fp, metaSrc, startX_src, startY_src, samples, lines, mean,
	      NULL, img);
  FCLOSE(fp);

  if (filter) {
    asfPrintStatus("\nFiltering source image subset with %s (%dx%d) ...\n",
		   uc(filter_str), size, size);
    filter_image(img, filtered_img, filter_type, size, lines, samples);
  }

  // Update metadata and write source subset to file
  metaSrc->general->line_count = lines;
  metaSrc->general->sample_count = samples;
  metaSrc->general->start_line = startY_src;
  metaSrc->general->start_sample = startX_src;
  meta_write(metaSrc, outFile);
  envi = meta2envi(metaSrc);
  write_envi_header(outFile, outFile, metaSrc, envi);

  fp = FOPEN(outFile, "wb");
  if (filter)
    put_float_lines(fp, metaSrc, 0, lines, filtered_img);
  else
    put_float_lines(fp, metaSrc, 0, lines, img);
  FCLOSE(fp);

  // Clean up
  FREE(img);
  meta_free(metaSrc);
  meta_free(metaTrg);

  // Exporting subsets to GeoTIFF
  if (geotiff) {
    output_format_t output_format=GEOTIFF;
    scale_t sample_mapping=SIGMA;

    asfPrintStatus("\nExporting source image subset to GeoTIFF ...\n");
    sprintf(outFile, "%s_sub", srcImage);
    asf_export(output_format, sample_mapping, outFile, outFile);
    asfPrintStatus("\nExporting target image subset to GeoTIFF ...\n");
    sprintf(outFile, "%s_sub", trgImage);
    asf_export(output_format, sample_mapping, outFile, outFile);
  }

  return (0);
}
Exemplo n.º 12
0
main(int argc, char *argv[]) 
{
  FILE *fpin, *fpout;
  
  float ibuff[CPX_PIX*2*LD];
  float **obuff;
  float b[CPX_PIX];
  float c[CPX_PIX/LA];

  int cla,nl;
  int i,j,k,line;
  int olines, osamps;
  int oline, osamp;
  double t;
  char basefile[256], infile[256], outbasefile[256], outfile[256], roifile[256];
  char *hdrfile;
  
  ymd_date date;
  hms_time time;
  meta_parameters *meta;

  char *mon[13]={"","Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep",
     "Oct","Nov","Dec"};
  
  char	 dir;			// orbit direction - A or D
  double x, y, z;		// state vector positions at start of segment
  double xdot, ydot, zdot;	// state vector veloctiy at start of segment
  int    META_ONLY = 0;		// only create meta file, no img file
  int	 SEPARATE_ROI_FILE = 0; // CLA roi file given?
  int    USE_TLES = 1;		// TLE/state vector switch
  int    ESA_FRAME = 0;		// switch to control output file names
  int    node = 0;
   
  asfSplashScreen(argc, argv); 

  if (argc<2 || argc>9) { give_usage(argc,argv); exit(1); }

  while ((cla=getopt(argc,argv,"mvcE:r:")) != -1)
    switch(cla) {
      case 'm':
        META_ONLY = 1;
	printf("Using meta only option\n");
	break;
      case 'r':
	strcpy(roifile,optarg);
	SEPARATE_ROI_FILE = 1;
	break;
      case 'E':
        ESA_FRAME = 1;
	node = atoi(optarg);
	break;
      case 'v':
        USE_TLES = 0;
	break;
      case 'c':
        USE_CLOCK_DRIFT = 1;
	break;
      case '?':
        give_usage(argc,argv);
        printf("Unknown option %s\n",optarg);
	exit(1);
      default:
        give_usage(argc,argv);
	exit(1);
    } 

  strcpy(basefile,argv[optind]);
  strcpy(infile,basefile);
  strcat(infile,".slc");

  /* if no separate roi.in file is specified, use the main name */
  if (SEPARATE_ROI_FILE == 0) {
    strcpy(roifile,basefile);
    strcat(roifile,".roi.in");
  }

  /* Read parameters from the ROI.in file */
  read_roi_infile(roifile);
  nl = npatches * patch_size;
  hdrfile = get_basename(datfilename);
  strcat(hdrfile,".hdr");
  
  /* Read the start time for this image from the hdr file */
  read_hdrfile(hdrfile);
  
  if (USE_TLES == 0) 
   {
    int cnt;
    int year, month, day, hour, min;
    double sec, thisSec;
    FILE *fpvec, *fpo;
    char tmp[256];
  
    sprintf(tmp,"/home/talogan/Seasat_State_Vectors/%3i.ebf",start_date);
    fpvec = fopen(tmp,"r");
    if (fpvec == NULL) {
      printf("Unable to open state vector file for day %i\n",start_date); 
      printf("Defaulting to using TLEs instead\n");
      USE_TLES = 1;
    } else {
      cnt = fscanf(fpvec,"%i %i %i %i %i %lf %lf %lf %lf %lf %lf %lf",&year,&month,&day,&hour,&min,&sec,&x,&y,&z,&xdot,&ydot,&zdot);
      thisSec = (double) ((hour*60+min)*60)+sec;

      /* seek to the correct second of the day for the START of this file 
      -----------------------------------------------------------------*/
      while (cnt == 12 && start_sec > (thisSec+1.0)) {
        cnt = fscanf(fpvec,"%i %i %i %i %i %lf %lf %lf %lf %lf %lf %lf",&year,&month,&day,&hour,&min,&sec,&x,&y,&z,&xdot,&ydot,&zdot);
        thisSec = (double) ((hour*60+min)*60)+sec;
      }
      printf("Found closest second %lf\n",thisSec);
  
      /* need to create a state vector file the start of this image
      ------------------------------------------------------------*/
      stateVector vec, last_vec;
      last_vec.pos.x = x; last_vec.pos.y = y; last_vec.pos.z = z;
      last_vec.vel.x = xdot; last_vec.vel.y = ydot; last_vec.vel.z = zdot;
      vec = propagate(last_vec,thisSec,start_sec);
      x = vec.pos.x; y = vec.pos.y; z = vec.pos.z;
      xdot = vec.vel.x; ydot = vec.vel.y; zdot = vec.vel.z;
    }
   }
  
  if (USE_TLES == 1) {
    /* get the correct state vector */
    printf("Propagating state vectors to requested time...\n");
    create_input_tle_file(s_date,s_time,"tle1.txt");
    propagate_state_vector("tle1.txt"); 
    printf("\n\nConverting state vectors from ECI to ECEF\n");
    fix_state_vectors(s_date.year,s_date.jd,s_time.hour,s_time.min,s_time.sec);
    remove("tle1.txt");
    remove("propagated_state_vector.txt");

    printf("Reading first state vector\n");
    FILE *fpvec = fopen("fixed_state_vector.txt","r");
    if (fscanf(fpvec,"%lf %lf %lf %lf %lf %lf %lf\n",&t,&x,&y,&z,&xdot,&ydot,&zdot)!=7) 
      { printf("ERROR: Unable to find state vector in fixed_state_vector.txt file\n"); exit(1); }
    fclose(fpvec);
    remove("fixed_state_vector.txt");
  }
  if (zdot > 0.0) dir = 'A'; else dir = 'D';

  /* set up output image parameters */
  olines = nl / LD;
  osamps = ns / LA;

  /* Create the meta file */
  printf("Initializing the meta structure\n");
  meta = raw_init();

  /* Propagate the state vectors */  
  printf("Creating state vectors\n");
  stateVector stVec;/*Source state vector*/

  stVec.pos.x = x;
  stVec.pos.y = y;
  stVec.pos.z = z;
  stVec.vel.x = xdot;
  stVec.vel.y = ydot;
  stVec.vel.z = zdot;

  date_jd2ymd(&s_date,&date);

  meta->state_vectors = meta_state_vectors_init(1);
  meta->state_vectors->vecs[0].vec = stVec;
  meta->state_vectors->year = date.year;
  meta->state_vectors->julDay = s_date.jd;
  meta->state_vectors->second = date_hms2sec(&s_time);
  meta->state_vectors->vecs[0].time = 0;
  int num_vecs = 2 + (int)(nl*PRI)/30.0;
  propagate_state(meta, num_vecs+1, (nl*PRI)/num_vecs);

  printf("Calculating scene geometry parameters\n");

  double RE = r_awgs84;
  double RP = r_awgs84 * sqrt(1-r_e2wgs84);
  
  double imgSec=date2sec(&s_date,&s_time);					// time at start of image
  int num = meta->state_vectors->num / 2;					// closest state vector to center of image
  double sourceSec = imgSec+meta->state_vectors->vecs[num].time;		// time at closest state vector
  double destSec = imgSec+meta->state_vectors->vecs[meta->state_vectors->num-1].time/2;	// time at center of image

  printf("Finding center state vector\n");
  stateVector midVec = propagate(meta->state_vectors->vecs[num].vec,sourceSec,destSec);	// state vector at middle time of image
      
  x = midVec.pos.x;
  y = midVec.pos.y;
  z = midVec.pos.z;
  xdot = midVec.vel.x;
  ydot = midVec.vel.y;
  zdot = midVec.vel.z;
  
  double geocentric_lat_nadir = asin(z / sqrt (x*x+y*y+z*z));
  double lon_nadir = atan2(x,y)*180/M_PI;
  double RE_nadir = (RE * RP) / sqrt((RP*cos(geocentric_lat_nadir)*RP*cos(geocentric_lat_nadir)) +
  				     (RE*sin(geocentric_lat_nadir)*RE*sin(geocentric_lat_nadir)));
  double Rsc = sqrt(x*x+y*y+z*z);
  double geodetic_lat_nadir = atan(tan(geocentric_lat_nadir)/(1-r_e2wgs84));
  double lat_nadir = geodetic_lat_nadir*180/M_PI;
  double gamma = geodetic_lat_nadir - geocentric_lat_nadir;
    
  printf("Filling in meta->general parameters\n");
  
  strcpy(meta->general->sensor,"SEASAT");
  strcpy(meta->general->sensor_name,"SAR");
  strcpy(meta->general->mode,"STD");
  strcpy(meta->general->processor,"ASPS-v" ASPS_VERSION_STRING);
  meta->general->data_type = REAL32;
  meta->general->image_data_type = AMPLITUDE_IMAGE;
  meta->general->radiometry = r_AMP;
  sprintf(meta->general->acquisition_date, "%02d-%s-%4d %02d:%02d:%02.0f",
          date.day, mon[date.month], date.year, s_time.hour, s_time.min, s_time.sec);
  meta->general->orbit = time2rev(s_date,s_time);
  meta->general->orbit_direction = dir;
  if (ESA_FRAME == 1) meta->general->frame = node;
  meta->general->band_count = 1;
  strcpy(meta->general->bands,"HH");
  meta->general->line_count = nl/LD;
  meta->general->sample_count = ns/LA;
  meta->general->start_line = 0; 
  meta->general->start_sample = 0;
  meta->general->line_scaling = 1;
  meta->general->sample_scaling = 1;
  meta->general->x_pixel_size = (C / (2.0 * fs)) * LA;
 
  switch (station_code) {
    case 5:
      strcpy(meta->general->receiving_station, "ULA");
      break;
    case 6:
      strcpy(meta->general->receiving_station, "GDS");
      break;
    case 7:
      strcpy(meta->general->receiving_station, "MIL");
      break;
    case 9:
      strcpy(meta->general->receiving_station, "UKO");
      break;
    case 10:
      strcpy(meta->general->receiving_station, "SNF");
      break;
  }
 
  double orbit_vel = sqrt(9.81*RE_nadir*RE_nadir / Rsc);
  double swath_vel = orbit_vel * RE_nadir / Rsc;
  
  meta->general->y_pixel_size = (swath_vel * PRI) * LD;    // TAL - Check the sc_vel...
  meta->general->re_major = r_awgs84;
  meta->general->re_minor = r_awgs84 * sqrt(1-r_e2wgs84);
  
//  meta->general->bit_error_rate = ???
//  meta->general->missing_lines = ???  
//  meta->general->no_data = ???

      
  /*Create the SAR metadata block*/
  
  printf("Creating the meta->sar block\n");
  if (!meta->sar) meta->sar = meta_sar_init();

  meta->sar->image_type = 'S';
  meta->sar->look_direction = 'R';
  meta->sar->azimuth_look_count = LD;
  meta->sar->range_look_count = LA;
  meta->sar->deskewed = 0;
  meta->sar->original_line_count = nl;
  meta->sar->original_sample_count = ns;
  meta->sar->line_increment = 1;
  meta->sar->sample_increment = 1;
  meta->sar->range_time_per_pixel = 1/(2*fs);
  
  // Should be this, right???    meta->sar->azimuth_time_per_pixel = PRI;
  // Second try is this one	 meta->sar->azimuth_time_per_pixel = (destSec - imgSec) / (meta->sar->original_line_count/2);
  
  meta->sar->azimuth_time_per_pixel = meta->general->y_pixel_size / swath_vel;
  meta->sar->azimuth_time_per_pixel *= -1;
  meta->sar->time_shift = fabs(meta->general->line_count*meta->sar->azimuth_time_per_pixel);
  
//  meta->sar->slant_shift = -1080;			// emperical value from a single delta scene
//  meta->sar->time_shift = 0.18;			// emperical value from a single delta scene

  if (USE_CLOCK_DRIFT ==1) meta->sar->slant_shift = SEASAT_SLANT_SHIFT; // -1000.0;
  else meta->sar->slant_shift = 0.0;

  meta->sar->slant_range_first_pixel = srf;
  meta->sar->wavelength = wavelength;
  meta->sar->prf = prf;
  meta->sar->earth_radius = meta_get_earth_radius(meta,	meta->general->line_count/2.0, meta->general->sample_count/2.0);
  meta->sar->satellite_height = Rsc;
  meta->sar->range_doppler_coefficients[0] = dop1*prf;
  meta->sar->range_doppler_coefficients[1] = dop2*prf;
  meta->sar->range_doppler_coefficients[2] = dop3*prf;
  meta->sar->azimuth_doppler_coefficients[0] = dop1*prf;
  meta->sar->azimuth_doppler_coefficients[1] = 0;
  meta->sar->azimuth_doppler_coefficients[2] = 0;
  
///  meta->sar->azimuth_processing_bandwidth = ????
  
  meta->sar->chirp_rate = chirp_slope;
  meta->sar->pulse_duration = pulse_duration;
  meta->sar->range_sampling_rate = fs;
  strcpy(meta->sar->polarization,"HH");
  meta->sar->multilook = 1;
  meta->sar->pitch = 0;
  meta->sar->roll = 0;
  meta->sar->yaw = 0;
///  meta->sar->incid_a[0-5] = ???

  printf("Creating the meta->location block\n");
  if (!meta->location) meta->location = meta_location_init();
  meta_get_corner_coords(meta);
  meta_get_latLon(meta,meta->general->line_count/2,meta->general->sample_count/2,0,
  		  &meta->general->center_latitude, &meta->general->center_longitude);

  if (ESA_FRAME==0) {
    strcpy(outbasefile,basefile);
  } else {
    sprintf(outbasefile,"SS_%.5i_SLANT_F%.4i",meta->general->orbit,meta->general->frame);
  }

  strcpy(outfile,outbasefile);
  strcat(outfile,".img");
  strcpy(meta->general->basename,outbasefile);

  if (META_ONLY==0) { 
    obuff = (float **) malloc (sizeof(float *)*olines);
    for (i=0; i<olines; i++) obuff[i] = (float *) malloc (sizeof(float)*osamps);
  
    /* Open the input slc file and output img file*/
    fpin = fopen(infile,"rb");
    if (fpin==NULL) {printf("ERROR: Unable to open input file %s\n",infile); exit(1);}
    fpout = fopen(outfile,"wb");

    /* Take the complex looks from the slc file to create the img file */
    printf("Taking complex looks from file %s to create %s\n",infile,outfile);
    oline = 0;
    for (line=0; line < nl; line+=LD) {
      if (line%2560==0) printf("\t%i\n",line);
      fread(ibuff,sizeof(float),ns*2*LD,fpin);

      /* take looks down */
      for (j=0; j<ns; j++) {
        b[j] = 0;
        for (i=0; i<LD; i++)
          b[j] = b[j] + (ibuff[(2*j)+(i*ns*2)]*ibuff[2*j+(i*ns*2)]) 
  		      + (ibuff[(2*j+1)+(i*ns*2)]*ibuff[(2*j+1)+(i*ns*2)]);    
      }
    
      /* take looks across */
      for (j=0; j<ns/LA; j++) {
        c[j] = 0;
        for (k=0;k<LA;k++)
          c[j] = c[j] + b[j*LA+k];
        c[j] = sqrt(c[j]);
      }
      byteswap(c,ns/LA);
      for (j=0; j<osamps; j++) obuff[oline][j] = c[j];
      oline++;
    }

    /* write out image in reverse order */
    for (j=0; j<olines; j++) fwrite(obuff[olines-j-1],sizeof(float),osamps,fpout); 
 
    fclose(fpout);
    fclose(fpin);
    free(obuff);
    
  }  /* END IF META_ONLY */   

  printf("Writing out the meta file\n");
  meta_write(meta, outbasefile);

  if (META_ONLY == 0) {
    char grfilename[256];
    float grPixSiz = 12.5;
    int err = 0;
    if (ESA_FRAME == 1) {
      char tmpstr[256];
      char cropfile[256];
      char tmpfile[256];
      
      /* create the ground range image */
      sprintf(grfilename,"temp_%.5i_STD_F%.4i",meta->general->orbit,meta->general->frame);
      sr2gr_pixsiz(outbasefile, grfilename, grPixSiz);
      
      /* crop the image to exact size */
      sprintf(cropfile,"SS_%.5i_STD_F%.4i",meta->general->orbit,meta->general->frame);
      trim(grfilename,cropfile,(long long)0,(long long)0,(long long)8000,(long long)8000);
      
      /* remove the non-cropped ground range image */
      strcat(strcpy(tmpstr,grfilename),".img");
      remove(tmpstr);
      strcat(strcpy(tmpstr,grfilename),".meta");
      remove(tmpstr);

      /* geocode and export to geotiff */
      sprintf(tmpstr,"asf_geocode -p utm %s %s_utm\n",cropfile,cropfile);
      err = system(tmpstr);
      if (err) {printf("Error returned from asf_geocode\n"); exit(1);}

      sprintf(tmpstr,"asf_export -format geotiff %s_utm %s\n",cropfile,cropfile);
      err = system(tmpstr);
      if (err) {printf("Error returned from asf_export to geotiff\n"); exit(1);}
 
      /* remove the utm projected internal format image */
      strcat(strcpy(tmpstr,cropfile),"_utm.img");
      remove(tmpstr);
      strcat(strcpy(tmpstr,cropfile),"_utm.meta");
      remove(tmpstr);
 
      /* this changes the basename in the metadata from blah_SLANT to blah_STD  */
      meta_parameters *crop_meta = meta_read(cropfile);
      strcpy(crop_meta->general->basename, cropfile);
      meta_write(crop_meta, cropfile);
      meta_free(crop_meta);
 
      /* create the dowsized QC image */
      sprintf(tmpstr,"resample -scale 0.125 %s %s_small\n",cropfile,cropfile);
      err = system(tmpstr);
      if (err) {printf("Error returned from resample\n"); exit(1);}
      
      sprintf(tmpfile,"%s_QCFULL",cropfile);
      sprintf(tmpstr,"asf_export -format jpeg %s_small %s\n",cropfile,tmpfile);
      err = system(tmpstr);
      if (err) {printf("Error returned from asf_export to jpeg\n"); exit(1);}
      
      /* remove the small .img file */
      strcat(strcpy(tmpstr,cropfile),"_small.img");
      remove(tmpstr);
      strcat(strcpy(tmpstr,cropfile),"_small.meta");
      remove(tmpstr);

      /* create the subsampled QC image */
      sprintf(tmpfile,"%s_QCSUB",cropfile);
      trim(cropfile,tmpfile,(long long)3500,(long long)3500,(long long)1000,(long long)1000);

      sprintf(tmpstr,"asf_export -format jpeg %s %s\n",tmpfile,tmpfile);
      err = system(tmpstr);
      if (err) {printf("Error returned from asf_export\n"); exit(1);}

      /* run make_seasat_h5 */
      sprintf(tmpstr,"make_seasat_h5 -gap %s.dis %s %s",basefile,cropfile,cropfile);
      err = system(tmpstr);
      if (err) {printf("Error returned from make_seasat_h5\n"); exit(1);}

      /* remove the subsampled QC .img file */
      strcat(strcpy(tmpstr,tmpfile),".img");
      remove(tmpstr);
      strcat(strcpy(tmpstr,tmpfile),".meta");
      remove(tmpstr);

      /* rename the ROI.in file to match the new file name */
      sprintf(tmpfile,"%s.roi.in",cropfile);
      rename(roifile,tmpfile);

    } else {
      strcpy(grfilename,basefile);
      strcat(grfilename,"G12");
      sr2gr_pixsiz(basefile, grfilename, grPixSiz);
    } 
  }

  exit(0);
}
Exemplo n.º 13
0
int geoid_adjust(const char *input_filename, const char *output_filename)
{
  char *input_img = appendExt(input_filename, ".img");
  char *input_meta = appendExt(input_filename, ".meta");

  char *output_img = appendExt(output_filename, ".img");
  char *output_meta = appendExt(output_filename, ".meta");

  if (!fileExists(input_img))
    asfPrintError("File not found: %s\n", input_img);
  if (!fileExists(input_meta))
    asfPrintError("File not found: %s\n", input_meta);

  meta_parameters *meta = meta_read(input_meta);
  int nl = meta->general->line_count;
  int ns = meta->general->sample_count;
  int ii, jj;

  FILE *fpIn = FOPEN(input_img, "rb");
  FILE *fpOut = FOPEN(output_img, "wb");
  float *buf;

  // Two ways we can do this:
  //   1) call meta_get_latLon at every point
  //   2) call meta_get_latLon at certain points and interpolate between
  // We will use the first when we have a lat/lon image, and the second for
  // everything else.
  int latlon_image = meta->projection &&
                     meta->projection->type == LAT_LONG_PSEUDO_PROJECTION;

  double avg = 0.0;
  int num=0;

  asfPrintStatus("Performing geoid correction.\n");
  asfPrintStatus(" Input file: %s\n", input_filename);
  asfPrintStatus(" Output file: %s\n", output_filename);

  if (latlon_image) {
    asfPrintStatus("Lat/Lon image, not using mapping interpolation.\n");
    buf = MALLOC(sizeof(float)*ns);
    for (ii=0; ii<nl; ++ii) {
      get_float_line(fpIn, meta, ii, buf);
      for (jj=0; jj<ns; ++jj) {
        double lat, lon;
        meta_get_latLon(meta, ii, jj, 0, &lat, &lon);
        if (buf[jj] > -900 && buf[jj] != meta->general->no_data)
        {
          float ht = get_geoid_height(lat,lon);
          buf[jj] += ht;
          avg += ht;
          ++num;
        }
      }
      put_float_line(fpOut, meta, ii, buf);
      asfLineMeter(ii,nl);
    }
  }
  else {
    asfPrintStatus("Not a Lat/Lon image, using mapping interpolation.\n");
    double tol = .0001;
    int size = find_grid_size(meta, 512, .1*tol);

    int test_mode = 1;
    buf = MALLOC(sizeof(float)*ns*size);

    // these are for tracking the quality of the bilinear interp
    // not used if test_mode is false
    int num_out_of_tol = 0;
    int num_checked = 0;
    int num_bad = 0;
    double max_err = 0;
    double avg_err = 0;

    for (ii=0; ii<nl; ii += size) {
      int line_lo = ii;
      int line_hi = ii + size;

      if (ii+size >= nl)
        size = nl-ii;

      get_float_lines(fpIn, meta, ii, size, buf);

      for (jj=0; jj<ns; jj += size) {
        double lats[4], lons[4];

        int samp_lo = jj;
        int samp_hi = jj + size;

        get_interp_params(meta, line_lo, line_hi, samp_lo, samp_hi, lats, lons);

        int iii, jjj;
        for (iii=0; iii<size; ++iii) {
          for (jjj=0; jjj<size && jj+jjj<ns; ++jjj) {
            int kkk = iii*ns + jj + jjj;
            assert(kkk < ns*size);

            double lat, lon;
            xy_interp(ii+iii, jj+jjj, line_lo, line_hi, samp_lo, samp_hi, lats, lons,
                      &lat, &lon);

            // random checking of the quality of our interpolations
            if (test_mode && iii%11==0 && jjj%13==0) {
              double real_lat, real_lon;
              img_to_latlon(meta, ii+iii, jj+jjj, &real_lat, &real_lon);
              double err = hypot(real_lat - lat, real_lon - lon);

              avg_err += err;
              if (err > max_err)
                max_err = err;

              if (err > .1*tol) {
                asfPrintStatus("Out of tolerance at %d,%d: (%f,%f) vs (%f,%f) -> %f\n",
                               ii+iii, jj+jjj, lat, lon, real_lat, real_lon,
                               err);
                ++num_out_of_tol;
              }
              if (err > tol) {
                asfPrintStatus("Error is larger than %f!\n", .01*tol);
                ++num_bad;
              }
              ++num_checked;
            }

            if (buf[kkk] > -900 && buf[kkk] != meta->general->no_data)
            {
              float ht = get_geoid_height(lat,lon);
              buf[kkk] += ht;
              avg += ht;
              ++num;
            }
          }  
        }
      }
      put_float_lines(fpOut, meta, ii, size, buf);
      asfPrintStatus("Completed %.1f%%  \r", 100.*ii/(double)nl);
    }
    asfPrintStatus("Completed 100%%   \n");
  }

  avg /= (double)(num);
  asfPrintStatus("Average correction: %f\n", avg);

  meta_write(meta, output_meta);
  meta_free(meta);

  FCLOSE(fpIn);
  FCLOSE(fpOut);

  FREE(buf);
  FREE(input_img);
  FREE(input_meta);
  FREE(output_img);
  FREE(output_meta);

  // success
  return 0;
}
Exemplo n.º 14
0
// return TRUE if there is any overlap between the two scenes
static int test_overlap(meta_parameters *meta1, meta_parameters *meta2)
{
    if (!meta_is_valid_double(meta1->general->center_longitude)) {
        int nl = meta1->general->line_count;
        int ns = meta1->general->sample_count;

        meta_get_latLon(meta1, nl/2, ns/2, 0,
            &meta1->general->center_latitude,
            &meta1->general->center_longitude);
    }

    if (!meta_is_valid_double(meta2->general->center_longitude)) {
        int nl = meta2->general->line_count;
        int ns = meta2->general->sample_count;

        meta_get_latLon(meta2, nl/2, ns/2, 0,
            &meta2->general->center_latitude,
            &meta2->general->center_longitude);
    }

    int zone1 = utm_zone(meta1->general->center_longitude);
    int zone2 = utm_zone(meta2->general->center_longitude);

    // if zone1 & zone2 differ by more than 1, we can stop now
    if (iabs(zone1-zone2) > 1) {
        return FALSE;
    }

    // The Plan:
    // Generate polygons for each metadata, then test of any pair of
    // line segments between the polygons intersect.

    // Other possibility: meta1 is completely contained within meta2,
    // or the reverse.

    // corners of meta1.
    double xp_1[5], yp_1[5];

    if (meta1->location) {
        // use the location block if available
        latLon2UTM_zone(meta1->location->lat_start_near_range,
            meta1->location->lon_start_near_range, 0, zone1, &xp_1[0], &yp_1[0]);
        latLon2UTM_zone(meta1->location->lat_start_far_range,
            meta1->location->lon_start_far_range, 0, zone1, &xp_1[1], &yp_1[1]);
        latLon2UTM_zone(meta1->location->lat_end_far_range,
            meta1->location->lon_end_far_range, 0, zone1, &xp_1[2], &yp_1[2]);
        latLon2UTM_zone(meta1->location->lat_end_near_range,
            meta1->location->lon_end_near_range, 0, zone1, &xp_1[3], &yp_1[3]);
    } else {
        double lat, lon;
        int nl1 = meta1->general->line_count;
        int ns1 = meta1->general->sample_count;

        // must call meta_get_latLon for each corner
        meta_get_latLon(meta1, 0, 0, 0, &lat, &lon);
        latLon2UTM_zone(lat, lon, 0, zone1, &xp_1[0], &yp_1[0]);

        meta_get_latLon(meta1, nl1-1, 0, 0, &lat, &lon);
        latLon2UTM_zone(lat, lon, 0, zone1, &xp_1[1], &yp_1[1]);

        meta_get_latLon(meta1, nl1-1, ns1-1, 0, &lat, &lon);
        latLon2UTM_zone(lat, lon, 0, zone1, &xp_1[2], &yp_1[2]);

        meta_get_latLon(meta1, 0, ns1-1, 0, &lat, &lon);
        latLon2UTM_zone(lat, lon, 0, zone1, &xp_1[3], &yp_1[3]);
    }

    // close the polygon
    xp_1[4] = xp_1[0];
    yp_1[4] = yp_1[0];

    // corners of meta2.
    double xp_2[5], yp_2[5];

    if (meta2->location) {
        // use the location block if available
        latLon2UTM_zone(meta2->location->lat_start_near_range,
            meta2->location->lon_start_near_range, 0, zone1, &xp_2[0], &yp_2[0]);
        latLon2UTM_zone(meta2->location->lat_start_far_range,
            meta2->location->lon_start_far_range, 0, zone1, &xp_2[1], &yp_2[1]);
        latLon2UTM_zone(meta2->location->lat_end_far_range,
            meta2->location->lon_end_far_range, 0, zone1, &xp_2[2], &yp_2[2]);
        latLon2UTM_zone(meta2->location->lat_end_near_range,
            meta2->location->lon_end_near_range, 0, zone1, &xp_2[3], &yp_2[3]);
    } else {
        double lat, lon;
        int nl2 = meta2->general->line_count;
        int ns2 = meta2->general->sample_count;

        // must call meta_get_latLon for each corner
        meta_get_latLon(meta2, 0, 0, 0, &lat, &lon);
        latLon2UTM_zone(lat, lon, 0, zone1, &xp_2[0], &yp_2[0]);

        meta_get_latLon(meta2, nl2-1, 0, 0, &lat, &lon);
        latLon2UTM_zone(lat, lon, 0, zone1, &xp_2[1], &yp_2[1]);

        meta_get_latLon(meta2, nl2-1, ns2-1, 0, &lat, &lon);
        latLon2UTM_zone(lat, lon, 0, zone1, &xp_2[2], &yp_2[2]);

        meta_get_latLon(meta2, 0, ns2-1, 0, &lat, &lon);
        latLon2UTM_zone(lat, lon, 0, zone1, &xp_2[3], &yp_2[3]);
    }

    // close the polygon
    xp_2[4] = xp_2[0];
    yp_2[4] = yp_2[0];

    // loop over each pair of line segments, testing for intersection
    int i, j;
    for (i = 0; i < 4; ++i) {
        for (j = 0; j < 4; ++j) {
            if (lineSegmentsIntersect(
                xp_1[i], yp_1[i], xp_1[i+1], yp_1[i+1],
                xp_2[j], yp_2[j], xp_2[j+1], yp_2[j+1]))
            {
                return TRUE;
            }
        }
    }

    // test for containment: meta2 in meta1
    int all_in=TRUE;
    for (i=0; i<4; ++i) {
        if (!pnpoly(5, xp_1, yp_1, xp_2[i], yp_2[i])) {
            all_in=FALSE;
            break;
        }
    }

    if (all_in)
        return TRUE;

    // test for containment: meta1 in meta2
    all_in = TRUE;
    for (i=0; i<4; ++i) {
        if (!pnpoly(5, xp_2, yp_2, xp_1[i], yp_1[i])) {
            all_in=FALSE;
            break;
        }
    }

    if (all_in)
        return TRUE;

    // no overlap
    return FALSE;
}
Exemplo n.º 15
0
static int save_as_asf(ImageInfo *ii,
                       const char *out_file, int what_to_save,
                       int strict_boundary, int load)
{
    // See if we can open the output file up front
    FILE *outFp = fopen(out_file, "wb");
    if (!outFp) {
        // failed to open the output file!
        char errbuf[1024];
        snprintf(errbuf, 1024, "Failed to open %s: %s", out_file,
            strerror(errno));
        message_box(errbuf);
        strcat(errbuf, "\n");
        printf("%s", errbuf);
        return FALSE; // failure
    }

    assert (g_poly->n > 0);
    assert (crosshair_line > 0 && crosshair_samp > 0);

    meta_parameters *meta = ii->meta;

    // figure out where to chop
    int line_min, line_max, samp_min, samp_max, nl, ns;
    compute_extent(meta, &line_min, &line_max, &samp_min, &samp_max,
        &nl, &ns);

    // generate metadata
    char *out_metaname = appendExt(out_file, ".meta");
    printf("Generating %s...\n", out_metaname);

    // data will be saved as floating point, except scaled pixel values,
    // which we can make bytes.
    data_type_t data_type = REAL32;
    if (what_to_save == SCALED_PIXEL_VALUE)
      data_type = ASF_BYTE;

    meta_parameters *out_meta =
      build_metadata(meta, out_file, nl, ns, line_min, samp_min, data_type,
                     what_to_save);

    // put_float_line() will always dump BYTE data if the optical block
    // is present... we want to be in control of the data type, so we must
    // wipe out this block
    if (out_meta->optical) {
      FREE(out_meta->optical);
      out_meta->optical=NULL;
    }

    if (what_to_save == LAT_LON_2_BAND) {
      out_meta->general->band_count = 2;
      strcpy(out_meta->general->bands, "LAT,LON");
    }

    // define clipping region, if necessary
    double xp[MAX_POLY_LEN+2], yp[MAX_POLY_LEN+2];
    int i,j,n=0;

    if (strict_boundary)
        define_clipping_region(meta, &n, xp, yp);

    float ndv = 0;
    if (meta_is_valid_double(out_meta->general->no_data))
        ndv = out_meta->general->no_data;
    else if (strict_boundary) // need to set a no data value in this case
        out_meta->general->no_data = 0.;

    meta_write(out_meta, out_metaname);

    // now actually write the data
    printf("Generating %s...\n", out_file);

    if (what_to_save == LAT_LON_2_BAND) {
      // dump a 2-band image, lat & lon data
      float *lats = MALLOC(sizeof(float)*ns);
      float *lons = MALLOC(sizeof(float)*ns);
      for (i=0; i<nl; ++i) {
        int l = line_min+i;
        for (j=0; j<ns; ++j) {
            int s = samp_min+j;
            if (!strict_boundary || pnpoly(n, xp, yp, s, l)) {
                double lat, lon;
                meta_get_latLon(meta, l, s, 0, &lat, &lon);
                lats[j] = (float)lat;
                lons[j] = (float)lon;
            }
            else {
                lats[j] = ndv;
                lons[j] = ndv;
            }
        }
        put_band_float_line(outFp, out_meta, 0, i, lats);
        put_band_float_line(outFp, out_meta, 1, i, lons);
        asfLineMeter(i,nl);
      }
      free(lats);
      free(lons);
    }
    else {
      // normal case
      float *buf = MALLOC(sizeof(float)*ns);
      for (i=0; i<nl; ++i) {
        int l = line_min+i;
        for (j=0; j<ns; ++j) {
            int s = samp_min+j;
            float val;
            if (!strict_boundary || pnpoly(n, xp, yp, s, l)) {
                val = get_data(ii, what_to_save, l, s);
            }
            else {
                val = ndv;
            }
            buf[j] = val;
        }
        put_float_line(outFp, out_meta, i, buf);
        asfLineMeter(i,nl);
      }
      free(buf);
    }
    fclose(outFp);
    meta_free(out_meta);

    // load the generated file if we were told to
    if (load)
        load_file(out_file);

    return TRUE;
}
Exemplo n.º 16
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;
}
Exemplo n.º 17
0
static int save_as_csv(ImageInfo *ii, 
                       const char *out_file, int what_to_save,
                       int strict_boundary, int load)
{
    int i,j;

    assert (g_poly->n > 0);
    assert (crosshair_line > 0 && crosshair_samp > 0);

    meta_parameters *meta = ii->meta;

    int line_min, line_max, samp_min, samp_max, nl, ns;
    compute_extent(meta, &line_min, &line_max, &samp_min, &samp_max,
        &nl, &ns);

    if (nl>500 || ns>500) {
        // too big for csv -- Excel etc. will choke
        char errbuf[1024];
        snprintf(errbuf, 1024,
             "\nRegion is too large (%dx%d) to export as CSV (500x500 max)\n\n",
             nl, ns);
        message_box(errbuf);
        printf("%s", errbuf);
        return FALSE; // failure
    }

    FILE *outFp = fopen(out_file, "w");
    if (!outFp) {
        // failed to open the output file!
        char errbuf[1024];
        snprintf(errbuf, 1024, "Failed to open %s: %s", out_file,
            strerror(errno));
        message_box(errbuf);
        strcat(errbuf, "\n");
        printf("%s", errbuf);
        return FALSE; // failure
    }

    printf("Generating %s...\n", out_file);

    // define clipping region, if necessary
    double xp[MAX_POLY_LEN+2], yp[MAX_POLY_LEN+2];
    int n=0;

    if (strict_boundary)
        define_clipping_region(meta, &n, xp, yp);

    // generate csv
    fprintf(outFp, ",");
    for (j=0; j<ns; ++j) {
      if (what_to_save==LAT_LON_2_BAND)        
        fprintf(outFp, "%d,%s", samp_min+j, j==ns-1 ? "\n" : ",");
      else
        fprintf(outFp, "%d%s", samp_min+j, j==ns-1 ? "\n" : ",");
    }
    if (what_to_save==LAT_LON_2_BAND) {
      fprintf(outFp, ",");
      for (j=0; j<ns; ++j) {
        fprintf(outFp, "Lat,Lon%s", j==ns-1 ? "\n" : ",");
      }
    }
    for (i=0; i<nl; ++i) {
        int l = line_min+i;
        fprintf(outFp, "%d,", l);
        for (j=0; j<ns; ++j) {
            int s = samp_min+j;
            if (what_to_save==LAT_LON_2_BAND) {
              float lat, lon;
              if (!strict_boundary || pnpoly(n, xp, yp, s, l)) {
                double dlat, dlon;
                meta_get_latLon(meta, l, s, 0, &dlat, &dlon);
                lat = (float)dlat;
                lon = (float)dlon;
              } else {
                lat = lon = 0.;
              }
              fprintf(outFp, "%f,%f%s", lat, lon, j==ns-1 ? "\n" : ",");
            }
            else {
              float val;
              if (!strict_boundary || pnpoly(n, xp, yp, s, l)) {
                val = get_data(ii, what_to_save, l, s);
              } else {
                val = 0;
              }
              fprintf(outFp, "%f%s", val, j==ns-1 ? "\n" : ",");
            }
        }
        asfLineMeter(i,nl);
    }

    fclose(outFp);

    // if requested, open up the csv with an external viewer
    if (load)
        open_csv(out_file);

    return TRUE;
}
Exemplo n.º 18
0
static void get_bounding_box_latlon(meta_parameters *meta,
                                    double *lat_lo, double *lat_hi,
                                    double *lon_lo, double *lon_hi)
{
    *lat_lo = *lon_lo = 999;
    *lat_hi = *lon_hi = -999;
    double size_lat;
    double size_lon;
    int nl = meta->general->line_count;
    int ns = meta->general->sample_count;

    if (meta->location) {
        meta_location *ml = meta->location;
        update_extents(ml->lat_start_near_range, ml->lon_start_near_range,
            lat_lo, lat_hi, lon_lo, lon_hi);
        update_extents(ml->lat_start_far_range, ml->lon_start_far_range,
            lat_lo, lat_hi, lon_lo, lon_hi);
        update_extents(ml->lat_end_near_range, ml->lon_end_near_range,
            lat_lo, lat_hi, lon_lo, lon_hi);
        update_extents(ml->lat_end_far_range, ml->lon_end_far_range,
            lat_lo, lat_hi, lon_lo, lon_hi);

        size_lat = fabs(ml->lat_start_far_range - ml->lat_start_near_range);
        size_lon = fabs(ml->lon_start_far_range - ml->lon_start_near_range);
    }
    else {
        double lat, lon;

        // must call meta_get_latLon for each corner
        meta_get_latLon(meta, 0, 0, 0, &lat, &lon);
        update_extents(lat, lon, lat_lo, lat_hi, lon_lo, lon_hi);
        size_lat = lat;
        size_lon = lon;

        meta_get_latLon(meta, 0, ns-1, 0, &lat, &lon);
        update_extents(lat, lon, lat_lo, lat_hi, lon_lo, lon_hi);
        size_lat -= lat;
        size_lon -= lon;

        meta_get_latLon(meta, nl-1, 0, 0, &lat, &lon);
        update_extents(lat, lon, lat_lo, lat_hi, lon_lo, lon_hi);

        meta_get_latLon(meta, nl-1, ns-1, 0, &lat, &lon);
        update_extents(lat, lon, lat_lo, lat_hi, lon_lo, lon_hi);

        size_lat = fabs(size_lat);
        size_lon = fabs(size_lon);
    }

    // Add a little bit of fudge to each -- we want there to be some room
    // for adjustment via the co-registration.

    // Try to add about 100 pixels worth to each top/left/bottom/right.
    // To get that much, we estimate how many pixels per lat & long degree
    // from the "size_lat/lon" variables we calculated above.

    // We aren't really concerned if this isn't too accurate.

    double lat_fudge = size_lat / (double)ns * 100;
    double lon_fudge = size_lon / (double)ns * 100;

    *lat_lo -= lat_fudge;
    *lat_hi += lat_fudge;

    *lon_lo -= lon_fudge;
    *lon_hi += lon_fudge;
}