예제 #1
0
char *get_terrasar_browse_file(const char *xml_file_name)
{
  xmlDoc *doc = xmlReadFile(xml_file_name, NULL, 0);
  if (!doc) {
    asfPrintWarning("Could not parse file %s\n", xml_file_name);
    return NULL;
  }

  char preview_file[2048];

  char *path = get_dirname(xml_file_name);
  if (strlen(path)>0) {
    strcpy(preview_file, path);
    if (preview_file[strlen(preview_file)-1] != '/')
      strcat(preview_file, "/");
  }
  else
    strcpy(preview_file, "");
  free(path);

  strcat(preview_file, xml_get_string_value(doc, 
         "level1Product.productComponents.browseImage.file.location.path"));
  strcat(preview_file, "/");
  strcat(preview_file, xml_get_string_value(doc, 
         "level1Product.productComponents.browseImage.file.location.filename"));
  
  return STRDUP(preview_file);
}
예제 #2
0
int handle_terrasar_file(const char *filename, char *meta_name, char *data_name,
			 char **err)
{
  // allocate error buffer, just in case we need it
  *err = (char *) MALLOC(sizeof(char)*1024);
  
  // check for metadata
  if (!fileExists(filename))
    meta_name = appendExt(filename, ".xml");
  else
    strcpy(meta_name, filename);
  if (!fileExists(meta_name)) {
    sprintf(*err, "Error opening TerraSAR-X file, metadata file (%s) does "
	    "not exist!\n", meta_name);
    return FALSE;
  }
  xmlDoc *doc = xmlReadFile(meta_name, NULL, 0);
  if (!doc) {
    sprintf(*err, "Could not parse file %s\n", meta_name);
    return FALSE;
  }
  
  // path from the xml (metadata) file
  char *path = get_dirname(filename);
  if (strlen(path)>0) {
    strcpy(data_name, path);
    if (data_name[strlen(data_name)-1] != '/')
      strcat(data_name, "/");
  }
  else
    strcpy(data_name, "");
  free(path);
  
  // strcat() on the path & file from the XML entry
  strcat(data_name, xml_get_string_value(doc, 
    "level1Product.productComponents.imageData[0].file.location.path"));
  strcat(data_name, "/");
  strcat(data_name, xml_get_string_value(doc, 
    "level1Product.productComponents.imageData[0].file.location.filename"));
  if (!fileExists(data_name)) {
    sprintf(*err, "Data file (%s) does not exist!\n", data_name);
    return FALSE;
  }

  // check data type
  terrasar_meta *terrasar = read_terrasar_meta(meta_name);
  if (!strcmp_case(terrasar->imageDataType, "COMPLEX") == 0 &&
      !strcmp_case(terrasar->imageDataFormat, "COSAR") == 0) {
    sprintf(*err, "Data type (%s) and data format (%s) currently not "
	    "supported!\n", 
	    terrasar->imageDataType, terrasar->imageDataFormat);
    return FALSE;
  }

  FREE(*err);
  err = NULL;
  return TRUE;
}
예제 #3
0
static double *read_radarsat2_lut(const char *dataFile, int gain_count)
{
    int ii;
    char *gainStr = (char *) MALLOC(sizeof(char)*100000);
    char *p, *q;
    double *gain = (double *) MALLOC(sizeof(double)*gain_count);
    xmlDoc *doc = xmlReadFile(dataFile, NULL, 0);
    strcpy(gainStr, xml_get_string_value(doc, "lut.gains"));
    p = gainStr;
    for (ii=0; ii<gain_count; ii++) {
        if (ii == 0)
            q = p;
        else {
            if (strchr(p, ' ')) {
                q = strchr(p, ' ');
                q++;
            }
        }
        sscanf(q, "%lf", &gain[ii]);
        p = q;
    }
    FREE(gainStr);
    xmlFreeDoc(doc);
    xmlCleanupParser();

    return gain;
}
예제 #4
0
long xml_get_long_value(xmlDoc *doc, char *format, ...)
{
  va_list ap;
  char str[4096];

  va_start(ap, format);
  vsnprintf(str, 4095, format, ap);
  va_end(ap);

  const char *val = xml_get_string_value(doc, str);
  if (val && strcmp(val, MAGIC_UNSET_STRING) != 0)
    return atol(val);
  else
    return MAGIC_UNSET_INT;
}
예제 #5
0
static void test_string3(xmlDoc *doc, char *expected, char *str, int a1, int a2)
{
  const char *val = xml_get_string_value(doc, str, a1, a2);
  int passed;

  if (!expected) {
    passed = val==NULL;
  }
  else {
    passed = strcmp(val, expected)==0;
  }

  if (passed) {
    ++n_ok;
  }
  else {
    printf("WRONG!  for key: %s\n"
           "  Expected: %s\n"
           "       Got: %s\n",
           str, expected, val);
    ++n_bad;
  }
}
예제 #6
0
terrasar_meta *read_terrasar_meta(const char *dataFile)
{
  int ii, kk, numStateVectors, numDopplerEstimates;
  ymd_date imgStartDate, imgDopplerDate, date;
  hms_time imgStartTime, imgDopplerTime, time;
  julian_date julianDate;
  char timeStr[30], str[50];
  tsx_doppler_params *tsx;

  terrasar_meta *terrasar = terrasar_meta_init();

  if (!fileExists(dataFile))
    asfPrintError("Metadata file (%s) does not exist!\n", dataFile);
  xmlDoc *doc = xmlReadFile(dataFile, NULL, 0);
  if (!doc)
    asfPrintError("Could not parse file %s\n", dataFile);

  strcpy(terrasar->filename, xml_get_string_value(doc, 
     "level1Product.productComponents.annotation.file.location.filename"));
  strcpy(terrasar->mission, xml_get_string_value(doc, 
     "level1Product.productInfo.missionInfo.mission"));
  strcpy(terrasar->sensor, xml_get_string_value(doc, 
     "level1Product.productInfo.acquisitionInfo.sensor"));
  strcpy(terrasar->imagingMode, xml_get_string_value(doc,
     "level1Product.productInfo.acquisitionInfo.imagingMode"));
  strcpy(terrasar->elevationBeamConfiguration, xml_get_string_value(doc, 
     "level1Product.productInfo.acquisitionInfo.elevationBeamConfiguration"));
  strcpy(terrasar->imageDataType, xml_get_string_value(doc, 
     "level1Product.productInfo.imageDataInfo.imageDataType"));
  terrasar->imageDataDepth = xml_get_int_value(doc, 
     "level1Product.productInfo.imageDataInfo.imageDataDepth");
  strcpy(terrasar->imageDataFormat, xml_get_string_value(doc, 
     "level1Product.productInfo.imageDataInfo.imageDataFormat"));
  strcpy(terrasar->azimuthTimeUTC, xml_get_string_value(doc, 
     "level1Product.productInfo.sceneInfo.sceneCenterCoord.azimuthTimeUTC"));
  terrasar->absOrbit = 
    xml_get_int_value(doc, "level1Product.productInfo.missionInfo.absOrbit");
  strcpy(terrasar->orbitDirection, xml_get_string_value(doc, 
     "level1Product.productInfo.missionInfo.orbitDirection"));
  terrasar->numberOfLayers = xml_get_int_value(doc, 
     "level1Product.productInfo.imageDataInfo.numberOfLayers");
  strcpy(terrasar->polarisationMode, xml_get_string_value(doc, 
     "level1Product.productInfo.acquisitionInfo.polarisationMode"));
  if (strcmp_case(terrasar->polarisationMode, "SINGLE") == 0)
    strcpy(terrasar->bands, xml_get_string_value(doc, 
    "level1Product.productInfo.acquisitionInfo.polarisationList.polLayer[0]"));
  else if (strcmp_case(terrasar->polarisationMode, "DUAL") == 0) {
    strcpy(terrasar->bands, xml_get_string_value(doc, 
    "level1Product.productInfo.acquisitionInfo.polarisationList.polLayer[0]"));
    strcat(terrasar->bands, ",");
    strcat(terrasar->bands, xml_get_string_value(doc, 
    "level1Product.productInfo.acquisitionInfo.polarisationList.polLayer[1]"));
  }
  else if (strcmp_case(terrasar->polarisationMode, "TWIN") == 0) {
    strcpy(terrasar->bands, xml_get_string_value(doc, 
    "level1Product.productInfo.acquisitionInfo.polarisationList.polLayer[0]"));
    strcat(terrasar->bands, ",");
    strcat(terrasar->bands, xml_get_string_value(doc, 
    "level1Product.productInfo.acquisitionInfo.polarisationList.polLayer[1]"));
  }
  else if (strcmp_case(terrasar->polarisationMode, "QUAD") == 0) {
    strcpy(terrasar->bands, xml_get_string_value(doc, 
    "level1Product.productInfo.acquisitionInfo.polarisationList.polLayer[0]"));
    strcat(terrasar->bands, ",");
    strcat(terrasar->bands, xml_get_string_value(doc, 
    "level1Product.productInfo.acquisitionInfo.polarisationList.polLayer[1]"));
    strcat(terrasar->bands, ",");
    strcat(terrasar->bands, xml_get_string_value(doc, 
    "level1Product.productInfo.acquisitionInfo.polarisationList.polLayer[2]"));
    strcat(terrasar->bands, ",");
    strcat(terrasar->bands, xml_get_string_value(doc, 
    "level1Product.productInfo.acquisitionInfo.polarisationList.polLayer[3]"));
  }
  terrasar->numberOfRows = xml_get_int_value(doc, 
     "level1Product.productInfo.imageDataInfo.imageRaster.numberOfRows");
  terrasar->numberOfColumns = xml_get_int_value(doc, 
     "level1Product.productInfo.imageDataInfo.imageRaster.numberOfColumns");
  strcpy(terrasar->projection, xml_get_string_value(doc, 
     "level1Product.productInfo.productVariantInfo.projection"));
  if (strcmp_case(terrasar->projection, "GROUNDRANGE") == 0)
    terrasar->rangeResolution = xml_get_double_value(doc, 
    "level1Product.productInfo.imageDataInfo.imageRaster."
    "groundRangeResolution");
  if (strcmp_case(terrasar->projection, "SLANTRANGE") == 0)
    terrasar->rangeResolution = xml_get_double_value(doc, 
       "level1Product.productSpecific.complexImageInfo.projectedSpacingRange."
       "slantRange");
  // FIXME: cover MAP case
  terrasar->azimuthResolution = xml_get_double_value(doc, 
     "level1Product.productInfo.imageDataInfo.imageRaster.azimuthResolution");
  terrasar->sceneCenterCoordLat = xml_get_double_value(doc, 
     "level1Product.productInfo.sceneInfo.sceneCenterCoord.lat");
  terrasar->sceneCenterCoordLon = xml_get_double_value(doc, 
     "level1Product.productInfo.sceneInfo.sceneCenterCoord.lon");
  strcpy(terrasar->lookDirection, xml_get_string_value(doc, 
     "level1Product.productInfo.acquisitionInfo.lookDirection"));
  terrasar->azimuthLooks = xml_get_int_value(doc, 
     "level1Product.productInfo.imageDataInfo.imageRaster.azimuthLooks");
  terrasar->rangeLooks = xml_get_int_value(doc, 
     "level1Product.productInfo.imageDataInfo.imageRaster.rangeLooks");
  strcpy(terrasar->imageCoordinateType, xml_get_string_value(doc, 
     "level1Product.productSpecific.complexImageInfo.imageCoordinateType"));
  terrasar->rowSpacing = xml_get_double_value(doc, 
     "level1Product.productInfo.imageDataInfo.imageRaster.rowSpacing");
  terrasar->columnSpacing =  xml_get_double_value(doc, 
     "level1Product.productInfo.imageDataInfo.imageRaster.columnSpacing");
  terrasar->rangeTimeFirst = xml_get_double_value(doc, 
     "level1Product.productInfo.sceneInfo.rangeTime.firstPixel");
  terrasar->rangeTimeLast = xml_get_double_value(doc, 
     "level1Product.productInfo.sceneInfo.rangeTime.lastPixel");
  terrasar->centerFrequency = xml_get_double_value(doc, 
     "level1Product.instrument.radarParameters.centerFrequency");
  terrasar->prf = xml_get_double_value(doc, 
     "level1Product.instrument.settings.settingRecord.PRF");
  terrasar->totalProcessedAzimuthBandwidth = xml_get_double_value(doc, 
     "level1Product.processing.processingParameter."
     "totalProcessedAzimuthBandwidth");
  // chirp rate ???
  terrasar->pulseLength = xml_get_double_value(doc, 
     "level1Product.processing.processingParameter.rangeCompression.chirps."
     "referenceChirp.pulseLength");
  terrasar->rsf = xml_get_double_value(doc, 
     "level1Product.instrument.settings.RSF");
  // pitch, roll, yaw ???

  // read Doppler values
  terrasar->doppler = meta_doppler_init();
  terrasar->doppler->type = tsx_doppler;
  numDopplerEstimates = xml_get_int_value(doc, 
     "level1Product.processing.doppler.dopplerCentroid[0]."
     "numberOfDopplerRecords");
  tsx = tsx_doppler_init(numDopplerEstimates);
  terrasar->doppler->tsx = tsx;
  strcpy(str, xml_get_string_value(doc, 
     "level1Product.processing.doppler.dopplerCentroid[0].dopplerEstimate[0]."
     "timeUTC"));
  date_terrasar2date(str, &imgDopplerDate, &imgDopplerTime);
  tsx->year = imgDopplerDate.year;
  date_ymd2jd(&imgDopplerDate, &julianDate);
  tsx->julDay = julianDate.jd;
  tsx->second = date_hms2sec(&imgDopplerTime);
  for (ii=0; ii<numDopplerEstimates; ii++) {
    strcpy(timeStr, xml_get_string_value(doc, 
       "level1Product.processing.doppler.dopplerCentroid[0]."
       "dopplerEstimate[%d].timeUTC", ii));
    date_terrasar2date(timeStr, &date, &time);
    tsx->dop[ii].time =
      time_difference(&date, &time, &imgDopplerDate, &imgDopplerTime);
    tsx->dop[ii].first_range_time = xml_get_double_value(doc, 
       "level1Product.processing.doppler.dopplerCentroid[0]."
       "dopplerEstimate[%d].combinedDoppler.validityRangeMin", ii);
    tsx->dop[ii].reference_time = xml_get_double_value(doc, 
       "level1Product.processing.doppler.dopplerCentroid[0]."
       "dopplerEstimate[%d].combinedDoppler.referencePoint", ii);
    tsx->dop[ii].poly_degree = xml_get_double_value(doc, 
       "level1Product.processing.doppler.dopplerCentroid[0]."
       "dopplerEstimate[%d].combinedDoppler.polynomialDegree", ii);
    tsx->dop[ii].coefficient = 
      (double *) MALLOC(sizeof(double) * (tsx->dop[ii].poly_degree+1));
    for (kk=0; kk<=tsx->dop[ii].poly_degree; kk++)
      tsx->dop[ii].coefficient[kk] = xml_get_double_value(doc, 
	 "level1Product.processing.doppler.dopplerCentroid[0]."
         "dopplerEstimate[%d].combinedDoppler.coefficient[%d]", ii, kk);
  }  

  // read state vectors
  strcpy(terrasar->sceneStart, xml_get_string_value(doc, 
     "level1Product.productInfo.sceneInfo.start.timeUTC"));
  date_terrasar2date(terrasar->sceneStart, &imgStartDate, &imgStartTime);
  strcpy(terrasar->sceneStop, xml_get_string_value(doc, 
     "level1Product.productInfo.sceneInfo.stop.timeUTC"));
  numStateVectors = xml_get_int_value(doc, 
     "level1Product.platform.orbit.orbitHeader.numStateVectors");
  terrasar->state_vectors = meta_state_vectors_init(numStateVectors);
  terrasar->state_vectors->year = imgStartDate.year;
  date_ymd2jd(&imgStartDate, &julianDate);
  terrasar->state_vectors->julDay = julianDate.jd;
  terrasar->state_vectors->second = date_hms2sec(&imgStartTime);
  for (ii=0; ii<numStateVectors; ii++) {
    sprintf(str, "level1Product.platform.orbit.stateVec[%d].timeUTC", ii);
    strcpy(timeStr, xml_get_string_value(doc, str));
    date_terrasar2date(timeStr, &date, &time);
    terrasar->state_vectors->vecs[ii].time =
      time_difference(&date, &time, &imgStartDate, &imgStartTime);
    sprintf(str, "level1Product.platform.orbit.stateVec[%d].posX", ii);
    terrasar->state_vectors->vecs[ii].vec.pos.x = 
      xml_get_double_value(doc, str);
    sprintf(str, "level1Product.platform.orbit.stateVec[%d].posY", ii);
    terrasar->state_vectors->vecs[ii].vec.pos.y = 
      xml_get_double_value(doc, str);
    sprintf(str, "level1Product.platform.orbit.stateVec[%d].posZ", ii);
    terrasar->state_vectors->vecs[ii].vec.pos.z = 
      xml_get_double_value(doc, str);
    sprintf(str, "level1Product.platform.orbit.stateVec[%d].velX", ii);
    terrasar->state_vectors->vecs[ii].vec.vel.x = 
      xml_get_double_value(doc, str);
    sprintf(str, "level1Product.platform.orbit.stateVec[%d].velY", ii);
    terrasar->state_vectors->vecs[ii].vec.vel.y = 
      xml_get_double_value(doc, str);
    sprintf(str, "level1Product.platform.orbit.stateVec[%d].velZ", ii);
    terrasar->state_vectors->vecs[ii].vec.vel.z = 
      xml_get_double_value(doc, str);
  }

  // read location information
  terrasar->sceneCornerCoord1Lat = xml_get_double_value(doc, 
     "level1Product.productInfo.sceneInfo.sceneCornerCoord[0].lat");
  terrasar->sceneCornerCoord1Lon = xml_get_double_value(doc, 
     "level1Product.productInfo.sceneInfo.sceneCornerCoord[0].lon");
  terrasar->sceneCornerCoord2Lat = xml_get_double_value(doc, 
     "level1Product.productInfo.sceneInfo.sceneCornerCoord[1].lat");
  terrasar->sceneCornerCoord2Lon = xml_get_double_value(doc, 
     "level1Product.productInfo.sceneInfo.sceneCornerCoord[1].lon");
  terrasar->sceneCornerCoord3Lat = xml_get_double_value(doc, 
     "level1Product.productInfo.sceneInfo.sceneCornerCoord[2].lat");
  terrasar->sceneCornerCoord3Lon = xml_get_double_value(doc, 
     "level1Product.productInfo.sceneInfo.sceneCornerCoord[2].lon");
  terrasar->sceneCornerCoord4Lat = xml_get_double_value(doc, 
     "level1Product.productInfo.sceneInfo.sceneCornerCoord[3].lat");
  terrasar->sceneCornerCoord4Lon = xml_get_double_value(doc, 
     "level1Product.productInfo.sceneInfo.sceneCornerCoord[3].lon");

  // read calibration information
  char calFlag[15];
  strcpy(calFlag, xml_get_string_value(doc,
     "level1Product.productInfo.productVariantInfo.radiometricCorrection"));
  if (strcmp_case(calFlag, "CALIBRATED") == 0)
    terrasar->cal_factor = xml_get_double_value(doc,
       "level1Product.calibration.calibrationConstant.calFactor");

  xmlFreeDoc(doc);
  xmlCleanupParser();

  return terrasar;
}
예제 #7
0
radarsat2_meta *read_radarsat2_meta_ext(const char *dataFile, int cal)
{
    int ii, numStateVectors, numDopplerEstimates;
    ymd_date imgStartDate, date;
    hms_time imgStartTime, time;
    julian_date julianDate;
    char timeStr[30], str[150];
    radarsat2_doppler_params *r2_doppler;

    radarsat2_meta *radarsat2 = radarsat2_meta_init();

    if (!fileExists(dataFile))
        asfPrintError("Metadata file (%s) does not exist!\n", dataFile);
    char *path = (char *) MALLOC(sizeof(char)*512);
    char *file = (char *) MALLOC(sizeof(char)*128);
    split_dir_and_file(dataFile, path, file);

    xmlDoc *doc = xmlReadFile(dataFile, NULL, 0);
    if (!doc)
        asfPrintError("Could not parse file %s\n", dataFile);

    strcpy(radarsat2->satellite, xml_get_string_value(doc,
            "product.sourceAttributes.satellite"));
    strcpy(radarsat2->sensor, xml_get_string_value(doc,
            "product.sourceAttributes.sensor"));
    strcpy(radarsat2->beamModeMnemonic, xml_get_string_value(doc,
            "product.sourceAttributes.beamModeMnemonic"));
    strcpy(radarsat2->acquisitionType, xml_get_string_value(doc,
            "product.sourceAttributes.radarParameters.acquisitionType"));
    strcpy(radarsat2->productType, xml_get_string_value(doc,
            "product.imageGenerationParameters.generalProcessingInformation."
            "productType"));
    strcpy(radarsat2->dataType, xml_get_string_value(doc,
            "product.imageAttributes.rasterAttributes.dataType"));
    strcpy(radarsat2->processingFacility, xml_get_string_value(doc,
            "product.imageGenerationParameters.generalProcessingInformation."
            "processingFacility"));
    strcpy(radarsat2->zeroDopplerAzimuthTime, xml_get_string_value(doc,
            "product.imageGenerationParameters.slantRangeToGroundRange."
            "zeroDopplerAzimuthTime"));
    strcpy(radarsat2->softwareVersion, xml_get_string_value(doc,
            "product.imageGenerationParameters.generalProcessingInformation."
            "softwareVersion"));
    radarsat2->bitsPerSample = xml_get_int_value(doc,
                               "product.productInfo.imageDataInfo.imageDataDepth");
    //radarsat2->absOrbit =
    //xml_get_int_value(doc, "product.productInfo.missionInfo.absOrbit");
    strcpy(radarsat2->passDirection, xml_get_string_value(doc,
            "product.sourceAttributes.orbitAndAttitude.orbitInformation."
            "passDirection"));
    // Number of bands needs to be derived from polarizations string
    int band_count = 0;
    char *attribute = (char *) MALLOC(sizeof(char)*128);
    char *fileName = (char *) MALLOC(sizeof(char)*512);
    strcpy(radarsat2->polarizations, xml_get_string_value(doc,
            "product.sourceAttributes.radarParameters.polarizations"));
    for (ii=0; ii<strlen(radarsat2->polarizations)-1; ii++)
        if (radarsat2->polarizations[ii] == ' ')
            radarsat2->polarizations[ii] = ',';
    if (strstr(radarsat2->polarizations, "HH"))
        band_count++;
    if (strstr(radarsat2->polarizations, "VV"))
        band_count++;
    if (strstr(radarsat2->polarizations, "HV"))
        band_count++;
    if (strstr(radarsat2->polarizations, "VH"))
        band_count++;
    radarsat2->band_count = band_count;
    strcpy(radarsat2->filename, "");
    strcpy(radarsat2->bands, "");
    // Park the filenames in the basename field of the metadata and replace
    // it with the directory name once we are done with importing the data
    for (ii=0; ii<band_count; ii++) {
        sprintf(str,
                "product.imageAttributes.fullResolutionImageData[%d].pole", ii);
        strcpy(attribute, xml_get_string_attribute(doc, str));
        sprintf(str, "product.imageAttributes.fullResolutionImageData[%d]", ii);
        strcpy(fileName, xml_get_string_value(doc, str));
        if (ii == 0) {
            sprintf(radarsat2->filename, "%s", fileName);
            sprintf(radarsat2->bands, "AMP-%s,PHASE-%s",
                    uc(attribute), uc(attribute));
        }
        else {
            strcat(radarsat2->filename, ",");
            strcat(radarsat2->filename, fileName);
            strcat(radarsat2->bands, ",");
            sprintf(str, "AMP-%s,PHASE-%s", uc(attribute), uc(attribute));
            strcat(radarsat2->bands, str);
        }
    }
    FREE(fileName);
    FREE(attribute);
    radarsat2->numberOfLines = xml_get_int_value(doc,
                               "product.imageAttributes.rasterAttributes.numberOfLines");
    radarsat2->numberOfSamplesPerLine = xml_get_int_value(doc,
                                        "product.imageAttributes.rasterAttributes.numberOfSamplesPerLine");
    radarsat2->sampledPixelSpacing = xml_get_double_value(doc,
                                     "product.imageAttributes.rasterAttributes.sampledPixelSpacing");
    radarsat2->sampledLineSpacing = xml_get_double_value(doc,
                                    "product.imageAttributes.rasterAttributes.sampledLineSpacing");
    radarsat2->semiMajorAxis = xml_get_double_value(doc,
                               "product.imageAttributes.geographicInformation."
                               "referenceEllipsoidParameters.semiMajorAxis");
    radarsat2->semiMinorAxis = xml_get_double_value(doc,
                               "product.imageAttributes.geographicInformation."
                               "referenceEllipsoidParameters.semiMinorAxis");
    strcpy(radarsat2->lineTimeOrdering, xml_get_string_value(doc,
            "product.imageAttributes.rasterAttributes.lineTimeOrdering"));
    strcpy(radarsat2->pixelTimeOrdering, xml_get_string_value(doc,
            "product.imageAttributes.rasterAttributes.pixelTimeOrdering"));
    strcpy(radarsat2->antennaPointing, xml_get_string_value(doc,
            "product.sourceAttributes.radarParameters.antennaPointing"));
    radarsat2->numberOfAzimuthLooks = xml_get_int_value(doc,
                                      "product.imageGenerationParameters.sarProcessingInformation."
                                      "numberOfAzimuthLooks");
    radarsat2->numberOfRangeLooks = xml_get_int_value(doc,
                                    "product.imageGenerationParameters.sarProcessingInformation."
                                    "numberOfRangeLooks");
    radarsat2->slantRangeNearEdge = xml_get_double_value(doc,
                                    "product.imageGenerationParameters.sarProcessingInformation."
                                    "slantRangeNearEdge");
    radarsat2->radarCenterFrequency = xml_get_double_value(doc,
                                      "product.sourceAttributes.radarParameters.radarCenterFrequency");
    radarsat2->pulseRepetitionFrequency = xml_get_double_value(doc,
                                          "product.sourceAttributes.radarParameters.pulseRepetitionFrequency");
    radarsat2->satelliteHeight = xml_get_double_value(doc,
                                 "product.imageGenerationParameters.sarProcessingInformation."
                                 "satelliteHeight");
    radarsat2->totalProcessedAzimuthBandwidth = xml_get_double_value(doc,
            "product.imageGenerationParameters.sarProcessingInformation."
            "totalProcessedAzimuthBandwidth");
    // chirp rate ???
    radarsat2->pulseLength = xml_get_double_value(doc,
                             "product.sourceAttributes.radarParameters.pulseLength");
    radarsat2->adcSamplingRate = xml_get_double_value(doc,
                                 "product.sourceAttributes.radarParameters.adcSamplingRate");
    // pitch, roll, yaw ???

    // read Doppler values
    radarsat2->doppler = meta_doppler_init();
    radarsat2->doppler->type = radarsat2_doppler;
    char *dopplerCentroidStr;
    dopplerCentroidStr = (char *) MALLOC(sizeof(char)*512);
    strcpy(dopplerCentroidStr, xml_get_string_value(doc,
            "product.imageGenerationParameters.dopplerCentroid."
            "dopplerCentroidCoefficients"));
    numDopplerEstimates = getNumParamsInString(dopplerCentroidStr);
    r2_doppler = radarsat2_doppler_init(numDopplerEstimates);
    radarsat2->doppler->r2 = r2_doppler;
    r2_doppler->ref_time_centroid = xml_get_double_value(doc,
                                    "product.imageGenerationParameters.dopplerCentroid."
                                    "dopplerCentroidReferenceTime");
    r2_doppler->ref_time_rate = xml_get_double_value(doc,
                                "product.imageGenerationParameters.dopplerRateValues."
                                "dopplerRateReferenceTime");
    char *dopplerRateStr;
    dopplerRateStr = (char *) MALLOC(sizeof(char)*512);
    strcpy(dopplerRateStr, xml_get_string_value(doc,
            "product.imageGenerationParameters.dopplerRateValues."
            "dopplerRateValuesCoefficients"));
    r2_doppler->time_first_sample = xml_get_double_value(doc,
                                    "product.imageGenerationParameters.slantRangeToGroundRange."
                                    "slantRangeTimeToFirstRangeSample");
    char *p, *q;
    p = dopplerCentroidStr;
    for (ii=0; ii<numDopplerEstimates; ii++) {
        if (ii == 0)
            q = p;
        else {
            if (strchr(p, ' ')) {
                q = strchr(p, ' ');
                q++;
            }
        }
        sscanf(q, "%lf", &r2_doppler->centroid[ii]);
        p = q;
    }
    FREE(dopplerCentroidStr);
    p = dopplerRateStr;
    for (ii=0; ii<numDopplerEstimates; ii++) {
        if (ii == 0)
            q = p;
        else {
            if (strchr(p, ' ')) {
                q = strchr(p, ' ');
                q++;
            }
        }
        sscanf(q, "%lf", &r2_doppler->rate[ii]);
        p = q;
    }
    FREE(dopplerRateStr);

    // read state vectors
    strcpy(radarsat2->zeroDopplerTimeFirstLine, xml_get_string_value(doc,
            "product.imageGenerationParameters.sarProcessingInformation."
            "zeroDopplerTimeFirstLine"));
    date_terrasar2date(radarsat2->zeroDopplerTimeFirstLine,
                       &imgStartDate, &imgStartTime);
    strcpy(radarsat2->zeroDopplerTimeLastLine, xml_get_string_value(doc,
            "product.imageGenerationParameters.sarProcessingInformation."
            "zeroDopplerTimeLastLine"));
    // Accommodate data stored in reverse time
    if (strcmp_case(radarsat2->lineTimeOrdering, "DECREASING") == 0)
        date_terrasar2date(radarsat2->zeroDopplerTimeLastLine,
                           &imgStartDate, &imgStartTime);

    // FIXME: determine numStateVector from data - count the entries
    //numStateVectors = xml_get_int_value(doc,
    //   "product.platform.orbit.orbitHeader.numStateVectors");
    numStateVectors = 5;
    radarsat2->state_vectors = meta_state_vectors_init(numStateVectors);
    radarsat2->state_vectors->year = imgStartDate.year;
    date_ymd2jd(&imgStartDate, &julianDate);
    radarsat2->state_vectors->julDay = julianDate.jd;
    radarsat2->state_vectors->second = date_hms2sec(&imgStartTime);
    for (ii=0; ii<numStateVectors; ii++) {
        sprintf(str, "product.sourceAttributes.orbitAndAttitude.orbitInformation."
                "stateVector[%d].timeStamp", ii);
        strcpy(timeStr, xml_get_string_value(doc, str));
        date_terrasar2date(timeStr, &date, &time);
        radarsat2->state_vectors->vecs[ii].time =
            time_difference(&date, &time, &imgStartDate, &imgStartTime);
        sprintf(str, "product.sourceAttributes.orbitAndAttitude.orbitInformation."
                "stateVector[%d].xPosition", ii);
        radarsat2->state_vectors->vecs[ii].vec.pos.x =
            xml_get_double_value(doc, str);
        sprintf(str, "product.sourceAttributes.orbitAndAttitude.orbitInformation."
                "stateVector[%d].yPosition", ii);
        radarsat2->state_vectors->vecs[ii].vec.pos.y =
            xml_get_double_value(doc, str);
        sprintf(str, "product.sourceAttributes.orbitAndAttitude.orbitInformation."
                "stateVector[%d].zPosition", ii);
        radarsat2->state_vectors->vecs[ii].vec.pos.z =
            xml_get_double_value(doc, str);
        sprintf(str, "product.sourceAttributes.orbitAndAttitude.orbitInformation."
                "stateVector[%d].xVelocity", ii);
        radarsat2->state_vectors->vecs[ii].vec.vel.x =
            xml_get_double_value(doc, str);
        sprintf(str, "product.sourceAttributes.orbitAndAttitude.orbitInformation."
                "stateVector[%d].yVelocity", ii);
        radarsat2->state_vectors->vecs[ii].vec.vel.y =
            xml_get_double_value(doc, str);
        sprintf(str, "product.sourceAttributes.orbitAndAttitude.orbitInformation."
                "stateVector[%d].zVelocity", ii);
        radarsat2->state_vectors->vecs[ii].vec.vel.z =
            xml_get_double_value(doc, str);
    }

    // read location information from the tie points
    ii = 0;
    int line=-99, pixel=-99, found=TRUE;
    while (found) {
        sprintf(str, "product.imageAttributes.geographicInformation."
                "geolocationGrid.imageTiePoint[%d].imageCoordinate.line", ii);
        line = (int) xml_get_double_value(doc, str);
        sprintf(str, "product.imageAttributes.geographicInformation."
                "geolocationGrid.imageTiePoint[%d].imageCoordinate.pixel", ii);
        pixel = (int) xml_get_double_value(doc, str);
        if (line < 0 || pixel < 0)
            found = FALSE;
        if (found) {
            if (line == 0 && pixel == 0) {
                sprintf(str, "product.imageAttributes.geographicInformation."
                        "geolocationGrid.imageTiePoint[%d].geodeticCoordinate."
                        "latitude", ii);
                radarsat2->sceneCornerCoord1Lat = xml_get_double_value(doc, str);
                sprintf(str, "product.imageAttributes.geographicInformation."
                        "geolocationGrid.imageTiePoint[%d].geodeticCoordinate."
                        "longitude", ii);
                radarsat2->sceneCornerCoord1Lon = xml_get_double_value(doc, str);
            }
            if (line == 0 && pixel == radarsat2->numberOfSamplesPerLine-1) {
                sprintf(str, "product.imageAttributes.geographicInformation."
                        "geolocationGrid.imageTiePoint[%d].geodeticCoordinate."
                        "latitude", ii);
                radarsat2->sceneCornerCoord2Lat = xml_get_double_value(doc, str);
                sprintf(str, "product.imageAttributes.geographicInformation."
                        "geolocationGrid.imageTiePoint[%d].geodeticCoordinate."
                        "longitude", ii);
                radarsat2->sceneCornerCoord2Lon = xml_get_double_value(doc, str);
            }
            if (line == radarsat2->numberOfLines-1 && pixel == 0) {
                sprintf(str, "product.imageAttributes.geographicInformation."
                        "geolocationGrid.imageTiePoint[%d].geodeticCoordinate."
                        "latitude", ii);
                radarsat2->sceneCornerCoord3Lat = xml_get_double_value(doc, str);
                sprintf(str, "product.imageAttributes.geographicInformation."
                        "geolocationGrid.imageTiePoint[%d].geodeticCoordinate."
                        "longitude", ii);
                radarsat2->sceneCornerCoord3Lon = xml_get_double_value(doc, str);
            }
            if (line == radarsat2->numberOfLines-1 &&
                    pixel == radarsat2->numberOfSamplesPerLine-1) {
                sprintf(str, "product.imageAttributes.geographicInformation."
                        "geolocationGrid.imageTiePoint[%d].geodeticCoordinate."
                        "latitude", ii);
                radarsat2->sceneCornerCoord4Lat = xml_get_double_value(doc, str);
                sprintf(str, "product.imageAttributes.geographicInformation."
                        "geolocationGrid.imageTiePoint[%d].geodeticCoordinate."
                        "longitude", ii);
                radarsat2->sceneCornerCoord4Lon = xml_get_double_value(doc, str);
            }
        }
        ii++;
    }

    // Read calibration information
    if (cal) {
        double sample_count = radarsat2->numberOfSamplesPerLine;
        attribute = (char *) MALLOC(sizeof(char)*128);
        fileName = (char *) MALLOC(sizeof(char)*512);
        for (ii=0; ii<3; ii++) {
            sprintf(str,
                    "product.imageAttributes.lookupTable[%d].incidenceAngleCorrection",
                    ii);
            strcpy(attribute, xml_get_string_attribute(doc, str));
            sprintf(str, "product.imageAttributes.lookupTable[%d]", ii);
            if (strlen(path) > 0)
                sprintf(fileName, "%s%s", path, xml_get_string_value(doc, str));
            else
                strcpy(fileName, xml_get_string_value(doc, str));
            if (strcmp_case(attribute, "Beta Nought") == 0)
                radarsat2->gains_beta = read_radarsat2_lut(fileName, sample_count);
            else if (strcmp_case(attribute, "Sigma Nought") == 0)
                radarsat2->gains_sigma = read_radarsat2_lut(fileName, sample_count);
            else if (strcmp_case(attribute, "Gamma") == 0)
                radarsat2->gains_gamma = read_radarsat2_lut(fileName, sample_count);
        }
        FREE(attribute);
        FREE(fileName);
    }

    xmlFreeDoc(doc);
    xmlCleanupParser();

    return radarsat2;
}
예제 #8
0
int isRadarsat2_ext(char *dataFile, int check_data, char **error)
{
  char dataType[25];
  char *message = NULL;
  int found = FALSE;
  char *inFile = MALLOC(sizeof(char)*(strlen(dataFile)+16));
  strcpy(inFile, dataFile);
  // Let's first check for an .xml extension
  char *ext = findExt(inFile);

  // Append extension in case we don't find it
  if (!fileExists(inFile) && ext == NULL) {
    strcat(inFile, ".xml");
    ext = findExt(inFile);
  }

  // If it has the correct extension, investigate it further
  // Might sound a little harsh but avoids some XML parser warning otherwise.
  if (fileExists(inFile) && ext && strcmp_case(ext, ".xml") == 0) {
    int ii, band_count = 0;
    char tmp[256], *path = NULL, *inDataName = NULL;
    char polarizations[25], satellite[25];
    FILE *fp;
    fp = fopen(inFile, "r");
    xmlDoc *doc = xmlReadFile(inFile, NULL, 0);
    if (doc) {
      strncpy_safe(satellite, 
	           xml_get_string_value(doc, "product.sourceAttributes.satellite"), 20);
      
      // only care about Radarsat-2 data
      if (strcmp_case(satellite, "RADARSAT-2") == 0) {
	
	found = TRUE;
	strncpy_safe(dataType, xml_get_string_value(doc, 
          "product.imageAttributes.rasterAttributes.dataType"), 20);
	if (strcmp_case(dataType, "COMPLEX") != 0) {
	  if (!message)
	    message = (char *) MALLOC(sizeof(char)*1024);
	  sprintf(tmp, "Wrong data type!\n"
		  "Polarimetric processing requires SLC data!\n");
	  strcat(message, tmp);
	  if (check_data)
  	  found = FALSE;
	}
	
	// path from the xml (metadata) file
	path = get_dirname(inFile);
	inDataName = (char *) MALLOC(sizeof(char)*(strlen(path)+512));
	strncpy_safe(polarizations, xml_get_string_value(doc, 
	  "product.sourceAttributes.radarParameters.polarizations"),20);
	for (ii=0; ii<strlen(polarizations)-1; ii++)
	  if (polarizations[ii] == ' ')
	  polarizations[ii] = ',';
	if (strstr(polarizations, "HH"))
	  band_count++;
	if (strstr(polarizations, "VV"))
	  band_count++;
	if (strstr(polarizations, "HV"))
	  band_count++;
	if (strstr(polarizations, "VH"))
	  band_count++;
	
	for (ii=0; ii<band_count; ii++) {
	  if (strlen(path)>0) {
	    strcpy(inDataName, path);
	    if (inDataName[strlen(inDataName)-1] != '/')
	      strcat(inDataName, "/");
	  }
	  else
	    strcpy(inDataName, "");
	  strcat(inDataName, xml_get_string_value(doc, 
	    "product.imageAttributes.fullResolutionImageData[%d]", ii));
	  if (!fileExists(inDataName)) {
	    if (!message)
	      message = (char *) MALLOC(sizeof(char)*1024);
	    sprintf(tmp, "Data file (%s) does not exist!\n", inDataName);
	    strcat(message, tmp);
	    if (check_data)
  	    found = FALSE;
	  }
	}
      }
    }
    if (fp) {
      fclose(fp);
      xmlFreeDoc(doc);
      xmlCleanupParser();
    }
  }    
  FREE(inFile);

  if (!found && message)
    *error = message;

  return found;
}
예제 #9
0
int isTerrasar_ext(char *dataFile, int checkPolarimetry, char **error)
{
  int found = FALSE;
  char *inFile = STRDUP(dataFile);
  // Let's first check for an .xml extension
  char *ext = findExt(inFile);

  // If it has the correct extension, investigate it further
  // Might sound a little harsh but avoids some XML parser warning otherwise.
  if (ext && strcmp_case(ext, ".xml") == 0) {
    char *satellite = NULL;
    char tmp[256], *message = NULL, *path=NULL, *inDataName=NULL;
    char imageDataType[25];
    int ii, numberOfLayers;
    satellite = (char *) MALLOC(sizeof(char)*25);
    FILE *fp;
    fp = fopen(inFile, "r");
    xmlDoc *doc = xmlReadFile(inFile, NULL, 0);
    if (doc) {
      strcpy(satellite, xml_get_string_value(doc, 
        "level1Product.productInfo.missionInfo.mission"));

      // only care about TerraSAR-X data
      if (satellite && 
	  (strncmp_case(satellite, "TSX", 3) == 0 ||
	   strncmp_case(satellite, "TDX", 3) == 0)) {

	found = TRUE;
	if (checkPolarimetry) {
	  strcpy(imageDataType, xml_get_string_value(doc, 
	     "level1Product.productInfo.imageDataInfo.imageDataType"));
	  if (strcmp_case(imageDataType, "COMPLEX") != 0) {
	    if (!message)
	      message = (char *) MALLOC(sizeof(char)*1024);
	    sprintf(tmp, "Wrong data type!\n"
		    "Polarimetric processing requires SLC data!\n");
	    strcat(message, tmp);
	    found = FALSE;
	  }
	}

	// path from the xml (metadata) file
	path = get_dirname(inFile);
	inDataName = (char *) MALLOC(sizeof(char)*(strlen(path)+100));
	numberOfLayers = xml_get_int_value(doc, 
	  "level1Product.productInfo.imageDataInfo.numberOfLayers");

	for (ii=0; ii<numberOfLayers; ii++) {
	  if (strlen(path)>0) {
	    strcpy(inDataName, path);
	    if (inDataName[strlen(inDataName)-1] != '/')
	      strcat(inDataName, "/");
	  }
	  else
	    strcpy(inDataName, "");
	  
	  // check whether data file exists
	  strcat(inDataName, xml_get_string_value(doc, 
	    "level1Product.productComponents.imageData[%d].file.location.path",
	    ii));
	  strcat(inDataName, "/");
	  strcat(inDataName, xml_get_string_value(doc, 
	    "level1Product.productComponents.imageData[%d].file.location."
	    "filename", ii));
	  if (!fileExists(inDataName)) {
	    if (!message)
	      message = (char *) MALLOC(sizeof(char)*1024);
	    sprintf(tmp, "Data file (%s) does not exist!\n", inDataName);
	    strcat(message, tmp);
	    found = FALSE;
	  }	
	}
      }
    }
    fclose(fp);
    xmlFreeDoc(doc);
    xmlCleanupParser();
    if (path)
      FREE(path);
    if (inDataName)
      FREE(inDataName);
    FREE(inFile);
  }

  return found;
}
예제 #10
0
int xml_get_element_exists(xmlDoc *doc, char *str)
{
  const char *val = xml_get_string_value(doc, str);
  return val != NULL;
}
예제 #11
0
int main(int argc, char *argv[])
{
  char inFile[512], *configFile=NULL, type[10];
  const int pid = getpid();
  extern int logflag, quietflag;
  int quiet_f;  /* log_f is a static global */
  int createFlag = FLAG_NOT_SET; // create configuration file flag
  int configFlag = FLAG_NOT_SET; // use configuration file flag

  logflag = quietflag = FALSE;
  log_f = quiet_f = FLAG_NOT_SET;

  // Begin command line parsing ***********************************************
  if (   (checkForOption("--help", argc, argv) != FLAG_NOT_SET)
      || (checkForOption("-h", argc, argv) != FLAG_NOT_SET)
      || (checkForOption("-help", argc, argv) != FLAG_NOT_SET) ) {
      print_help();
  }
  get_asf_share_dir_with_argv0(argv[0]);
  handle_license_and_version_args(argc, argv, ASF_NAME_STRING);

  // Check which options were provided
  log_f    = checkForOption("-log", argc, argv);
  quiet_f  = checkForOption("-quiet", argc, argv);
  createFlag = checkForOption("-create", argc, argv);
  configFlag = checkForOption("-config", argc, argv);

  // We need to make sure the user specified the proper number of arguments
  int needed_args = 1 + REQUIRED_ARGS; // command & REQUIRED_ARGS
  int num_flags = 0;
  if (log_f != FLAG_NOT_SET) {needed_args += 2; num_flags++;} // option & param
  if (quiet_f != FLAG_NOT_SET) {needed_args += 1; num_flags++;} // option
  if (createFlag != FLAG_NOT_SET) {needed_args += 3; num_flags++;} // option & params
  if (configFlag != FLAG_NOT_SET) {needed_args += 2; num_flags++;} // option & param

  // Make sure we have the right number of args
  if(argc != needed_args) {
    print_usage();
  }

  // Make sure all options occur before the config file name argument
  if (num_flags == 1 &&
      (log_f   > 1 ||
       quiet_f > 1))
  {
    print_usage();
  }
  else if (num_flags > 1 &&
	   (log_f   >= argc - REQUIRED_ARGS - 1 ||
            quiet_f >= argc - REQUIRED_ARGS - 1))
  {
    print_usage();
  }

  // Make sure that only one option is used
  if (createFlag != FLAG_NOT_SET && configFlag != FLAG_NOT_SET)
    asfPrintError("The tool can either create or use the "
		  "configuration file, not both!\n");

  // Do the actual flagging & such for each flag
  if (createFlag != FLAG_NOT_SET) {
    sprintf(type, "%s", argv[createFlag+1]);
    configFile = (char *) MALLOC(sizeof(char)*1024);
    sprintf(configFile, "%s", argv[createFlag+2]);
  }
  if (configFlag != FLAG_NOT_SET) {
    configFile = (char *) MALLOC(sizeof(char)*1024);
    sprintf(configFile, "%s", argv[configFlag+1]);
  }
  if (log_f != FLAG_NOT_SET) {
    strcpy(logFile, argv[log_f+1]);
  }
  else {
    // default behavior: log to tmp<pid>.log
    sprintf(logFile, "tmp%i.log", pid);
  }
  logflag = TRUE;
  fLog = FOPEN(logFile, "a");
  // Set old school quiet flag (for use in our libraries)
  quietflag = quiet_f != FLAG_NOT_SET;

  // Fetch required arguments
  strcpy(inFile, argv[argc-1]);

  // Report the command line
  asfSplashScreen(argc, argv);

  // Initialze structure
  dataset_t *data = (dataset_t *) MALLOC(sizeof(dataset_t));

  strcpy(data->dataset_id, MAGIC_UNSET_STRING);
  strcpy(data->origin, MAGIC_UNSET_STRING);
  strcpy(data->title, MAGIC_UNSET_STRING);
  strcpy(data->online_link, MAGIC_UNSET_STRING);
  data->west_bounding = MAGIC_UNSET_DOUBLE;
  data->east_bounding = MAGIC_UNSET_DOUBLE;
  data->north_bounding = MAGIC_UNSET_DOUBLE;
  data->south_bounding = MAGIC_UNSET_DOUBLE;
  data->near_start_lat = MAGIC_UNSET_DOUBLE;
  data->near_start_lon = MAGIC_UNSET_DOUBLE;
  data->far_start_lat = MAGIC_UNSET_DOUBLE;
  data->far_start_lon = MAGIC_UNSET_DOUBLE;
  data->far_end_lat = MAGIC_UNSET_DOUBLE;
  data->far_end_lon = MAGIC_UNSET_DOUBLE;
  data->near_end_lat = MAGIC_UNSET_DOUBLE;
  data->near_end_lon = MAGIC_UNSET_DOUBLE;
  data->center_lat = MAGIC_UNSET_DOUBLE;
  data->center_lon = MAGIC_UNSET_DOUBLE;
  strcpy(data->processing_level, MAGIC_UNSET_STRING);
  strcpy(data->platform, MAGIC_UNSET_STRING);
  strcpy(data->instrument, MAGIC_UNSET_STRING);
  data->band_count = MAGIC_UNSET_INT;
  data->browse_location = NULL;
  data->browse_format = NULL;
  strcpy(data->access, MAGIC_UNSET_STRING);
  strcpy(data->copyright, MAGIC_UNSET_STRING);
  data->start_time = NULL;
  data->center_time = NULL;
  data->end_time = NULL;
  strcpy(data->orbit_direction, MAGIC_UNSET_STRING);
  strcpy(data->mode, MAGIC_UNSET_STRING);
  strcpy(data->spatial_reference, MAGIC_UNSET_STRING);
  strcpy(data->cell_value, MAGIC_UNSET_STRING);
  strcpy(data->raster_object, MAGIC_UNSET_STRING);
  data->row_count = MAGIC_UNSET_INT;
  data->col_count = MAGIC_UNSET_INT;
  strcpy(data->format, MAGIC_UNSET_STRING);
  data->fees = MAGIC_UNSET_DOUBLE;

  // Open XML for reading
  xmlDoc *doc = xmlReadFile(inFile, NULL, 0);
  if (!doc)
    asfPrintError("Could not parse metadata file (%s)\n", inFile);

  // Read in all parameters and perform error checking
  char string[512], tmp[255], errorMessage[8192]="Metadata parsing errors:\n";
  int nValue, error = FALSE;
  double fValue;

  // Dataset ID
  strcpy(string, xml_get_string_value(doc, "metadata.idinfo.datsetid"));
  if (strlen(string) > MAX_DATASET_ID) {
    error = TRUE;
    sprintf(tmp, "Dataset ID - String length: %d, allowed characters: %d\n", 
	    (int) strlen(string), MAX_DATASET_ID);
    strcat(errorMessage, tmp);
  }
  else {
    strcpy(data->dataset_id, 
	   xml_get_string_value(doc, "metadata.idinfo.datsetid"));
    //printf("Dataset ID: %s\n", data->dataset_id);
  }

  // Origin
  strcpy(string, xml_get_string_value(doc, 
    "metadata.idinfo.citation.citeinfo.origin"));
  if (strlen(string) > MAX_ORIGIN) {
    error = TRUE;
    sprintf(tmp, "Origin - String length: %d, allowed characters: %d\n",
	    (int) strlen(string), MAX_ORIGIN);
    strcat(errorMessage, tmp);
  }
  else {
    strcpy(data->origin, xml_get_string_value(doc, 
      "metadata.idinfo.citation.citeinfo.origin"));
    //printf("Origin: %s\n", data->origin);
  }

  // Title
  strcpy(string, xml_get_string_value(doc, 
    "metadata.idinfo.citation.citeinfo.title"));
  if (strlen(string) > MAX_TITLE) {
    error = TRUE;
    sprintf(tmp, "Title - String length: %d, allowed characters: %d\n",
	    (int) strlen(string), MAX_TITLE);
    strcat(errorMessage, tmp);
  }
  else {
    strcpy(data->title, xml_get_string_value(doc, 
      "metadata.idinfo.citation.citeinfo.title"));
    //printf("Title: %s\n", data->title);
  }

  // Online link
  strcpy(string, xml_get_string_value(doc, 
    "metadata.idinfo.citation.citeinfo.onlink"));
  if (strlen(string) > MAX_ONLINE_LINK) {
    error = TRUE;
    sprintf(tmp, "Online link - String length: %d, allowed characters: %d\n",
	    (int) strlen(string), MAX_ONLINE_LINK);
    strcat(errorMessage, tmp);
  }
  else {
    strcpy(data->online_link, xml_get_string_value(doc, 
      "metadata.idinfo.citation.citeinfo.onlink"));
    //printf("Online link: %s\n", data->online_link);
  }

  // West bounding coordinate
  fValue = xml_get_double_value(doc, "metadata.idinfo.spdom.bounding.westbc");
  if (fValue < -180.0 || fValue > 180.0) {
    error = TRUE;
    sprintf(tmp, "West bounding coordinate - Value (%.4lf) outside the "
	    "expected value range (-180.0 < value < 180.0)\n", fValue);
    strcat(errorMessage, tmp);
  }
  else {
    data->west_bounding =
      xml_get_double_value(doc, "metadata.idinfo.spdom.bounding.westbc");
    //printf("West bounding coordinate: %.4lf\n", data->west_bounding);
  }

  // East bounding coordinate
  fValue = xml_get_double_value(doc, "metadata.idinfo.spdom.bounding.eastbc");
  if (fValue < -180.0 || fValue > 180.0) {
    error = TRUE;
    sprintf(tmp, "East bounding coordinate - Value (%.4lf) outside the "
	    "expected value range (-180.0 < value < 180.0)\n", fValue);
    strcat(errorMessage, tmp);
  }
  else {
    data->east_bounding =
      xml_get_double_value(doc, "metadata.idinfo.spdom.bounding.eastbc");
    //printf("East bounding coordinate: %.4lf\n", data->east_bounding);
  }

  // North bounding coordinate
  fValue = xml_get_double_value(doc, "metadata.idinfo.spdom.bounding.northbc");
  if (fValue < -90.0 || fValue > 90.0) {
    error = TRUE;
    sprintf(tmp, "West bounding coordinate - Value (%.4lf) outside the "
	    "expected value range (-90.0 < value < 90.0)\n", fValue);
    strcat(errorMessage, tmp);
  }
  else {
    data->north_bounding =
      xml_get_double_value(doc, "metadata.idinfo.spdom.bounding.northbc");
    //printf("West bounding coordinate: %.4lf\n", data->north_bounding);
  }

  // South bounding coordinate
  fValue = xml_get_double_value(doc, "metadata.idinfo.spdom.bounding.southbc");
  if (fValue < -90.0 || fValue > 90.0) {
    error = TRUE;
    sprintf(tmp, "South bounding coordinate - Value (%.4lf) outside the "
	    "expected value range (-90.0 < value < 90.0)\n", fValue);
    strcat(errorMessage, tmp);
  }
  else {
    data->south_bounding =
      xml_get_double_value(doc, "metadata.idinfo.spdom.bounding.southbc");
    //printf("South bounding coordinate: %.4lf\n", data->south_bounding);
  }

  // Open KML for reading
  char centerFile[512], boundaryFile[512], *baseName;
  char coordStr[50];
  float height;
  baseName = get_basename(inFile);
  sprintf(boundaryFile, "%s_boundary.kml", baseName);
  sprintf(centerFile, "%s_center.kml", baseName);

  xmlDoc *xmlBoundary = xmlReadFile(boundaryFile, NULL, 0);
  if (!xmlBoundary)
    asfPrintError("Could not parse boundary file (%s)\n", boundaryFile);
  else {
    strcpy(coordStr, xml_get_string_value(xmlBoundary, 
      "kml.Document.Placemark.Polygon.outerBoundaryIs.LinearRing.coordinates"));    sscanf(coordStr, "%f,%f,%f\n%f,%f,%f\n%f,%f,%f\n%f,%f", 
	   &data->near_start_lat, &data->near_start_lon, &height,
	   &data->near_end_lat, &data->near_end_lon, &height,
	   &data->far_end_lat, &data->far_end_lon, &height,
	   &data->far_start_lat, &data->far_start_lon);
    //printf("Near start latitude: %.4f\n", data->near_start_lat);
    //printf("Near start longitude: %.4f\n", data->near_start_lon);
    //printf("Near end latitude: %.4f\n", data->near_end_lat);
    //printf("Near end longitude: %.4f\n", data->near_end_lon);
    //printf("Far start latitude: %.4f\n", data->far_start_lat);
    //printf("Far start longitude: %.4f\n", data->far_start_lon);
    //printf("Far end latitude: %.4f\n", data->far_end_lat);
    //printf("Far end longitude: %.4f\n", data->far_end_lon);
  }
  xmlFreeDoc(xmlBoundary);

  xmlDoc *xmlCenter = xmlReadFile(centerFile, NULL, 0);
  if (!xmlCenter)
    asfPrintWarning("Could not parse center point file (%s)\n", centerFile);
  else {
    strcpy(coordStr, xml_get_string_value(xmlCenter, 
      "kml.Document.Placemark.Point.coordinates"));
    sscanf(coordStr, "%f,%f", &data->center_lat, &data->center_lon);
    //printf("Center latitude: %.4f\n", data->center_lat);
    //printf("Center longitude: %.4f\n", data->center_lon);
  }
  xmlFreeDoc(xmlCenter);

  // Processing level
  strcpy(string, xml_get_string_value(doc, 
    "metadata.idinfo.proclevl.prolevid"));
  if (strlen(string) > MAX_PROCESSING_LEVEL) {
    error = TRUE;
    sprintf(tmp, 
	    "Processing level - String length: %d, allowed characters: %d\n",
	    (int) strlen(string), MAX_PROCESSING_LEVEL);
    strcat(errorMessage, tmp);
  }
  else {
    strcpy(data->processing_level, xml_get_string_value(doc, 
      "metadata.idinfo.proclevl.prolevid"));
    //printf("Processing level: %s\n", data->processing_level);
  }

  // Place
  strcpy(string, xml_get_string_value(doc, 
    "metadata.idinfo.keywords.place.placekey[0]"));
  if (strlen(string) > MAX_PLACE) {
    error = TRUE;
    sprintf(tmp, 
	    "Place - String length: %d, allowed characters: %d\n",
	    (int) strlen(string), MAX_PLACE);
    strcat(errorMessage, tmp);
  }
  else {
    data->place = (char *) MALLOC(sizeof(char)*MAX_PLACE);
    strcpy(data->place, xml_get_string_value(doc, 
      "metadata.idinfo.keywords.place.placekey[0]"));
    //printf("Place: %s\n", data->place);
  }

  // Platform
  strcpy(string, xml_get_string_value(doc, 
    "metadata.idinfo.plainsid.platflnm"));
  if (strlen(string) > MAX_PLATFORM) {
    error = TRUE;
    sprintf(tmp, "Platform - String length: %d, allowed characters: %d\n",
	    (int) strlen(string), MAX_PLATFORM);
    strcat(errorMessage, tmp);
  }
  else {
    strcpy(data->platform, xml_get_string_value(doc, 
      "metadata.idinfo.plainsid.platflnm"));
    //printf("Platform: %s\n", data->platform);
  }

  // Instrument
  strcpy(string, xml_get_string_value(doc, 
    "metadata.idinfo.plainsid.instflnm"));
  if (strlen(string) > MAX_INSTRUMENT) {
    error = TRUE;
    sprintf(tmp, "Instrument - String length: %d, allowed characters: %d\n",
	    (int) strlen(string), MAX_INSTRUMENT);
    strcat(errorMessage, tmp);
  }
  else {
    strcpy(data->instrument, xml_get_string_value(doc, 
      "metadata.idinfo.plainsid.instflnm"));
    //printf("Instrument: %s\n", data->instrument);
  }

  // Number of bands
  nValue = xml_get_int_value(doc, "metadata.idinfo.bandidnt.numbands");
  if (nValue < 0) {
    error = TRUE;
    sprintf(tmp, "Number of bands - Value (%i) outside the "
	    "expected value range (value > 0)\n", nValue);
    strcat(errorMessage, tmp);
  }
  else {
    data->band_count =
      xml_get_int_value(doc, "metadata.idinfo.bandidnt.numbands");
    //printf("Number of bands: %i\n", data->band_count);
  }

  // Browse image location
  strcpy(string, xml_get_string_value(doc, "metadata.idinfo.browse.browsen"));
  if (strlen(string) > MAX_BROWSE_LOCATION) {
    error = TRUE;
    sprintf(tmp, "Browse image location - String length: %d, allowed "
	    "characters: %d\n", (int) strlen(string), MAX_BROWSE_LOCATION);
    strcat(errorMessage, tmp);
  }
  else if (strcmp_case(string, MAGIC_UNSET_STRING) != 0) {
    data->browse_location = (char *) MALLOC(sizeof(char)*MAX_BROWSE_LOCATION);
    strcpy(data->browse_location, xml_get_string_value(doc, 
      "metadata.idinfo.browse.browsen"));
    //printf("Browse image location: %s\n", data->browse_location);
  }

  // Browse image format
  strcpy(string, xml_get_string_value(doc, "metadata.idinfo.browse.browset"));
  if (strlen(string) > MAX_BROWSE_FORMAT) {
    error = TRUE;
    sprintf(tmp, "Browse image format - String length: %d, allowed characters:"
	    " %d\n", (int) strlen(string), MAX_BROWSE_FORMAT);
    strcat(errorMessage, tmp);
  }
  else if (strcmp_case(string, MAGIC_UNSET_STRING) != 0) {
    data->browse_format = (char *) MALLOC(sizeof(char)*MAX_BROWSE_FORMAT);
    strcpy(data->browse_format, xml_get_string_value(doc, 
      "metadata.idinfo.browse.browset"));
    //printf("Browse format: %s\n", data->browse_format);
  }

  // Data access level
  strcpy(string, xml_get_string_value(doc, 
    "metadata.idinfo.secinfo.secclass"));
  if (strlen(string) > MAX_ACCESS) {
    error = TRUE;
    sprintf(tmp, "Data access level - String length: %d, allowed characters: "
	    "%d\n", (int) strlen(string), MAX_ACCESS);
    strcat(errorMessage, tmp);
  }
  else {
    strcpy(data->access, xml_get_string_value(doc, 
      "metadata.idinfo.secinfo.secclass"));
    //printf("Data access level: %s\n", data->access);
  }

  // Copyright
  strcpy(string, xml_get_string_value(doc, "metadata.idinfo.copyright"));
  if (strlen(string) > MAX_COPYRIGHT) {
    error = TRUE;
    sprintf(tmp, "Copyright - String length: %d, allowed characters: %d\n",
	    (int) strlen(string), MAX_COPYRIGHT);
    strcat(errorMessage, tmp);
  }
  else {
    strcpy(data->copyright, xml_get_string_value(doc, 
      "metadata.idinfo.copyright"));
    //printf("Copyright: %s\n", data->copyright);
  }

  // Start time
  char dateStr[25], timeStr[25], *message;
  int year, month, day, hour, minute, second;
  strcpy(dateStr, xml_get_string_value(doc, 
    "metadata.idinfo.timeperd.timeinfo.rngdates.begdate"));
  year = subStr(0, 4, dateStr);
  month = subStr(4, 2, dateStr);
  day = subStr(6, 2, dateStr);
  strcpy(timeStr, xml_get_string_value(doc, 
    "metadata.idinfo.timeperd.timeinfo.rngdates.begtime"));
  hour = subStr(0, 2, timeStr);
  minute = subStr(2, 2, timeStr);
  second = subStr(4, 2, timeStr);
  if (strcmp_case(dateStr, MAGIC_UNSET_STRING) != 0 &&
      strcmp_case(timeStr, MAGIC_UNSET_STRING) != 0) {
    if (isNumeric(dateStr) && isNumeric(timeStr)) {
      message = checkTime(year, month, day, hour, minute, second);
      if (message) {
	error = TRUE;
	sprintf(tmp, "Start time - %s", message);
	strcat(errorMessage, tmp);
      }
      else {
	data->start_time = (char *) MALLOC(sizeof(char)*MAX_START_TIME);
	sprintf(data->start_time, "%04d-%02d-%02d %02d:%02d:%02d", 
		year, month, day, hour, minute, second);
	//printf("Start time: %s\n", data->start_time);
      }
    }
  }

  // Center time
  strcpy(dateStr, xml_get_string_value(doc, 
    "metadata.idinfo.timeperd.timeinfo.sngdate.caldate"));
  year = subStr(0, 4, dateStr);
  month = subStr(4, 2, dateStr);
  day = subStr(6, 2, dateStr);
  strcpy(timeStr, xml_get_string_value(doc, 
    "metadata.idinfo.timeperd.timeinfo.sngdate.time"));
  hour = subStr(0, 2, timeStr);
  minute = subStr(2, 2, timeStr);
  second = subStr(4, 2, timeStr);
  if (strcmp_case(dateStr, MAGIC_UNSET_STRING) != 0 &&
      strcmp_case(timeStr, MAGIC_UNSET_STRING) != 0) {
    if (isNumeric(dateStr) && isNumeric(timeStr)) {
      message = checkTime(year, month, day, hour, minute, second);
      if (message) {
	error = TRUE;
	sprintf(tmp, "Center time - %s", message);
	strcat(errorMessage, tmp);
      }
      else {
	data->center_time = (char *) MALLOC(sizeof(char)*MAX_CENTER_TIME);
	sprintf(data->center_time, "%04d-%02d-%02d %02d:%02d:%02d", 
		year, month, day, hour, minute, second);
	//printf("Center time: %s\n", data->center_time);
      }
    }
  }

  // End time
  strcpy(dateStr, xml_get_string_value(doc, 
    "metadata.idinfo.timeperd.timeinfo.rngdates.enddate"));
  year = subStr(0, 4, dateStr);
  month = subStr(4, 2, dateStr);
  day = subStr(6, 2, dateStr);
  strcpy(timeStr, xml_get_string_value(doc, 
    "metadata.idinfo.timeperd.timeinfo.rngdates.endtime"));
  hour = subStr(0, 2, timeStr);
  minute = subStr(2, 2, timeStr);
  second = subStr(4, 2, timeStr);
  if (strcmp_case(dateStr, MAGIC_UNSET_STRING) != 0 &&
      strcmp_case(timeStr, MAGIC_UNSET_STRING) != 0) {
    if (isNumeric(dateStr) && isNumeric(timeStr)) {
      message = checkTime(year, month, day, hour, minute, second);
      if (message) {
	error = TRUE;
	sprintf(tmp, "End time - %s", message);
	strcat(errorMessage, tmp);
      }
      else {
	data->end_time = (char *) MALLOC(sizeof(char)*MAX_END_TIME);
	sprintf(data->end_time, "%04d-%02d-%02d %02d:%02d:%02d", 
		year, month, day, hour, minute, second);
	//printf("End time: %s\n", data->end_time);
      }
    }
  }

  // Orbit direction
  nValue = xml_get_int_value(doc, "metadata.dataqual.acqinfo.ascdscin");
  if (nValue != MAGIC_UNSET_INT) {
    if (nValue < 0 || nValue > 1) {
      error = TRUE;
      sprintf(tmp, "Orbit direction - Value (%i) outside the "
	      "expected value range (0 <= value <= 1)\n", nValue);
      strcat(errorMessage, tmp);
    }
    else {
      if (nValue == 0)
	strcpy(data->orbit_direction, "Ascending");
      else if (nValue == 1)
	strcpy(data->orbit_direction, "Descending");
      //printf("Orbit direction: %s\n", data->orbit_direction);
    }
  }
  else
    strcpy(data->orbit_direction, "Unknown");

  // Imaging mode
  strcpy(string, xml_get_string_value(doc, "metadata.idinfo.plainsid.mode"));
  if (strcmp_case(string, MAGIC_UNSET_STRING) != 0) {
    if (strlen(string) > MAX_MODE) {
      error = TRUE;
      sprintf(tmp, "Imaging mode - String length: %d, allowed characters: %d"
	      "\n", (int) strlen(string), MAX_MODE);
      strcat(errorMessage, tmp);
    }
    else {
      strcpy(data->mode, 
	     xml_get_string_value(doc, "metadata.idinfo.plainsid.mode"));
      //printf("Imaging mode: %s\n", data->mode);
    }
  }
  else
    strcpy(data->mode, "Unknown");

  // Spatial reference
  strcpy(string, xml_get_string_value(doc, "metadata.spdoinfo.direct"));
  if (strcmp_case(string, "Point") !=  0 &&
      strcmp_case(string, "Vector") != 0 &&
      strcmp_case(string, "Raster") != 0) {
    error = TRUE;
    sprintf(tmp, "Spatial reference - String (%s) not valid; expected "
	    "\"Point\", \"Vector\" or \"Raster\"\n", string);
    strcat(errorMessage, tmp);
  }
  else {
    strcpy(data->spatial_reference, 
	   xml_get_string_value(doc, "metadata.spdoinfo.direct"));
    //printf("Spatial reference: %s\n", data->spatial_reference);
  }

  // Cell value type
  strcpy(string, xml_get_string_value(doc, 
    "metadata.spdoinfo.rastinfo.cvaltype"));
  if (strlen(string) > MAX_CELL_VALUE) {
    error = TRUE;
    sprintf(tmp, 
	    "Cell value type - String length: %d, allowed characters: %d\n",
	    (int) strlen(string), MAX_CELL_VALUE);
    strcat(errorMessage, tmp);
  }
  else {
    strcpy(data->cell_value, xml_get_string_value(doc, 
      "metadata.spdoinfo.rastinfo.cvaltype"));
    //printf("Cell value type: %s\n", data->cell_value);
  }

  // Raster object type
  strcpy(string, xml_get_string_value(doc, 
    "metadata.spdoinfo.rastinfo.rasttype"));
  if (strcmp_case(string, "Point") != 0 &&
      strcmp_case(string, "Pixel") != 0 &&
      strcmp_case(string, "Grid Cell") != 0 &&
      strcmp_case(string, "Voxel") != 0 &&
      strcmp_case(string, "Swath") != 0) {
    error = TRUE;
    sprintf(tmp, "Raster object type - String (%s) not valid; expected "
	    "\"Point\", \"Pixel\", \"Grid Cell\", \"Voxel\" or \"Swath\".\n",
	    string);
    strcat(errorMessage, tmp);
  }
  else {
    strcpy(data->raster_object, xml_get_string_value(doc, 
      "metadata.spdoinfo.rastinfo.rasttype"));
    //printf("Raster object type: %s\n", data->raster_object);
  }

  // Number of rows
  nValue = xml_get_int_value(doc, "metadata.spdoinfo.rastinfo.rowcount");
  if (nValue < 0) {
    error = TRUE;
    sprintf(tmp, "Number of rows - Value (%i) outside the "
	    "expected value range (value > 0)\n", nValue);
    strcat(errorMessage, tmp);
  }
  else {
    data->row_count =
      xml_get_int_value(doc, "metadata.spdoinfo.rastinfo.rowcount");
    //printf("Number of rows: %i\n", data->row_count);
  }

  // Number of columns
  nValue = xml_get_int_value(doc, "metadata.spdoinfo.rastinfo.colcount");
  if (nValue < 0) {
    error = TRUE;
    sprintf(tmp, "Number of columns - Value (%i) outside the "
	    "expected value range (value > 0)\n", nValue);
    strcat(errorMessage, tmp);
  }
  else {
    data->col_count =
      xml_get_int_value(doc, "metadata.spdoinfo.rastinfo.colcount");
    //printf("Number of columns: %i\n", data->col_count);
  }

  // Format name
  strcpy(string, xml_get_string_value(doc, 
    "metadata.distinfo.stdorder.digform.digtinfo.formname"));
  if (strlen(string) > MAX_FORMAT) {
    error = TRUE;
    sprintf(tmp, 
	    "Format name - String length: %d, allowed characters: %d\n",
	    (int) strlen(string), MAX_FORMAT);
    strcat(errorMessage, tmp);
  }
  else {
    strcpy(data->format, xml_get_string_value(doc, 
      "metadata.distinfo.stdorder.digform.digtinfo.formname"));
    //printf("Format name: %s\n", data->format);
  }

  // Fees
  fValue = xml_get_double_value(doc, "metadata.distinfo.stdorder.fees");
  if (fValue < 0.0) {
    error = TRUE;
    sprintf(tmp, "Fees - Value (%.2lf) outside the expected value range "
	    "(value >= 0.0)\n", fValue);
    strcat(errorMessage, tmp);
  }
  else {
    data->fees = xml_get_double_value(doc, "metadata.distinfo.stdorder.fees");
    //printf("Fees: %.2lf\n", data->fees);
  }

  if (error)
    asfPrintError("%s", errorMessage);

  xmlFreeDoc(doc);
  xmlCleanupParser();

  FREE(configFile);
  FCLOSE(fLog);
  remove(logFile);

  // Add dataset to database
  addData(data);

  FREE(data);

  asfPrintStatus("\nSuccessful completion!\n\n");

  return(EXIT_SUCCESS);
}