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; }
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; } }
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); } }
/******************************************************************* * 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); } }
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); }
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); } }
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; }
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; }
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); }
/* 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); }
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); }
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); }
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; }
// 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; }
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; }
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; }
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; }
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; }