org.esa.s2tbx.dataio.s2.l1c.L1cMetadataProc.java Source code

Java tutorial

Introduction

Here is the source code for org.esa.s2tbx.dataio.s2.l1c.L1cMetadataProc.java

Source

/*
 * Copyright (C) 2014-2015 CS-SI (foss-contact@thor.si.c-s.fr)
 * Copyright (C) 2013-2015 Brockmann Consult GmbH (info@brockmann-consult.de)
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 3 of the License, or (at your option)
 * any later version.
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, see http://www.gnu.org/licenses/
 */

package org.esa.s2tbx.dataio.s2.l1c;

import https.psd_13_sentinel2_eo_esa_int.dico._1_0.pdgs.dimap.*;
import https.psd_13_sentinel2_eo_esa_int.psd.s2_pdi_level_1c_tile_metadata.Level1C_Tile;
import https.psd_13_sentinel2_eo_esa_int.psd.user_product_level_1c.Level1C_User_Product;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.Transformer;
import org.apache.commons.math3.util.Pair;
import org.esa.s2tbx.dataio.s2.*;
import org.esa.s2tbx.dataio.s2.filepatterns.S2DatastripDirFilename;
import org.esa.s2tbx.dataio.s2.filepatterns.S2DatastripFilename;
import org.esa.s2tbx.dataio.s2.ortho.filepatterns.S2OrthoDatastripFilename;
import org.esa.s2tbx.dataio.s2.ortho.filepatterns.S2OrthoGranuleDirFilename;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.*;

/**
 * @author opicas-p
 */
public class L1cMetadataProc extends S2MetadataProc {

    public static JAXBContext getJaxbContext() throws JAXBException, FileNotFoundException {
        ClassLoader s2c = Level1C_User_Product.class.getClassLoader();
        return JAXBContext.newInstance(S2MetadataType.L1C, s2c);
    }

    private static S2SpectralInformation makeSpectralInformation(S2BandConstants bandConstant,
            S2SpatialResolution resolution) {
        return new S2SpectralInformation(bandConstant.getPhysicalName(), resolution,
                makeSpectralBandImageFileTemplate(bandConstant.getFilenameBandId()),
                "Reflectance in band " + bandConstant.getPhysicalName(), "dl", bandConstant.getBandIndex(),
                bandConstant.getWavelengthMin(), bandConstant.getWavelengthMax(),
                bandConstant.getWavelengthCentral());
    }

    private static String makeSpectralBandImageFileTemplate(String bandFileId) {
        /* Sample :
        MISSION_ID : S2A
        SITECENTRE : MTI_
        CREATIONDATE : 20150813T201603
        ABSOLUTEORBIT : A000734
        TILENUMBER : T32TQR
        RESOLUTION : 10 | 20 | 60
         */
        return String.format(
                "IMG_DATA%s{{MISSION_ID}}_OPER_MSI_L1C_TL_{{SITECENTRE}}_{{CREATIONDATE}}_{{ABSOLUTEORBIT}}_{{TILENUMBER}}_%s.jp2",
                File.separator, bandFileId);
    }

