/* * Copyright (C) 2010 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.snap.rcp.spectrum; import com.bc.ceres.core.ProgressMonitor; import com.bc.ceres.glevel.MultiLevelModel; import org.esa.snap.core.datamodel.Band; import org.esa.snap.core.datamodel.Placemark; import org.esa.snap.core.image.ImageManager; import org.esa.snap.core.util.Debug; import org.esa.snap.core.util.ProductUtils; import org.esa.snap.core.util.math.IndexValidator; import org.esa.snap.core.util.math.Range; import org.esa.snap.ui.diagram.AbstractDiagramGraph; import java.awt.geom.AffineTransform; import java.awt.geom.Point2D; import java.util.Arrays; import java.util.Comparator; class SpectrumGraph extends AbstractDiagramGraph { private Placemark placemark; private Band[] bands; private double[] energies; private double[] wavelengths; private final Range energyRange; private final Range wavelengthRange; SpectrumGraph(Placemark placemark, Band[] bands) { Debug.assertNotNull(bands); this.placemark = placemark; this.bands = bands; energyRange = new Range(); wavelengthRange = new Range(); setBands(bands); } public Placemark getPlacemark() { return placemark; } @Override public String getXName() { return "Wavelength"; } @Override public String getYName() { return placemark != null ? placemark.getLabel() : "Cursor"; } @Override public int getNumValues() { return bands.length; } @Override public double getXValueAt(int index) { return wavelengths[index]; } @Override public double getYValueAt(int index) { if (energies[index] == bands[index].getGeophysicalNoDataValue()) { return Double.NaN; } return energies[index]; } @Override public double getXMin() { return wavelengthRange.getMin(); } @Override public double getXMax() { return wavelengthRange.getMax(); } @Override public double getYMin() { return energyRange.getMin(); } @Override public double getYMax() { return energyRange.getMax(); } public Band[] getBands() { return bands; } public void setBands(Band[] bands) { Debug.assertNotNull(bands); this.bands = bands.clone(); Arrays.sort(this.bands, new Comparator<Band>() { @Override public int compare(Band band1, Band band2) { final float v = band1.getSpectralWavelength() - band2.getSpectralWavelength(); return v < 0.0F ? -1 : v > 0.0F ? 1 : 0; } }); if (wavelengths == null || wavelengths.length != this.bands.length) { wavelengths = new double[this.bands.length]; } if (energies == null || energies.length != this.bands.length) { energies = new double[this.bands.length]; } for (int i = 0; i < wavelengths.length; i++) { wavelengths[i] = this.bands[i].getSpectralWavelength(); energies[i] = 0.0f; } Range.computeRangeDouble(wavelengths, IndexValidator.TRUE, wavelengthRange, ProgressMonitor.NULL); Range.computeRangeDouble(energies, IndexValidator.TRUE, energyRange, ProgressMonitor.NULL); } public void readValues() { Debug.assertNotNull(bands); for (int i = 0; i < bands.length; i++) { final Band band = bands[i]; if (placemark != null) { // position of placemark is given in image (L0) coordinates // we have to transform them to the current level final MultiLevelModel multiLevelModel = band.getMultiLevelModel(); final AffineTransform i2mTransform = multiLevelModel.getImageToModelTransform(0); final AffineTransform m2iTransform = multiLevelModel.getModelToImageTransform(0); final Point2D modelPixel = i2mTransform.transform(placemark.getPixelPos(), null); final Point2D imagePixel = m2iTransform.transform(modelPixel, null); int pixelX = (int) Math.floor(imagePixel.getX()); int pixelY = (int) Math.floor(imagePixel.getY()); energies[i] = getSample(band, pixelX, pixelY, 0); } } IndexValidator validator = new IndexValidator() { @Override public boolean validateIndex(int index) { return energies[index] != bands[index].getGeophysicalNoDataValue(); } }; Range.computeRangeDouble(energies, validator, energyRange, ProgressMonitor.NULL); // no invalidate() call here, SpectrumDiagram does this } private double getSample(Band band, int pixelX, int pixelY, int level) { return ProductUtils.getGeophysicalSampleAsDouble(band, pixelX, pixelY, level); } @Override public void dispose() { placemark = null; bands = null; energies = null; wavelengths = null; super.dispose(); } }