示例#1
0
/**********************************************************
 * meta_incid:  Returns the incidence angle
 * This is the angle measured by the target between straight
 * up and the satellite. Returns radians.*/
double meta_incid(meta_parameters *meta,double y,double x)
{
  // No effort has been made to make this routine work with
  // pseudoprojected images.
  if (strcmp_case(meta->general->sensor, "UAVSAR") == 0)
    // placeholder for incidence angle information, most likely coming from
    // a band in the image file
    return 0.0;
  else
    assert (meta->projection == NULL || 
	    meta->projection->type != LAT_LONG_PSEUDO_PROJECTION);

  double sr = meta_get_slant(meta,y,x);

  if (meta_uses_incid_polynomial(meta)) {
    // Use the incidence angle polynomial if it is available and non-zero.
    double R = sr/1000.;
    double R2=R*R;
    return
      meta->sar->incid_a[0] +
      meta->sar->incid_a[1] * R +
      meta->sar->incid_a[2] * R2 +
      meta->sar->incid_a[3] * R2 * R +
      meta->sar->incid_a[4] * R2 * R2 +
      meta->sar->incid_a[5] * R2 * R2 * R;

  } else {
    double er = meta_get_earth_radius(meta,y,x);
    double ht = meta_get_sat_height(meta,y,x);
    return PI-acos((SQR(sr) + SQR(er) - SQR(ht)) / (2.0*sr*er));
  }
}
示例#2
0
quadratic_2d get_incid(char *sarName, meta_parameters *meta)
{
  int ll, kk;
  quadratic_2d q;
  stateVector stVec;
  int projected = FALSE;
  double *line, *sample, *incidence_angle;
  double earth_radius, satellite_height, time, range;
  double firstIncid, re, rp;

  // Init
  incidence_angle = (double *) MALLOC(sizeof(double)*GRID*GRID);
  line = (double *) MALLOC(sizeof(double)*GRID*GRID);
  sample = (double *) MALLOC(sizeof(double)*GRID*GRID);
  int nl = meta->general->line_count;
  int ns = meta->general->sample_count;
  re = meta->general->re_major;
  rp = meta->general->re_minor;
  projected = (meta->projection) ? TRUE : FALSE;

  // Populate array of incidence angles from er, sh, and r for each pixel
  // in the grid
  for (ll = 0; ll < GRID; ll++) {
    for (kk = 0; kk < GRID; kk++) {
      line[ll*GRID+kk] = ll * nl / GRID;
      sample[ll*GRID+kk] = kk * ns / GRID;
      if (projected) {
        earth_radius = meta_get_earth_radius(meta, ll, kk);
        satellite_height = meta_get_sat_height(meta, ll, kk);
        range = get_slant_range(meta, earth_radius, satellite_height,
                                sample[ll*GRID+kk]);
      }
      else {
        time = meta_get_time(meta, line[ll*GRID+kk], sample[ll*GRID+kk]);
        stVec = meta_get_stVec(meta, time);
        earth_radius = get_earth_radius(time, stVec, re, rp);
        satellite_height = get_satellite_height(time, stVec);
        range = get_slant_range(meta, earth_radius, satellite_height,
                                sample[ll*GRID+kk]);
      }
      incidence_angle[ll*GRID+kk] = get_incidence_angle(earth_radius, satellite_height, range);

      if (ll==0 && kk==0) {
        firstIncid = incidence_angle[0];
      }
    }
  }

  // Fit a 2D quadratic to the grid of incidence angles
  q   = find_quadratic(incidence_angle, line, sample, GRID*GRID);
  q.A = firstIncid;

  // Clean up
  FREE(line);
  FREE(sample);
  FREE(incidence_angle);

  return q;
}
示例#3
0
static double map_gr2sr(meta_parameters *meta, double l, double s)
{
    double ht = meta_get_sat_height(meta, l, s);
    double er = meta_get_earth_radius(meta, l, s);
    double srfp = meta_get_slant(meta, l, 0);
    double grfp = er * acos((ht*ht+er*er-srfp*srfp)/(2.*ht*er));
    double grcp = grfp + s * meta->transform->target_pixel_size;
    double srcp = sqrt(ht*ht+er*er-2.*ht*er*cos(grcp/er));
    return (srcp - srfp)/meta->transform->source_pixel_size;
}
示例#4
0
/**********************************************************
 * meta_look: Return the look angle
 * This is the angle measured by the satellite between
 * earth's center and the target point x. Returns radians*/