    public static S2Metadata.ProductCharacteristics getProductOrganization(Level1C_User_Product product) {
        S2Metadata.ProductCharacteristics characteristics = new S2Metadata.ProductCharacteristics();
        characteristics
                .setSpacecraft(product.getGeneral_Info().getProduct_Info().getDatatake().getSPACECRAFT_NAME());
        characteristics.setDatasetProductionDate(
                product.getGeneral_Info().getProduct_Info().getDatatake().getDATATAKE_SENSING_START().toString());
        characteristics.setProcessingLevel(
                product.getGeneral_Info().getProduct_Info().getPROCESSING_LEVEL().getValue().value());
        characteristics.setMetaDataLevel(
                product.getGeneral_Info().getProduct_Info().getQuery_Options().getMETADATA_LEVEL());

        List<S2BandInformation> aInfo = new ArrayList<>();
        /*
         * User products do not provide these information
         * so we hardcode them
         *
            
        if (product.getGeneral_Info().getProduct_Image_Characteristics().getSpectral_Information_List() != null) {
        List<A_PRODUCT_INFO_USERL1C.Product_Image_Characteristics.Spectral_Information_List.Spectral_Information> spectralInfoList = product.getGeneral_Info().getProduct_Image_Characteristics().getSpectral_Information_List().getSpectral_Information();
            
        for (A_PRODUCT_INFO_USERL1C.Product_Image_Characteristics.Spectral_Information_List.Spectral_Information sin : spectralInfoList) {
            S2SpectralInformation data = new S2SpectralInformation();
            data.setBandId(Integer.parseInt(sin.getBandId()));
            data.setPhysicalBand(sin.getPhysicalBand().value());
            data.setResolution(S2SpatialResolution.valueOfResolution(sin.getRESOLUTION()));
            
            int size = sin.getSpectral_Response().getVALUES().size();
            data.setSpectralResponseValues(ArrayUtils.toPrimitive(sin.getSpectral_Response().getVALUES().toArray(new Double[size])));
            data.setWavelengthCentral(sin.getWavelength().getCENTRAL().getValue());
            data.setWavelengthMax(sin.getWavelength().getMAX().getValue());
            data.setWavelengthMin(sin.getWavelength().getMIN().getValue());
            
            aInfo.add(data);
        }
        }
        */
        aInfo.add(makeSpectralInformation(S2BandConstants.B1, S2SpatialResolution.R60M));
        aInfo.add(makeSpectralInformation(S2BandConstants.B2, S2SpatialResolution.R10M));
        aInfo.add(makeSpectralInformation(S2BandConstants.B3, S2SpatialResolution.R10M));
        aInfo.add(makeSpectralInformation(S2BandConstants.B4, S2SpatialResolution.R10M));
        aInfo.add(makeSpectralInformation(S2BandConstants.B5, S2SpatialResolution.R20M));
        aInfo.add(makeSpectralInformation(S2BandConstants.B6, S2SpatialResolution.R20M));
        aInfo.add(makeSpectralInformation(S2BandConstants.B7, S2SpatialResolution.R20M));
        aInfo.add(makeSpectralInformation(S2BandConstants.B8, S2SpatialResolution.R10M));
        aInfo.add(makeSpectralInformation(S2BandConstants.B8A, S2SpatialResolution.R20M));
        aInfo.add(makeSpectralInformation(S2BandConstants.B9, S2SpatialResolution.R60M));
        aInfo.add(makeSpectralInformation(S2BandConstants.B10, S2SpatialResolution.R60M));
        aInfo.add(makeSpectralInformation(S2BandConstants.B11, S2SpatialResolution.R20M));
        aInfo.add(makeSpectralInformation(S2BandConstants.B12, S2SpatialResolution.R20M));

        int size = aInfo.size();
        characteristics.setBandInformations(aInfo.toArray(new S2BandInformation[size]));

        return characteristics;
    }

    public static Collection<String> getTiles(Level1C_User_Product product) {
        A_PRODUCT_INFO.Product_Organisation info = product.getGeneral_Info().getProduct_Info()
                .getProduct_Organisation();

        List<A_PRODUCT_INFO.Product_Organisation.Granule_List> aGranuleList = info.getGranule_List();

        Transformer tileSelector;
        tileSelector = o -> {
            A_PRODUCT_INFO.Product_Organisation.Granule_List ali = (A_PRODUCT_INFO.Product_Organisation.Granule_List) o;
            A_PRODUCT_ORGANIZATION.Granules gr = ali.getGranules();
            return gr.getGranuleIdentifier();
        };

        return CollectionUtils.collect(aGranuleList, tileSelector);
    }

    public static S2DatastripFilename getDatastrip(Level1C_User_Product product) {
        A_PRODUCT_INFO.Product_Organisation info = product.getGeneral_Info().getProduct_Info()
                .getProduct_Organisation();
        List<A_PRODUCT_INFO.Product_Organisation.Granule_List> aGranuleList = info.getGranule_List();

        String dataStripMetadataFilenameCandidate = aGranuleList.get(0).getGranules().getDatastripIdentifier();
        S2DatastripDirFilename dirDatastrip = S2DatastripDirFilename.create(dataStripMetadataFilenameCandidate,
                null);

        S2DatastripFilename datastripFilename = null;
        if (dirDatastrip != null) {
            String fileName = dirDatastrip.getFileName(null);

            if (fileName != null) {
                datastripFilename = S2OrthoDatastripFilename.create(fileName);
            }
        }

        return datastripFilename;
    }

