meta_parameters* radarsat2meta(radarsat2_meta *radarsat2) { ymd_date date, imgStartDate, imgStopDate; hms_time time, imgStartTime, imgStopTime; meta_parameters *meta; char *mon[13]= {"","Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep", "Oct","Nov","Dec" }; double lat, lon, height, re, rp; // Allocate memory for metadata structure meta = raw_init(); // General block strcpy(meta->general->basename, radarsat2->filename); strcpy(meta->general->sensor, radarsat2->satellite); strcpy(meta->general->sensor_name, radarsat2->sensor); strcpy(meta->general->mode, radarsat2->beamModeMnemonic); sprintf(meta->general->processor, "%s %s", radarsat2->processingFacility, radarsat2->softwareVersion); meta->general->data_type = REAL32; if (strcmp_case(radarsat2->dataType, "COMPLEX") == 0) meta->general->image_data_type = COMPLEX_IMAGE; //else if (strcmp_case(radarsat2->dataType, "DETECTED") == 0) // meta->general->image_data_type = AMPLITUDE_IMAGE; meta->general->radiometry = r_AMP; date_terrasar2date(radarsat2->zeroDopplerAzimuthTime, &date, &time); sprintf(meta->general->acquisition_date, "%02d-%s-%4d %02d:%02d:%02.0f", date.day, mon[date.month], date.year, time.hour, time.min, time.sec); //meta->general->orbit = radarsat2->absOrbit; if (strcmp_case(radarsat2->passDirection, "ASCENDING") == 0) meta->general->orbit_direction = 'A'; else if (strcmp_case(radarsat2->passDirection, "DESCENDING") == 0) meta->general->orbit_direction = 'D'; if (strcmp_case(radarsat2->dataType, "COMPLEX") == 0) meta->general->band_count = radarsat2->band_count * 2; else meta->general->band_count = radarsat2->band_count; strcpy(meta->general->bands, radarsat2->bands); meta->general->line_count = radarsat2->numberOfLines; meta->general->sample_count = radarsat2->numberOfSamplesPerLine; meta->general->start_line = 0; meta->general->start_sample = 0; meta->general->x_pixel_size = radarsat2->sampledPixelSpacing; meta->general->y_pixel_size = radarsat2->sampledLineSpacing; //meta->general->center_latitude = radarsat2->sceneCenterCoordLat; //meta->general->center_longitude = radarsat2->sceneCenterCoordLon; meta->general->re_major = radarsat2->semiMajorAxis; meta->general->re_minor = radarsat2->semiMinorAxis; // SAR block meta->sar = meta_sar_init(); if (strcmp_case(radarsat2->productType, "SLC") == 0) meta->sar->image_type = 'S'; if (strcmp_case(radarsat2->antennaPointing, "LEFT") == 0) meta->sar->look_direction = 'L'; else if (strcmp_case(radarsat2->antennaPointing, "RIGHT") == 0) meta->sar->look_direction = 'R'; meta->sar->azimuth_look_count = radarsat2->numberOfAzimuthLooks; meta->sar->range_look_count = radarsat2->numberOfRangeLooks; meta->sar->deskewed = 1; 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; date_terrasar2date(radarsat2->zeroDopplerTimeFirstLine, &imgStartDate, &imgStartTime); date_terrasar2date(radarsat2->zeroDopplerTimeLastLine, &imgStopDate, &imgStopTime); meta->sar->azimuth_time_per_pixel = date_difference(&imgStopDate, &imgStopTime, &imgStartDate, &imgStartTime) / meta->general->line_count; meta->sar->range_time_per_pixel = meta->general->x_pixel_size * 2.0 / speedOfLight; meta->sar->slant_range_first_pixel = radarsat2->slantRangeNearEdge; meta->sar->slant_shift = 0.0; meta->sar->time_shift = 0.0; meta->sar->wavelength = SPD_LIGHT / radarsat2->radarCenterFrequency; meta->sar->prf = radarsat2->pulseRepetitionFrequency; meta->sar->satellite_height = radarsat2->satelliteHeight; meta->sar->azimuth_processing_bandwidth = radarsat2->totalProcessedAzimuthBandwidth; // FIXME: chirp_rate ??? meta->sar->pulse_duration = radarsat2->pulseLength; meta->sar->range_sampling_rate = radarsat2->adcSamplingRate; if (strcmp_case(radarsat2->polarizations, "HH,VV,HV,VH") == 0) { meta->general->image_data_type = POLARIMETRIC_IMAGE; strcpy(meta->sar->polarization, "quad-pol"); } else strcpy(meta->sar->polarization, radarsat2->polarizations); if (strcmp_case(radarsat2->dataType, "COMPLEX") == 0) meta->sar->multilook = FALSE; // FIXME: pitch, roll, yaw ??? // Doppler block meta->doppler = radarsat2->doppler; // State vectors meta->state_vectors = radarsat2->state_vectors; // Propagate the state vectors to start, center, end int vector_count = 3; double data_int = date_difference(&imgStopDate, &imgStopTime, &imgStartDate, &imgStartTime) / 2.0; while (fabs(data_int) > 10.0) { data_int /= 2; vector_count = vector_count*2-1; } propagate_state(meta, vector_count, data_int); // Location block meta->location = meta_location_init(); meta->location->lat_start_near_range = radarsat2->sceneCornerCoord1Lat; meta->location->lon_start_near_range = radarsat2->sceneCornerCoord1Lon; meta->location->lat_start_far_range = radarsat2->sceneCornerCoord2Lat; meta->location->lon_start_far_range = radarsat2->sceneCornerCoord2Lon; meta->location->lat_end_near_range = radarsat2->sceneCornerCoord3Lat; meta->location->lon_end_near_range = radarsat2->sceneCornerCoord3Lon; meta->location->lat_end_far_range = radarsat2->sceneCornerCoord4Lat; meta->location->lon_end_far_range = radarsat2->sceneCornerCoord4Lon; // Still need to determine center location, really only needed to get // the earth radius straight meta->general->center_longitude = (radarsat2->sceneCornerCoord1Lon + radarsat2->sceneCornerCoord2Lon + radarsat2->sceneCornerCoord3Lon + radarsat2->sceneCornerCoord4Lon) / 4.0; location_to_latlon(meta, meta->general->sample_count/2, meta->general->line_count/2, 0.0, &lat, &lon, &height); meta->general->center_latitude = lat; meta->general->center_longitude = lon; lat = meta->general->center_latitude * D2R; re = meta->general->re_major; rp = meta->general->re_minor; meta->sar->earth_radius = (re*rp) / sqrt(rp*rp*cos(lat)*cos(lat)+re*re*sin(lat)*sin(lat)); meta->sar->satellite_height += meta->sar->earth_radius; return meta; }
/******************************************************************* * meta_get_latLon: * Converts given line and sample to geodetic latitude and longitude. * Works with all image types.*/ int meta_get_latLon(meta_parameters *meta, double yLine, double xSample,double elev, double *lat,double *lon) { double hgt; if (meta->projection) { /*Map-Projected. Use projection information to calculate lat & lon.*/ double px,py,pz=0.0; px = meta->projection->startX + ((xSample + meta->general->start_sample) * meta->projection->perX); py = meta->projection->startY + ((yLine + meta->general->start_line) * meta->projection->perY); /*Currently have to handle scansar separately, because it depends on a lot more info than the other projections */ if (meta->projection->type == SCANSAR_PROJECTION) { scan_to_latlon(meta, px, py, elev, lat, lon, &hgt); } else { proj_to_latlon(meta->projection, px, py, pz, lat, lon, &hgt); *lat *= R2D; *lon *= R2D; } } else if (meta->airsar) { double l = yLine, s = xSample; if (meta->sar) { l = meta->general->start_line + meta->general->line_scaling * yLine; s = meta->general->start_sample + meta->general->sample_scaling * xSample; } airsar_to_latlon(meta, s, l, elev, lat, lon); } else if (meta->uavsar) { double l = yLine, s = xSample; if (meta->sar) { l = meta->general->start_line + meta->general->line_scaling * yLine; s = meta->general->start_sample + meta->general->sample_scaling * xSample; } uavsar_to_latlon(meta, s, l, elev, lat, lon); } else if (meta->latlon) { int nLine = (int)(yLine + 0.5); int nSample = (int)(xSample + 0.5); int sample_count = meta->general->sample_count; *lat = meta->latlon->lat[nLine*sample_count + nSample]; *lon = meta->latlon->lon[nLine*sample_count + nSample]; } else if (meta->transform) { /* ALOS data (not projected) -- use transform block */ double l = yLine, s = xSample; if (meta->sar) { s = meta->general->start_sample + meta->general->sample_scaling * s; l = meta->general->start_line + meta->general->line_scaling * l; } if (meta->sar && meta->sar->image_type == 'G' && strcmp_case(meta->transform->type, "slant") == 0) { // map s (sample) value from Ground to Slant double new_s = map_gr2sr(meta, l, s); //printf("meta_get_latLon -- mapped gr to sr: %f -> %f\n", s, new_s); s = new_s; } else if (meta->sar && meta->sar->image_type == 'S' && strcmp_case(meta->transform->type, "ground") == 0) { // not implemented, don't think we need this? asfPrintError("meta_get_latLon: ground transform block " "with a slant range image.\n"); double new_s = map_sr2gr(meta, l, s); //printf("meta_get_latLon -- mapped sr to gr: %f -> %f\n", s, new_s); s = new_s; } alos_to_latlon(meta, s, l, elev, lat, lon, &hgt); //printf("alos_to_latlon: %f, %f ==> %f, %f\n", l, s, *lat, *lon); } else if (meta->sar && (meta->sar->image_type=='S' || meta->sar->image_type=='G')) { /*Slant or ground range. Use state vectors and doppler.*/ double slant,doppler,time; meta_get_timeSlantDop(meta,yLine,xSample,&time,&slant,&doppler); meta_timeSlantDop2latLon(meta, time,slant,doppler,elev, lat,lon); } else if (meta->location) { double l = yLine, s = xSample; if (meta->sar) { l = meta->general->start_line + meta->general->line_scaling * yLine; s = meta->general->start_sample + meta->general->sample_scaling * xSample; } location_to_latlon(meta, s, l, elev, lat, lon, &hgt); } else { /*Bogus image type.*/ asfPrintError( "meta_get_latLon: Couldn't figure out what kind of image this is!\n" "meta->transform = %p, so it isn't ALOS.\n" "meta->sar = %p, and it isn't Slant/Ground range.\n" "meta->projection = %p, so it isn't Projected, or Scansar.\n" "meta->location = %p, so doesn't have location information.\n" "meta->general->name: %s\n", meta->transform, meta->sar, meta->projection, meta->location, meta->general ? meta->general->basename : "(null)"); return 1; /* Not Reached */ } //if (*lon < -180) *lon += 360; //if (*lon > 180) *lon -= 360; return 0; }