/*
* 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.io;
import java.awt.Rectangle;
import java.awt.geom.AffineTransform;
import java.awt.image.Raster;
import java.awt.image.RenderedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.spi.IIORegistry;
import javax.imageio.spi.ImageReaderSpi;
import javax.xml.bind.JAXBException;
import org.opengis.geometry.Envelope;
import org.opengis.coverage.grid.GridEnvelope;
import org.opengis.metadata.spatial.PixelOrientation;
import org.opengis.metadata.Metadata;
import org.opengis.metadata.identification.Resolution;
import org.opengis.metadata.identification.Identification;
import org.opengis.metadata.identification.DataIdentification;
import org.junit.*;
import org.apache.sis.test.DependsOn;
import org.geotoolkit.test.TestData;
import org.geotoolkit.test.image.ImageTestBase;
import org.apache.sis.geometry.Envelope2D;
import org.geotoolkit.coverage.grid.GridGeometry2D;
import org.geotoolkit.coverage.grid.GridCoverage2D;
import org.geotoolkit.image.io.plugin.TextMatrixImageReader;
import org.geotoolkit.image.io.plugin.TextMatrixImageReaderTest;
import org.geotoolkit.image.io.plugin.WorldFileImageReader;
import org.geotoolkit.image.io.plugin.WorldFileImageReaderTest;
import org.geotoolkit.image.SampleModels;
import org.apache.sis.xml.XML;
import static org.apache.sis.test.Assert.*;
import static org.apache.sis.test.TestUtilities.getSingleton;
/**
* Tests {@link ImageCoverageReader}. This test will read the {@code "matrix.txt"} file
* defined in the {@code org/geotoolkit/image/io/plugin/test-data} directory because it
* is the easiest one to debug.
*
* @author Martin Desruisseaux (Geomatys)
* @version 3.18
*
* @since 3.09
*/
@DependsOn({TextMatrixImageReaderTest.class, WorldFileImageReaderTest.class})
public final strictfp class ImageCoverageReaderTest extends ImageTestBase {
/**
* Small number for comparison of floating point values.
*/
private static final float EPS = 1E-9f;
/**
* Creates a new test suite.
*/
public ImageCoverageReaderTest() {
super(ImageCoverageReader.class);
}
/**
* Registers a "matrix" reader forced to the US format.
*/
@BeforeClass
public static void registerReaderUS() {
final IIORegistry registry = IIORegistry.getDefaultInstance();
final ImageReaderSpi spi = new TextMatrixImageReaderTest.Spi();
final ImageReaderSpi old = registry.getServiceProviderByClass(TextMatrixImageReader.Spi.class);
assertTrue(registry.registerServiceProvider(spi, ImageReaderSpi.class));
assertTrue(registry.setOrdering(ImageReaderSpi.class, spi, old));
WorldFileImageReader.Spi.registerDefaults(registry);
}
/**
* Deregisters the reader defined by {@link #registerReaderUS()}.
*/
@AfterClass
public static void deregisterReaderUS() {
final IIORegistry registry = IIORegistry.getDefaultInstance();
final ImageReaderSpi spi= registry.getServiceProviderByClass(TextMatrixImageReaderTest.Spi.class);
assertTrue(registry.deregisterServiceProvider(spi, ImageReaderSpi.class));
WorldFileImageReader.Spi.unregisterDefaults(registry);
}
/**
* Tests the reading of ISO 19115 metadata. This also tests indirectly the reading of stream
* and image metadata. Note that correct metadata are required for correct working of read
* operations.
*
* @throws IOException If the text file can not be open (should not happen).
* @throws CoverageStoreException Should not happen.
* @throws JAXBException If the metadata can not be marshalled to XML (should not happen).
*
* @since 3.18
*/
@Test
@Ignore("Need to be revisited during the migration to Apache SIS.")
public void testMetadata() throws IOException, CoverageStoreException, JAXBException {
final ImageCoverageReaderInspector reader = new ImageCoverageReaderInspector("readFull");
reader.setInput(TestData.file(TextMatrixImageReaderTest.class, "matrix.txt"));
assertEquals(WorldFileImageReader.class, reader.imageReader.getClass());
final Metadata metadata = reader.getMetadata();
final Identification identification = getSingleton(metadata.getIdentificationInfo());
final Resolution resolution = getSingleton(((DataIdentification) identification).getSpatialResolutions());
assertEquals(Double.valueOf(1000), resolution.getDistance());
final String xml = XML.marshal(metadata);
assertFalse("Nothing to write.", xml.isEmpty());
assertXmlEquals(TestData.url(ImageCoverageReaderTest.class, "MatrixMetadata.xml"),
xml, 0.0001, null, new String[] {"xmlns:*", "xsi:schemaLocation"});
}
/**
* Reads the full image.
*
* @throws IOException If the text file can not be open (should not happen).
* @throws CoverageStoreException Should not happen.
*/
@Test
public void readFull() throws IOException, CoverageStoreException {
final ImageCoverageReaderInspector reader = new ImageCoverageReaderInspector("readFull");
reader.setInput(TestData.file(TextMatrixImageReaderTest.class, "matrix.txt"));
assertEquals(WorldFileImageReader.class, reader.imageReader.getClass());
/*
* Check the grid geometry before to attempt to read the image.
*/
final GridGeometry2D gridGeometry = reader.getGridGeometry(0);
final GridEnvelope gridEnvelope = gridGeometry.getExtent();
assertEquals("Grid dimension", 2, gridEnvelope.getDimension());
assertEquals("Image columns", 0, gridEnvelope.getLow(0));
assertEquals("Image rows", 0, gridEnvelope.getLow(1));
assertEquals("Image columns", 19, gridEnvelope.getHigh(0)); // Inclusive
assertEquals("Image rows", 41, gridEnvelope.getHigh(1)); // Inclusive
assertTrue("Image bounds", new Rectangle(20,42).equals(gridGeometry.getExtent2D()));
assertTrue("Grid to CRS (Java2D)", new AffineTransform(1000, 0, 0, -1000, -10000, 21000)
.equals(gridGeometry.getGridToCRS(PixelOrientation.UPPER_LEFT)));
assertTrue("Grid to CRS (OGC)", new AffineTransform(1000, 0, 0, -1000, -9500, 20500)
.equals(gridGeometry.getGridToCRS())); // Equivalent to PixelOrientation.CENTER
/*
* Read the image and check again its grid geometry, this time directly on the
* rendered image. The grid geometry should be equivalent to the one checked above.
*/
final GridCoverage2D gridCoverage = reader.read(0, null);
if (out != null) {
out.println(reader);
}
assertTrue("No transformation expected.", reader.getReadMatchesRequest());
final RenderedImage image = gridCoverage.getRenderedImage();
assertEquals("Image columns", 0, image.getMinX());
assertEquals("Image rows", 0, image.getMinY());
assertEquals("Image columns", 20, image.getWidth());
assertEquals("Image rows", 42, image.getHeight());
assertEquals("Grid geometry", gridGeometry, gridCoverage.getGridGeometry());
/*
* Check the envelope, which should be the envelope of the full coverage.
*/
final Envelope envelope = gridCoverage.getEnvelope();
assertEquals("Envelope X", -10000, envelope.getMinimum(0), EPS);
assertEquals("Envelope Y", -21000, envelope.getMinimum(1), EPS);
assertEquals("Envelope X", 10000, envelope.getMaximum(0), EPS);
assertEquals("Envelope Y", 21000, envelope.getMaximum(1), EPS);
/*
* Check a few values. This is a convenient way to ensure that
* the right portion of the image has been read.
*/
final Raster raster = image.getData();
assertEquals(-1.123f, raster.getSampleFloat( 0, 0, 0), EPS);
assertEquals(-1.251f, raster.getSampleFloat(19, 0, 0), EPS);
assertEquals(-1.075f, raster.getSampleFloat( 0, 41, 0), EPS);
assertEquals(Float.NaN, raster.getSampleFloat(19, 41, 0), EPS);
reader.dispose();
}
/**
* Reads a region of the image.
*
* @throws IOException If the text file can not be open (should not happen).
* @throws CoverageStoreException Should not happen.
*/
@Test
public void readRegion() throws IOException, CoverageStoreException {
final ImageCoverageReaderInspector reader = new ImageCoverageReaderInspector("readRegion");
reader.setInput(TestData.file(TextMatrixImageReaderTest.class, "matrix.txt"));
assertEquals(WorldFileImageReader.class, reader.imageReader.getClass());
/*
* Read the image and check its grid geometry directly on the rendered image.
*/
final GridCoverageReadParam param = new GridCoverageReadParam();
param.setEnvelope(new Envelope2D(null, -1000, -2000, 8000 - -1000, 12000 - -2000));
final GridCoverage2D gridCoverage = reader.read(0, param);
if (out != null) {
out.println(reader);
}
assertTrue("No transformation expected.", reader.getReadMatchesRequest());
final RenderedImage image = gridCoverage.getRenderedImage();
assertEquals("Image columns", 0, image.getMinX());
assertEquals("Image rows", 0, image.getMinY());
assertEquals("Image columns", 9, image.getWidth());
assertEquals("Image rows", 14, image.getHeight());
/*
* Check the envelope, which should be the same than the requested one
* (in this particular test case, since the reader does not have to clip
* the envelope or snap to grid coordinates).
*/
final Envelope envelope = gridCoverage.getEnvelope();
assertEquals("Envelope X", -1000, envelope.getMinimum(0), EPS);
assertEquals("Envelope Y", -2000, envelope.getMinimum(1), EPS);
assertEquals("Envelope X", 8000, envelope.getMaximum(0), EPS);
assertEquals("Envelope Y", 12000, envelope.getMaximum(1), EPS);
/*
* Check a few values. This is a convenient way to ensure that
* the right portion of the image has been read.
*/
final Raster raster = image.getData();
assertEquals(12.783f, raster.getSampleFloat(0, 0, 0), EPS);
assertEquals(Float.NaN, raster.getSampleFloat(8, 0, 0), EPS);
assertEquals(26.769f, raster.getSampleFloat(0, 13, 0), EPS);
assertEquals(27.949f, raster.getSampleFloat(8, 13, 0), EPS);
reader.dispose();
}
/**
* Reads the same region than above, with a subsampling.
*
* @throws IOException If the text file can not be open (should not happen).
* @throws CoverageStoreException Should not happen.
*/
@Test
public void readSubsampledRegion() throws IOException, CoverageStoreException {
final ImageCoverageReaderInspector reader = new ImageCoverageReaderInspector("readSubsampledRegion");
reader.setInput(TestData.file(TextMatrixImageReaderTest.class, "matrix.txt"));
assertEquals(WorldFileImageReader.class, reader.imageReader.getClass());
/*
* Read the image and check its grid geometry directly on the rendered image.
*/
final GridCoverageReadParam param = new GridCoverageReadParam();
param.setEnvelope(new Envelope2D(null, -1000, -2000, 8000 - -1000, 12000 - -2000));
param.setResolution(2000, 3000);
final GridCoverage2D gridCoverage = reader.read(0, param);
if (out != null) {
out.println(reader);
}
assertTrue("No transformation expected.", reader.getReadMatchesRequest());
final RenderedImage image = gridCoverage.getRenderedImage();
assertEquals("Image columns", 0, image.getMinX());
assertEquals("Image rows", 0, image.getMinY());
assertEquals("Image columns", 5, image.getWidth());
assertEquals("Image rows", 5, image.getHeight());
/*
* Check the envelope, which should be sightly bigger than the requested one in
* order to contains fully the requested envelope, taking subsampling on account.
*/
final Envelope envelope = gridCoverage.getEnvelope();
assertEquals("Envelope X", -1000, envelope.getMinimum(0), EPS);
assertEquals("Envelope Y", -3000, envelope.getMinimum(1), EPS);
assertEquals("Envelope X", 9000, envelope.getMaximum(0), EPS);
assertEquals("Envelope Y", 12000, envelope.getMaximum(1), EPS);
/*
* Check a few values. This is a convenient way to ensure that
* the right portion of the image has been read.
*/
final Raster raster = image.getData();
assertEquals(12.783f, raster.getSampleFloat(0, 0, 0), EPS);
assertEquals(Float.NaN, raster.getSampleFloat(4, 0, 0), EPS);
assertEquals(25.454f, raster.getSampleFloat(0, 4, 0), EPS);
assertEquals(28.902f, raster.getSampleFloat(4, 4, 0), EPS);
reader.dispose();
}
/**
* Reads an image twice, asking for different parts. The purpose of this test is to ensure
* that {@link ImageReader} are properly used (with the right input set) when recycled. For
* this test, we need an image reader which doesn't accept {@link File} object directly.
*
* @throws IOException If the text file can not be open (should not happen).
* @throws CoverageStoreException Should not happen.
*/
@Test
public void readTwice() throws IOException, CoverageStoreException {
final ImageCoverageReaderInspector reader = new ImageCoverageReaderInspector("readTwice");
final File file = TestData.file(SampleModels.class, "Contour.png");
reader.setInput(file);
assertNotNull(reader.read(0, null));
if (out != null) {
out.println(reader);
}
reader.reset();
reader.setInput(file);
assertNotNull(reader.read(0, null));
if (out != null) {
out.println(reader);
}
reader.dispose();
}
}