Example #1
0
  private MetadataElement getProcessingGraphMetadata() {
    final MetadataElement processingGraphMetadata = globalMetadata.asMetadataElement();

    final MetadataElement node_0 = processingGraphMetadata.getElement("node.0");
    node_0.addElement(metadataAggregator.getMetadata());
    return processingGraphMetadata;
  }
  private void addNoiseAbstractedMetadata(final MetadataElement origProdRoot) throws IOException {

    MetadataElement noiseElement = origProdRoot.getElement("noise");
    if (noiseElement == null) {
      noiseElement = new MetadataElement("noise");
      origProdRoot.addElement(noiseElement);
    }
    final String calibFolder = getRootFolder() + "annotation" + '/' + "calibration";
    final String[] filenames = listFiles(calibFolder);

    if (filenames != null) {
      for (String metadataFile : filenames) {
        if (metadataFile.startsWith("noise")) {

          final Document xmlDoc =
              XMLSupport.LoadXML(getInputStream(calibFolder + '/' + metadataFile));
          final Element rootElement = xmlDoc.getRootElement();
          final String name = metadataFile.replace("noise-", "");
          final MetadataElement nameElem = new MetadataElement(name);
          noiseElement.addElement(nameElem);
          AbstractMetadataIO.AddXMLMetadata(rootElement, nameElem);
        }
      }
    }
  }
  @Override
  public Product createProduct() throws IOException {

    final MetadataElement newRoot = addMetaData();
    findImages();

    final MetadataElement absRoot = newRoot.getElement(AbstractMetadata.ABSTRACT_METADATA_ROOT);
    determineProductDimensions(absRoot);

    final int sceneWidth = absRoot.getAttributeInt(AbstractMetadata.num_samples_per_line);
    final int sceneHeight = absRoot.getAttributeInt(AbstractMetadata.num_output_lines);

    final Product product =
        new Product(getProductName(), getProductType(), sceneWidth, sceneHeight);
    updateProduct(product, newRoot);

    addBands(product);
    addGeoCoding(product);

    product.setName(getProductName());
    // product.setProductType(getProductType());
    product.setDescription(getProductDescription());

    ReaderUtils.addMetadataProductSize(product);

    return product;
  }
 private static MetadataElement findElementContaining(
     final MetadataElement parent,
     final String elemName,
     final String attribName,
     final String attValue) {
   final MetadataElement[] elems = parent.getElements();
   for (MetadataElement elem : elems) {
     if (elem.getName().equalsIgnoreCase(elemName) && elem.containsAttribute(attribName)) {
       String value = elem.getAttributeString(attribName);
       if (value != null && value.equalsIgnoreCase(attValue)) return elem;
     }
   }
   return null;
 }
  @Override
  protected void addAbstractedMetadataHeader(final MetadataElement root) throws IOException {

    final MetadataElement absRoot = AbstractMetadata.addAbstractedMetadataHeader(root);
    final MetadataElement origProdRoot = AbstractMetadata.addOriginalProductMetadata(root);

    addManifestMetadata(getProductName(), absRoot, origProdRoot, false);
    acqMode = absRoot.getAttributeString(AbstractMetadata.ACQUISITION_MODE);
    setSLC(absRoot.getAttributeString(AbstractMetadata.SAMPLE_TYPE).equals("COMPLEX"));

    // get metadata for each band
    addBandAbstractedMetadata(absRoot, origProdRoot);
    addCalibrationAbstractedMetadata(origProdRoot);
    addNoiseAbstractedMetadata(origProdRoot);
  }
  public static ProductData.UTC getTime(final MetadataElement elem, final String tag) {

    String start = elem.getAttributeString(tag, AbstractMetadata.NO_METADATA_STRING);
    start = start.replace("T", "_");

    return AbstractMetadata.parseUTC(start, Sentinel1Constants.sentinelDateFormat);
  }
  private static void addOrbitStateVectors(
      final MetadataElement absRoot, final MetadataElement orbitList) {
    final MetadataElement orbitVectorListElem =
        absRoot.getElement(AbstractMetadata.orbit_state_vectors);

    final MetadataElement[] stateVectorElems = orbitList.getElements();
    for (int i = 1; i <= stateVectorElems.length; ++i) {
      addVector(AbstractMetadata.orbit_vector, orbitVectorListElem, stateVectorElems[i - 1], i);
    }

    // set state vector time
    if (absRoot
        .getAttributeUTC(AbstractMetadata.STATE_VECTOR_TIME, AbstractMetadata.NO_METADATA_UTC)
        .equalElems(AbstractMetadata.NO_METADATA_UTC)) {

      AbstractMetadata.setAttribute(
          absRoot,
          AbstractMetadata.STATE_VECTOR_TIME,
          ReaderUtils.getTime(stateVectorElems[0], "time", standardDateFormat));
    }
  }
  private void determineProductDimensions(final MetadataElement absRoot) throws IOException {
    int totalWidth = 0, maxHeight = 0, k = 0;
    String pol = null;
    for (Map.Entry<String, ImageIOFile> stringImageIOFileEntry : bandImageFileMap.entrySet()) {
      final ImageIOFile img = stringImageIOFileEntry.getValue();
      final String imgName = img.getName().toLowerCase();
      final String bandMetadataName = imgBandMetadataMap.get(imgName);
      if (bandMetadataName == null) {
        throw new IOException("Metadata for measurement dataset " + imgName + " not found");
      }

      if (k == 0) {
        pol = bandMetadataName.substring(bandMetadataName.lastIndexOf("_") + 1);
      } else if (!bandMetadataName.substring(bandMetadataName.lastIndexOf("_") + 1).equals(pol)) {
        continue;
      }
      k++;

      final MetadataElement bandMetadata = absRoot.getElement(bandMetadataName);
      int width = bandMetadata.getAttributeInt(AbstractMetadata.num_samples_per_line);
      int height = bandMetadata.getAttributeInt(AbstractMetadata.num_output_lines);
      totalWidth += width;
      if (height > maxHeight) {
        maxHeight = height;
      }
    }

    if (isSLC() && isTOPSAR()) { // approximate does not account for overlap
      absRoot.setAttributeInt(AbstractMetadata.num_samples_per_line, totalWidth);
      absRoot.setAttributeInt(AbstractMetadata.num_output_lines, maxHeight);
    }
  }
  private double getBandTerrainHeight(final MetadataElement prodElem) {
    final MetadataElement generalAnnotation = prodElem.getElement("generalAnnotation");
    final MetadataElement terrainHeightList = generalAnnotation.getElement("terrainHeightList");

    double heightSum = 0.0;

    final MetadataElement[] heightList = terrainHeightList.getElements();
    int cnt = 0;
    for (MetadataElement terrainHeight : heightList) {
      heightSum += terrainHeight.getAttributeDouble("value");
      ++cnt;
    }
    return heightSum / cnt;
  }
  private static void addVector(
      final String name,
      final MetadataElement orbitVectorListElem,
      final MetadataElement orbitElem,
      final int num) {
    final MetadataElement orbitVectorElem = new MetadataElement(name + num);

    final MetadataElement positionElem = orbitElem.getElement("position");
    final MetadataElement velocityElem = orbitElem.getElement("velocity");

    orbitVectorElem.setAttributeUTC(
        AbstractMetadata.orbit_vector_time,
        ReaderUtils.getTime(orbitElem, "time", standardDateFormat));

    orbitVectorElem.setAttributeDouble(
        AbstractMetadata.orbit_vector_x_pos, positionElem.getAttributeDouble("x", 0));
    orbitVectorElem.setAttributeDouble(
        AbstractMetadata.orbit_vector_y_pos, positionElem.getAttributeDouble("y", 0));
    orbitVectorElem.setAttributeDouble(
        AbstractMetadata.orbit_vector_z_pos, positionElem.getAttributeDouble("z", 0));
    orbitVectorElem.setAttributeDouble(
        AbstractMetadata.orbit_vector_x_vel, velocityElem.getAttributeDouble("x", 0));
    orbitVectorElem.setAttributeDouble(
        AbstractMetadata.orbit_vector_y_vel, velocityElem.getAttributeDouble("y", 0));
    orbitVectorElem.setAttributeDouble(
        AbstractMetadata.orbit_vector_z_vel, velocityElem.getAttributeDouble("z", 0));

    orbitVectorListElem.addElement(orbitVectorElem);
  }
 private static MetadataElement findElement(final MetadataElement elem, final String name) {
   final MetadataElement metadataWrap = elem.getElement("metadataWrap");
   final MetadataElement xmlData = metadataWrap.getElement("xmlData");
   return xmlData.getElement(name);
 }
  @Override
  protected void addGeoCoding(final Product product) {

    TiePointGrid latGrid = product.getTiePointGrid(OperatorUtils.TPG_LATITUDE);
    TiePointGrid lonGrid = product.getTiePointGrid(OperatorUtils.TPG_LONGITUDE);
    if (latGrid != null && lonGrid != null) {
      setLatLongMetadata(product, latGrid, lonGrid);

      final TiePointGeoCoding tpGeoCoding = new TiePointGeoCoding(latGrid, lonGrid, Datum.WGS_84);
      product.setGeoCoding(tpGeoCoding);
      return;
    }

    final MetadataElement absRoot = AbstractMetadata.getAbstractedMetadata(product);
    final String acquisitionMode = absRoot.getAttributeString(AbstractMetadata.ACQUISITION_MODE);
    int numOfSubSwath;
    switch (acquisitionMode) {
      case "IW":
        numOfSubSwath = 3;
        break;
      case "EW":
        numOfSubSwath = 5;
        break;
      default:
        return;
    }

    String[] bandNames = product.getBandNames();
    Band firstSWBand = null, lastSWBand = null;
    boolean firstSWBandFound = false, lastSWBandFound = false;
    for (String bandName : bandNames) {
      if (!firstSWBandFound && bandName.contains(acquisitionMode + 1)) {
        firstSWBand = product.getBand(bandName);
        firstSWBandFound = true;
      }

      if (!lastSWBandFound && bandName.contains(acquisitionMode + numOfSubSwath)) {
        lastSWBand = product.getBand(bandName);
        lastSWBandFound = true;
      }
    }
    if (firstSWBand == null && lastSWBand == null) return;

    final GeoCoding firstSWBandGeoCoding = bandGeocodingMap.get(firstSWBand);
    final int firstSWBandHeight = firstSWBand.getRasterHeight();

    final GeoCoding lastSWBandGeoCoding = bandGeocodingMap.get(lastSWBand);
    final int lastSWBandWidth = lastSWBand.getRasterWidth();
    final int lastSWBandHeight = lastSWBand.getRasterHeight();

    final PixelPos ulPix = new PixelPos(0, 0);
    final PixelPos llPix = new PixelPos(0, firstSWBandHeight - 1);
    final GeoPos ulGeo = new GeoPos();
    final GeoPos llGeo = new GeoPos();
    firstSWBandGeoCoding.getGeoPos(ulPix, ulGeo);
    firstSWBandGeoCoding.getGeoPos(llPix, llGeo);

    final PixelPos urPix = new PixelPos(lastSWBandWidth - 1, 0);
    final PixelPos lrPix = new PixelPos(lastSWBandWidth - 1, lastSWBandHeight - 1);
    final GeoPos urGeo = new GeoPos();
    final GeoPos lrGeo = new GeoPos();
    lastSWBandGeoCoding.getGeoPos(urPix, urGeo);
    lastSWBandGeoCoding.getGeoPos(lrPix, lrGeo);

    final float[] latCorners = {
      (float) ulGeo.getLat(), (float) urGeo.getLat(), (float) llGeo.getLat(), (float) lrGeo.getLat()
    };
    final float[] lonCorners = {
      (float) ulGeo.getLon(), (float) urGeo.getLon(), (float) llGeo.getLon(), (float) lrGeo.getLon()
    };

    ReaderUtils.addGeoCoding(product, latCorners, lonCorners);

    AbstractMetadata.setAttribute(absRoot, AbstractMetadata.first_near_lat, ulGeo.getLat());
    AbstractMetadata.setAttribute(absRoot, AbstractMetadata.first_near_long, ulGeo.getLon());
    AbstractMetadata.setAttribute(absRoot, AbstractMetadata.first_far_lat, urGeo.getLat());
    AbstractMetadata.setAttribute(absRoot, AbstractMetadata.first_far_long, urGeo.getLon());

    AbstractMetadata.setAttribute(absRoot, AbstractMetadata.last_near_lat, llGeo.getLat());
    AbstractMetadata.setAttribute(absRoot, AbstractMetadata.last_near_long, llGeo.getLon());
    AbstractMetadata.setAttribute(absRoot, AbstractMetadata.last_far_lat, lrGeo.getLat());
    AbstractMetadata.setAttribute(absRoot, AbstractMetadata.last_far_long, lrGeo.getLon());

    // add band geocoding
    final Band[] bands = product.getBands();
    for (Band band : bands) {
      band.setGeoCoding(bandGeocodingMap.get(band));
    }
  }
  static void addManifestMetadata(
      final String productName,
      final MetadataElement absRoot,
      final MetadataElement origProdRoot,
      boolean isOCN) {
    final String defStr = AbstractMetadata.NO_METADATA_STRING;
    final int defInt = AbstractMetadata.NO_METADATA;

    final MetadataElement XFDU = origProdRoot.getElement("XFDU");
    final MetadataElement informationPackageMap = XFDU.getElement("informationPackageMap");
    final MetadataElement contentUnit = informationPackageMap.getElement("contentUnit");

    AbstractMetadata.setAttribute(absRoot, AbstractMetadata.PRODUCT, productName);
    final String descriptor = contentUnit.getAttributeString("textInfo", defStr);
    AbstractMetadata.setAttribute(absRoot, AbstractMetadata.SPH_DESCRIPTOR, descriptor);
    AbstractMetadata.setAttribute(absRoot, AbstractMetadata.antenna_pointing, "right");

    final MetadataElement metadataSection = XFDU.getElement("metadataSection");
    final MetadataElement[] metadataObjectList = metadataSection.getElements();

    for (MetadataElement metadataObject : metadataObjectList) {
      final String id = metadataObject.getAttributeString("ID", defStr);
      if (id.endsWith("Annotation") || id.endsWith("Schema")) {
        // continue;
      } else if (id.equals("processing")) {
        final MetadataElement processing = findElement(metadataObject, "processing");
        final MetadataElement facility = processing.getElement("facility");
        final MetadataElement software = facility.getElement("software");
        final String org = facility.getAttributeString("organisation");
        final String name = software.getAttributeString("name");
        final String version = software.getAttributeString("version");
        AbstractMetadata.setAttribute(
            absRoot, AbstractMetadata.ProcessingSystemIdentifier, org + ' ' + name + ' ' + version);

        final ProductData.UTC start = getTime(processing, "start");
        AbstractMetadata.setAttribute(absRoot, AbstractMetadata.PROC_TIME, start);
      } else if (id.equals("acquisitionPeriod")) {
        final MetadataElement acquisitionPeriod = findElement(metadataObject, "acquisitionPeriod");
        final ProductData.UTC startTime = getTime(acquisitionPeriod, "startTime");
        final ProductData.UTC stopTime = getTime(acquisitionPeriod, "stopTime");
        AbstractMetadata.setAttribute(absRoot, AbstractMetadata.first_line_time, startTime);
        AbstractMetadata.setAttribute(absRoot, AbstractMetadata.last_line_time, stopTime);

      } else if (id.equals("platform")) {
        final MetadataElement platform = findElement(metadataObject, "platform");
        String missionName = platform.getAttributeString("familyName", "Sentinel-1");
        final String number = platform.getAttributeString("number", defStr);
        if (!missionName.equals("ENVISAT")) missionName += number;
        AbstractMetadata.setAttribute(absRoot, AbstractMetadata.MISSION, missionName);

        final MetadataElement instrument = platform.getElement("instrument");
        AbstractMetadata.setAttribute(
            absRoot, AbstractMetadata.SWATH, instrument.getAttributeString("swath", defStr));
        String acqMode = instrument.getAttributeString("mode", defStr);
        if (acqMode == null || acqMode.equals(defStr)) {
          final MetadataElement extensionElem = instrument.getElement("extension");
          if (extensionElem != null) {
            final MetadataElement instrumentModeElem = extensionElem.getElement("instrumentMode");
            if (instrumentModeElem != null)
              acqMode = instrumentModeElem.getAttributeString("mode", defStr);
          }
        }
        AbstractMetadata.setAttribute(absRoot, AbstractMetadata.ACQUISITION_MODE, acqMode);
      } else if (id.equals("measurementOrbitReference")) {
        final MetadataElement orbitReference = findElement(metadataObject, "orbitReference");
        final MetadataElement orbitNumber =
            findElementContaining(orbitReference, "OrbitNumber", "type", "start");
        final MetadataElement relativeOrbitNumber =
            findElementContaining(orbitReference, "relativeOrbitNumber", "type", "start");
        AbstractMetadata.setAttribute(
            absRoot,
            AbstractMetadata.ABS_ORBIT,
            orbitNumber.getAttributeInt("orbitNumber", defInt));
        AbstractMetadata.setAttribute(
            absRoot,
            AbstractMetadata.REL_ORBIT,
            relativeOrbitNumber.getAttributeInt("relativeOrbitNumber", defInt));
        AbstractMetadata.setAttribute(
            absRoot, AbstractMetadata.CYCLE, orbitReference.getAttributeInt("cycleNumber", defInt));

        String pass = orbitReference.getAttributeString("pass", defStr);
        if (pass.equals(defStr)) {
          final MetadataElement extension = orbitReference.getElement("extension");
          final MetadataElement orbitProperties = extension.getElement("orbitProperties");
          pass = orbitProperties.getAttributeString("pass", defStr);
        }
        AbstractMetadata.setAttribute(absRoot, AbstractMetadata.PASS, pass);
      } else if (id.equals("measurementFrameSet")) {

      } else if (id.equals("generalProductInformation")) {
        MetadataElement generalProductInformation =
            findElement(metadataObject, "generalProductInformation");
        if (generalProductInformation == null)
          generalProductInformation = findElement(metadataObject, "standAloneProductInformation");

        String productType = "unknown";
        if (isOCN) {
          productType = "OCN";
        } else {
          if (generalProductInformation != null)
            productType = generalProductInformation.getAttributeString("productType", defStr);
        }
        AbstractMetadata.setAttribute(absRoot, AbstractMetadata.PRODUCT_TYPE, productType);
        if (productType.contains("SLC")) {
          AbstractMetadata.setAttribute(absRoot, AbstractMetadata.SAMPLE_TYPE, "COMPLEX");
        } else {
          AbstractMetadata.setAttribute(absRoot, AbstractMetadata.SAMPLE_TYPE, "DETECTED");
          AbstractMetadata.setAttribute(absRoot, AbstractMetadata.srgr_flag, 1);
        }
      }
    }
  }
  @Override
  protected void addBands(final Product product) {

    String bandName;
    boolean real = true;
    Band lastRealBand = null;
    String unit;

    final MetadataElement absRoot = AbstractMetadata.getAbstractedMetadata(product);
    for (Map.Entry<String, ImageIOFile> stringImageIOFileEntry : bandImageFileMap.entrySet()) {
      final ImageIOFile img = stringImageIOFileEntry.getValue();
      final String imgName = img.getName().toLowerCase();
      final MetadataElement bandMetadata = absRoot.getElement(imgBandMetadataMap.get(imgName));
      final String swath = bandMetadata.getAttributeString(AbstractMetadata.swath);
      final String pol = bandMetadata.getAttributeString(AbstractMetadata.polarization);
      final int width = bandMetadata.getAttributeInt(AbstractMetadata.num_samples_per_line);
      final int height = bandMetadata.getAttributeInt(AbstractMetadata.num_output_lines);

      String tpgPrefix = "";
      String suffix = pol;
      if (isSLC() && isTOPSAR()) {
        suffix = swath + '_' + pol;
        tpgPrefix = swath;
      }

      int numImages = img.getNumImages();
      if (isSLC()) {
        numImages *= 2; // real + imaginary
      }
      for (int i = 0; i < numImages; ++i) {

        if (isSLC()) {
          for (int b = 0; b < img.getNumBands(); ++b) {
            if (real) {
              bandName = "i" + '_' + suffix;
              unit = Unit.REAL;
            } else {
              bandName = "q" + '_' + suffix;
              unit = Unit.IMAGINARY;
            }

            final Band band = new Band(bandName, ProductData.TYPE_INT16, width, height);
            band.setUnit(unit);

            product.addBand(band);
            bandMap.put(band, new ImageIOFile.BandInfo(band, img, i, b));
            AbstractMetadata.addBandToBandMap(bandMetadata, bandName);

            if (real) {
              lastRealBand = band;
            } else {
              ReaderUtils.createVirtualIntensityBand(product, lastRealBand, band, '_' + suffix);
            }
            real = !real;

            // add tiepointgrids and geocoding for band
            addTiePointGrids(band, imgName, tpgPrefix);

            // reset to null so it doesn't adopt a geocoding from the bands
            product.setGeoCoding(null);
          }
        } else {
          for (int b = 0; b < img.getNumBands(); ++b) {
            bandName = "Amplitude" + '_' + suffix;
            final Band band = new Band(bandName, ProductData.TYPE_INT32, width, height);
            band.setUnit(Unit.AMPLITUDE);

            product.addBand(band);
            bandMap.put(band, new ImageIOFile.BandInfo(band, img, i, b));
            AbstractMetadata.addBandToBandMap(bandMetadata, bandName);

            SARReader.createVirtualIntensityBand(product, band, '_' + suffix);

            // add tiepointgrids and geocoding for band
            addTiePointGrids(band, imgName, tpgPrefix);
          }
        }
      }
    }
  }
  private static void addSRGRCoefficients(
      final MetadataElement absRoot, final MetadataElement coordinateConversion) {
    if (coordinateConversion == null) return;
    final MetadataElement coordinateConversionList =
        coordinateConversion.getElement("coordinateConversionList");
    if (coordinateConversionList == null) return;

    final MetadataElement srgrCoefficientsElem =
        absRoot.getElement(AbstractMetadata.srgr_coefficients);

    int listCnt = 1;
    for (MetadataElement elem : coordinateConversionList.getElements()) {
      final MetadataElement srgrListElem =
          new MetadataElement(AbstractMetadata.srgr_coef_list + '.' + listCnt);
      srgrCoefficientsElem.addElement(srgrListElem);
      ++listCnt;

      final ProductData.UTC utcTime = ReaderUtils.getTime(elem, "azimuthTime", standardDateFormat);
      srgrListElem.setAttributeUTC(AbstractMetadata.srgr_coef_time, utcTime);

      final double grOrigin = elem.getAttributeDouble("gr0", 0);
      AbstractMetadata.addAbstractedAttribute(
          srgrListElem,
          AbstractMetadata.ground_range_origin,
          ProductData.TYPE_FLOAT64,
          "m",
          "Ground Range Origin");
      AbstractMetadata.setAttribute(srgrListElem, AbstractMetadata.ground_range_origin, grOrigin);

      final String coeffStr =
          elem.getElement("grsrCoefficients").getAttributeString("grsrCoefficients", "");
      if (!coeffStr.isEmpty()) {
        final StringTokenizer st = new StringTokenizer(coeffStr);
        int cnt = 1;
        while (st.hasMoreTokens()) {
          final double coefValue = Double.parseDouble(st.nextToken());

          final MetadataElement coefElem =
              new MetadataElement(AbstractMetadata.coefficient + '.' + cnt);
          srgrListElem.addElement(coefElem);
          ++cnt;
          AbstractMetadata.addAbstractedAttribute(
              coefElem,
              AbstractMetadata.srgr_coef,
              ProductData.TYPE_FLOAT64,
              "",
              "SRGR Coefficient");
          AbstractMetadata.setAttribute(coefElem, AbstractMetadata.srgr_coef, coefValue);
        }
      }
    }
  }
  private static void addDopplerCentroidCoefficients(
      final MetadataElement absRoot, final MetadataElement dopplerCentroid) {
    if (dopplerCentroid == null) return;
    final MetadataElement dcEstimateList = dopplerCentroid.getElement("dcEstimateList");
    if (dcEstimateList == null) return;

    final MetadataElement dopplerCentroidCoefficientsElem =
        absRoot.getElement(AbstractMetadata.dop_coefficients);

    int listCnt = 1;
    for (MetadataElement elem : dcEstimateList.getElements()) {
      final MetadataElement dopplerListElem =
          new MetadataElement(AbstractMetadata.dop_coef_list + '.' + listCnt);
      dopplerCentroidCoefficientsElem.addElement(dopplerListElem);
      ++listCnt;

      final ProductData.UTC utcTime = ReaderUtils.getTime(elem, "azimuthTime", standardDateFormat);
      dopplerListElem.setAttributeUTC(AbstractMetadata.dop_coef_time, utcTime);

      final double refTime = elem.getAttributeDouble("t0", 0) * 1e9; // s to ns
      AbstractMetadata.addAbstractedAttribute(
          dopplerListElem,
          AbstractMetadata.slant_range_time,
          ProductData.TYPE_FLOAT64,
          "ns",
          "Slant Range Time");
      AbstractMetadata.setAttribute(dopplerListElem, AbstractMetadata.slant_range_time, refTime);

      final String coeffStr =
          elem.getElement("geometryDcPolynomial").getAttributeString("geometryDcPolynomial", "");
      if (!coeffStr.isEmpty()) {
        final StringTokenizer st = new StringTokenizer(coeffStr);
        int cnt = 1;
        while (st.hasMoreTokens()) {
          final double coefValue = Double.parseDouble(st.nextToken());

          final MetadataElement coefElem =
              new MetadataElement(AbstractMetadata.coefficient + '.' + cnt);
          dopplerListElem.addElement(coefElem);
          ++cnt;
          AbstractMetadata.addAbstractedAttribute(
              coefElem,
              AbstractMetadata.dop_coef,
              ProductData.TYPE_FLOAT64,
              "",
              "Doppler Centroid Coefficient");
          AbstractMetadata.setAttribute(coefElem, AbstractMetadata.dop_coef, coefValue);
        }
      }
    }
  }
  private void addBandAbstractedMetadata(
      final MetadataElement absRoot, final MetadataElement origProdRoot) throws IOException {

    MetadataElement annotationElement = origProdRoot.getElement("annotation");
    if (annotationElement == null) {
      annotationElement = new MetadataElement("annotation");
      origProdRoot.addElement(annotationElement);
    }

    // collect range and azimuth spacing
    double rangeSpacingTotal = 0;
    double azimuthSpacingTotal = 0;
    boolean commonMetadataRetrieved = false;

    double heightSum = 0.0;

    int numBands = 0;
    final String annotFolder = getRootFolder() + "annotation";
    final String[] filenames = listFiles(annotFolder);
    if (filenames != null) {
      for (String metadataFile : filenames) {

        final Document xmlDoc =
            XMLSupport.LoadXML(getInputStream(annotFolder + '/' + metadataFile));
        final Element rootElement = xmlDoc.getRootElement();
        final MetadataElement nameElem = new MetadataElement(metadataFile);
        annotationElement.addElement(nameElem);
        AbstractMetadataIO.AddXMLMetadata(rootElement, nameElem);

        final MetadataElement prodElem = nameElem.getElement("product");
        final MetadataElement adsHeader = prodElem.getElement("adsHeader");

        final String swath = adsHeader.getAttributeString("swath");
        final String pol = adsHeader.getAttributeString("polarisation");

        final ProductData.UTC startTime = getTime(adsHeader, "startTime");
        final ProductData.UTC stopTime = getTime(adsHeader, "stopTime");

        final String bandRootName = AbstractMetadata.BAND_PREFIX + swath + '_' + pol;
        final MetadataElement bandAbsRoot =
            AbstractMetadata.addBandAbstractedMetadata(absRoot, bandRootName);
        final String imgName = FileUtils.exchangeExtension(metadataFile, ".tiff");
        imgBandMetadataMap.put(imgName, bandRootName);

        AbstractMetadata.setAttribute(bandAbsRoot, AbstractMetadata.SWATH, swath);
        AbstractMetadata.setAttribute(bandAbsRoot, AbstractMetadata.polarization, pol);
        AbstractMetadata.setAttribute(bandAbsRoot, AbstractMetadata.annotation, metadataFile);
        AbstractMetadata.setAttribute(bandAbsRoot, AbstractMetadata.first_line_time, startTime);
        AbstractMetadata.setAttribute(bandAbsRoot, AbstractMetadata.last_line_time, stopTime);

        if (AbstractMetadata.isNoData(absRoot, AbstractMetadata.mds1_tx_rx_polar)) {
          AbstractMetadata.setAttribute(absRoot, AbstractMetadata.mds1_tx_rx_polar, pol);
        } else {
          AbstractMetadata.setAttribute(absRoot, AbstractMetadata.mds2_tx_rx_polar, pol);
        }

        final MetadataElement imageAnnotation = prodElem.getElement("imageAnnotation");
        final MetadataElement imageInformation = imageAnnotation.getElement("imageInformation");

        AbstractMetadata.setAttribute(
            absRoot,
            AbstractMetadata.data_take_id,
            Integer.parseInt(adsHeader.getAttributeString("missionDataTakeId")));
        AbstractMetadata.setAttribute(
            absRoot,
            AbstractMetadata.slice_num,
            Integer.parseInt(imageInformation.getAttributeString("sliceNumber")));

        rangeSpacingTotal += imageInformation.getAttributeDouble("rangePixelSpacing");
        azimuthSpacingTotal += imageInformation.getAttributeDouble("azimuthPixelSpacing");

        AbstractMetadata.setAttribute(
            bandAbsRoot,
            AbstractMetadata.line_time_interval,
            imageInformation.getAttributeDouble("azimuthTimeInterval"));
        AbstractMetadata.setAttribute(
            bandAbsRoot,
            AbstractMetadata.num_samples_per_line,
            imageInformation.getAttributeInt("numberOfSamples"));
        AbstractMetadata.setAttribute(
            bandAbsRoot,
            AbstractMetadata.num_output_lines,
            imageInformation.getAttributeInt("numberOfLines"));
        AbstractMetadata.setAttribute(
            bandAbsRoot,
            AbstractMetadata.sample_type,
            imageInformation.getAttributeString("pixelValue").toUpperCase());

        heightSum += getBandTerrainHeight(prodElem);

        if (!commonMetadataRetrieved) {
          // these should be the same for all swaths
          // set to absRoot

          final MetadataElement generalAnnotation = prodElem.getElement("generalAnnotation");
          final MetadataElement productInformation =
              generalAnnotation.getElement("productInformation");
          final MetadataElement processingInformation =
              imageAnnotation.getElement("processingInformation");
          final MetadataElement swathProcParamsList =
              processingInformation.getElement("swathProcParamsList");
          final MetadataElement swathProcParams = swathProcParamsList.getElement("swathProcParams");
          final MetadataElement rangeProcessing = swathProcParams.getElement("rangeProcessing");
          final MetadataElement azimuthProcessing = swathProcParams.getElement("azimuthProcessing");

          AbstractMetadata.setAttribute(
              absRoot,
              AbstractMetadata.range_sampling_rate,
              productInformation.getAttributeDouble("rangeSamplingRate") / Constants.oneMillion);
          AbstractMetadata.setAttribute(
              absRoot,
              AbstractMetadata.radar_frequency,
              productInformation.getAttributeDouble("radarFrequency") / Constants.oneMillion);
          AbstractMetadata.setAttribute(
              absRoot,
              AbstractMetadata.line_time_interval,
              imageInformation.getAttributeDouble("azimuthTimeInterval"));

          AbstractMetadata.setAttribute(
              absRoot,
              AbstractMetadata.slant_range_to_first_pixel,
              imageInformation.getAttributeDouble("slantRangeTime") * Constants.halfLightSpeed);

          final MetadataElement downlinkInformationList =
              generalAnnotation.getElement("downlinkInformationList");
          final MetadataElement downlinkInformation =
              downlinkInformationList.getElement("downlinkInformation");

          AbstractMetadata.setAttribute(
              absRoot,
              AbstractMetadata.pulse_repetition_frequency,
              downlinkInformation.getAttributeDouble("prf"));

          AbstractMetadata.setAttribute(
              absRoot,
              AbstractMetadata.range_bandwidth,
              rangeProcessing.getAttributeDouble("processingBandwidth") / Constants.oneMillion);
          AbstractMetadata.setAttribute(
              absRoot,
              AbstractMetadata.azimuth_bandwidth,
              azimuthProcessing.getAttributeDouble("processingBandwidth"));

          AbstractMetadata.setAttribute(
              absRoot,
              AbstractMetadata.range_looks,
              rangeProcessing.getAttributeDouble("numberOfLooks"));
          AbstractMetadata.setAttribute(
              absRoot,
              AbstractMetadata.azimuth_looks,
              azimuthProcessing.getAttributeDouble("numberOfLooks"));

          if (!isTOPSAR() || !isSLC()) {
            AbstractMetadata.setAttribute(
                absRoot,
                AbstractMetadata.num_output_lines,
                imageInformation.getAttributeInt("numberOfLines"));
            AbstractMetadata.setAttribute(
                absRoot,
                AbstractMetadata.num_samples_per_line,
                imageInformation.getAttributeInt("numberOfSamples"));
          }

          addOrbitStateVectors(absRoot, generalAnnotation.getElement("orbitList"));
          addSRGRCoefficients(absRoot, prodElem.getElement("coordinateConversion"));
          addDopplerCentroidCoefficients(absRoot, prodElem.getElement("dopplerCentroid"));

          commonMetadataRetrieved = true;
        }

        ++numBands;
      }
    }

    // set average to absRoot
    AbstractMetadata.setAttribute(
        absRoot, AbstractMetadata.range_spacing, rangeSpacingTotal / (double) numBands);
    AbstractMetadata.setAttribute(
        absRoot, AbstractMetadata.azimuth_spacing, azimuthSpacingTotal / (double) numBands);

    AbstractMetadata.setAttribute(
        absRoot, AbstractMetadata.avg_scene_height, heightSum / filenames.length);
  }
  private void addTiePointGrids(final Band band, final String imgXMLName, final String tpgPrefix) {

    // System.out.println("S1L1Dir.addTiePointGrids: band = " + band.getName() + " imgXMLName = " +
    // imgXMLName + " tpgPrefix = " + tpgPrefix);

    final Product product = band.getProduct();
    String pre = "";
    if (!tpgPrefix.isEmpty()) pre = tpgPrefix + '_';

    final TiePointGrid existingLatTPG = product.getTiePointGrid(pre + OperatorUtils.TPG_LATITUDE);
    final TiePointGrid existingLonTPG = product.getTiePointGrid(pre + OperatorUtils.TPG_LONGITUDE);
    if (existingLatTPG != null && existingLonTPG != null) {
      // System.out.println("for band = " + band.getName() + ", use existing TPG");
      // reuse geocoding
      final TiePointGeoCoding tpGeoCoding =
          new TiePointGeoCoding(existingLatTPG, existingLonTPG, Datum.WGS_84);
      band.setGeoCoding(tpGeoCoding);
      return;
    }
    // System.out.println("add new TPG for band = " + band.getName());
    final String annotation = FileUtils.exchangeExtension(imgXMLName, ".xml");
    final MetadataElement origProdRoot = AbstractMetadata.getOriginalProductMetadata(product);
    final MetadataElement annotationElem = origProdRoot.getElement("annotation");
    final MetadataElement imgElem = annotationElem.getElement(annotation);
    final MetadataElement productElem = imgElem.getElement("product");
    final MetadataElement geolocationGrid = productElem.getElement("geolocationGrid");
    final MetadataElement geolocationGridPointList =
        geolocationGrid.getElement("geolocationGridPointList");

    final MetadataElement[] geoGrid = geolocationGridPointList.getElements();

    // System.out.println("geoGrid.length = " + geoGrid.length);

    final double[] latList = new double[geoGrid.length];
    final double[] lngList = new double[geoGrid.length];
    final double[] incidenceAngleList = new double[geoGrid.length];
    final double[] elevAngleList = new double[geoGrid.length];
    final double[] rangeTimeList = new double[geoGrid.length];
    final int[] x = new int[geoGrid.length];
    final int[] y = new int[geoGrid.length];

    // Loop through the list of geolocation grid points, assuming that it represents a row-major
    // rectangular grid.
    int gridWidth = 0, gridHeight = 0;
    int i = 0;
    for (MetadataElement ggPoint : geoGrid) {
      latList[i] = ggPoint.getAttributeDouble("latitude", 0);
      lngList[i] = ggPoint.getAttributeDouble("longitude", 0);
      incidenceAngleList[i] = ggPoint.getAttributeDouble("incidenceAngle", 0);
      elevAngleList[i] = ggPoint.getAttributeDouble("elevationAngle", 0);
      rangeTimeList[i] =
          ggPoint.getAttributeDouble("slantRangeTime", 0) * Constants.oneBillion; // s to ns

      x[i] = (int) ggPoint.getAttributeDouble("pixel", 0);
      y[i] = (int) ggPoint.getAttributeDouble("line", 0);
      if (x[i] == 0) {
        // This means we are at the start of a new line
        if (gridWidth
            == 0) // Here we are implicitly assuming that the pixel horizontal spacing is assumed to
                  // be the same from line to line.
        gridWidth = i;
        ++gridHeight;
      }
      ++i;
    }

    // System.out.println("geoGrid w = " + gridWidth + "; h = " + gridHeight);

    final int newGridWidth = gridWidth;
    final int newGridHeight = gridHeight;
    final float[] newLatList = new float[newGridWidth * newGridHeight];
    final float[] newLonList = new float[newGridWidth * newGridHeight];
    final float[] newIncList = new float[newGridWidth * newGridHeight];
    final float[] newElevList = new float[newGridWidth * newGridHeight];
    final float[] newslrtList = new float[newGridWidth * newGridHeight];
    final int sceneRasterWidth = band.getSceneRasterWidth();
    final int sceneRasterHeight = band.getSceneRasterHeight();
    final double subSamplingX = (double) sceneRasterWidth / (newGridWidth - 1);
    final double subSamplingY = (double) sceneRasterHeight / (newGridHeight - 1);

    getListInEvenlySpacedGrid(
        sceneRasterWidth,
        sceneRasterHeight,
        gridWidth,
        gridHeight,
        x,
        y,
        latList,
        newGridWidth,
        newGridHeight,
        subSamplingX,
        subSamplingY,
        newLatList);

    getListInEvenlySpacedGrid(
        sceneRasterWidth,
        sceneRasterHeight,
        gridWidth,
        gridHeight,
        x,
        y,
        lngList,
        newGridWidth,
        newGridHeight,
        subSamplingX,
        subSamplingY,
        newLonList);

    getListInEvenlySpacedGrid(
        sceneRasterWidth,
        sceneRasterHeight,
        gridWidth,
        gridHeight,
        x,
        y,
        incidenceAngleList,
        newGridWidth,
        newGridHeight,
        subSamplingX,
        subSamplingY,
        newIncList);

    getListInEvenlySpacedGrid(
        sceneRasterWidth,
        sceneRasterHeight,
        gridWidth,
        gridHeight,
        x,
        y,
        elevAngleList,
        newGridWidth,
        newGridHeight,
        subSamplingX,
        subSamplingY,
        newElevList);

    getListInEvenlySpacedGrid(
        sceneRasterWidth,
        sceneRasterHeight,
        gridWidth,
        gridHeight,
        x,
        y,
        rangeTimeList,
        newGridWidth,
        newGridHeight,
        subSamplingX,
        subSamplingY,
        newslrtList);

    TiePointGrid latGrid = product.getTiePointGrid(pre + OperatorUtils.TPG_LATITUDE);
    if (latGrid == null) {
      latGrid =
          new TiePointGrid(
              pre + OperatorUtils.TPG_LATITUDE,
              newGridWidth,
              newGridHeight,
              0.5f,
              0.5f,
              subSamplingX,
              subSamplingY,
              newLatList);
      latGrid.setUnit(Unit.DEGREES);
      product.addTiePointGrid(latGrid);
    }

    TiePointGrid lonGrid = product.getTiePointGrid(pre + OperatorUtils.TPG_LONGITUDE);
    if (lonGrid == null) {
      lonGrid =
          new TiePointGrid(
              pre + OperatorUtils.TPG_LONGITUDE,
              newGridWidth,
              newGridHeight,
              0.5f,
              0.5f,
              subSamplingX,
              subSamplingY,
              newLonList,
              TiePointGrid.DISCONT_AT_180);
      lonGrid.setUnit(Unit.DEGREES);
      product.addTiePointGrid(lonGrid);
    }

    if (product.getTiePointGrid(pre + OperatorUtils.TPG_INCIDENT_ANGLE) == null) {
      final TiePointGrid incidentAngleGrid =
          new TiePointGrid(
              pre + OperatorUtils.TPG_INCIDENT_ANGLE,
              newGridWidth,
              newGridHeight,
              0.5f,
              0.5f,
              subSamplingX,
              subSamplingY,
              newIncList);
      incidentAngleGrid.setUnit(Unit.DEGREES);
      product.addTiePointGrid(incidentAngleGrid);
    }

    if (product.getTiePointGrid(pre + OperatorUtils.TPG_ELEVATION_ANGLE) == null) {
      final TiePointGrid elevAngleGrid =
          new TiePointGrid(
              pre + OperatorUtils.TPG_ELEVATION_ANGLE,
              newGridWidth,
              newGridHeight,
              0.5f,
              0.5f,
              subSamplingX,
              subSamplingY,
              newElevList);
      elevAngleGrid.setUnit(Unit.DEGREES);
      product.addTiePointGrid(elevAngleGrid);
    }

    if (product.getTiePointGrid(pre + OperatorUtils.TPG_SLANT_RANGE_TIME) == null) {
      final TiePointGrid slantRangeGrid =
          new TiePointGrid(
              pre + OperatorUtils.TPG_SLANT_RANGE_TIME,
              newGridWidth,
              newGridHeight,
              0.5f,
              0.5f,
              subSamplingX,
              subSamplingY,
              newslrtList);
      slantRangeGrid.setUnit(Unit.NANOSECONDS);
      product.addTiePointGrid(slantRangeGrid);
    }

    final TiePointGeoCoding tpGeoCoding = new TiePointGeoCoding(latGrid, lonGrid, Datum.WGS_84);
    bandGeocodingMap.put(band, tpGeoCoding);
  }
Example #19
0
  /** Update the metadata in the target product. */
  private void updateTargetProductMetadata() {

    final MetadataElement abs = AbstractMetadata.getAbstractedMetadata(targetProduct);

    abs.getAttribute(AbstractMetadata.abs_calibration_flag).getData().setElemBoolean(true);
  }