Esempio n. 1
0
meta_parameters* uavsar_insar2meta(uavsar_insar *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, "InSAR");
  strcpy(meta->general->processor, "JPL version ");
  strcat(meta->general->processor, params->processor);
  if (params->type == INSAR_AMP || params->type == INSAR_AMP_GRD) {
    if (params->type == INSAR_AMP) 
      strcpy(meta->general->mode, "AMP");
    else if (params->type == INSAR_AMP_GRD) 
      strcpy(meta->general->mode, "AMP_GRD");
    meta->general->image_data_type = AMPLITUDE_IMAGE;
  }
  else if (params->type == INSAR_INT || params->type == INSAR_INT_GRD) {
    if (params->type == INSAR_INT)
      strcpy(meta->general->mode, "INT");
    else if (params->type == INSAR_INT_GRD)
      strcpy(meta->general->mode, "INT_GRD");
    meta->general->image_data_type = INTERFEROGRAM;
  }
  else if (params->type == INSAR_UNW || params->type == INSAR_UNW_GRD) {
    if (params->type == INSAR_UNW)
      strcpy(meta->general->mode, "UNW");
    else if (params->type == INSAR_UNW_GRD)
      strcpy(meta->general->mode, "UNW_GRD");
    meta->general->image_data_type = UNWRAPPED_PHASE;
  }
  else if (params->type == INSAR_COR || params->type == INSAR_COR_GRD) {
    if (params->type == INSAR_COR)
      strcpy(meta->general->mode, "COR");
    else if (params->type == INSAR_COR_GRD)
      strcpy(meta->general->mode, "COR_GRD");
    meta->general->image_data_type = COHERENCE_IMAGE;
  }
  else if (params->type == INSAR_HGT_GRD) {
    strcpy(meta->general->mode, "HGT_GRD");
    meta->general->image_data_type = DEM;
  }
  else
    strcpy(meta->general->mode, "unknown");
  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 a = params->semi_major;
  double ecc2 = params->eccentricity;
  meta->general->re_minor = sqrt((1-ecc2)*a*a);
  // no information on bit error rate, missing lines and no data
  
  // SAR block
  meta->sar = meta_sar_init();
  strcpy(meta->sar->polarization, params->polarization);
  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';
  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
  // no information on earth radius and 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;

  // Projection block
  if (params->type >= INSAR_AMP_GRD && params->type <= INSAR_HGT_GRD) {
    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;

    // FIXME: Check that the following is correct - needs some data
    // 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;
  }

  // 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;

  return meta;
}
Esempio n. 2
0
void uavsar_to_latlon(meta_parameters *meta,
                      double xSample, double yLine, double height,
                      double *lat, double *lon)
{
    if (!meta->uavsar)
        asfPrintError("uavsar_to_latlon() called with no uavsar block!\n");

    const double a = 6378137.0;           // semi-major axis
    const double b = 6356752.3412;          // semi-minor axis
    const double e2 = 0.00669437999014;   // ellipticity
    const double e12 = 0.00673949674228;  // second eccentricity

    // we try to cache the matrices needed for the computation
    // this makes sure we don't reuse the cache incorrectly (i.e., on
    // data (=> an uavsar block) which doesn't match what we cached for)
    static meta_uavsar *cached_uavsar_block = NULL;

    // these are the cached transformation parameters
    static matrix *m = NULL;
    static double ra=-999, o1=-999, o2=-999, o3=-999;

    if (!m)
        m = matrix_alloc(3,3); // only needs to be done once

    // if we aren't calculating with the exact same airsar block, we
    // need to recalculate the transformation block
    int recalc = !cached_uavsar_block ||
        cached_uavsar_block->lat_peg_point != meta->uavsar->lat_peg_point ||
        cached_uavsar_block->lon_peg_point != meta->uavsar->lon_peg_point ||
        cached_uavsar_block->head_peg_point != meta->uavsar->head_peg_point;

    if (recalc) {
        // cache airsar block, so we can be sure we're not reusing
        // the stored data incorrectly
        if (cached_uavsar_block)
            free(cached_uavsar_block);
        cached_uavsar_block = meta_uavsar_init();
        *cached_uavsar_block = *(meta->uavsar);

        // now precalculate data
        double lat_peg = meta->uavsar->lat_peg_point*D2R;
        double lon_peg = meta->uavsar->lon_peg_point*D2R;
        double head_peg = meta->uavsar->head_peg_point*D2R;
        double re = a / sqrt(1-e2*sin(lat_peg)*sin(lat_peg));
        double rn = (a*(1-e2)) / pow(1-e2*sin(lat_peg)*sin(lat_peg), 1.5);
        ra = (re*rn) / (re*cos(head_peg)*cos(head_peg)+rn*sin(head_peg)*sin(head_peg));

        matrix *m1, *m2;
        m1 = matrix_alloc(3,3);
        m2 = matrix_alloc(3,3);

        m1->coeff[0][0] = -sin(lon_peg);
        m1->coeff[0][1] = -sin(lat_peg)*cos(lon_peg);
        m1->coeff[0][2] = cos(lat_peg)*cos(lon_peg);
        m1->coeff[1][0] = cos(lon_peg);
        m1->coeff[1][1] = -sin(lat_peg)*sin(lon_peg);
        m1->coeff[1][2] = cos(lat_peg)*sin(lon_peg);
        m1->coeff[2][0] = 0.0;
        m1->coeff[2][1] = cos(lat_peg);
        m1->coeff[2][2] = sin(lat_peg);

        m2->coeff[0][0] = 0.0;
        m2->coeff[0][1] = sin(head_peg);
        m2->coeff[0][2] = -cos(head_peg);
        m2->coeff[1][0] = 0.0;
        m2->coeff[1][1] = cos(head_peg);
        m2->coeff[1][2] = sin(head_peg);
        m2->coeff[2][0] = 1.0;
        m2->coeff[2][1] = 0.0;
        m2->coeff[2][2] = 0.0;

        o1 = re*cos(lat_peg)*cos(lon_peg)-ra*cos(lat_peg)*cos(lon_peg);
        o2 = re*cos(lat_peg)*sin(lon_peg)-ra*cos(lat_peg)*sin(lon_peg);
        o3 = re*(1-e2)*sin(lat_peg)-ra*sin(lat_peg);

        matrix_mult(m,m1,m2);
        matrix_free(m1);
        matrix_free(m2);
    }

    // Make sure we didn't miss anything
    assert(ra != -999 && o1 != -999 && o2 != -999 && o3 != -999);

    //------------------------------------------------------------------
    // Now the actual computation, using the cached matrix etc

    // convenience aliases
    double c0 = meta->uavsar->cross_track_offset;
    double s0 = meta->uavsar->along_track_offset;
    double ypix = meta->general->y_pixel_size/meta->general->line_scaling;
    double xpix = meta->general->x_pixel_size/meta->general->sample_scaling;

    // radar coordinates
    double c_lat = (xSample*xpix+c0)/ra;
    double s_lon = (yLine*ypix+s0)/ra;

    //height += meta->airsar->gps_altitude;

    // radar coordinates in WGS84
    double t1 = (ra+height)*cos(c_lat)*cos(s_lon);
    double t2 = (ra+height)*cos(c_lat)*sin(s_lon);
    double t3 = (ra+height)*sin(c_lat);

    double c1 = m->coeff[0][0]*t1 + m->coeff[0][1]*t2 + m->coeff[0][2]*t3;
    double c2 = m->coeff[1][0]*t1 + m->coeff[1][1]*t2 + m->coeff[1][2]*t3;
    double c3 = m->coeff[2][0]*t1 + m->coeff[2][1]*t2 + m->coeff[2][2]*t3;

    // shift into local Cartesian coordinates
    double x = c1 + o1;// + 9.0;
    double y = c2 + o2;// - 161.0;
    double z = c3 + o3;// - 179.0;

    // local Cartesian coordinates into geographic coordinates
    double d = sqrt(x*x+y*y);
    double theta = atan2(z*a, d*b);
    *lat = R2D*atan2(z+e12*b*sin(theta)*sin(theta)*sin(theta),
                     d-e2*a*cos(theta)*cos(theta)*cos(theta));
    *lon = R2D*atan2(y, x);
}
Esempio n. 3
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;
}