    public static S2DatastripDirFilename getDatastripDir(Level1C_User_Product product) {
        A_PRODUCT_INFO.Product_Organisation info = product.getGeneral_Info().getProduct_Info()
                .getProduct_Organisation();
        List<A_PRODUCT_INFO.Product_Organisation.Granule_List> aGranuleList = info.getGranule_List();
        String granule = aGranuleList.get(0).getGranules().getGranuleIdentifier();
        S2OrthoGranuleDirFilename grafile = S2OrthoGranuleDirFilename.create(granule);

        S2DatastripDirFilename datastripDirFilename = null;
        if (grafile != null) {
            String fileCategory = grafile.fileCategory;
            String dataStripMetadataFilenameCandidate = aGranuleList.get(0).getGranules().getDatastripIdentifier();
            datastripDirFilename = S2DatastripDirFilename.create(dataStripMetadataFilenameCandidate, fileCategory);

        }
        return datastripDirFilename;
    }

    public static Map<S2SpatialResolution, L1cMetadata.TileGeometry> getTileGeometries(Level1C_Tile product) {
        A_GEOMETRIC_INFO_TILE info = product.getGeometric_Info();
        A_GEOMETRIC_INFO_TILE.Tile_Geocoding tgeo = info.getTile_Geocoding();

        List<A_TILE_DESCRIPTION.Geoposition> poss = tgeo.getGeoposition();
        List<A_TILE_DESCRIPTION.Size> sizz = tgeo.getSize();

        Map<S2SpatialResolution, L1cMetadata.TileGeometry> resolutions = new HashMap<>();

        for (A_TILE_DESCRIPTION.Geoposition gpos : poss) {
            S2SpatialResolution resolution = S2SpatialResolution.valueOfResolution(gpos.getResolution());
            L1cMetadata.TileGeometry tgeox = new L1cMetadata.TileGeometry();
            tgeox.setUpperLeftX(gpos.getULX());
            tgeox.setUpperLeftY(gpos.getULY());
            tgeox.setxDim(gpos.getXDIM());
            tgeox.setyDim(gpos.getYDIM());
            resolutions.put(resolution, tgeox);
        }

        for (A_TILE_DESCRIPTION.Size asize : sizz) {
            S2SpatialResolution resolution = S2SpatialResolution.valueOfResolution(asize.getResolution());
            L1cMetadata.TileGeometry tgeox = resolutions.get(resolution);
            tgeox.setNumCols(asize.getNCOLS());
            tgeox.setNumRows(asize.getNROWS());
        }

        return resolutions;
    }

    public static L1cMetadata.AnglesGrid getSunGrid(Level1C_Tile product) {
        A_GEOMETRIC_INFO_TILE.Tile_Angles ang = product.getGeometric_Info().getTile_Angles();

        L1cMetadata.AnglesGrid ag = null;
        if (ang != null) {
            A_SUN_INCIDENCE_ANGLE_GRID sun = ang.getSun_Angles_Grid();

            int azrows = sun.getAzimuth().getValues_List().getVALUES().size();
            int azcolumns = sun.getAzimuth().getValues_List().getVALUES().get(0).getValue().size();

            int zenrows = sun.getZenith().getValues_List().getVALUES().size();
            int zencolumns = sun.getZenith().getValues_List().getVALUES().get(0).getValue().size();

            ag = new L1cMetadata.AnglesGrid();
            ag.setAzimuth(new float[azrows][azcolumns]);
            ag.setZenith(new float[zenrows][zencolumns]);

            for (int rowindex = 0; rowindex < azrows; rowindex++) {
                List<Float> azimuths = sun.getAzimuth().getValues_List().getVALUES().get(rowindex).getValue();
                for (int colindex = 0; colindex < azcolumns; colindex++) {
                    ag.getAzimuth()[rowindex][colindex] = azimuths.get(colindex);
                }
            }

            for (int rowindex = 0; rowindex < zenrows; rowindex++) {
                List<Float> zeniths = sun.getZenith().getValues_List().getVALUES().get(rowindex).getValue();
                for (int colindex = 0; colindex < zencolumns; colindex++) {
                    ag.getZenith()[rowindex][colindex] = zeniths.get(colindex);
                }
            }
        }

        return ag;
    }

