package org.esa.beam.dataio.smos; import com.bc.ceres.binio.CompoundMember; import com.bc.ceres.binio.CompoundType; import com.bc.ceres.binio.DataContext; import com.bc.ceres.binio.SequenceData; import com.bc.ceres.glevel.MultiLevelImage; import com.bc.ceres.glevel.MultiLevelSource; import com.bc.ceres.glevel.support.DefaultMultiLevelImage; import org.esa.beam.dataio.smos.dddb.BandDescriptor; import org.esa.beam.dataio.smos.dddb.Dddb; import org.esa.beam.dataio.smos.dddb.Family; import org.esa.beam.framework.datamodel.Band; import org.esa.beam.framework.datamodel.Product; import org.esa.beam.smos.EEFilePair; import org.esa.beam.smos.dgg.SmosDgg; import org.esa.beam.util.io.FileUtils; import java.awt.*; import java.awt.geom.Area; import java.awt.geom.Rectangle2D; import java.io.IOException; class GlobalSmosFile extends ExplorerFile { private final SequenceData[] zones; protected GlobalSmosFile(EEFilePair eeFilePair, DataContext dataContext) throws IOException { super(eeFilePair, dataContext); final SequenceData zoneSequence = getDataBlock().getSequence(0); zones = new SequenceData[zoneSequence.getElementCount()]; for (int i = 0; i < zones.length; i++) { zones[i] = zoneSequence.getCompound(i).getSequence(1); } } @Override public final Area getArea() { return new Area(new Rectangle2D.Double(-180.0, -90.0, 360.0, 180.0)); } @Override public Product createProduct() throws IOException { final String productName = FileUtils.getFilenameWithoutExtension(getDataFile()); final String productType = getProductType(); final Dimension dimension = ProductHelper.getSceneRasterDimension(); final Product product = new Product(productName, productType, dimension.width, dimension.height); product.setFileLocation(getDataFile()); product.setPreferredTileSize(512, 512); ProductHelper.addMetadata(product.getMetadataRoot(), this); product.setGeoCoding(ProductHelper.createGeoCoding(dimension)); final CompoundType compoundType = (CompoundType) zones[0].getType().getElementType(); final Family<BandDescriptor> descriptors = Dddb.getInstance().getBandDescriptors(getDataFormat().getName()); if (descriptors != null) { for (final BandDescriptor descriptor : descriptors.asList()) { addBand(product, descriptor, compoundType); } } return product; } private void addBand(Product product, BandDescriptor descriptor, CompoundType compoundType) { if (!descriptor.isVisible()) { return; } final int memberIndex = compoundType.getMemberIndex(descriptor.getMemberName()); if (memberIndex >= 0) { final CompoundMember member = compoundType.getMember(memberIndex); final int dataType = ProductHelper.getDataType(member.getType()); final Band band = product.addBand(descriptor.getBandName(), dataType); band.setScalingOffset(descriptor.getScalingOffset()); band.setScalingFactor(descriptor.getScalingFactor()); if (descriptor.hasFillValue()) { band.setNoDataValueUsed(true); band.setNoDataValue(descriptor.getFillValue()); } if (!descriptor.getValidPixelExpression().isEmpty()) { band.setValidPixelExpression(descriptor.getValidPixelExpression()); } if (!descriptor.getUnit().isEmpty()) { band.setUnit(descriptor.getUnit()); } if (!descriptor.getDescription().isEmpty()) { band.setDescription(descriptor.getDescription()); } if (descriptor.getFlagDescriptors() != null) { ProductHelper.addFlagsAndMasks(product, band, descriptor.getFlagCodingName(), descriptor.getFlagDescriptors()); } final ValueProvider valueProvider = createValueProvider(descriptor); band.setSourceImage(createSourceImage(band, valueProvider)); band.setImageInfo(ProductHelper.createImageInfo(band, descriptor)); } } private ValueProvider createValueProvider(final BandDescriptor descriptor) { return new ValueProvider() { @Override public final Area getArea() { return GlobalSmosFile.this.getArea(); } @Override public final byte getValue(int seqnum, byte noDataValue) { final int zoneIndex = SmosDgg.seqnumToZoneId(seqnum) - 1; final int gridIndex = SmosDgg.seqnumToSeqnumInZone(seqnum) - 1; try { return zones[zoneIndex].getCompound(gridIndex).getByte(descriptor.getMemberName()); } catch (IOException e) { return noDataValue; } } @Override public final short getValue(int seqnum, short noDataValue) { final int zoneIndex = SmosDgg.seqnumToZoneId(seqnum) - 1; final int gridIndex = SmosDgg.seqnumToSeqnumInZone(seqnum) - 1; try { return zones[zoneIndex].getCompound(gridIndex).getShort(descriptor.getMemberName()); } catch (IOException e) { return noDataValue; } } @Override public final int getValue(int seqnum, int noDataValue) { final int zoneIndex = SmosDgg.seqnumToZoneId(seqnum) - 1; final int gridIndex = SmosDgg.seqnumToSeqnumInZone(seqnum) - 1; try { return zones[zoneIndex].getCompound(gridIndex).getInt(descriptor.getMemberName()); } catch (IOException e) { return noDataValue; } } @Override public final float getValue(int gridPointId, float noDataValue) { final int zoneIndex = SmosDgg.seqnumToZoneId(gridPointId) - 1; final int gridIndex = SmosDgg.seqnumToSeqnumInZone(gridPointId) - 1; try { return zones[zoneIndex].getCompound(gridIndex).getFloat(descriptor.getMemberName()); } catch (IOException e) { return noDataValue; } } }; } private MultiLevelImage createSourceImage(final Band band, final ValueProvider valueProvider) { return new DefaultMultiLevelImage(createMultiLevelSource(band, valueProvider)); } private MultiLevelSource createMultiLevelSource(Band band, ValueProvider valueProvider) { return new SmosMultiLevelSource(band, valueProvider); } }