double meta_look(meta_parameters *meta,double y,double x)
{
  // No effort has been made to make this routine work with
  // pseudoprojected images.
  assert (meta->projection == NULL
      || meta->projection->type != LAT_LONG_PSEUDO_PROJECTION);

    double sr = meta_get_slant(meta,y,x);
    double er = meta_get_earth_radius(meta,y,x);
    double ht = meta_get_sat_height(meta,y,x);
    return acos((SQR(sr) + SQR(ht) - SQR(er)) / (2.0*sr*ht));
}
示例#5
0
static double map_sr2gr(meta_parameters *meta, double l, double s)
{
    double ht = meta_get_sat_height(meta, l, s);
    double srfp = meta_get_slant(meta, l, 0);
    double er = meta_get_earth_radius(meta, l, s);
    double x = 1. + (ht - er)/er;
    double y0 = srfp / er;
    double grfp = er * acos((1. + x*x - y0*y0)/(2.*x));
    double srcp = srfp + s*meta->transform->source_pixel_size;
    double y1 = srcp/er;
    double grcp = er*acos((1. + x*x - y1*y1)/(2.*x));
    return (grcp - grfp)/meta->transform->target_pixel_size;
}
/*******************************************************
 * slantRange2groundPixel:
 * Calculate the ground range pixel from the total slant
 * range*/
int slantRange2groundPixel(meta_parameters *meta,double slant)
{
    double a,x,y,Gr0, GrX;
    double Rsc, Re;
    int    groundPixel;

    Rsc = meta_get_sat_height(meta, meta->general->line_count/2, 0);
    Re  = meta_get_earth_radius(meta, meta->general->line_count/2, 0);

    a = (Rsc-Re)/Re;
    x = 1+a;

    y = meta->sar->slant_range_first_pixel / Re;

    Gr0 = Re * acos((1.0 + x*x - y*y) / (2.0 * x));

    y = slant/Re;
    GrX = Re * acos((1.0 + x*x - y*y) / (2.0 * x));

    if (!meta_is_valid_double(Gr0) || !meta_is_valid_double(GrX)) {
        asfPrintError("Cannot convert slant range to ground range.\n");
    }

    if (meta && meta->projection && meta_is_valid_double(meta->projection->perX)) {
        groundPixel = (int) ((GrX-Gr0)/meta->projection->perX)+0.5;
//        printf("Slant %f :: ",slant);
//        printf("GP = (%f-%f) / %f = %i\n",GrX,Gr0,meta->projection->perX,groundPixel);
    }
    else if (meta &&
             meta->general->data_type != COMPLEX_BYTE &&
             meta->general->data_type != COMPLEX_INTEGER16 &&
             meta->general->data_type != COMPLEX_INTEGER32 &&
             meta->general->data_type != COMPLEX_REAL32 &&
             meta->general->data_type != COMPLEX_REAL64
            )
    {
        groundPixel = (int) ((GrX-Gr0)/meta->general->x_pixel_size)+0.5;
//        printf("Slant %f :: ",slant);
//        printf("GP = (%f-%f) / %f = %i\n",GrX,Gr0,meta->general->x_pixel_size,groundPixel);
    }
    else {
        groundPixel=0;    // just to quiet the compiler warning
        asfPrintError("Cannot convert slant range to ground range without a valid perX size.\n");
    }

    return(groundPixel);}