    public static L1cMetadata.AnglesGrid[] getAnglesGrid(Level1C_Tile product) {
        A_GEOMETRIC_INFO_TILE.Tile_Angles ang = product.getGeometric_Info().getTile_Angles();

        L1cMetadata.AnglesGrid[] darr = null;
        if (ang != null) {
            List<AN_INCIDENCE_ANGLE_GRID> filteredListe = ang.getViewing_Incidence_Angles_Grids();

            Map<Pair<String, String>, AN_INCIDENCE_ANGLE_GRID> theMap = new LinkedHashMap<>();
            for (AN_INCIDENCE_ANGLE_GRID aGrid : filteredListe) {
                theMap.put(new Pair<>(aGrid.getBandId(), aGrid.getDetectorId()), aGrid);
            }

            List<AN_INCIDENCE_ANGLE_GRID> incilist = new ArrayList<>(theMap.values());

            darr = new L1cMetadata.AnglesGrid[incilist.size()];
            for (int index = 0; index < incilist.size(); index++) {
                AN_INCIDENCE_ANGLE_GRID angleGrid = incilist.get(index);

                int azrows2 = angleGrid.getAzimuth().getValues_List().getVALUES().size();
                int azcolumns2 = angleGrid.getAzimuth().getValues_List().getVALUES().get(0).getValue().size();

                int zenrows2 = angleGrid.getZenith().getValues_List().getVALUES().size();
                int zencolumns2 = angleGrid.getZenith().getValues_List().getVALUES().get(0).getValue().size();

                L1cMetadata.AnglesGrid ag2 = new L1cMetadata.AnglesGrid();
                ag2.setAzimuth(new float[azrows2][azcolumns2]);
                ag2.setZenith(new float[zenrows2][zencolumns2]);

                for (int rowindex = 0; rowindex < azrows2; rowindex++) {
                    List<Float> azimuths = angleGrid.getAzimuth().getValues_List().getVALUES().get(rowindex)
                            .getValue();
                    for (int colindex = 0; colindex < azcolumns2; colindex++) {
                        ag2.getAzimuth()[rowindex][colindex] = azimuths.get(colindex);
                    }
                }

                for (int rowindex = 0; rowindex < zenrows2; rowindex++) {
                    List<Float> zeniths = angleGrid.getZenith().getValues_List().getVALUES().get(rowindex)
                            .getValue();
                    for (int colindex = 0; colindex < zencolumns2; colindex++) {
                        ag2.getZenith()[rowindex][colindex] = zeniths.get(colindex);
                    }
                }

                ag2.setBandId(Integer.parseInt(angleGrid.getBandId()));
                ag2.setDetectorId(Integer.parseInt(angleGrid.getDetectorId()));
                darr[index] = ag2;
            }
        }

        return darr;
    }

    public static S2Metadata.MaskFilename[] getMasks(Level1C_Tile aTile, File file) {
        A_QUALITY_INDICATORS_INFO_TILE qualityInfo = aTile.getQuality_Indicators_Info();

        S2Metadata.MaskFilename[] maskFileNamesArray = null;
        if (qualityInfo != null) {
            List<A_MASK_LIST.MASK_FILENAME> masks = aTile.getQuality_Indicators_Info().getPixel_Level_QI()
                    .getMASK_FILENAME();
            List<L1cMetadata.MaskFilename> aMaskList = new ArrayList<>();
            for (A_MASK_LIST.MASK_FILENAME filename : masks) {
                File QIData = new File(file.getParent(), "QI_DATA");
                File GmlData = new File(QIData, filename.getValue());
                aMaskList.add(new L1cMetadata.MaskFilename(filename.getBandId(), filename.getType(), GmlData));
            }

            maskFileNamesArray = aMaskList.toArray(new L1cMetadata.MaskFilename[aMaskList.size()]);
        }
        return maskFileNamesArray;
    }
}