/*
* Geotoolkit.org - An Open Source Java GIS Toolkit
* http://www.geotoolkit.org
*
* (C) 2010-2012, Open Source Geospatial Foundation (OSGeo)
* (C) 2010-2012, Geomatys
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License.
*
* This library 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
* Lesser General Public License for more details.
*/
package org.geotoolkit.coverage.sql;
import java.awt.Dimension;
import java.awt.Rectangle;
import java.io.IOException;
import java.sql.SQLException;
import java.awt.geom.Point2D;
import java.awt.image.RenderedImage;
import java.awt.image.IndexColorModel;
import org.opengis.referencing.crs.ProjectedCRS;
import org.apache.sis.test.DependsOn;
import org.geotoolkit.coverage.GridSampleDimension;
import org.geotoolkit.coverage.grid.GridCoverage2D;
import org.geotoolkit.coverage.grid.ViewType;
import org.geotoolkit.coverage.io.CoverageStoreException;
import org.geotoolkit.internal.sql.table.CatalogTestBase;
import org.apache.sis.referencing.CommonCRS;
import org.geotoolkit.image.color.ScaledColorSpace;
import org.junit.*;
import static org.junit.Assert.*;
/**
* Tests {@link GridCoverageLoader}. This is actually tested indirectly, through calls
* to {@link GridCoverageEntry} methods.
*
* @author Martin Desruisseaux (Geomatys)
* @version 3.15
*
* @since 3.10 (derived from Seagis)
*/
@DependsOn(GridCoverageTableTest.class)
public final strictfp class GridCoverageLoaderTest extends CatalogTestBase {
/**
* Creates a new test suite.
*/
public GridCoverageLoaderTest() {
super(GridCoverageLoader.class);
}
/**
* Tests loading an image of temperature data in WGS84 CRS.
*
* @throws SQLException If the test can't connect to the database.
* @throws IOException If the image can not be read.
* @throws CoverageStoreException If a logical error occurred.
*/
@Test
public void testTemperature2D() throws SQLException, IOException, CoverageStoreException {
final GridCoverageTable table = getDatabase().getTable(GridCoverageTable.class);
table.envelope.clear();
table.envelope.setTimeRange(LayerTableTest.SUB_START_TIME, LayerTableTest.SUB_END_TIME);
table.setLayer(LayerTableTest.TEMPERATURE);
final GridCoverageReference entry = table.getEntry();
requireImageData();
final GridCoverage2D coverage = entry.read(null, null);
assertSame("Coverage shall be cached.", coverage, entry.getCoverage(null));
checkTemperatureCoverage(coverage);
final RenderedImage image = coverage.getRenderedImage();
assertEquals(4096, image.getWidth());
assertEquals(2048, image.getHeight());
table.release();
show(coverage.view(ViewType.RENDERED));
}
/**
* Checks the {@code GridCoverage2D} instance for the temperature sample data.
* Doesn't check the image size, since it depends on the requested envelope.
* <p>
* <b>NOTE:</b> The sample values tested by this method are those of the coverage
* at the {@value LayerTableTest#SAMPLE_TIME} date.
*/
static void checkTemperatureCoverage(final GridCoverage2D coverage) {
assertEqualsApproximatively(CommonCRS.WGS84.normalizedGeographic(), coverage.getCoordinateReferenceSystem2D());
/*
* Check the SampleDimensions.
*/
assertSame("The coverage shall be geophysics.", coverage, coverage.view(ViewType.GEOPHYSICS));
final GridSampleDimension[] bands = coverage.getSampleDimensions();
assertEquals("Expected exactly one band.", 1, bands.length);
final GridSampleDimension band = bands[0];
assertSame("The band shall be geophysics.", band, band.geophysics(true));
SampleDimensionTableTest.checkTemperatureDimension(band.geophysics(false));
/*
* Check the ColorSpace, which should be a special instance for floating point values.
*/
RenderedImage image = coverage.getRenderedImage();
assertTrue("Expected the Geotk ColorSpace for floating point values.",
image.getColorModel().getColorSpace() instanceof ScaledColorSpace);
/*
* Ensure that the rendered view is backed by an appropriate IndexColorModel.
*/
final GridCoverage2D rendered = coverage.view(ViewType.RENDERED);
assertNotSame("Rendered view should not be the same than geophysics.", coverage, rendered);
image = rendered.getRenderedImage();
assertTrue("Rendered view shall use an IndexColorModel.",
image.getColorModel() instanceof IndexColorModel);
final IndexColorModel cm = (IndexColorModel) image.getColorModel();
assertEquals(256, cm.getMapSize());
assertEquals(8, cm.getPixelSize());
/*
* Check the sample values at an an arbitrary position. Note that this is okay to use
* a large tolerance factor since the purpose is not to test the 'evaluate' accuracy,
* but rather to check that "geophysics" and "rendered" views are not confused. The
* actual value vary a bit for image of different resolution or slightly different date.
*/
double[] buffer = null;
final Point2D pos = new Point2D.Double(-10, -20);
double value = (buffer = coverage.evaluate(pos, buffer))[0];
assertEquals("Geophysics value.", 23.7, value, 0.8);
value = (buffer = rendered.evaluate(pos, buffer))[0];
assertEquals("Rendered value.", 178, value, 5);
}
/**
* Tests loading a NetCDF image in Mercator CRS.
*
* @throws SQLException If the test can't connect to the database.
* @throws IOException If the image can not be read.
* @throws CoverageStoreException If a logical error occurred.
*/
@Test
public void testCoriolis() throws SQLException, IOException, CoverageStoreException {
final GridCoverageTable table = getDatabase().getTable(GridCoverageTable.class);
table.envelope.clear();
table.envelope.setVerticalRange(100, 110);
table.setLayer(LayerTableTest.NETCDF);
final GridCoverageReference entry = table.getEntry();
requireImageData();
final GridCoverage2D coverage = entry.read(null, null);
assertSame("Coverage shall be cached.", coverage, entry.getCoverage(null));
checkCoriolisCoverage(coverage);
final RenderedImage image = coverage.getRenderedImage();
assertEquals(720, image.getWidth());
assertEquals(499, image.getHeight());
table.release();
show(coverage.view(ViewType.RENDERED));
}
/**
* Checks the {@code GridCoverage2D} instance for the Coriolis sample data.
* Doesn't check the image size, since it depends on the requested envelope.
* <p>
* <b>NOTE:</b> The sample values tested by this method are those of the coverage
* at the 100 metres depth.
*/
static void checkCoriolisCoverage(final GridCoverage2D coverage) {
assertTrue(coverage.getCoordinateReferenceSystem2D() instanceof ProjectedCRS);
/*
* Check the SampleDimensions.
*/
assertSame("The coverage shall be geophysics.", coverage, coverage.view(ViewType.GEOPHYSICS));
final GridSampleDimension[] bands = coverage.getSampleDimensions();
assertEquals("Expected exactly one band.", 1, bands.length);
final GridSampleDimension band = bands[0];
assertSame("The band shall be geophysics.", band, band.geophysics(true));
/*
* Check the ColorSpace, which should be a special instance for floating point values.
*/
RenderedImage image = coverage.getRenderedImage();
assertTrue("Expected the Geotk ColorSpace for floating point values.",
image.getColorModel().getColorSpace() instanceof ScaledColorSpace);
/*
* Ensure that the rendered view is backed by an appropriate IndexColorModel.
*/
final GridCoverage2D rendered = coverage.view(ViewType.RENDERED);
assertNotSame("Rendered view should not be the same than geophysics.", coverage, rendered);
image = rendered.getRenderedImage();
assertTrue("Rendered view shall use an IndexColorModel.",
image.getColorModel() instanceof IndexColorModel);
final IndexColorModel cm = (IndexColorModel) image.getColorModel();
assertEquals("Color map size", 16, cm.getPixelSize());
assertEquals("Note: if the map size is 65536, it would mean that Geotk failed " +
"to convert signed integer values to unsigned integers.", 43002, cm.getMapSize());
assertEquals("Transparent pixel", 0, cm.getTransparentPixel());
/*
* Check the sample values at an an arbitrary position. Note that this is okay to use
* a large tolerance factor since the purpose is not to test the 'evaluate' accuracy,
* but rather to check that "geophysics" and "rendered" views are not confused. The
* actual value vary a bit for image of different resolution or slightly different date.
*/
double[] buffer = null;
final Point2D pos = new Point2D.Double(-10, -20);
double value = (buffer = coverage.evaluate(pos, buffer))[0];
assertEquals("Geophysics value.", 16.76, value, 0.8);
value = (buffer = rendered.evaluate(pos, buffer))[0];
assertEquals("Rendered value.", 19762, value, 5);
}
/**
* Tests loading a tiled image.
*
* @throws SQLException If the test can't connect to the database.
* @throws IOException If the image can not be read.
* @throws CoverageStoreException If a logical error occurred.
*/
@Test
public void testBluemarble() throws SQLException, IOException, CoverageStoreException {
final GridCoverageTable table = getDatabase().getTable(GridCoverageTable.class);
table.envelope.clear();
table.setLayer(LayerTableTest.BLUEMARBLE);
table.envelope.setHorizontalRange(new Rectangle(-100, -40, 200, 80));
table.envelope.setPreferredImageSize(new Dimension(100, 80));
final GridCoverageReference entry = table.getEntry();
requireImageData();
final GridCoverage2D coverage = entry.read(table.envelope, null);
checkBluemarbleCoverage(coverage);
final RenderedImage image = coverage.getRenderedImage();
// The image should be slightly larger than the requested side because
// MosaicImageReader should have selected a more efficient size.
assertEquals(134, image.getWidth());
assertEquals(107, image.getHeight());
table.release();
show(coverage.view(ViewType.RENDERED));
}
/**
* Checks the {@code GridCoverage2D} instance for the Bluemarble sample data.
* Doesn't check the image size, since it depends on the requested envelope.
*/
static void checkBluemarbleCoverage(final GridCoverage2D coverage) {
assertEqualsApproximatively(CommonCRS.WGS84.normalizedGeographic(), coverage.getCoordinateReferenceSystem2D());
/*
* Check the SampleDimensions.
*/
assertSame("The coverage shall be rendered.", coverage, coverage.view(ViewType.RENDERED));
final GridSampleDimension[] bands = coverage.getSampleDimensions();
assertEquals("Expected RGB bands.", 3, bands.length);
}
/**
* Tests a layer which contain 2 bands.
*
* @throws SQLException If the test can't connect to the database.
* @throws IOException If the image can not be read.
* @throws CoverageStoreException If a logical error occurred.
*/
@Test
public void testMars2D() throws SQLException, IOException, CoverageStoreException {
final GridCoverageTable table = getDatabase().getTable(GridCoverageTable.class);
table.envelope.clear();
table.envelope.setTimeRange(date("2007-05-22 00:24:00"), date("2007-05-22 00:36:00"));
table.setLayer(LayerTableTest.GEOSTROPHIC_CURRENT);
final GridCoverageReference entry = table.getEntry();
requireImageData();
final GridCoverage2D coverage = entry.read(table.envelope, null);
checkMars2DCoverage(coverage);
table.release();
show(coverage.view(ViewType.RENDERED));
}
/**
* Checks the {@code GridCoverage2D} instance for the Mars2D sample data.
* Doesn't check the image size, since it depends on the requested envelope.
*/
static void checkMars2DCoverage(final GridCoverage2D coverage) {
assertEqualsApproximatively(CommonCRS.WGS84.normalizedGeographic(), coverage.getCoordinateReferenceSystem2D());
/*
* Check the SampleDimensions.
*/
assertSame("The coverage shall be geophysics.", coverage, coverage.view(ViewType.GEOPHYSICS));
final GridSampleDimension[] bands = coverage.getSampleDimensions();
assertEquals("Expected 2 bands.", 2, bands.length);
}
}