示例#7
0
void scan_to_latlon(meta_parameters *meta,
        double x, double y, double z,
        double *lat_d, double *lon, double *height)
{
  double qlat, qlon;
  double lat,radius;
  vector pos;
  meta_projection *proj = meta->projection;

  if (z != 0.0) {
    // height correction applies directly to y (range direction)
    double line, samp;
    line = (y-proj->startY)/proj->perY - meta->general->start_line;
    samp = (x-proj->startX)/proj->perX - meta->general->start_sample;
    double sr = meta_get_slant(meta,line,samp);
    double er = proj->param.atct.rlocal;
    double ht = meta_get_sat_height(meta,line,samp);
    double cos_ang = (sr*sr + er*er - ht*ht)/(2.0*sr*er);
    if (cos_ang > 1) cos_ang = 1;
    if (cos_ang < -1) cos_ang = -1;
    double incid = PI-acos(cos_ang);
    x += z*tan(PI/2-incid);
  }

  if (meta->sar->look_direction=='R')
    qlat = -x/proj->param.atct.rlocal; /* Right looking sar */
  else
    qlat =  x/proj->param.atct.rlocal; /* Left looking sar */
  qlon = y/(proj->param.atct.rlocal*cos(qlat));

  sph2cart(proj->param.atct.rlocal, qlat, qlon, &pos);

  rotate_z(&pos,-proj->param.atct.alpha3);
  rotate_y(&pos,-proj->param.atct.alpha2);
  rotate_z(&pos,-proj->param.atct.alpha1);

  cart2sph(pos,&radius,&lat,lon);
  *lon *= R2D;
  lat *= R2D;
  *lat_d = atand(tand(lat) / (1-ecc2(proj->re_minor,proj->re_major)));
  *height = z;  // FIXME: Do we need to correct the height at all?
}
示例#8
0
static void gr2sr_vec(meta_parameters *meta, float srinc, float *gr2sr,
                      int apply_pp_earth_radius_fix)
{
  int    i;             /* Counter                                       */
  float  r_sc;          /* radius from center of the earth for satellite */
  float  r_earth;       /* radius of the earth                           */
  float  r_close;       /* near slant range distance                     */
  float  rg0, rg;        /* Ground range to first pixel, G.R. to cur pix  */
  float  a, x, x2, y;   /* temporaries                                   */
  float  grinc;  /* Slant and Ground range pixel spacings         */
  float  rslant;        /* slant range distance to current pixel         */

  /* Radius from the center of the earth to the spacecraft, slant range to
     first pixel, and radius of the earth */
  r_sc = meta_get_sat_height(meta, 0, 0);
  r_close = meta_get_slant(meta,0,0);

  if (apply_pp_earth_radius_fix)
      r_earth = meta_get_earth_radius_pp(meta);
  else
      r_earth = meta_get_earth_radius(meta,0,0);

  /* Set the ground range and slant range increments */
  grinc = meta->general->x_pixel_size;

  /* calculate ground range to first point */
  a = (r_sc-r_earth)/r_earth;
  x = 1.0+a;
  x2 = x * x;
  y = r_close/r_earth;
  rg0 = r_earth * acos((1.0 + x2 - y*y) / (2.0*x));
  /* begin loop */
  for(i = 0; i<MAX_IMG_SIZE; i++) {
    rslant = r_close + i *srinc;
    y = rslant/r_earth;
    rg = r_earth*acos((1.0+x2-y*y)/(2.0*x));
    gr2sr[i] = (rg - rg0)/grinc;
  }
}
示例#9
0
double meta_get_slant(meta_parameters *meta,double yLine, double xSample)
{
  // 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->sar->image_type=='S')/*Slant range is easy.*/
        return meta->sar->slant_range_first_pixel
            + (xSample+meta->general->start_sample) * meta->general->x_pixel_size
            + meta->sar->slant_shift;
    else if (meta->sar->image_type=='G')/*Ground range is tougher.*/
    {/*We figure out the ground angle, phi, for this pixel, then
    use that and the law of cosines to find the slant range.*/
        double er = meta_get_earth_radius(meta,yLine,xSample);
        double ht = meta_get_sat_height(meta,yLine,xSample);
        double minPhi = acos((SQR(ht)+SQR(er)
            - SQR(meta->sar->slant_range_first_pixel)) / (2.0*ht*er));
        double phi = minPhi+
            (xSample+meta->general->start_sample)*(meta->general->x_pixel_size / er);
        double slantRng = sqrt(SQR(ht)+SQR(er)-2.0*ht*er*cos(phi));
        return slantRng + meta->sar->slant_shift;
    }
    else if (meta->sar->image_type=='P' ||
         meta->sar->image_type=='R')
    {
        double time,slant;
        meta_get_timeSlantDop(meta,yLine,xSample,&time,&slant,NULL);
        return slant+meta->sar->slant_shift;
    }
    else /*Unknown image type.*/
    {
        printf("Error!  Unknown SAR image type '%c' passed to meta_get_slant!\n",
            meta->sar->image_type);
        exit(1);
    }
    return 0.0;/*<- for whining compilers.*/
}
示例#10
0
static void sr2gr_vec(meta_parameters *meta, float srinc, float newSize,
                      float *sr2gr)
{
    double rg,rg0;/*Ground range distances from nadir, along curve of earth.*/
    double ht,re,sr;/*S/C height, earth radius, slant range [m]*/
    int    ii;
    
    ht = meta_get_sat_height(meta, 0, 0);
    re = meta_get_earth_radius(meta, 0, 0);
    sr = meta_get_slant(meta,0,0);
    
    /* calculate ground range to first point */
    rg0 = re * acos((ht*ht+re*re-sr*sr) / (2*ht*re));
    
    /* begin loop */
    rg = rg0;
    for (ii = 0; ii<MAX_IMG_SIZE; ii++)
    {
        double this_slant = sqrt(ht*ht+re*re-2.0*ht*re*cos(rg/re));
        sr2gr[ii] = (this_slant - sr) / srinc;
        rg += newSize;
    }
}
meta_parameters* vp2meta(vexcel_plain *vp)
{
  vp_doppler_centroid_parameters doppler_params;
  meta_parameters *meta;
  char *mon[13]={"","Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep",
     "Oct","Nov","Dec"};
  ymd_date ymd, ref_date;
  hms_time time, ref_time;
  julian_date jd;
  int i, nStVec;

  // Initialize the meta structure
  meta = raw_init();

  // Fill general block
  strcpy(meta->general->basename, vp->gli_product.image_desc.title);
  strcpy(meta->general->sensor, vp->sensor.instrument_name);
  strcpy(meta->general->sensor_name, vp->sensor.sensor_name);
  // FIXME: need to handle multibeam data
  strcpy(meta->general->mode, vp->sensor.beam[0].beam_name);
  strcpy(meta->general->processor, vp->gli_product.processor_name);
  if (vp->gli_product.image_desc.bytes_per_pixel == 1)
    meta->general->data_type = ASF_BYTE;
  else if (vp->gli_product.image_desc.bytes_per_pixel == 2)
    meta->general->data_type = INTEGER16;
  else if (vp->gli_product.image_desc.bytes_per_pixel == 4)
    meta->general->data_type = REAL32;
  meta->general->image_data_type = AMPLITUDE_IMAGE;
  meta->general->radiometry = r_AMP;
  date_dssr2date(vp->gli_product.orbit_nr_date, &ymd, &time);
  sprintf(meta->general->acquisition_date, "%2d-%s-%4d", 
	  ymd.day, mon[ymd.month], ymd.year);
  meta->general->orbit = vp->gli_product.orbit_nr;
  if (strncmp(vp->flight_path_direction, "ASCENDING", 9) == 0)
    meta->general->orbit_direction = 'A';
  else
    meta->general->orbit_direction = 'D';
  meta->general->frame = MAGIC_UNSET_INT;
  meta->general->band_count = vp->sensor.nr_beams;
  strcpy(meta->general->bands, "AMP");
  meta->general->line_count = vp->gli_product.image_desc.nr_lines;;
  meta->general->sample_count = vp->gli_product.image_desc.nr_pixels;
  meta->general->start_line = 0;
  meta->general->start_sample = 0;
  meta->general->x_pixel_size = vp->gli_product.image_desc.line_spacing;
  meta->general->y_pixel_size = vp->gli_product.image_desc.pixel_spacing;
  meta->general->center_latitude = 
    vp->gli_product.image_desc.coord.center_line_center_pixel.lat;
  meta->general->center_longitude = 
    vp->gli_product.image_desc.coord.center_line_center_pixel.lon;;
  meta->general->re_major = 
    vp->gli_product.image_desc.coord.earth_model.major;
  meta->general->re_minor = 
    vp->gli_product.image_desc.coord.earth_model.minor;
  meta->general->bit_error_rate = MAGIC_UNSET_DOUBLE;
  meta->general->missing_lines = 0;
  meta->general->no_data = MAGIC_UNSET_DOUBLE;

  // Fill SAR block
  meta->sar = meta_sar_init();
  // working with assumptions here
  meta->sar->image_type = 'G';
  if (vp->sensor.clock_angle >= 0.0)
    meta->sar->look_direction = 'R';
  else
    meta->sar->look_direction = 'L';
  meta->sar->azimuth_look_count = vp->gli_product.azimuth_looks;
  meta->sar->range_look_count = vp->gli_product.range_looks;
  meta->sar->deskewed = vp->gli_product.skew_flag;
  meta->sar->original_line_count = meta->general->line_count;
  meta->sar->original_sample_count = meta->general->sample_count;
  meta->sar->line_increment = 1;
  meta->sar->sample_increment = 1;
  meta->sar->range_time_per_pixel = 
    fabs((2.0 * vp->gli_product.image_desc.pixel_spacing) / SPD_LIGHT);
  meta->sar->azimuth_time_per_pixel = vp->gli_product.time_per_line;
  meta->sar->slant_range_first_pixel = vp->gli_product.near_range;
  meta->sar->slant_shift = 0.0;
  if (meta->general->orbit_direction == 'D')
    meta->sar->time_shift = 0.0;
  else if (meta->general->orbit_direction == 'A')
    meta->sar->time_shift = 
      fabs(meta->sar->original_line_count * meta->sar->azimuth_time_per_pixel);
  else
    meta->sar->time_shift = MAGIC_UNSET_DOUBLE;
  meta->sar->wavelength = SPD_LIGHT / vp->sensor.beam[0].carrier_freq;
  meta->sar->prf = vp->sensor.beam[0].prf;
  meta->sar->earth_radius_pp = MAGIC_UNSET_DOUBLE;
  strcpy(meta->sar->satellite_binary_time, MAGIC_UNSET_STRING);
  strcpy(meta->sar->satellite_clock_time, MAGIC_UNSET_STRING);
  doppler_params = vp->sensor.beam[0].doppler_centroid_parameters;
  // FIXME: Check units for higher coefficients
  meta->sar->range_doppler_coefficients[0] =
    doppler_params.doppler_centroid_coefficients.a[0];
  meta->sar->range_doppler_coefficients[1] =
    doppler_params.doppler_centroid_coefficients.a[1];
  meta->sar->range_doppler_coefficients[2] =
    doppler_params.doppler_centroid_coefficients.a[2];

  for (i=0; i<3; i++)
    meta->sar->azimuth_doppler_coefficients[i] = 0.0;
  meta->sar->azimuth_processing_bandwidth = 
    vp->gli_product.processor_bandwidth;
  meta->sar->chirp_rate = vp->sensor.beam[0].chirp_rate;
  meta->sar->pulse_duration = vp->sensor.beam[0].pulse_length;
  meta->sar->range_sampling_rate = vp->sensor.beam[0].sampling_freq;
  strcpy(meta->sar->polarization,
	 vp->sensor.beam[0].polarization_block.polarization[0].polarization);
  meta->sar->multilook = 1;
  meta->sar->pitch = vp->sensor.ephemeris.attitude.pitch;
  meta->sar->roll = vp->sensor.ephemeris.attitude.roll;
  meta->sar->yaw = vp->sensor.ephemeris.attitude.yaw;

  // Fill state vector structure
  nStVec = vp->sensor.ephemeris.sv_block.nr_sv;
  meta->state_vectors = meta_state_vectors_init(nStVec);
  date_dssr2date(vp->sensor.ephemeris.sv_block.state_vector[0].date, 
		 &ref_date, &ref_time);
  meta->state_vectors->year = ref_date.year;
  date_ymd2jd(&ref_date, &jd);
  meta->state_vectors->julDay = jd.jd;
  meta->state_vectors->second = date_hms2sec(&ref_time);
  meta->state_vectors->vector_count = nStVec;
  for (i=0; i<nStVec; i++) {
    date_dssr2date(vp->sensor.ephemeris.sv_block.state_vector[i].date, 
		   &ymd, &time);
    meta->state_vectors->vecs[i].time = 
      date_difference(&ref_date, &ref_time, &ymd, &time);
    meta->state_vectors->vecs[i].vec.pos.x = 
      vp->sensor.ephemeris.sv_block.state_vector[i].x;
    meta->state_vectors->vecs[i].vec.pos.y =
      vp->sensor.ephemeris.sv_block.state_vector[i].y;
    meta->state_vectors->vecs[i].vec.pos.z =
      vp->sensor.ephemeris.sv_block.state_vector[i].z;
    meta->state_vectors->vecs[i].vec.vel.x = 
      vp->sensor.ephemeris.sv_block.state_vector[i].xv;
    meta->state_vectors->vecs[i].vec.vel.y =
      vp->sensor.ephemeris.sv_block.state_vector[i].yv;
    meta->state_vectors->vecs[i].vec.vel.z =
      vp->sensor.ephemeris.sv_block.state_vector[i].zv;
  }
  date_dssr2date(vp->gli_product.first_line, &ymd, &time);
  double shift = date_difference(&ref_date, &ref_time, &ymd, &time);
  int sign;
  if (compare_time(&ymd, &time, &ref_date, &ref_time) > 0)
    sign = -1;
  else
    sign = 1;
  for (i=0; i<nStVec; i++)
    meta->state_vectors->vecs[i].time += sign * shift;
  meta->state_vectors->second = date_hms2sec(&time);
  double interval = 
    meta->general->line_count * meta->sar->azimuth_time_per_pixel / 2;
  propagate_state(meta, 3, interval);
  meta->sar->earth_radius = 
    meta_get_earth_radius(meta, meta->general->line_count/2, 
			  meta->general->sample_count/2);
  meta->sar->satellite_height = 
    meta_get_sat_height(meta, meta->general->line_count/2,
			meta->general->sample_count/2);  

  // Fill location block
  meta->location = meta_location_init();
  meta->location->lat_start_near_range =
    vp->gli_product.image_desc.coord.first_line_first_pixel.lat;
  meta->location->lon_start_near_range =
    vp->gli_product.image_desc.coord.first_line_first_pixel.lon;
  meta->location->lat_start_far_range =
    vp->gli_product.image_desc.coord.first_line_last_pixel.lat;
  meta->location->lon_start_far_range =
    vp->gli_product.image_desc.coord.first_line_last_pixel.lon;
  meta->location->lat_end_near_range =
    vp->gli_product.image_desc.coord.last_line_first_pixel.lat;
  meta->location->lon_end_near_range =
    vp->gli_product.image_desc.coord.last_line_first_pixel.lon;
  meta->location->lat_end_far_range =
    vp->gli_product.image_desc.coord.last_line_last_pixel.lat;
  meta->location->lon_end_far_range =
    vp->gli_product.image_desc.coord.last_line_last_pixel.lon;

  return meta;
}